I'm committing the attached patch which adds a parser for the XML property files to java.util.Properties. There are still some problems with actually using this, due to the XML parser stumbling over the Sun DTD (which shouldn't even be being parsed, but still is). I'll file a bug on this shortly. The patch does work, with a input properties file hacked to use a locally modified version of the DTD.
Changelog:
2005-10-23 Andrew John Hughes <[EMAIL PROTECTED]>
* java/util/Properties.java
(storeToXML(OutputStream,String,String)): Added null pointer checks.
(loadFromXML(InputStream)): Implemented.
(PropertiesHandler): New class to handle parsing events.
(PropertiesHandler()): New constructor.
(startDTD(String,String,String)): Implemented.
(startElement(String,String,String,Attributes)): Implemented.
(characters(char[],int,int)): Implemented.
(endElement(String,String,String)): Implemented.
(endDocument()): Implemented.
--
Andrew :-)
Please avoid sending me Microsoft Office (e.g. Word, PowerPoint) attachments.
See http://www.fsf.org/philosophy/no-word-attachments.html
"Value your freedom, or you will lose it, teaches history.
`Don't bother us with politics' respond those who don't want to learn."
-- Richard Stallman
Escape the Java Trap with GNU Classpath!
http://www.gnu.org/philosophy/java-trap.html
public class gcj extends Freedom implements Java { ... }
Index: java/util/Properties.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/util/Properties.java,v
retrieving revision 1.33
diff -u -3 -p -u -r1.33 Properties.java
--- java/util/Properties.java 16 Oct 2005 23:25:56 -0000 1.33
+++ java/util/Properties.java 23 Oct 2005 21:46:26 -0000
@@ -47,6 +47,16 @@ import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.DefaultHandler2;
+
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.DOMImplementation;
@@ -604,6 +614,7 @@ label = Name:\\u0020</pre>
* @param comment a comment to include at the top of the XML file, or
* <code>null</code> if one is not required.
* @throws IOException if the serialization fails.
+ * @throws NullPointerException if <code>os</code> is null.
* @since 1.5
*/
public void storeToXML(OutputStream os, String comment)
@@ -625,11 +636,17 @@ label = Name:\\u0020</pre>
* <code>null</code> if one is not required.
* @param encoding the encoding to use for the XML output.
* @throws IOException if the serialization fails.
+ * @throws NullPointerException if <code>os</code> or <code>encoding</code>
+ * is null.
* @since 1.5
*/
public void storeToXML(OutputStream os, String comment, String encoding)
throws IOException
{
+ if (os == null)
+ throw new NullPointerException("Null output stream supplied.");
+ if (encoding == null)
+ throw new NullPointerException("Null encoding supplied.");
try
{
DOMImplementationRegistry registry =
@@ -681,5 +698,198 @@ label = Name:\\u0020</pre>
.initCause(e);
}
}
+
+ /**
+ * <p>
+ * Decodes the contents of the supplied <code>InputStream</code> as
+ * an XML file, which represents a set of properties. The format of
+ * the XML file must match the DTD
+ * <a href="http://java.sun.com/dtd/properties.dtd">
+ * http://java.sun.com/dtd/properties.dtd</a>.
+ * </p>
+ *
+ * @param in the input stream from which to receive the XML data.
+ * @throws IOException if an I/O error occurs in reading the input data.
+ * @throws InvalidPropertiesFormatException if the input data does not
+ * constitute an XML properties
+ * file.
+ * @throws NullPointerException if <code>in</code> is null.
+ * @since 1.5
+ */
+ public void loadFromXML(InputStream in)
+ throws IOException, InvalidPropertiesFormatException
+ {
+ if (in == null)
+ throw new NullPointerException("Null input stream supplied.");
+ try
+ {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(false); /* Don't use the URI */
+ XMLReader parser = factory.newSAXParser().getXMLReader();
+ PropertiesHandler handler = new PropertiesHandler();
+ parser.setContentHandler(handler);
+ parser.setProperty("http://xml.org/sax/properties/lexical-handler",
+ handler);
+ parser.parse(new InputSource(in));
+ }
+ catch (SAXException e)
+ {
+ throw (InvalidPropertiesFormatException)
+ new InvalidPropertiesFormatException("Error in parsing XML.").
+ initCause(e);
+ }
+ catch (ParserConfigurationException e)
+ {
+ throw (IOException)
+ new IOException("An XML parser could not be found.").
+ initCause(e);
+ }
+ }
+
+ /**
+ * This class deals with the parsing of XML using
+ * <a href="http://java.sun.com/dtd/properties.dtd">
+ * http://java.sun.com/dtd/properties.dtd</a>.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.5
+ */
+ private class PropertiesHandler
+ extends DefaultHandler2
+ {
+
+ /**
+ * The current key.
+ */
+ private String key;
+
+ /**
+ * The current value.
+ */
+ private String value;
+
+ /**
+ * A flag to check whether a valid DTD declaration has been seen.
+ */
+ private boolean dtdDeclSeen;
+
+ /**
+ * Constructs a new Properties handler.
+ */
+ public PropertiesHandler()
+ {
+ key = null;
+ value = null;
+ dtdDeclSeen = false;
+ }
+
+ /**
+ * <p>
+ * Captures the start of the DTD declarations, if they exist.
+ * A valid properties file must declare the following doctype:
+ * </p>
+ * <p>
+ * <code>!DOCTYPE properties SYSTEM
+ * "http://java.sun.com/dtd/properties.dtd"</code>
+ * </p>
+ *
+ * @param name the name of the document type.
+ * @param publicId the public identifier that was declared, or
+ * null if there wasn't one.
+ * @param systemId the system identifier that was declared, or
+ * null if there wasn't one.
+ * @throws SAXException if some error occurs in parsing.
+ */
+ public void startDTD(String name, String publicId, String systemId)
+ throws SAXException
+ {
+ if (name.equals("properties") &&
+ publicId == null &&
+ systemId.equals("http://java.sun.com/dtd/properties.dtd"))
+ {
+ dtdDeclSeen = true;
+ }
+ else
+ throw new SAXException("Invalid DTD declaration: " + name);
+ }
+
+ /**
+ * Captures the start of an XML element.
+ *
+ * @param uri the namespace URI.
+ * @param localName the local name of the element inside the namespace.
+ * @param qName the local name qualified with the namespace URI.
+ * @param attributes the attributes of this element.
+ * @throws SAXException if some error occurs in parsing.
+ */
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes)
+ throws SAXException
+ {
+ if (qName.equals("entry"))
+ {
+ int index = attributes.getIndex("key");
+ if (index != -1)
+ key = attributes.getValue(index);
+ }
+ else if (qName.equals("comment") || qName.equals("properties"))
+ {
+ /* Ignore it */
+ }
+ else
+ throw new SAXException("Invalid tag: " + qName);
+ }
+
+ /**
+ * Captures characters within an XML element.
+ *
+ * @param ch the array of characters.
+ * @param start the start index of the characters to use.
+ * @param length the number of characters to use from the start index on.
+ * @throws SAXException if some error occurs in parsing.
+ */
+ public void characters(char[] ch, int start, int length)
+ throws SAXException
+ {
+ if (key != null)
+ value = new String(ch,start,length);
+ }
+
+ /**
+ * Captures the end of an XML element.
+ *
+ * @param uri the namespace URI.
+ * @param localName the local name of the element inside the namespace.
+ * @param qName the local name qualified with the namespace URI.
+ * @throws SAXException if some error occurs in parsing.
+ */
+ public void endElement(String uri, String localName,
+ String qName)
+ throws SAXException
+ {
+ if (qName.equals("entry"))
+ {
+ if (value == null)
+ value = "";
+ setProperty(key, value);
+ key = null;
+ value = null;
+ }
+ }
+
+ /**
+ * Captures the end of the XML document. If a DTD declaration has
+ * not been seen, the document is erroneous and an exception is thrown.
+ *
+ * @throws SAXException if the correct DTD declaration didn't appear.
+ */
+ public void endDocument()
+ throws SAXException
+ {
+ if (!dtdDeclSeen)
+ throw new SAXException("No appropriate DTD declaration was seen.");
+ }
+
+ } // class PropertiesHandler
} // class Properties
signature.asc
Description: Digital signature
_______________________________________________ Classpath-patches mailing list [email protected] http://lists.gnu.org/mailman/listinfo/classpath-patches
