Author: rwatler
Date: Fri Aug 7 17:57:09 2009
New Revision: 802106
URL: http://svn.apache.org/viewvc?rev=802106&view=rev
Log:
make Java preferences adapters purely transient backed by persistent
preferences implementation: do not use Java's AbstractPreferences
implementation since it locks all preferences in memory by keeping roots,
parents, and children for each node in the preferences hierarchy
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/pom.xml
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/pom.xml
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/pom.xml?rev=802106&r1=802105&r2=802106&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/pom.xml
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/pom.xml
Fri Aug 7 17:57:09 2009
@@ -50,6 +50,10 @@
<groupId>${pom.groupId}</groupId>
<artifactId>jetspeed-rdbms</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>jetspeed-commons</artifactId>
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java?rev=802106&r1=802105&r2=802106&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java
Fri Aug 7 17:57:09 2009
@@ -87,8 +87,8 @@
// which can be disposed at once for all
PreferencesProviderWrapper ppw = new
PreferencesProviderWrapper(preferencesProvider);
preferencesProvider = null;
- userRoot = new PreferencesImpl(null, ppw, "",
PreferencesImpl.USER_NODE_TYPE);
- systemRoot = new PreferencesImpl(null, ppw, "",
PreferencesImpl.SYSTEM_NODE_TYPE);
+ userRoot = new PreferencesImpl(ppw, "/",
PreferencesImpl.USER_NODE_TYPE);
+ systemRoot = new PreferencesImpl(ppw, "/",
PreferencesImpl.SYSTEM_NODE_TYPE);
// set/update the Java Preferences userRoot and systeRoot
PreferencesRootWrapper instances
((Observer)Preferences.userRoot()).update(null, userRoot);
((Observer)Preferences.systemRoot()).update(null, systemRoot);
@@ -103,7 +103,7 @@
{
((Observer) Preferences.userRoot()).update(null, null);
((Observer) Preferences.systemRoot()).update(null, null);
- userRoot.ppw.dispose();
+ userRoot.getProvider().dispose();
userRoot = null;
systemRoot = null;
}
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java?rev=802106&r1=802105&r2=802106&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java
Fri Aug 7 17:57:09 2009
@@ -16,16 +16,16 @@
*/
package org.apache.jetspeed.prefs.impl;
+import java.io.OutputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
-import java.util.prefs.AbstractPreferences;
-import java.util.prefs.BackingStoreException;
+import java.util.prefs.NodeChangeListener;
import java.util.prefs.Preferences;
+import java.util.prefs.PreferenceChangeListener;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.codec.binary.Base64;
import org.apache.jetspeed.prefs.FailedToCreateNodeException;
import org.apache.jetspeed.prefs.NodeAlreadyExistsException;
import org.apache.jetspeed.prefs.NodeDoesNotExistException;
@@ -34,62 +34,181 @@
import org.apache.jetspeed.prefs.om.impl.PropertyImpl;
/**
- * <p>
- * S {...@link Preferences}implementation relying on Jetspeed OJB based
- * persistence plugin.
- * </p>
+ * PreferencesImpl
+ *
+ * transient non-caching implementation relying on Jetspeed OJB based
+ * persistence plugin
*
* @author <a href="mailto:[email protected]">David Le Strat </a>
- * @author <a href="mailto:[email protected]">Ate Douma</a>
+ * @author <a href="mailto:[email protected]">Ate Douma</a>
+ * @author <a href="mailto:[email protected]">Randy Watler</a>
*/
-public class PreferencesImpl extends AbstractPreferences
+public class PreferencesImpl extends Preferences
{
-
/** User <tt>Preferences<tt> node type. */
public static final int USER_NODE_TYPE = 0;
/** System <tt>Preferences</tt> node type. */
public static final int SYSTEM_NODE_TYPE = 1;
- /** Logger. */
- private static final Log log = LogFactory.getLog(PreferencesImpl.class);
-
- PreferencesProviderWrapper ppw;
-
- String nodeName;
-
- int nodeType;
+ private String path;
+ private PreferencesProviderWrapper ppw;
+ private int type;
+ private boolean removed;
/**
- * <p>
- * Constructs a root node in the underlying datastore if they have not yet
- * been created.
- * </p>
- * <p>
- * Logs a warning if the underlying datastore is unavailable.
- * </p>
+ * Construct Java preferences transient view of persistent Jetspeed
+ * preferences that will not be cached.
*
- * @param parent The parent object.
- * @param nodeName The node name.
- * @param nodeType The node type.
+ * @param ppw preferences provider
+ * @param path absolute path
+ * @param type user or system type
*/
- PreferencesImpl(PreferencesImpl parent, PreferencesProviderWrapper ppw,
String nodeName, int nodeType) throws IllegalStateException
+ public PreferencesImpl(PreferencesProviderWrapper ppw, String path, int
type)
{
- super(parent, nodeName);
this.ppw = ppw;
- this.nodeName = nodeName;
- this.nodeType = nodeType;
- // aggressively fetch/create node
+ this.path = path;
+ this.type = type;
+ this.removed = false;
+ // get/create persistent node
getNode();
}
- /**
- * @see java.util.prefs.Preferences#childrenNamesSpi()
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#put(java.lang.String, java.lang.String)
*/
- public String[] childrenNamesSpi() throws BackingStoreException
+ public void put(String key, String value)
{
- Collection nodes = ppw.provider().getChildren(getNode());
-
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // get persistent node and properties
+ Node node = getNode();
+ Collection properties = node.getNodeProperties();
+ // if the property exists, update its value.
+ boolean propFound = false;
+ for (Iterator i = properties.iterator(); i.hasNext();)
+ {
+ Property curProp = (Property) i.next();
+ if ((null != curProp) && (null != curProp.getPropertyName()) &&
curProp.getPropertyName().equals(key))
+ {
+ propFound = true;
+ curProp.setPropertyValue(value);
+ curProp.setModifiedDate(new
Timestamp(System.currentTimeMillis()));
+ break;
+ }
+ }
+ // add new property value
+ if (!propFound)
+ {
+ properties.add(new PropertyImpl(node.getNodeId(), key, value));
+ }
+ // update node
+ ppw.provider().storeNode(node);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#get(java.lang.String, java.lang.String)
+ */
+ public String get(String key, String def)
+ {
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // get persistent node and properties
+ Node node = getNode();
+ Collection properties = node.getNodeProperties();
+ // return value
+ for (Iterator i = properties.iterator(); i.hasNext();)
+ {
+ Property curProp = (Property) i.next();
+ if ((null != curProp) && (null != curProp.getPropertyName()) &&
(curProp.getPropertyName().equals(key)))
+ {
+ return curProp.getPropertyValue();
+ }
+ }
+ return def;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#remove(java.lang.String)
+ */
+ public void remove(String key)
+ {
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // get persistent node and properties
+ Node node = getNode();
+ Collection properties = node.getNodeProperties();
+ // remove property if found
+ boolean removed = false;
+ for (Iterator i = properties.iterator(); i.hasNext();)
+ {
+ Property curProp = (Property) i.next();
+ if ((curProp.getPropertyName().equals(key)))
+ {
+ i.remove();
+ removed = true;
+ break;
+ }
+ }
+ // update node if removed
+ if (removed)
+ {
+ ppw.provider().storeNode(node);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#keys()
+ */
+ public String[] keys()
+ {
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // get persistent node and properties
+ Node node = getNode();
+ Collection properties = node.getNodeProperties();
+ // extract property names from nod
+ ArrayList propertyNames = new ArrayList();
+ if ((null != properties) && properties.size() > 0)
+ {
+ for (Iterator j = properties.iterator(); j.hasNext();)
+ {
+ Property curprop = (Property) j.next();
+ if ((null != curprop) && (null != curprop.getPropertyName())
&& !propertyNames.contains(curprop.getPropertyName()))
+ {
+ propertyNames.add(curprop.getPropertyName());
+ }
+ }
+ }
+ return (String[]) propertyNames.toArray(new
String[propertyNames.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#childrenNames()
+ */
+ public String[] childrenNames()
+ {
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // get persistent node and child nodes
+ Node node = getNode();
+ Collection nodes = ppw.provider().getChildren(node);
+ // get child node names
if (null != nodes)
{
ArrayList childrenNames = new ArrayList(nodes.size());
@@ -107,214 +226,507 @@
return new String[0];
}
}
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#removeNode()
+ */
+ public void removeNode()
+ {
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // check for removal of root node
+ if (path.equals("/"))
+ {
+ throw new UnsupportedOperationException("Root preferences node
cannot be removed");
+ }
+ // get persistent node and parent
+ Node node = getNode(path, type, false);
+ if (node != null)
+ {
+ Node parentNode = getNode(parentPath(path), type, false);
+ if (parentNode != null)
+ {
+ // remove persistent node and children
+ removeNodeAndChildren(parentNode, node);
+ }
+ }
+ // flag preference as removed
+ removed = true;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#nodeExists(java.lang.String)
+ */
+ public boolean nodeExists(String path)
+ {
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // construct absolute path if necessary
+ if (path.charAt(0) != '/')
+ {
+ if (!this.path.equals("/"))
+ {
+ path = this.path+"/"+path;
+ }
+ else
+ {
+ path = "/"+path;
+ }
+ }
+ // check to see if persistent node exists
+ return (getNode(path, type, false) != null);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#sync()
+ */
+ public void sync()
+ {
+ }
- /**
- * @see java.util.prefs.Preferences#childSpi(java.lang.String)
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#flush()
*/
- public AbstractPreferences childSpi(String name)
+ public void flush()
{
- return new PreferencesImpl(this, ppw, name, nodeType);
}
- /**
- * @see java.util.prefs.Preferences#flushSpi()
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#parent()
*/
- public void flushSpi() throws BackingStoreException
+ public Preferences parent()
{
+ // check removed state
+ if (removed)
+ {
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // construct parent preference
+ if (!path.equals("/"))
+ {
+ return new PreferencesImpl(ppw, parentPath(path), type);
+ }
+ return null;
}
- /**
- * @see java.util.prefs.Preferences#getSpi(java.lang.String)
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#node(java.lang.String)
*/
- public String getSpi(String key)
+ public Preferences node(String path)
{
- String value = null;
- Collection properties = getNode().getNodeProperties();
- for (Iterator i = properties.iterator(); i.hasNext();)
+ // check removed state
+ if (removed)
{
- Property curProp = (Property) i.next();
- if ((null != curProp) && (null != curProp.getPropertyName()) &&
(curProp.getPropertyName().equals(key)))
+ throw new IllegalStateException("Preferences node removed");
+ }
+ // construct absolute path if necessary
+ if (path.charAt(0) != '/')
+ {
+ if (!this.path.equals("/"))
{
- value = curProp.getPropertyValue();
+ path = this.path+"/"+path;
+ }
+ else
+ {
+ path = "/"+path;
}
}
- return value;
+ // return new preference
+ return new PreferencesImpl(ppw, path, type);
}
-
- /**
- * @see java.util.prefs.Preferences#keysSpi()
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#name()
*/
- public String[] keysSpi()
+ public String name()
{
- ArrayList propertyNames = new ArrayList();
+ // get name from path
+ return pathName(path);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#absolutePath()
+ */
+ public String absolutePath()
+ {
+ // return path
+ return path;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#isUserNode()
+ */
+ public boolean isUserNode()
+ {
+ // test type
+ return (type == USER_NODE_TYPE);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#clear()
+ */
+ public void clear()
+ {
+ // remove all keys
+ String[] keys = keys();
+ for (int i = 0; (i < keys.length); i++)
+ {
+ remove(keys[i]);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see
java.util.prefs.Preferences#addPreferenceChangeListener(java.util.prefs.PreferenceChangeListener)
+ */
+ public void addPreferenceChangeListener(PreferenceChangeListener pcl)
+ {
+ // change listeners not supported
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see
java.util.prefs.Preferences#removePreferenceChangeListener(java.util.prefs.PreferenceChangeListener)
+ */
+ public void removePreferenceChangeListener(PreferenceChangeListener pcl)
+ {
+ // change listeners not supported
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see
java.util.prefs.Preferences#addNodeChangeListener(java.util.prefs.NodeChangeListener)
+ */
+ public void addNodeChangeListener(NodeChangeListener ncl)
+ {
+ // change listeners not supported
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see
java.util.prefs.Preferences#removeNodeChangeListener(java.util.prefs.NodeChangeListener)
+ */
+ public void removeNodeChangeListener(NodeChangeListener ncl)
+ {
+ // change listeners not supported
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#putInt(java.lang.String, int)
+ */
+ public void putInt(String key, int value)
+ {
+ put(key, Integer.toString(value));
+ }
- Collection propCol = getNode().getNodeProperties();
- if ((null != propCol) && propCol.size() > 0)
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#getInt(java.lang.String, int)
+ */
+ public int getInt(String key, int def)
+ {
+ try
{
- for (Iterator j = propCol.iterator(); j.hasNext();)
+ String value = get(key, null);
+ if (value != null)
{
- Property curprop = (Property) j.next();
- if ((null != curprop) && (null != curprop.getPropertyName())
- && !propertyNames.contains(curprop.getPropertyName()))
- {
- propertyNames.add(curprop.getPropertyName());
- }
+ return Integer.parseInt(value);
}
}
-
- return (String[]) propertyNames.toArray(new
String[propertyNames.size()]);
+ catch (NumberFormatException nfe)
+ {
+ }
+ return def;
}
- /**
- * @see java.util.prefs.Preferences#putSpi(java.lang.String,
- * java.lang.String)
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#putLong(java.lang.String, long)
*/
- public void putSpi(String key, String value)
+ public void putLong(String key, long value)
{
- Node node = getNode();
- Collection properties = node.getNodeProperties();
- if (null == properties)
- {
- log.error("Could not retrieve node property: [key: " + key + ",
value:" + value + "]");
- return;
- }
+ put(key, Long.toString(value));
+ }
- // If the property exists, update its value.
- boolean propFound = false;
- for (Iterator i = properties.iterator(); i.hasNext();)
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#getLong(java.lang.String, long)
+ */
+ public long getLong(String key, long def)
+ {
+ try
{
- Property curProp = (Property) i.next();
- if ((null != curProp) && (null != curProp.getPropertyName()) &&
curProp.getPropertyName().equals(key))
+ String value = get(key, null);
+ if (value != null)
{
- propFound = true;
- curProp.setPropertyValue(value);
- curProp.setModifiedDate(new
Timestamp(System.currentTimeMillis()));
- if (log.isDebugEnabled())
- {
- log.debug("Update existing property: " +
curProp.toString());
- }
- // Property found, we break.
- break;
+ return Long.parseLong(value);
}
}
- if (!propFound)
+ catch (NumberFormatException nfe)
{
- properties.add(new PropertyImpl(node.getNodeId(), key, value));
}
+ return def;
+ }
- ppw.provider().storeNode(node);
-
- // mark stored node as old
- newNode = false;
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#putBoolean(java.lang.String, boolean)
+ */
+ public void putBoolean(String key, boolean value)
+ {
+ put(key, String.valueOf(value));
}
- /**
- * @see java.util.prefs.Preferences#removeNodeSpi()
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#getBoolean(java.lang.String, boolean)
*/
- public void removeNodeSpi() throws BackingStoreException
+ public boolean getBoolean(String key, boolean def)
{
- // remove node from db
- Node parentNode = null;
- Preferences parent = parent();
- if (parent != null && parent instanceof PreferencesImpl)
+ String value = get(key, null);
+ if (value != null)
{
- parentNode = ((PreferencesImpl) parent).getNode();
+ if (value.equalsIgnoreCase("true"))
+ {
+ return true;
+ }
+ else if (value.equalsIgnoreCase("false"))
+ {
+ return false;
+ }
}
- ppw.provider().removeNode(parentNode, getNode());
+ return def;
+ }
- // mark removed node as new
- newNode = true;
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#putFloat(java.lang.String, float)
+ */
+ public void putFloat(String key, float value)
+ {
+ put(key, Float.toString(value));
}
- /**
- * @see java.util.prefs.Preferences#removeSpi(java.lang.String)
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#getFloat(java.lang.String, float)
*/
- public void removeSpi(String key)
+ public float getFloat(String key, float def)
{
- boolean removed = false;
- Node node = getNode();
- Collection properties = node.getNodeProperties();
- for (Iterator i = properties.iterator(); i.hasNext();)
+ try
{
- Property curProp = (Property) i.next();
+ String value = get(key, null);
+ if (value != null)
+ {
+ return Float.parseFloat(value);
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ return def;
+ }
- if ((curProp.getPropertyName().equals(key)))
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#putDouble(java.lang.String, double)
+ */
+ public void putDouble(String key, double value)
+ {
+ put(key, Double.toString(value));
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#getDouble(java.lang.String, double)
+ */
+ public double getDouble(String key, double def)
+ {
+ try
+ {
+ String value = get(key, null);
+ if (value != null)
{
- i.remove();
- removed = true;
+ return Double.parseDouble(value);
}
}
- if (removed)
+ catch (NumberFormatException nfe)
{
- ppw.provider().storeNode(node);
+ }
+ return def;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#putByteArray(java.lang.String, byte[])
+ */
+ public void putByteArray(String key, byte[] value)
+ {
+ put(key, new String(Base64.encodeBase64(value)));
+ }
- // mark stored node as old
- newNode = false;
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#getByteArray(java.lang.String, byte[])
+ */
+ public byte[] getByteArray(String key, byte[] def)
+ {
+ String value = get(key, null);
+ if (value != null)
+ {
+ return Base64.decodeBase64(value.getBytes());
}
+ return def;
}
- /**
- * @see java.util.prefs.Preferences#syncSpi()
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#exportNode(java.io.OutputStream)
+ */
+ public void exportNode(OutputStream os)
+ {
+ // export not supported
+ throw new UnsupportedOperationException();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#exportSubtree(java.io.OutputStream)
*/
- public void syncSpi() throws BackingStoreException
+ public void exportSubtree(OutputStream os)
{
- flushSpi();
+ // export not supported
+ throw new UnsupportedOperationException();
}
+ /* (non-Javadoc)
+ * @see java.util.prefs.Preferences#toString()
+ */
+ public String toString()
+ {
+ // return string representation of preference node
+ return (isUserNode() ? "User" : "System")+" Preference Node: "+path;
+ }
+
/**
+ * Get preferences persistence provider.
*
- * <p>
- * getNode
- * </p>
+ * @return preferences provider
+ */
+ public PreferencesProviderWrapper getProvider()
+ {
+ return ppw;
+ }
+
+ /**
+ * Get or create persistent preference node for this preferences node.
*
- * @return
+ * @return persistent preference node
*/
- public Node getNode()
+ private Node getNode()
{
- Node node;
+ return getNode(path, type, true);
+ }
+
+ /**
+ * Get or create persistent preference node.
+ *
+ * @param path absolute path
+ * @param type user or system type
+ * @param create flag to enable node creation on access
+ * @return persistent preference node
+ */
+ private Node getNode(String path, int type, boolean create)
+ {
+ // access node
+ Node node = null;
try
{
- node = ppw.provider().getNode(absolutePath(), nodeType);
- newNode = false;
+ node = ppw.provider().getNode(path, type);
}
catch (NodeDoesNotExistException e1)
{
- try
- {
- Preferences parent = parent();
- if ((parent != null) && (parent instanceof PreferencesImpl))
- {
- node =
ppw.provider().createNode(((PreferencesImpl)parent).getNode(), nodeName,
nodeType, absolutePath());
- }
- else
- {
- node = ppw.provider().createNode(null, nodeName, nodeType,
absolutePath());
- }
- newNode = true;
- }
- catch (FailedToCreateNodeException e)
- {
- IllegalStateException ise = new IllegalStateException("Failed
to create new Preferences of type " + nodeType + " for path " + absolutePath());
- ise.initCause(e);
- throw ise;
- }
- catch (NodeAlreadyExistsException e)
+ // create if required and does not exist
+ if (create)
{
try
{
- node = ppw.provider().getNode(absolutePath(), nodeType);
- newNode = false;
+ // create node and set new
+ String parentPath = parentPath(path);
+ String name = pathName(path);
+ if (parentPath.length() > 0)
+ {
+ node = ppw.provider().createNode(getNode(parentPath,
type, true), name, type, path);
+ }
+ else
+ {
+ node = ppw.provider().createNode(null, name, type,
path);
+ }
}
- catch (NodeDoesNotExistException e2)
+ catch (FailedToCreateNodeException e)
{
- // If we get this at this point something is very wrong
- IllegalStateException ise = new
IllegalStateException("Unable to create node for Preferences of type " +
nodeType + " for path " + absolutePath() + ". " +
- "If
you see this exception at this, it more than likely means that the Preferences
backing store is corrupt.");
- ise.initCause(e2);
+ IllegalStateException ise = new
IllegalStateException("Failed to create new Preferences of type " + type + "
for path " + path);
+ ise.initCause(e);
throw ise;
}
+ catch (NodeAlreadyExistsException e)
+ {
+ // retry to create node in case just created
+ try
+ {
+ node = ppw.provider().getNode(path, type);
+ }
+ catch (NodeDoesNotExistException e2)
+ {
+ // If we get this at this point something is very wrong
+ IllegalStateException ise = new
IllegalStateException("Unable to create node for Preferences of type " + type +
" for path " + path + ". " +
+
"If you see this exception at this, it more than likely means that the
Preferences backing store is corrupt.");
+ ise.initCause(e2);
+ throw ise;
+ }
+ }
}
}
return node;
}
+
+ /**
+ * Recursively remove node and all child nodes.
+ *
+ * @param parentNode parent of node to remove
+ * @param node preference node to remove
+ */
+ private void removeNodeAndChildren(Node parentNode, Node node)
+ {
+ Collection nodes = ppw.provider().getChildren(node);
+ if (null != nodes)
+ {
+ for (Iterator i = nodes.iterator(); i.hasNext();)
+ {
+ Node childNode = (Node) i.next();
+ removeNodeAndChildren(node, childNode);
+ }
+ }
+ ppw.provider().removeNode(parentNode, node);
+ }
+
+ /**
+ * Utility to compute parent path from node path.
+ *
+ * @param path absolute node path
+ * @return parent node path
+ */
+ private static String parentPath(String path)
+ {
+ int lastIndex = path.lastIndexOf('/');
+ if (lastIndex > 0)
+ {
+ return path.substring(0, lastIndex);
+ }
+ return "/";
+ }
+
+ /**
+ * Utility to extract node name from node path.
+ *
+ * @param path absolute node path
+ * @return node name
+ */
+ private static String pathName(String path)
+ {
+ return path.substring(path.lastIndexOf('/')+1);
+ }
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]