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 2013/05/13 22:24:53 UTC

svn commit: r1482083 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/ test/java/org/apache/commons/configuration/

Author: oheger
Date: Mon May 13 20:24:53 2013
New Revision: 1482083

URL: http://svn.apache.org/r1482083
Log:
The special methods of INIConfiguration now use the configuration's Synchronizer.

Modified:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/INIConfiguration.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestINIConfiguration.java

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java?rev=1482083&r1=1482082&r2=1482083&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/BaseHierarchicalConfiguration.java Mon May 13 20:24:53 2013
@@ -845,7 +845,9 @@ public class BaseHierarchicalConfigurati
      * configuration and initializes it. This method also takes care that data
      * structures are created to manage all {@code SubnodeConfiguration}
      * instances with support for updates. They are stored, so that they can be
-     * triggered when this configuration is changed.
+     * triggered when this configuration is changed. <strong>Important
+     * note:</strong> This method expects that a write lock is held on this
+     * configuration!
      *
      * @param node the root node of the new {@code SubnodeConfiguration}
      * @param key the key to this node

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/INIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/INIConfiguration.java?rev=1482083&r1=1482082&r2=1482083&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/INIConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/INIConfiguration.java Mon May 13 20:24:53 2013
@@ -716,22 +716,30 @@ public class INIConfiguration extends Ba
         boolean globalSection = false;
         boolean inSection = false;
 
-        for (ConfigurationNode node : getRootNode().getChildren())
+        beginRead();
+        try
         {
-            if (isSectionNode(node))
+            for (ConfigurationNode node : getRootNode().getChildren())
             {
-                inSection = true;
-                sections.add(node.getName());
-            }
-            else
-            {
-                if (!inSection && !globalSection)
+                if (isSectionNode(node))
+                {
+                    inSection = true;
+                    sections.add(node.getName());
+                }
+                else
                 {
-                    globalSection = true;
-                    sections.add(null);
+                    if (!inSection && !globalSection)
+                    {
+                        globalSection = true;
+                        sections.add(null);
+                    }
                 }
             }
         }
+        finally
+        {
+            endRead();
+        }
 
         return sections;
     }
@@ -779,7 +787,17 @@ public class INIConfiguration extends Ba
             {
                 // the passed in key does not map to exactly one node
                 // obtain the node for the section, create it on demand
-                return createAndInitializeSubnodeConfiguration(getSectionNode(name), null, false);
+                // (creation of a SubnodeConfiguration has to be synchronized)
+                beginWrite();
+                try
+                {
+                    return createAndInitializeSubnodeConfiguration(
+                            getSectionNode(name), null, false);
+                }
+                finally
+                {
+                    endWrite();
+                }
             }
         }
     }
@@ -816,18 +834,23 @@ public class INIConfiguration extends Ba
     {
         ViewNode parent = new ViewNode();
 
-        for (ConfigurationNode node : getRootNode().getChildren())
+        beginWrite();
+        try
         {
-            if (!isSectionNode(node))
+            for (ConfigurationNode node : getRootNode().getChildren())
             {
-                synchronized (node)
+                if (!isSectionNode(node))
                 {
                     parent.addChild(node);
                 }
             }
-        }
 
-        return createAndInitializeSubnodeConfiguration(parent, null, false);
+            return createAndInitializeSubnodeConfiguration(parent, null, false);
+        }
+        finally
+        {
+            endWrite();
+        }
     }
 
     /**

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestINIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestINIConfiguration.java?rev=1482083&r1=1482082&r2=1482083&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestINIConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestINIConfiguration.java Mon May 13 20:24:53 2013
@@ -19,6 +19,7 @@ package org.apache.commons.configuration
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
@@ -33,8 +34,10 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.commons.configuration.SynchronizerTestImpl.Methods;
 import org.apache.commons.configuration.builder.FileBasedBuilderParametersImpl;
 import org.apache.commons.configuration.builder.FileBasedConfigurationBuilder;
+import org.apache.commons.configuration.sync.ReadWriteSynchronizer;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -607,6 +610,7 @@ public class TestINIConfiguration
             throws ConfigurationException, InterruptedException
     {
         INIConfiguration config = setUpConfig(INI_DATA_GLOBAL);
+        config.setSynchronizer(new ReadWriteSynchronizer());
         final int threadCount = 10;
         GlobalSectionTestThread[] threads = new GlobalSectionTestThread[threadCount];
         for (int i = 0; i < threadCount; i++)
@@ -918,6 +922,86 @@ public class TestINIConfiguration
     }
 
     /**
+     * Tests whether synchronization is performed when querying the
+     * configuration's sections.
+     */
+    @Test
+    public void testGetSectionsSynchronized() throws ConfigurationException
+    {
+        INIConfiguration config = setUpConfig(INI_DATA);
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        config.setSynchronizer(sync);
+        assertFalse("No sections", config.getSections().isEmpty());
+        sync.verify(Methods.BEGIN_READ, Methods.END_READ);
+    }
+
+    /**
+     * Helper method for testing whether the access to a section is
+     * synchronized. This method delegates to the method with the same name
+     * passing in default methods.
+     *
+     * @param sectionName the name of the section to be queried
+     * @throws ConfigurationException if an error occurs
+     */
+    private void checkGetSectionSynchronized(String sectionName)
+            throws ConfigurationException
+    {
+        checkGetSectionSynchronized(sectionName, Methods.BEGIN_WRITE,
+                Methods.END_WRITE);
+    }
+
+    /**
+     * Helper method for testing whether the access to a section causes the
+     * specified methods to be called on the synchronizer.
+     *
+     * @param sectionName the name of the section to be queried
+     * @param expMethods the expected methods
+     * @throws ConfigurationException if an error occurs
+     */
+    private void checkGetSectionSynchronized(String sectionName,
+            Methods... expMethods) throws ConfigurationException
+    {
+        INIConfiguration config = setUpConfig(INI_DATA);
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        config.setSynchronizer(sync);
+        assertNotNull("No global section", config.getSection(sectionName));
+        sync.verify(expMethods);
+    }
+
+    /**
+     * Tests whether access to the global section is synchronized.
+     */
+    @Test
+    public void testGetSectionGlobalSynchronized()
+            throws ConfigurationException
+    {
+        checkGetSectionSynchronized(null);
+    }
+
+    /**
+     * Tests whether access to an existing section is synchronized.
+     */
+    @Test
+    public void testGetSectionExistingSynchronized()
+            throws ConfigurationException
+    {
+        // 1 x configurationAt(), then direct access to root node
+        checkGetSectionSynchronized("section1");
+    }
+
+    /**
+     * Tests whether access to a non-existing section is synchronized.
+     */
+    @Test
+    public void testGetSectionNonExistingSynchronized()
+            throws ConfigurationException
+    {
+        checkGetSectionSynchronized("Non-existing-section?",
+                Methods.BEGIN_WRITE, Methods.END_WRITE, Methods.BEGIN_WRITE,
+                Methods.END_WRITE);
+    }
+
+    /**
      * A thread class for testing concurrent access to the global section.
      */
     private static class GlobalSectionTestThread extends Thread