Author: oheger
Date: Sun Apr  9 10:30:37 2006
New Revision: 392787

URL: http://svn.apache.org/viewcvs?rev=392787&view=rev
Log:
XMLConfiguration now keeps the public and system ID of the DOCTYPE declaration; 
fix for issue 39227

Modified:
    
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
    
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
    jakarta/commons/proper/configuration/trunk/xdocs/changes.xml

Modified: 
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java?rev=392787&r1=392786&r2=392787&view=diff
==============================================================================
--- 
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
 (original)
+++ 
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
 Sun Apr  9 10:30:37 2006
@@ -114,6 +114,12 @@
     /** Stores the name of the root element. */
     private String rootElementName;
 
+    /** Stores the public ID from the DOCTYPE.*/
+    private String publicID;
+
+    /** Stores the system ID from the DOCTYPE.*/
+    private String systemID;
+
     /** Stores the document builder that should be used for loading.*/
     private DocumentBuilder documentBuilder;
 
@@ -235,6 +241,58 @@
     }
 
     /**
+     * Returns the public ID of the DOCTYPE declaration from the loaded XML
+     * document. This is <b>null</b> if no document has been loaded yet or if
+     * the document does not contain a DOCTYPE declaration with a public ID.
+     *
+     * @return the public ID
+     * @since 1.3
+     */
+    public String getPublicID()
+    {
+        return publicID;
+    }
+
+    /**
+     * Sets the public ID of the DOCTYPE declaration. When this configuration 
is
+     * saved, a DOCTYPE declaration will be constructed that contains this
+     * public ID.
+     *
+     * @param publicID the public ID
+     * @since 1.3
+     */
+    public void setPublicID(String publicID)
+    {
+        this.publicID = publicID;
+    }
+
+    /**
+     * Returns the system ID of the DOCTYPE declaration from the loaded XML
+     * document. This is <b>null</b> if no document has been loaded yet or if
+     * the document does not contain a DOCTYPE declaration with a system ID.
+     *
+     * @return the system ID
+     * @since 1.3
+     */
+    public String getSystemID()
+    {
+        return systemID;
+    }
+
+    /**
+     * Sets the system ID of the DOCTYPE declaration. When this configuration 
is
+     * saved, a DOCTYPE declaration will be constructed that contains this
+     * system ID.
+     *
+     * @param publicID the public ID
+     * @since 1.3
+     */
+    public void setSystemID(String systemID)
+    {
+        this.systemID = systemID;
+    }
+
+    /**
      * Returns the value of the validating flag.
      *
      * @return the validating flag
@@ -288,6 +346,11 @@
      */
     public void initProperties(Document document, boolean elemRefs)
     {
+        if (document.getDoctype() != null)
+        {
+            setPublicID(document.getDoctype().getPublicId());
+            setSystemID(document.getDoctype().getSystemId());
+        }
         constructHierarchy(getRoot(), document.getDocumentElement(), elemRefs);
     }
 
@@ -561,15 +624,9 @@
     {
         try
         {
-            Transformer transformer = 
TransformerFactory.newInstance().newTransformer();
+            Transformer transformer = createTransformer();
             Source source = new DOMSource(createDocument());
             Result result = new StreamResult(writer);
-
-            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            if (getEncoding() != null)
-            {
-                transformer.setOutputProperty(OutputKeys.ENCODING, 
getEncoding());
-            }
             transformer.transform(source, result);
         }
         catch (TransformerException e)
@@ -579,6 +636,40 @@
     }
 
     /**
+     * Creates and initializes the transformer used for save operations. This
+     * base implementation initializes all of the default settings like
+     * indention mode and the DOCTYPE. Derived classes may overload this method
+     * if they have specific needs.
+     *
+     * @return the transformer to use for a save operation
+     * @throws TransformerException if an error occurs
+     * @since 1.3
+     */
+    protected Transformer createTransformer() throws TransformerException
+    {
+        Transformer transformer = TransformerFactory.newInstance()
+                .newTransformer();
+
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        if (getEncoding() != null)
+        {
+            transformer.setOutputProperty(OutputKeys.ENCODING, getEncoding());
+        }
+        if (getPublicID() != null)
+        {
+            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
+                    getPublicID());
+        }
+        if (getSystemID() != null)
+        {
+            transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
+                    getSystemID());
+        }
+
+        return transformer;
+    }
+
+    /**
      * Creates a copy of this object. The new configuration object will contain
      * the same properties as the original, but it will lose any connection to 
a
      * source document (if one exists). This is to avoid race conditions if 
both
@@ -786,7 +877,7 @@
     {
         /** Stores the document to be constructed. */
         private Document document;
