java.util.prefs
Class AbstractPreferences

java.lang.Object
  extended by java.util.prefs.Preferences
      extended by java.util.prefs.AbstractPreferences

public abstract class AbstractPreferences
extends Preferences

Partial implementation of a Preference node.

Since:
1.4

Field Summary
protected  Object lock
          Object used to lock this preference node.
protected  boolean newNode
          Set to true in the contructor if the node did not exist in the backing store when this preference node object was created.
 
Fields inherited from class java.util.prefs.Preferences
MAX_KEY_LENGTH, MAX_NAME_LENGTH, MAX_VALUE_LENGTH
 
Constructor Summary
protected AbstractPreferences(AbstractPreferences parent, String name)
          Creates a new AbstractPreferences node with the given parent and name.
 
Method Summary
 String absolutePath()
          Returns the absolute path name of this preference node.
 void addNodeChangeListener(NodeChangeListener listener)
          Add a listener which is notified when a sub-node of this node is added or removed.
 void addPreferenceChangeListener(PreferenceChangeListener listener)
          Add a listener which is notified when a value in this node is added, changed, or removed.
protected  AbstractPreferences[] cachedChildren()
          Returns all known unremoved children of this node.
 String[] childrenNames()
          Returns all the direct sub nodes of this preferences node.
protected abstract  String[] childrenNamesSpi()
          Returns the names of the sub nodes of this preference node.
protected abstract  AbstractPreferences childSpi(String name)
          Returns a child note with the given name.
 void clear()
          Removes all entries from this preferences node.
 void exportNode(OutputStream os)
          Export this node, but not its descendants, as XML to the indicated output stream.
 void exportSubtree(OutputStream os)
          Export this node and all its descendants as XML to the indicated output stream.
 void flush()
          Writes all preference changes on this and any subnode that have not yet been written to the backing store.
protected abstract  void flushSpi()
          Writes all entries of this preferences node that have not yet been written to the backing store and possibly creates this node in the backing store, if it does not yet exist.
 String get(String key, String defaultVal)
          Returns the value associated with the key in this preferences node.
 boolean getBoolean(String key, boolean defaultVal)
          Convenience method for getting the given entry as a boolean.
 byte[] getByteArray(String key, byte[] defaultVal)
          Convenience method for getting the given entry as a byte array.
protected  AbstractPreferences getChild(String name)
          Returns the child sub node if it exists in the backing store or null if it does not exist.
 double getDouble(String key, double defaultVal)
          Convenience method for getting the given entry as a double.
 float getFloat(String key, float defaultVal)
          Convenience method for getting the given entry as a float.
 int getInt(String key, int defaultVal)
          Convenience method for getting the given entry as an integer.
 long getLong(String key, long defaultVal)
          Convenience method for getting the given entry as a long.
protected abstract  String getSpi(String key)
          Returns the value associated with the key in this preferences node or null when the key does not exist in this preferences node.
protected  boolean isRemoved()
          Returns true if this node has been removed with the removeNode() method, false otherwise.
 boolean isUserNode()
          Returns true if this node comes from the user preferences tree, false if it comes from the system preferences tree.
 String[] keys()
          Returns an (possibly empty) array with all the keys of the preference entries of this node.
protected abstract  String[] keysSpi()
          Returns an (possibly empty) array with all the keys of the preference entries of this node.
 String name()
          Returns the name of this preferences node.
 Preferences node(String path)
          Returns a sub node of this preferences node if the given path is relative (does not start with a '/') or a sub node of the root if the path is absolute (does start with a '/').
 boolean nodeExists(String path)
          Returns true if the node that the path points to exists in memory or in the backing store.
 Preferences parent()
          Returns the parent preferences node of this node or null if this is the root of the preferences tree.
 void put(String key, String value)
          Sets the value of the given preferences entry for this node.
 void putBoolean(String key, boolean value)
          Convenience method for setting the given entry as a boolean.
 void putByteArray(String key, byte[] value)
          Convenience method for setting the given entry as an array of bytes.
 void putDouble(String key, double value)
          Convenience method for setting the given entry as a double.
 void putFloat(String key, float value)
          Convenience method for setting the given entry as a float.
 void putInt(String key, int value)
          Convenience method for setting the given entry as an integer.
 void putLong(String key, long value)
          Convenience method for setting the given entry as a long.
