You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2006/04/16 19:55:57 UTC

svn commit: r394529 - /jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/

Author: oheger
Date: Sun Apr 16 10:55:55 2006
New Revision: 394529

URL: http://svn.apache.org/viewcvs?rev=394529&view=rev
Log:
Added event listener support to basic configuration classes

Modified:
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractHierarchicalFileConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/BaseConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
    jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java?rev=394529&r1=394528&r2=394529&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java Sun Apr 16 10:55:55 2006
@@ -26,12 +26,32 @@
 
 import org.apache.commons.collections.Predicate;
 import org.apache.commons.collections.iterators.FilterIterator;
+import org.apache.commons.configuration.event.EventSource;
 import org.apache.commons.lang.BooleanUtils;
 
 /**
- * Abstract configuration class. Provide basic functionality but does not store
- * any data. If you want to write your own Configuration class then you should
- * implement only abstract methods from this class.
+ * <p>Abstract configuration class. Provides basic functionality but does not
+ * store any data.</p>
+ * <p>If you want to write your own Configuration class then you should
+ * implement only abstract methods from this class. A lot of functionality
+ * needed by typical implementations of the <code>Configuration</conde>
+ * interface is already provided by this base class. Following is a list of
+ * feauters implemented here:
+ * <ul><li>Data conversion support. The various data types required by the
+ * <code>Configuration</code> interface are already handled by this base class.
+ * A concrete sub class only needs to provide a generic <code>getProperty()</code>
+ * method.</li>
+ * <li>Support for variable interpolation. Property values containing special
+ * variable tokens (like <code>${var}</code>) will be replaced by their
+ * corresponding values.</li>
+ * <li>Support for string lists. The values of properties to be added to this
+ * configuration are checked whether they contain a list delimiter character. If
+ * this is the case and if list splitting is enabled, the string is splitted and
+ * multiple values are added for this property.</li>
+ * <li>Basic event support. Whenever this configuration is modified registered
+ * event listeners are notified. Refer to the various <code>EVENT_XXX</code>
+ * constants to get an impression about which event types are supported.</li>
+ * </ul></p>
  *
  * @author <a href="mailto:ksh@scand.com">Konstantin Shaposhnikov </a>
  * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger </a>
@@ -39,8 +59,20 @@
  * @version $Id: AbstractConfiguration.java,v 1.29 2004/12/02 22:05:52 ebourg
  * Exp $
  */
