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]