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:27:03 UTC

svn commit: r1482087 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/XMLConfiguration.java test/java/org/apache/commons/configuration/TestXMLConfiguration.java

Author: oheger
Date: Mon May 13 20:27:02 2013
New Revision: 1482087

URL: http://svn.apache.org/r1482087
Log:
Some special methods of XMLConfiguration now call the Synchronizer correctly.
Updated Javadoc regarding thread-safety.

Modified:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLConfiguration.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLConfiguration.java

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLConfiguration.java?rev=1482087&r1=1482086&r2=1482087&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/XMLConfiguration.java Mon May 13 20:27:02 2013
@@ -159,9 +159,17 @@ import org.xml.sax.helpers.DefaultHandle
  * features can be found in the documentation of
  * {@link AbstractFileConfiguration}.</p>
  *
- * <p><em>Note:</em>Configuration objects of this type can be read concurrently
- * by multiple threads. However if one of these threads modifies the object,
- * synchronization has to be performed manually.</p>
+ * <p>Like other {@code Configuration} implementations, this class uses a
+ * {@code Synchronizer} object to control concurrent access. By choosing a
+ * suitable implementation of the {@code Synchronizer} interface, an instance
+ * can be made thread-safe or not. Note that access to most of the properties
+ * typically set through a builder is not protected by the {@code Synchronizer}.
+ * The intended usage is that these properties are set once at construction
+ * time through the builder and after that remain constant. If you wish to
+ * change such properties during life time of an instance, you have to use
+ * the {@code lock()} and {@code unlock()} methods manually to ensure that
+ * other threads see your changes.
+ * </p>
  *
  * @since commons-configuration 1.0
  *
@@ -259,13 +267,13 @@ public class XMLConfiguration extends Ba
     @Override
     protected String getRootElementNameInternal()
     {
-        if (getDocument() == null)
+        if (document == null)
         {
             return (rootElementName == null) ? DEFAULT_ROOT_NAME : rootElementName;
         }
         else
         {
-            return getDocument().getDocumentElement().getNodeName();
+            return document.getDocumentElement().getNodeName();
         }
     }
 
@@ -330,7 +338,15 @@ public class XMLConfiguration extends Ba
      */
     public String getPublicID()
     {
-        return publicID;
+        beginRead();
+        try
+        {
+            return publicID;
+        }
+        finally
+        {
+            endRead();
+        }
     }
 
     /**
@@ -343,7 +359,15 @@ public class XMLConfiguration extends Ba
      */
     public void setPublicID(String publicID)
     {
-        this.publicID = publicID;
+        beginWrite();
+        try
+        {
+            this.publicID = publicID;
+        }
+        finally
+        {
+            endWrite();
+        }
     }
 
     /**
@@ -356,7 +380,15 @@ public class XMLConfiguration extends Ba
      */
     public String getSystemID()
     {
-        return systemID;
+        beginRead();
+        try
+        {
+            return systemID;
+        }
+        finally
+        {
+            endRead();
+        }
     }
 
     /**
@@ -369,7 +401,15 @@ public class XMLConfiguration extends Ba
      */
     public void setSystemID(String systemID)
     {
-        this.systemID = systemID;
+        beginWrite();
+        try
+        {
+            this.systemID = systemID;
+        }
+        finally
+        {
+            endWrite();
+        }
     }
 
     /**
@@ -460,7 +500,15 @@ public class XMLConfiguration extends Ba
      */
     public Document getDocument()
     {
-        return document;
+        beginRead();
+        try
+        {
+            return document;
+        }
+        finally
+        {
+            endRead();
+        }
     }
 
     /**
@@ -936,6 +984,7 @@ public class XMLConfiguration extends Ba
      */
     public void validate() throws ConfigurationException
     {
+        beginWrite();
         try
         {
             Transformer transformer = createTransformer();
@@ -963,6 +1012,10 @@ public class XMLConfiguration extends Ba
         {
             throw new ConfigurationException("Validation failed", pce);
         }
+        finally
+        {
+            endWrite();
+        }
     }
 
     /**
@@ -985,15 +1038,15 @@ public class XMLConfiguration extends Ba
         {
             transformer.setOutputProperty(OutputKeys.ENCODING, locator.getEncoding());
         }
-        if (getPublicID() != null)
+        if (publicID != null)
         {
             transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
-                    getPublicID());
+                    publicID);
         }
-        if (getSystemID() != null)
+        if (systemID != null)
         {
             transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
-                    getSystemID());
+                    systemID);
         }
 
         return transformer;

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLConfiguration.java?rev=1482087&r1=1482086&r2=1482087&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestXMLConfiguration.java Mon May 13 20:27:02 2013
@@ -40,6 +40,7 @@ import javax.xml.parsers.DocumentBuilder
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+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.io.FileHandler;
@@ -1468,7 +1469,10 @@ public class TestXMLConfiguration
         conf.setSchemaValidation(true);
         load(conf, testFile2);
         conf.setProperty("Employee.SSN", "123456789");
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        conf.setSynchronizer(sync);
         conf.validate();
+        sync.verify(Methods.BEGIN_WRITE, Methods.END_WRITE);
         saveTestConfig();
         conf = new XMLConfiguration();
         load(conf, testSaveConf.getAbsolutePath());
@@ -1626,6 +1630,46 @@ public class TestXMLConfiguration
     }
 
     /**
+     * Tests whether the system ID is accessed in a synchronized manner.
+     */
+    @Test
+    public void testSystemIdSynchronized()
+    {
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        conf.setSynchronizer(sync);
+        conf.setSystemID(SYSTEM_ID);
+        assertEquals("SystemID not set", SYSTEM_ID, conf.getSystemID());
+        sync.verify(Methods.BEGIN_WRITE, Methods.END_WRITE, Methods.BEGIN_READ,
+                Methods.END_READ);
+    }
+
+    /**
+     * Tests whether the public ID is accessed in a synchronized manner.
+     */
+    @Test
+    public void testPublicIdSynchronized()
+    {
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        conf.setSynchronizer(sync);
+        conf.setPublicID(PUBLIC_ID);
+        assertEquals("PublicID not set", PUBLIC_ID, conf.getPublicID());
+        sync.verify(Methods.BEGIN_WRITE, Methods.END_WRITE, Methods.BEGIN_READ,
+                Methods.END_READ);
+    }
+
+    /**
+     * Tests whether access to the document is synchronized.
+     */
+    @Test
+    public void testGetDocumentSynchronized()
+    {
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        conf.setSynchronizer(sync);
+        assertNotNull("No document", conf.getDocument());
+        sync.verify(Methods.BEGIN_READ, Methods.END_READ);
+    }
+
+    /**
      * Removes the test output file if it exists.
      */
     private void removeTestFile()