-public abstract class AbstractConfiguration implements Configuration
+public abstract class AbstractConfiguration extends EventSource implements Configuration
 {
+    /** Constant for the add property event type.*/
+    public static final int EVENT_ADD_PROPERTY = 1;
+
+    /** Constant for the clear property event type.*/
+    public static final int EVENT_CLEAR_PROPERTY = 2;
+
+    /** Constant for the set property event type.*/
+    public static final int EVENT_SET_PROPERTY = 3;
+
+    /** Constant for the clear configuration event type.*/
+    public static final int EVENT_CLEAR = 4;
+
     /** start token */
     protected static final String START_TOKEN = "${";
 
@@ -187,6 +219,8 @@
      */
     public void addProperty(String key, Object value)
     {
+        fireEvent(EVENT_ADD_PROPERTY, key, value, true);
+
         if (!isDelimiterParsingDisabled())
         {
             Iterator it = PropertyConverter.toIterator(value, getListDelimiter());
@@ -199,6 +233,8 @@
         {
             addPropertyDirect(key, value);
         }
+
+        fireEvent(EVENT_ADD_PROPERTY, key, value, false);
     }
 
     /**
@@ -279,32 +315,74 @@
      */
     public void setProperty(String key, Object value)
     {
-        clearProperty(key);
-        addProperty(key, value);
+        fireEvent(EVENT_SET_PROPERTY, key, value, true);
+        setDetailEvents(false);
+        try
+        {
+            clearProperty(key);
+            addProperty(key, value);
+        }
+        finally
+        {
+            setDetailEvents(true);
+        }
+        fireEvent(EVENT_SET_PROPERTY, key, value, false);
     }
 
     /**
-     * {@inheritDoc}
+     * Removes the specified property from this configuration. This
+     * implementation performs some preparations and then delegates to
+     * <code>clearPropertyDirect()</code>, which will do the real work.
+     *
+     * @param key the key to be removed
      */
-    public abstract void clearProperty(String key);
+    public void clearProperty(String key)
+    {
+        fireEvent(EVENT_CLEAR_PROPERTY, key, null, true);
+        clearPropertyDirect(key);
+        fireEvent(EVENT_CLEAR_PROPERTY, key, null, false);
+    }
+
+    /**
+     * Removes the specified property from this configuration. This method is
+     * called by <code>clearProperty()</code> after it has done some
+     * preparations. It should be overriden in sub classes. This base
+     * implementation is just left empty.
+     *
+     * @param key the key to be removed
+     */
+    protected void clearPropertyDirect(String key)
+    {
+        // override in sub classes
+    }
 
     /**
      * {@inheritDoc}
      */
     public void clear()
     {
-        Iterator it = getKeys();
-        while (it.hasNext())
+        fireEvent(EVENT_CLEAR, null, null, true);
+        setDetailEvents(false);
+        try
         {
-            String key = (String) it.next();
-            it.remove();
-
-            if (containsKey(key))
+            Iterator it = getKeys();
+            while (it.hasNext())
             {
-                // workaround for Iterators that do not remove the property on calling remove()
-                clearProperty(key);
+                String key = (String) it.next();
+                it.remove();
+
+                if (containsKey(key))
+                {
+                    // workaround for Iterators that do not remove the property on calling remove()
+                    clearProperty(key);
+                }
             }
         }
+        finally
+        {
+            setDetailEvents(true);
+        }
+        fireEvent(EVENT_CLEAR, null, null, false);
     }
 
     /**

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java?rev=394529&r1=394528&r2=394529&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java Sun Apr 16 10:55:55 2006
@@ -76,6 +76,9 @@
  */
 public abstract class AbstractFileConfiguration extends BaseConfiguration implements FileConfiguration
 {
+    /** Constant for the configuration reload event.*/
+    public static final int EVENT_RELOAD = 20;
+
     /** Stores the file name.*/
     protected String fileName;
 
@@ -709,8 +712,18 @@
 
                     if (strategy.reloadingRequired())
                     {
-                        clear();
-                        load();
+                        fireEvent(EVENT_RELOAD, null, getURL(), true);
+                        setDetailEvents(false);
+                        try
+                        {
+                            clear();
+                            load();
+                        }
+                        finally
+                        {
+                            setDetailEvents(true);
+                        }
+                        fireEvent(EVENT_RELOAD, null, getURL(), false);
 
                         // notify the strategy
                         strategy.reloadingPerformed();
@@ -760,6 +773,31 @@
             {
                 noReload--;
             }
+        }
+    }
+
+    /**
+     * Sends an event to all registered listeners. This implementation ensures
+     * that no reloads are performed while the listeners are invoked. So
+     * infinite loops can be avoided that can be caused by event listeners
+     * accessing the configuration's properties when they are invoked.
+     *
+     * @param type the event type
+     * @param propName the name of the property
+     * @param propValue the value of the property
+     * @param before the before update flag
+     */
+    protected void fireEvent(int type, String propName, Object propValue,
+            boolean before)
+    {
+        enterNoReload();
+        try
+        {
+            super.fireEvent(type, propName, propValue, before);
+        }
+        finally
+        {
+            exitNoReload();
         }
     }
 

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractHierarchicalFileConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractHierarchicalFileConfiguration.java?rev=394529&r1=394528&r2=394529&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractHierarchicalFileConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractHierarchicalFileConfiguration.java Sun Apr 16 10:55:55 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 The Apache Software Foundation.
+ * Copyright 2005-2006 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License")
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,8 @@
 import java.net.URL;
 import java.util.Iterator;
 
+import org.apache.commons.configuration.event.ConfigurationEvent;
+import org.apache.commons.configuration.event.ConfigurationListener;
 import org.apache.commons.configuration.reloading.ReloadingStrategy;
 
 /**
@@ -44,10 +46,12 @@
     /** Stores the delegate used for implementing functionality related to the
      * <code>FileConfiguration</code> interface.
      */
-    private FileConfigurationDelegate delegate = createDelegate();
+    private FileConfigurationDelegate delegate;
 
     protected AbstractHierarchicalFileConfiguration()
     {
+        delegate = createDelegate();
+        initDelegate(delegate);
     }
 
     /**
@@ -58,6 +62,7 @@
      */
     public AbstractHierarchicalFileConfiguration(String fileName) throws ConfigurationException
     {
+        this();
         // store the file name
         delegate.setPath(fileName);
 
@@ -73,6 +78,7 @@
      */
     public AbstractHierarchicalFileConfiguration(File file) throws ConfigurationException
     {
+        this();
         // set the file and update the url, the base path and the file name
         setFile(file);
 
@@ -91,6 +97,7 @@
      */
     public AbstractHierarchicalFileConfiguration(URL url) throws ConfigurationException
     {
+        this();
         // set the URL and update the base path and the file name
         setURL(url);
 
@@ -244,7 +251,15 @@
 
     public void reload()
     {
-        delegate.reload();
+        setDetailEvents(false);
+        try
+        {
+            delegate.reload();
+        }
+        finally
+        {
+            setDetailEvents(true);
+        }
     }
 
     public String getEncoding()
@@ -293,6 +308,32 @@
     protected FileConfigurationDelegate createDelegate()
     {
         return new FileConfigurationDelegate();
+    }
+
+    /**
+     * Helper method for initializing the file configuration delegate.
+     *
+     * @param del the delegate
+     */
+    private void initDelegate(FileConfigurationDelegate del)
+    {
+        del.addConfigurationListener(new ConfigurationListener()
+        {
+            public void configurationChanged(ConfigurationEvent event)
+            {
+                // deliver reload events to registered listeners
+                setDetailEvents(true);
+                try
+                {
+                    fireEvent(event.getType(), event.getPropertyName(), event
+                            .getPropertyValue(), event.isBeforeUpdate());
+                }
+                finally
+                {
+                    setDetailEvents(false);
+                }
+            }
+        });
     }
 
     /**

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/BaseConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/BaseConfiguration.java?rev=394529&r1=394528&r2=394529&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/BaseConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/BaseConfiguration.java Sun Apr 16 10:55:55 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Copyright 2001-2006 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License")
  * you may not use this file except in compliance with the License.
@@ -124,7 +124,7 @@
      *
      * @param key the key to remove along with corresponding value.
      */
-    public void clearProperty(String key)
+    protected void clearPropertyDirect(String key)
     {
         if (containsKey(key))
         {
@@ -137,7 +137,9 @@
      */
     public void clear()
     {
+        fireEvent(EVENT_CLEAR, null, null, true);
         store.clear();
+        fireEvent(EVENT_CLEAR, null, null, false);
     }
 
     /**

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=394529&r1=394528&r2=394529&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java Sun Apr 16 10:55:55 2006
@@ -100,6 +100,12 @@
  */
 public class HierarchicalConfiguration extends AbstractConfiguration implements Serializable, Cloneable
 {
+    /** Constant for the clear tree event.*/
+    public static final int EVENT_CLEAR_TREE = 10;
+
+    /** Constant for the add nodes event.*/
+    public static final int EVENT_ADD_NODES = 11;
+
     /** Stores the default expression engine to be used for new objects.*/
     private static ExpressionEngine defaultExpressionEngine = new DefaultExpressionEngine();
 
@@ -315,6 +321,7 @@
             return;
         }
 
+        fireEvent(EVENT_ADD_NODES, key, nodes, true);
         ConfigurationNode parent;
         List target = fetchNodeList(key);
         if (target.size() == 1)
@@ -346,6 +353,7 @@
                 parent.addChild(child);
             }
         }
+        fireEvent(EVENT_ADD_NODES, key, nodes, false);
     }
 
     /**
@@ -509,6 +517,8 @@
      */
     public void setProperty(String key, Object value)
     {
+        fireEvent(EVENT_SET_PROPERTY, key, value, true);
+
         Iterator itNodes = fetchNodeList(key).iterator();
         Iterator itValues;
         if (!isDelimiterParsingDisabled())
@@ -535,6 +545,8 @@
         {
             clearNode((ConfigurationNode) itNodes.next());
         }
+
+        fireEvent(EVENT_SET_PROPERTY, key, value, false);
     }
 
     /**
@@ -547,12 +559,14 @@
      */
     public void clearTree(String key)
     {
+        fireEvent(EVENT_CLEAR_TREE, key, null, true);
         List nodes = fetchNodeList(key);
 
         for (Iterator it = nodes.iterator(); it.hasNext();)
         {
             removeNode((ConfigurationNode) it.next());
         }
+        fireEvent(EVENT_CLEAR_TREE, key, nodes, false);
     }
 
     /**
@@ -564,12 +578,15 @@
      */
     public void clearProperty(String key)
     {
+        fireEvent(EVENT_CLEAR_PROPERTY, key, null, true);
         List nodes = fetchNodeList(key);
 
         for (Iterator it = nodes.iterator(); it.hasNext();)
         {
             clearNode((ConfigurationNode) it.next());
         }
+
+        fireEvent(EVENT_CLEAR_PROPERTY, key, null, false);
     }
 
     /**

Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java?rev=394529&r1=394528&r2=394529&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/MapConfiguration.java Sun Apr 16 10:55:55 2006
@@ -103,7 +103,7 @@
         return map.containsKey(key);
     }
 
-    public void clearProperty(String key)
+    protected void clearPropertyDirect(String key)
     {
         map.remove(key);
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org