You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2008/04/06 21:56:00 UTC
svn commit: r645292 -
/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/flat/AbstractFlatConfiguration.java
Author: oheger
Date: Sun Apr 6 12:55:55 2008
New Revision: 645292
URL: http://svn.apache.org/viewvc?rev=645292&view=rev
Log:
Initial implementation of AbstractFlatConfiguration
Modified:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/flat/AbstractFlatConfiguration.java
Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/flat/AbstractFlatConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/flat/AbstractFlatConfiguration.java?rev=645292&r1=645291&r2=645292&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/flat/AbstractFlatConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/flat/AbstractFlatConfiguration.java Sun Apr 6 12:55:55 2008
@@ -16,7 +16,13 @@
*/
package org.apache.commons.configuration2.flat;
+import java.util.Iterator;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.apache.commons.configuration2.AbstractConfiguration;
+import org.apache.commons.configuration2.event.ConfigurationEvent;
+import org.apache.commons.configuration2.event.ConfigurationListener;
/**
* <p>
@@ -63,7 +69,56 @@
* which manipulate a value of a property with multiple values.
*/
public static final int EVENT_PROPERTY_CHANGED = 9;
-
+
+ /** Stores the <code>NodeHandler</code> used by this configuration. */
+ private FlatNodeHandler nodeHandler;
+
+ /** Stores the root node of this configuration. */
+ private FlatNode rootNode;
+
+ /** A lock for protecting the root node. */
+ private Lock lockRoot;
+
+ /**
+ * Creates a new instance of <code>AbstractFlatConfiguration</code>.
+ */
+ protected AbstractFlatConfiguration()
+ {
+ lockRoot = new ReentrantLock();
+ nodeHandler = new FlatNodeHandler(this);
+
+ // Add event handler that invalidates the node structure if required
+ addConfigurationListener(new ConfigurationListener()
+ {
+ /**
+ * Reacts on change events. Asks the node handler whether the
+ * received event was caused by an update of the node structure. If
+ * not, the structure has to be invalidated.
+ */
+ public void configurationChanged(ConfigurationEvent event)
+ {
+ if (!event.isBeforeUpdate())
+ {
+ if (!getNodeHandler().isInternalUpdate())
+ {
+ invalidateRootNode();
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Returns the <code>NodeHandler</code> used by this configuration. This
+ * is a handler that can deal with flat nodes.
+ *
+ * @return the <code>NodeHandler</code> used
+ */
+ public FlatNodeHandler getNodeHandler()
+ {
+ return nodeHandler;
+ }
+
/**
* Modifies a specific value of a property with multiple values. If a
* property has multiple values, this method can be used to alter a specific
@@ -71,9 +126,9 @@
* values. If the index is invalid (i.e. less than 0 or greater than the
* number of existing values), the value will be added to the existing
* values of this property. This method takes care of firing the appropriate
- * events and delegates to <code>setPropertyValueDirect()</code>. It generates
- * a <code>EVENT_PROPERTY_CHANGED</code> event that contains the key of the
- * affected property.
+ * events and delegates to <code>setPropertyValueDirect()</code>. It
+ * generates a <code>EVENT_PROPERTY_CHANGED</code> event that contains the
+ * key of the affected property.
*
* @param key the key of the property
* @param index the index of the value to change
@@ -92,9 +147,9 @@
* property has multiple values, this method can be used for removing a
* single value (identified by its 0-based index). If the index is out of
* range, no action is performed; in this case <b>false</b> is returned.
- * This method takes care of firing the appropriate
- * events and delegates to <code>clearPropertyValueDirect()</code>. It generates
- * a <code>EVENT_PROPERTY_CHANGED</code> event that contains the key of the
+ * This method takes care of firing the appropriate events and delegates to
+ * <code>clearPropertyValueDirect()</code>. It generates a
+ * <code>EVENT_PROPERTY_CHANGED</code> event that contains the key of the
* affected property.
*
* @param key the key of the property
@@ -108,19 +163,109 @@
fireEvent(EVENT_PROPERTY_CHANGED, key, null, false);
return result;
}
-
+
+ /**
+ * Returns the root node of this configuration. A node hierarchy for this
+ * configuration (consisting of <code>FlatNode</code> objects) is created
+ * on demand. This method returns the root node of this hierarchy. It checks
+ * whether a valid root node exists. If this is not the case,
+ * <code>constructNodeHierarchy()</code> is called to setup the node
+ * structure. Modifications on this configuration that cause the node
+ * hierarchy to get out of sync with the data stored in this configuration
+ * cause the root node to be invalidated. It will then be re-created on next
+ * access. <em>Implementation note:</em> This method is thread-safe; it
+ * can be invoked concurrently by multiple threads.
+ *
+ * @return the root node of this configuration
+ */
+ public FlatNode getRootNode()
+ {
+ lockRoot.lock();
+ try
+ {
+ if (rootNode == null)
+ {
+ rootNode = constructNodeHierarchy();
+ }
+ return rootNode;
+ }
+ finally
+ {
+ lockRoot.unlock();
+ }
+ }
+
+ /**
+ * Returns the maximum index of the property with the given key. This method
+ * can be used to find out how many values are stored for a given property.
+ * A return value of -1 means that this property is unknown. A value of 0
+ * indicates that there is a single value, 1 means there are two values,
+ * etc.
+ *
+ * @param key the key of the property
+ * @return the maximum index of a value of this property
+ */
+ public abstract int getMaxIndex(String key);
+
+ /**
+ * Creates a hierarchy of <code>FlatNode</code> objects that corresponds
+ * to the data stored in this configuration. This implementation relies on
+ * the methods <code>getKeys()</code> and <code>getMaxIndex()</code> to
+ * obtain the data required for constructing the node hierarchy.
+ *
+ * @return the root node of this hierarchy
+ */
+ protected FlatNode constructNodeHierarchy()
+ {
+ FlatRootNode root = new FlatRootNode();
+ for (Iterator<String> it = getKeys(); it.hasNext();)
+ {
+ String key = it.next();
+ int maxIndex = getMaxIndex(key);
+ for (int i = 0; i <= maxIndex; i++)
+ {
+ root.addChild(key, true);
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * Invalidates the root node of this configuration's node structure. This
+ * method is called when this configuration instance is updated, so that its
+ * data is out of sync with the node structure. It causes the root node and
+ * the whole hierarchy to be re-created when it is accessed for the next
+ * time.
+ */
+ protected void invalidateRootNode()
+ {
+ lockRoot.lock();
+ try
+ {
+ rootNode = null;
+ }
+ finally
+ {
+ lockRoot.unlock();
+ }
+ }
+
/**
* Performs the actual modification of the specified property value. This
* method is called by <code>setPropertyValue()</code>.
+ *
* @param key the key of the property
* @param index the index of the value to change
* @param value the new value
*/
- protected abstract void setPropertyValueDirect(String key, int index, Object value);
-
+ protected abstract void setPropertyValueDirect(String key, int index,
+ Object value);
+
/**
- * Performs the actual remove property value operation. This method is called
- * by <code>clearPropertyValue()</code>.
+ * Performs the actual remove property value operation. This method is
+ * called by <code>clearPropertyValue()</code>.
+ *
* @param key the key of the property
* @param index the index of the value to delete
* @return a flag whether the value could be removed