summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/java/util/Properties.java
diff options
context:
space:
mode:
authormark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-15 23:20:01 +0000
committermark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-15 23:20:01 +0000
commit3b3101d8b5ae4f08a16c0b7111da6cad41bbd282 (patch)
treea5eb7cf42a51869cc8aa1fad7ad6a90cca47fdd8 /libjava/classpath/java/util/Properties.java
parent7e55c49d7d91ef9f09e93c1100119b1ab3652446 (diff)
downloadppe42-gcc-3b3101d8b5ae4f08a16c0b7111da6cad41bbd282.tar.gz
ppe42-gcc-3b3101d8b5ae4f08a16c0b7111da6cad41bbd282.zip
Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated. * Makefile.in: Likewise. * scripts/makemake.tcl: Use glob -nocomplain. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107049 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/java/util/Properties.java')
-rw-r--r--libjava/classpath/java/util/Properties.java348
1 files changed, 341 insertions, 7 deletions
diff --git a/libjava/classpath/java/util/Properties.java b/libjava/classpath/java/util/Properties.java
index f00615ba0bf..7c468da8b4f 100644
--- a/libjava/classpath/java/util/Properties.java
+++ b/libjava/classpath/java/util/Properties.java
@@ -47,6 +47,25 @@ 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;
+import org.w3c.dom.Element;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+
/**
* A set of persistent properties, which can be saved or loaded from a stream.
* A property list may also contain defaults, searched if the main list
@@ -200,12 +219,15 @@ label = Name:\\u0020</pre>
// The characters up to the next Whitespace, ':', or '='
// describe the key. But look for escape sequences.
- StringBuffer key = new StringBuffer();
+ // Try to short-circuit when there is no escape char.
+ int start = pos;
+ boolean needsEscape = line.indexOf('\\', pos) != -1;
+ StringBuilder key = needsEscape ? new StringBuilder() : null;
while (pos < line.length()
&& ! Character.isWhitespace(c = line.charAt(pos++))
&& c != '=' && c != ':')
{
- if (c == '\\')
+ if (needsEscape && c == '\\')
{
if (pos == line.length())
{
@@ -249,11 +271,20 @@ label = Name:\\u0020</pre>
}
}
}
- else
+ else if (needsEscape)
key.append(c);
}
boolean isDelim = (c == ':' || c == '=');
+
+ String keyString;
+ if (needsEscape)
+ keyString = key.toString();
+ else if (isDelim || Character.isWhitespace(c))
+ keyString = line.substring(start, pos - 1);
+ else
+ keyString = line.substring(start, pos);
+
while (pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos)))
pos++;
@@ -266,7 +297,15 @@ label = Name:\\u0020</pre>
pos++;
}
- StringBuffer element = new StringBuffer(line.length() - pos);
+ // Short-circuit if no escape chars found.
+ if (!needsEscape)
+ {
+ put(keyString, line.substring(pos));
+ continue;
+ }
+
+ // Escape char found so iterate through the rest of the line.
+ StringBuilder element = new StringBuilder(line.length() - pos);
while (pos < line.length())
{
c = line.charAt(pos++);
@@ -322,7 +361,7 @@ label = Name:\\u0020</pre>
else
element.append(c);
}
- put(key.toString(), element.toString());
+ put(keyString, element.toString());
}
}
@@ -386,7 +425,7 @@ label = Name:\\u0020</pre>
Iterator iter = entrySet ().iterator ();
int i = size ();
- StringBuffer s = new StringBuffer (); // Reuse the same buffer.
+ StringBuilder s = new StringBuilder (); // Reuse the same buffer.
while (--i >= 0)
{
Map.Entry entry = (Map.Entry) iter.next ();
@@ -529,7 +568,7 @@ label = Name:\\u0020</pre>
* leading spaces must be escaped for the value
* @see #store(OutputStream, String)
*/
- private void formatForOutput(String str, StringBuffer buffer, boolean key)
+ private void formatForOutput(String str, StringBuilder buffer, boolean key)
{
if (key)
{
@@ -578,4 +617,299 @@ label = Name:\\u0020</pre>
head = key;
}
}
+
+ /**
+ * <p>
+ * Encodes the properties as an XML file using the UTF-8 encoding.
+ * The format of the XML file matches the DTD
+ * <a href="http://java.sun.com/dtd/properties.dtd">
+ * http://java.sun.com/dtd/properties.dtd</a>.
+ * </p>
+ * <p>
+ * Invoking this method provides the same behaviour as invoking
+ * <code>storeToXML(os, comment, "UTF-8")</code>.
+ * </p>
+ *
+ * @param os the stream to output to.
+ * @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)
+ throws IOException
+ {
+ storeToXML(os, comment, "UTF-8");
+ }
+
+ /**
+ * <p>
+ * Encodes the properties as an XML file using the supplied encoding.
+ * The format of the XML file matches the DTD
+ * <a href="http://java.sun.com/dtd/properties.dtd">
+ * http://java.sun.com/dtd/properties.dtd</a>.
+ * </p>
+ *
+ * @param os the stream to output to.
+ * @param comment a comment to include at the top of the XML file, or
+ * <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 =
+ DOMImplementationRegistry.newInstance();
+ DOMImplementation domImpl = registry.getDOMImplementation("LS 3.0");
+ DocumentType doctype =
+ domImpl.createDocumentType("properties", null,
+ "http://java.sun.com/dtd/properties.dtd");
+ Document doc = domImpl.createDocument(null, "properties", doctype);
+ Element root = doc.getDocumentElement();
+ if (comment != null)
+ {
+ Element commentElement = doc.createElement("comment");
+ commentElement.appendChild(doc.createTextNode(comment));
+ root.appendChild(commentElement);
+ }
+ Iterator iterator = entrySet().iterator();
+ while (iterator.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ Element entryElement = doc.createElement("entry");
+ entryElement.setAttribute("key", (String) entry.getKey());
+ entryElement.appendChild(doc.createTextNode((String)
+ entry.getValue()));
+ root.appendChild(entryElement);
+ }
+ DOMImplementationLS loadAndSave = (DOMImplementationLS) domImpl;
+ LSSerializer serializer = loadAndSave.createLSSerializer();
+ LSOutput output = loadAndSave.createLSOutput();
+ output.setByteStream(os);
+ output.setEncoding(encoding);
+ serializer.write(doc, output);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw (IOException)
+ new IOException("The XML classes could not be found.").initCause(e);
+ }
+ catch (InstantiationException e)
+ {
+ throw (IOException)
+ new IOException("The XML classes could not be instantiated.")
+ .initCause(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw (IOException)
+ new IOException("The XML classes could not be accessed.")
+ .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 (gnu_andrew@member.fsf.org)
+ * @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
OpenPOWER on IntegriCloud