-        
+
         /** Stores the list delimiter.*/
         private char listDelimiter = AbstractConfiguration.
                 getDefaultListDelimiter();

Modified: 
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?rev=392787&r1=392786&r2=392787&view=diff
==============================================================================
--- 
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
 (original)
+++ 
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
 Sun Apr  9 10:30:37 2006
@@ -49,6 +49,18 @@
     /** Constant for the used encoding.*/
     static final String ENCODING = "ISO-8859-1";
 
+    /** Constant for the test system ID.*/
+    static final String SYSTEM_ID = "properties.dtd";
+
+    /** Constant for the test public ID.*/
+    static final String PUBLIC_ID = "-//Commons Configuration//DTD Test 
Configuration 1.3//EN";
+
+    /** Constant for the DOCTYPE declaration.*/
+    static final String DOCTYPE_DECL = " PUBLIC \"" + PUBLIC_ID + "\" \"" + 
SYSTEM_ID + "\">";
+
+    /** Constant for the DOCTYPE prefix.*/
+    static final String DOCTYPE = "<!DOCTYPE ";
+
     /** The File that we test with */
     private String testProperties = new 
File("conf/test.xml").getAbsolutePath();
     private String testProperties2 = new 
File("conf/testDigesterConfigurationInclude1.xml").getAbsolutePath();
@@ -800,7 +812,48 @@
         assertTrue("Encoding was written to file", out.toString().indexOf(
                 "encoding=\"UTF-") >= 0);
     }
-    
+
+    /**
+     * Tests whether the DOCTYPE survives a save operation.
+     */
+    public void testSaveWithDoctype() throws ConfigurationException
+    {
+        String content = "<?xml  version=\"1.0\"?>"
+                + DOCTYPE
+                + "properties"
+                + DOCTYPE_DECL
+                + "<properties version=\"1.0\"><entry 
key=\"test\">value</entry></properties>";
+        StringReader in = new StringReader(content);
+        conf = new XMLConfiguration();
+        conf.setFileName("conf/testDtd.xml");
+        conf.load();
+        conf.clear();
+        conf.load(in);
+
+        assertEquals("Wrong public ID", PUBLIC_ID, conf.getPublicID());
+        assertEquals("Wrong system ID", SYSTEM_ID, conf.getSystemID());
+        StringWriter out = new StringWriter();
+        conf.save(out);
+        System.out.println(out.toString());
+        assertTrue("Did not find DOCTYPE", out.toString().indexOf(DOCTYPE) >= 
0);
+    }
+
+    /**
+     * Tests setting public and system IDs for the D'OCTYPE and then saving the
+     * configuration. This should generate a DOCTYPE declaration.
+     */
+    public void testSaveWithDoctypeIDs() throws ConfigurationException
+    {
+        assertNull("A public ID was found", conf.getPublicID());
+        assertNull("A system ID was found", conf.getSystemID());
+        conf.setPublicID(PUBLIC_ID);
+        conf.setSystemID(SYSTEM_ID);
+        StringWriter out = new StringWriter();
+        conf.save(out);
+        assertTrue("Did not find DOCTYPE", out.toString().indexOf(
+                DOCTYPE + "testconfig" + DOCTYPE_DECL) >= 0);
+    }
+
     /**
      * Removes the test output file if it exists.
      */
@@ -811,7 +864,7 @@
             assertTrue(testSaveConf.delete());
         }
     }
-    
+
     /**
      * Helper method for checking if a save operation was successful. Loads a
      * saved configuration and then tests against a reference configuration.

Modified: jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/xdocs/changes.xml?rev=392787&r1=392786&r2=392787&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/changes.xml Sun Apr  9 
10:30:37 2006
@@ -23,6 +23,13 @@
   <body>
 
     <release version="1.3-SNAPSHOT" date="in SVN">
+      <action dev="oheger" type="update" issue="39227">
+        XMLConfiguration used to drop the DOCTYPE declaration when saving the
+        configuration. It is now able to extract the DTD's public and system ID
+        and write them back (more complex DOCTYPE declarations are still not 
supported).
+        With the new methods setSystemID() and setPublicID(), the DOCTYPE
+        declaration can be configured.
+      </action>
       <action dev="ebourg" type="add" issue="39068">
         Added two new constructors in CompositeConfiguration accepting a
         collection of configurations as a parameter.



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to