protected abstract  void putSpi(String key, String value)
          Sets the value of the given preferences entry for this node.
 void remove(String key)
          Removes the preferences entry from this preferences node.
 void removeNode()
          Removes this and all subnodes from the backing store and clears all entries.
 void removeNodeChangeListener(NodeChangeListener listener)
          Remove the indicated node change listener from the list of listeners to notify.
protected abstract  void removeNodeSpi()
          Clears this node from this VM and removes it from the backing store.
 void removePreferenceChangeListener(PreferenceChangeListener listener)
          Remove the indicated preference change listener from the list of listeners to notify.
protected abstract  void removeSpi(String key)
          Removes the given key entry from this preferences node.
 void sync()
          Writes and reads all preference changes to and from this and any subnodes.
protected abstract  void syncSpi()
          Writes all entries of this preferences node that have not yet been written to the backing store and reads any entries that have changed in the backing store but that are not yet visible in this VM.
 String toString()
          Returns the String given by (isUserNode() ?
 
Methods inherited from class java.util.prefs.Preferences
importPreferences, systemNodeForPackage, systemRoot, userNodeForPackage, userRoot
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

lock

protected final Object lock
Object used to lock this preference node. Any thread only locks nodes downwards when it has the lock on the current node. No method should synchronize on the lock of any of its parent nodes while holding the lock on the current node.


newNode

protected boolean newNode
Set to true in the contructor if the node did not exist in the backing store when this preference node object was created. Should be set in the constructor of a subclass. Defaults to false. Used to fire node changed events.

Constructor Detail

AbstractPreferences

protected AbstractPreferences(AbstractPreferences parent,
                              String name)
Creates a new AbstractPreferences node with the given parent and name.

Parameters:
parent - the parent of this node or null when this is the root node
name - the name of this node, can not be null, only 80 characters maximum, must be empty when parent is null and cannot contain any '/' characters
Throws:
IllegalArgumentException - when name is null, greater then 80 characters, not the empty string but parent is null or contains a '/' character
Method Detail

absolutePath

public String absolutePath()
Returns the absolute path name of this preference node. The absolute path name of a node is the path name of its parent node plus a '/' plus its own name. If the node is the root node and has no parent then its path name is "" and its absolute path name is "/".

Specified by:
absolutePath in class Preferences

isUserNode

public boolean isUserNode()
Returns true if this node comes from the user preferences tree, false if it comes from the system preferences tree.

Specified by:
isUserNode in class Preferences

name

public String name()
Returns the name of this preferences node. The name of the node cannot be null, can be mostly 80 characters and cannot contain any '/' characters. The root node has as name "".

Specified by:
name in class Preferences

toString

public String toString()
Returns the String given by (isUserNode() ? "User":"System") + " Preference Node: " + absolutePath()

Specified by:
toString in class Preferences
Returns:
the String representing this Object, which may be null
See Also:
Object.getClass(), Object.hashCode(), Class.getName(), Integer.toHexString(int)

cachedChildren

protected final AbstractPreferences[] cachedChildren()
Returns all known unremoved children of this node.

Returns:
All known unremoved children of this node

childrenNames

public String[] childrenNames()
                       throws BackingStoreException
Returns all the direct sub nodes of this preferences node. Needs access to the backing store to give a meaningfull answer.

This implementation locks this node, checks if the node has not yet been removed and throws an IllegalStateException when it has been. Then it creates a new TreeSet and adds any already cached child nodes names. To get any uncached names it calls childrenNamesSpi() and adds the result to the set. Finally it calls toArray() on the created set. When the call to childrenNamesSpi thows an BackingStoreException this method will not catch that exception but propagate the exception to the caller.

Specified by:
childrenNames in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached
IllegalStateException - when this node has been removed

node

public Preferences node(String path)
Returns a sub node of this preferences node if the given path is relative (does not start with a '/') or a sub node of the root if the path is absolute (does start with a '/').

This method first locks this node and checks if the node has not been removed, if it has been removed it throws an exception. Then if the path is relative (does not start with a '/') it checks if the path is legal (does not end with a '/' and has no consecutive '/' characters). Then it recursively gets a name from the path, gets the child node from the child-cache of this node or calls the childSpi() method to create a new child sub node. This is done recursively on the newly created sub node with the rest of the path till the path is empty. If the path is absolute (starts with a '/') the lock on this node is droped and this method is called on the root of the preferences tree with as argument the complete path minus the first '/'.

Specified by:
node in class Preferences
Throws:
IllegalStateException - if this node has been removed
IllegalArgumentException - if the path contains two or more consecutive '/' characters, ends with a '/' charactor and is not the string "/" (indicating the root node) or any name on the path is more than 80 characters long

nodeExists

public boolean nodeExists(String path)
                   throws BackingStoreException
Returns true if the node that the path points to exists in memory or in the backing store. Otherwise it returns false or an exception is thrown. When this node is removed the only valid parameter is the empty string (indicating this node), the return value in that case will be false.

Specified by:
nodeExists in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached
IllegalStateException - if this node has been removed and the path is not the empty string (indicating this node)
IllegalArgumentException - if the path contains two or more consecutive '/' characters, ends with a '/' charactor and is not the string "/" (indicating the root node) or any name on the path is more then 80 characters long

getChild

protected AbstractPreferences getChild(String name)
                                throws BackingStoreException
Returns the child sub node if it exists in the backing store or null if it does not exist. Called (indirectly) by nodeExists() when a child node name can not be found in the cache.

Gets the lock on this node, calls childrenNamesSpi() to get an array of all (possibly uncached) children and compares the given name with the names in the array. If the name is found in the array childSpi() is called to get an instance, otherwise null is returned.

Throws:
BackingStoreException - when the backing store cannot be reached

isRemoved

protected boolean isRemoved()
Returns true if this node has been removed with the removeNode() method, false otherwise.

Gets the lock on this node and then returns a boolean field set by removeNode methods.


parent

public Preferences parent()
Returns the parent preferences node of this node or null if this is the root of the preferences tree.

Gets the lock on this node, checks that the node has not been removed and returns the parent given to the constructor.

Specified by:
parent in class Preferences
Throws:
IllegalStateException - if this node has been removed

exportNode

public void exportNode(OutputStream os)
                throws BackingStoreException,
                       IOException
Description copied from class: Preferences
Export this node, but not its descendants, as XML to the indicated output stream. The XML will be encoded using UTF-8 and will use a specified document type:
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">

Specified by:
exportNode in class Preferences
Parameters:
os - the output stream to which the XML is sent
Throws:
BackingStoreException - if preference data cannot be read
IOException - if an error occurs while writing the XML

exportSubtree

public void exportSubtree(OutputStream os)
                   throws BackingStoreException,
                          IOException
Description copied from class: Preferences
Export this node and all its descendants as XML to the indicated output stream. The XML will be encoded using UTF-8 and will use a specified document type:
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">

Specified by:
exportSubtree in class Preferences
Parameters:
os - the output stream to which the XML is sent
Throws:
BackingStoreException - if preference data cannot be read
IOException - if an error occurs while writing the XML

keys

public String[] keys()
              throws BackingStoreException
Returns an (possibly empty) array with all the keys of the preference entries of this node.

This method locks this node and checks if the node has not been removed, if it has been removed it throws an exception, then it returns the result of calling keysSpi().

Specified by:
keys in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached
IllegalStateException - if this node has been removed

get

public String get(String key,
                  String defaultVal)
Returns the value associated with the key in this preferences node. If the default value of the key cannot be found in the preferences node entries or something goes wrong with the backing store the supplied default value is returned.

Checks that key is not null and not larger then 80 characters, locks this node, and checks that the node has not been removed. Then it calls keySpi() and returns the result of that method or the given default value if it returned null or throwed an exception.

Specified by:
get in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

getBoolean

public boolean getBoolean(String key,
                          boolean defaultVal)
Convenience method for getting the given entry as a boolean. When the string representation of the requested entry is either "true" or "false" (ignoring case) then that value is returned, otherwise the given default boolean value is returned.

Specified by:
getBoolean in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

getByteArray

public byte[] getByteArray(String key,
                           byte[] defaultVal)
Convenience method for getting the given entry as a byte array. When the string representation of the requested entry is a valid Base64 encoded string (without any other characters, such as newlines) then the decoded Base64 string is returned as byte array, otherwise the given default byte array value is returned.

Specified by:
getByteArray in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

getDouble

public double getDouble(String key,
                        double defaultVal)
Convenience method for getting the given entry as a double. When the string representation of the requested entry can be decoded with Double.parseDouble() then that double is returned, otherwise the given default double value is returned.

Specified by:
getDouble in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

getFloat

public float getFloat(String key,
                      float defaultVal)
Convenience method for getting the given entry as a float. When the string representation of the requested entry can be decoded with Float.parseFloat() then that float is returned, otherwise the given default float value is returned.

Specified by:
getFloat in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

getInt

public int getInt(String key,
                  int defaultVal)
Convenience method for getting the given entry as an integer. When the string representation of the requested entry can be decoded with Integer.parseInt() then that integer is returned, otherwise the given default integer value is returned.

Specified by:
getInt in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

getLong

public long getLong(String key,
                    long defaultVal)
Convenience method for getting the given entry as a long. When the string representation of the requested entry can be decoded with Long.parseLong() then that long is returned, otherwise the given default long value is returned.

Specified by:
getLong in class Preferences
Throws:
IllegalArgumentException - if key is larger then 80 characters
IllegalStateException - if this node has been removed
NullPointerException - if key is null

put

public void put(String key,
                String value)
Sets the value of the given preferences entry for this node. Key and value cannot be null, the key cannot exceed 80 characters and the value cannot exceed 8192 characters.

The result will be immediately visible in this VM, but may not be immediately written to the backing store.

Checks that key and value are valid, locks this node, and checks that the node has not been removed. Then it calls putSpi().

Specified by:
put in class Preferences
Throws:
NullPointerException - if either key or value are null
IllegalArgumentException - if either key or value are to large
IllegalStateException - when this node has been removed

putBoolean

public void putBoolean(String key,
                       boolean value)
Convenience method for setting the given entry as a boolean. The boolean is converted with Boolean.toString(value) and then stored in the preference entry as that string.

Specified by:
putBoolean in class Preferences
Throws:
NullPointerException - if key is null
IllegalArgumentException - if the key length is to large
IllegalStateException - when this node has been removed

putByteArray

public void putByteArray(String key,
                         byte[] value)
Convenience method for setting the given entry as an array of bytes. The byte array is converted to a Base64 encoded string and then stored in the preference entry as that string.

Note that a byte array encoded as a Base64 string will be about 1.3 times larger then the original length of the byte array, which means that the byte array may not be larger about 6 KB.

Specified by:
putByteArray in class Preferences
Throws:
NullPointerException - if either key or value are null
IllegalArgumentException - if either key or value are to large
IllegalStateException - when this node has been removed

putDouble

public void putDouble(String key,
                      double value)
Convenience method for setting the given entry as a double. The double is converted with Double.toString(double) and then stored in the preference entry as that string.

Specified by:
putDouble in class Preferences
Throws:
NullPointerException - if the key is null
IllegalArgumentException - if the key length is to large
IllegalStateException - when this node has been removed

putFloat

public void putFloat(String key,
                     float value)
Convenience method for setting the given entry as a float. The float is converted with Float.toString(float) and then stored in the preference entry as that string.

Specified by:
putFloat in class Preferences
Throws:
NullPointerException - if the key is null
IllegalArgumentException - if the key length is to large
IllegalStateException - when this node has been removed

putInt

public void putInt(String key,
                   int value)
Convenience method for setting the given entry as an integer. The integer is converted with Integer.toString(int) and then stored in the preference entry as that string.

Specified by:
putInt in class Preferences
Throws:
NullPointerException - if the key is null
IllegalArgumentException - if the key length is to large
IllegalStateException - when this node has been removed

putLong

public void putLong(String key,
                    long value)
Convenience method for setting the given entry as a long. The long is converted with Long.toString(long) and then stored in the preference entry as that string.

Specified by:
putLong in class Preferences
Throws:
NullPointerException - if the key is null
IllegalArgumentException - if the key length is to large
IllegalStateException - when this node has been removed

remove

public void remove(String key)
Removes the preferences entry from this preferences node.

The result will be immediately visible in this VM, but may not be immediately written to the backing store.

This implementation checks that the key is not larger then 80 characters, gets the lock of this node, checks that the node has not been removed and calls removeSpi with the given key.

Specified by:
remove in class Preferences
Throws:
NullPointerException - if the key is null
IllegalArgumentException - if the key length is to large
IllegalStateException - when this node has been removed

clear

public void clear()
           throws BackingStoreException
Removes all entries from this preferences node. May need access to the backing store to get and clear all entries.

The result will be immediately visible in this VM, but may not be immediatly written to the backing store.

This implementation locks this node, checks that the node has not been removed and calls keys() to get a complete array of keys for this node. For every key found removeSpi() is called.

Specified by:
clear in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached
IllegalStateException - if this node has been removed

flush

public void flush()
           throws BackingStoreException
Writes all preference changes on this and any subnode that have not yet been written to the backing store. This has no effect on the preference entries in this VM, but it makes sure that all changes are visible to other programs (other VMs might need to call the sync() method to actually see the changes to the backing store.

Locks this node, calls the flushSpi() method, gets all the (cached - already existing in this VM) subnodes and then calls flushSpi() on every subnode with this node unlocked and only that particular subnode locked.

Specified by:
flush in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached

sync

public void sync()
          throws BackingStoreException
Writes and reads all preference changes to and from this and any subnodes. This makes sure that all local changes are written to the backing store and that all changes to the backing store are visible in this preference node (and all subnodes).

Checks that this node is not removed, locks this node, calls the syncSpi() method, gets all the subnodes and then calls syncSpi() on every subnode with this node unlocked and only that particular subnode locked.

Specified by:
sync in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached
IllegalStateException - if this node has been removed

removeNode

public void removeNode()
                throws BackingStoreException
Removes this and all subnodes from the backing store and clears all entries. After removal this instance will not be useable (except for a few methods that don't throw a InvalidStateException), even when a new node with the same path name is created this instance will not be usable again.

Checks that this is not a root node. If not it locks the parent node, then locks this node and checks that the node has not yet been removed. Then it makes sure that all subnodes of this node are in the child cache, by calling childSpi() on any children not yet in the cache. Then for all children it locks the subnode and removes it. After all subnodes have been purged the child cache is cleared, this nodes removed flag is set and any listeners are called. Finally this node is removed from the child cache of the parent node.

Specified by:
removeNode in class Preferences
Throws:
BackingStoreException - when the backing store cannot be reached
IllegalStateException - if this node has already been removed
UnsupportedOperationException - if this is a root node

addNodeChangeListener

public void addNodeChangeListener(NodeChangeListener listener)
Add a listener which is notified when a sub-node of this node is added or removed.

Specified by:
addNodeChangeListener in class Preferences
Parameters:
listener - the listener to add

addPreferenceChangeListener

public void addPreferenceChangeListener(PreferenceChangeListener listener)
Add a listener which is notified when a value in this node is added, changed, or removed.

Specified by:
addPreferenceChangeListener in class Preferences
Parameters:
listener - the listener to add

removeNodeChangeListener

public void removeNodeChangeListener(NodeChangeListener listener)
Remove the indicated node change listener from the list of listeners to notify.

Specified by:
removeNodeChangeListener in class Preferences
Parameters:
listener - the listener to remove

removePreferenceChangeListener

public void removePreferenceChangeListener(PreferenceChangeListener listener)
Remove the indicated preference change listener from the list of listeners to notify.

Specified by:
removePreferenceChangeListener in class Preferences
Parameters:
listener - the listener to remove

childrenNamesSpi

protected abstract String[] childrenNamesSpi()
                                      throws BackingStoreException
Returns the names of the sub nodes of this preference node. This method only has to return any not yet cached child names, but may return all names if that is easier. It must not return null when there are no children, it has to return an empty array in that case. Since this method must consult the backing store to get all the sub node names it may throw a BackingStoreException.

Called by childrenNames() with this node locked.

Throws:
BackingStoreException

childSpi

protected abstract AbstractPreferences childSpi(String name)
Returns a child note with the given name. This method is called by the node() method (indirectly through the getNode() helper method) with this node locked if a sub node with this name does not already exist in the child cache. If the child node did not aleady exist in the backing store the boolean field newNode of the returned node should be set.

Note that this method should even return a non-null child node if the backing store is not available since it may not throw a BackingStoreException.


keysSpi

protected abstract String[] keysSpi()
                             throws BackingStoreException
Returns an (possibly empty) array with all the keys of the preference entries of this node.

Called by keys() with this node locked if this node has not been removed. May throw an exception when the backing store cannot be accessed.

Throws:
BackingStoreException - when the backing store cannot be reached

getSpi

protected abstract String getSpi(String key)
Returns the value associated with the key in this preferences node or null when the key does not exist in this preferences node.

Called by key() with this node locked after checking that key is valid, not null and that the node has not been removed. key() will catch any exceptions that this method throws.


putSpi

protected abstract void putSpi(String key,
                               String value)
Sets the value of the given preferences entry for this node. The implementation is not required to propagate the change to the backing store immediately. It may not throw an exception when it tries to write to the backing store and that operation fails, the failure should be registered so a later invocation of flush() or sync() can signal the failure.

Called by put() with this node locked after checking that key and value are valid and non-null.


removeSpi

protected abstract void removeSpi(String key)
Removes the given key entry from this preferences node. The implementation is not required to propagate the change to the backing store immediately. It may not throw an exception when it tries to write to the backing store and that operation fails, the failure should be registered so a later invocation of flush() or sync() can signal the failure.

Called by remove() with this node locked after checking that the key is valid and non-null.


flushSpi

protected abstract void flushSpi()
                          throws BackingStoreException
Writes all entries of this preferences node that have not yet been written to the backing store and possibly creates this node in the backing store, if it does not yet exist. Should only write changes to this node and not write changes to any subnodes. Note that the node can be already removed in this VM. To check if that is the case the implementation can call isRemoved().

Called (indirectly) by flush() with this node locked.

Throws:
BackingStoreException

syncSpi

protected abstract void syncSpi()
                         throws BackingStoreException
Writes all entries of this preferences node that have not yet been written to the backing store and reads any entries that have changed in the backing store but that are not yet visible in this VM. Should only sync this node and not change any of the subnodes. Note that the node can be already removed in this VM. To check if that is the case the implementation can call isRemoved().

Called (indirectly) by sync() with this node locked.

Throws:
BackingStoreException

removeNodeSpi

protected abstract void removeNodeSpi()
                               throws BackingStoreException
Clears this node from this VM and removes it from the backing store. After this method has been called the node is marked as removed.

Called (indirectly) by removeNode() with this node locked after all the sub nodes of this node have already been removed.

Throws:
BackingStoreException