You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/06/07 14:06:53 UTC
svn commit: r412383 - in
/incubator/harmony/enhanced/classlib/trunk/modules/luni/src:
main/java/java/util/InvalidPropertiesFormatException.java
main/java/java/util/Properties.java
test/java/tests/api/java/util/PropertiesTest.java
Author: tellison
Date: Wed Jun 7 05:06:52 2006
New Revision: 412383
URL: http://svn.apache.org/viewvc?rev=412383&view=rev
Log:
Apply patch HARMONY-563 (Java 5 Enhancement: java.util.Properties should implement methods loadFromXML, storeToXML)
Added:
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/InvalidPropertiesFormatException.java (with props)
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Properties.java
incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/PropertiesTest.java
Added: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/InvalidPropertiesFormatException.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/InvalidPropertiesFormatException.java?rev=412383&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/InvalidPropertiesFormatException.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/InvalidPropertiesFormatException.java Wed Jun 7 05:06:52 2006
@@ -0,0 +1,43 @@
+/* Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package java.util;
+
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+
+public class InvalidPropertiesFormatException extends IOException {
+
+ public InvalidPropertiesFormatException(String m) {
+ super(m);
+ }
+
+ public InvalidPropertiesFormatException(Throwable c) {
+ initCause(c);
+ }
+
+ private void writeObject(ObjectOutputStream out)
+ throws NotSerializableException{
+ throw new NotSerializableException();
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws NotSerializableException{
+ throw new NotSerializableException();
+ }
+}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/InvalidPropertiesFormatException.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Properties.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Properties.java?rev=412383&r1=412382&r2=412383&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Properties.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Properties.java Wed Jun 7 05:06:52 2006
@@ -22,8 +22,23 @@
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
+import java.io.StringReader;
import java.security.AccessController;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
import org.apache.harmony.luni.util.PriviAction;
/**
@@ -38,6 +53,19 @@
private static final long serialVersionUID = 4112578634029874840L;
+ private DocumentBuilder builder = null;
+
+ private static final String PROP_DTD_NAME
+ = "http://java.sun.com/dtd/properties.dtd";
+
+ private static final String PROP_DTD
+ = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + " <!ELEMENT properties (comment?, entry*) >"
+ + " <!ATTLIST properties version CDATA #FIXED \"1.0\" >"
+ + " <!ELEMENT comment (#PCDATA) >"
+ + " <!ELEMENT entry (#PCDATA) >"
+ + " <!ATTLIST entry key CDATA #REQUIRED >";
+
/**
* The default values for this Properties.
*/
@@ -463,4 +491,160 @@
writer.flush();
}
+ public synchronized void loadFromXML(InputStream in)
+ throws IOException, InvalidPropertiesFormatException {
+ if (in == null) {
+ throw new NullPointerException();
+ }
+
+ if (builder == null) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(true);
+
+ try {
+ builder = factory.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new Error(e);
+ }
+
+ builder.setErrorHandler(new ErrorHandler() {
+ public void warning(SAXParseException e) throws SAXException {
+ throw e;
+ }
+
+ public void error(SAXParseException e) throws SAXException {
+ throw e;
+ }
+
+ public void fatalError(SAXParseException e) throws SAXException {
+ throw e;
+ }
+ });
+
+ builder.setEntityResolver(new EntityResolver() {
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException, IOException {
+ if (systemId.equals(PROP_DTD_NAME)) {
+ InputSource result = new InputSource(new StringReader(
+ PROP_DTD));
+ result.setSystemId(PROP_DTD_NAME);
+ return result;
+ }
+ throw new SAXException(
+ "Invalid DOCTYPE declaration: " + systemId);
+ }
+ });
+ }
+
+ try {
+ Document doc = builder.parse(in);
+ NodeList entries = doc.getElementsByTagName("entry");
+ if (entries == null) {
+ return;
+ }
+ int entriesListLength = entries.getLength();
+
+ for (int i = 0; i < entriesListLength; i++) {
+ Element entry = (Element) entries.item(i);
+ String key = entry.getAttribute("key");
+ String value = entry.getTextContent();
+
+ /*
+ * key != null & value != null
+ * but key or(and) value can be empty String
+ */
+ put(key, value);
+ }
+ } catch (IOException e) {
+ throw e;
+ } catch (SAXException e) {
+ throw new InvalidPropertiesFormatException(e);
+ }
+ }
+
+ public void storeToXML(OutputStream os, String comment)
+ throws IOException {
+ storeToXML(os, comment, "UTF-8");
+ }
+
+ public synchronized void storeToXML(OutputStream os, String comment,
+ String encoding) throws IOException {
+ String encodingCanonicalName;
+
+ if (os == null || encoding == null) {
+ throw new NullPointerException();
+ }
+
+ if (lineSeparator == null) {
+ lineSeparator = (String) AccessController
+ .doPrivileged(new PriviAction("line.separator"));
+ }
+
+ /*
+ * Uncomment following code when java.nio.charset.Charset class will
+ * be implemented. We can write to XML file using encoding parameter
+ * but note that some aliases for encodings are not supported
+ * by the XML parser. Thus we have to know canonical name for encoding
+ * used to store data in XML since the XML parser must recognize
+ * encoding name used to store data.
+ */
+
+ //try {
+ // encodingCanonicalName = Charset.forName(encoding).name();
+ //} catch (IllegalCharsetNameException e) {
+ // System.out.println("Warning: encoding name " + encoding +" is illegal, "
+ // + "using UTF-8 as default encoding");
+ // encodingCanonicalName = "UTF-8";
+ //} catch (UnsupportedCharsetException e) {
+ // System.out.println("Warning: encoding " + encoding +" is not supported, "
+ // + "using UTF-8 as default encoding");
+ // encodingCanonicalName = "UTF-8";
+ //}
+
+ /*
+ * We use UTF-8 as default encoding. Delete the line of code that
+ * follows this comment when java.nio.charset.Charset class will be
+ * implemented.
+ */
+ encodingCanonicalName = "UTF-8";
+
+ OutputStreamWriter osw = new OutputStreamWriter(os,
+ encodingCanonicalName);
+ StringBuffer buf = new StringBuffer(200);
+ buf.append("<?xml version=\"1.0\" encoding=\"" + encodingCanonicalName
+ + "\"?>" + lineSeparator);
+ buf.append("<!DOCTYPE properties SYSTEM \"" + PROP_DTD_NAME
+ + "\">" + lineSeparator);
+ buf.append("<properties>" + lineSeparator);
+ if (comment != null) {
+ buf.append("<comment>" + substitutePredefinedEntries(comment)
+ + "</comment>" + lineSeparator);
+ }
+ Iterator iter = entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String keyValue = (String) entry.getKey();
+ String entryValue = (String) entry.getValue();
+ buf.append("<entry key=\"" + substitutePredefinedEntries(keyValue)
+ + "\">" + substitutePredefinedEntries(entryValue)
+ + "</entry>" + lineSeparator);
+ }
+ buf.append("</properties>" + lineSeparator);
+
+ osw.write(buf.toString());
+ osw.flush();
+ }
+
+ private String substitutePredefinedEntries(String s) {
+
+ /*
+ * substitution for predefined character entities
+ * to use them safely in XML
+ */
+ return s.replaceAll("&", "&")
+ .replaceAll("<", "<")
+ .replaceAll(">", ">")
+ .replaceAll("\u0027", "'")
+ .replaceAll("\"", """);
+ }
}
Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/PropertiesTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/PropertiesTest.java?rev=412383&r1=412382&r2=412383&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/PropertiesTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/util/PropertiesTest.java Wed Jun 7 05:06:52 2006
@@ -23,6 +23,7 @@
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;
+import java.util.InvalidPropertiesFormatException;
import tests.support.resource.Support_Resources;
@@ -327,6 +328,116 @@
}
/**
+ * @tests java.util.Properties#loadFromXML(java.io.InputStream)
+ */
+ public void test_loadFromXMLLjava_io_InputStream() {
+ // Test for method void java.util.Properties.loadFromXML(java.io.InputStream)
+ Properties prop = null;
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.loadFromXML(is = new ByteArrayInputStream(writePropertiesXMLUTF_8()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "value3", prop.getProperty(
+ "key3"));
+ assertEquals("Failed to load correct properties", "value1", prop.getProperty(
+ "key1"));
+
+ try {
+ InputStream is;
+ prop = new Properties();
+ prop.loadFromXML(is = new ByteArrayInputStream(writePropertiesXMLISO_8859_1()));
+ is.close();
+ } catch (Exception e) {
+ fail("Exception during load test : " + e.getMessage());
+ }
+ assertEquals("Failed to load correct properties", "value2", prop.getProperty(
+ "key2"));
+ assertEquals("Failed to load correct properties", "value1", prop.getProperty(
+ "key1"));
+ }
+
+ /**
+ * @tests java.util.Properties#storeToXML(java.io.OutputStream, java.lang.String, java.lang.String)
+ */
+ public void test_storeToXMLLjava_io_OutputStreamLjava_lang_StringLjava_lang_String() {
+ // Test for method void java.util.Properties.storeToXML(java.io.OutputStream,
+ // java.lang.String, java.lang.String)
+ Properties myProps = new Properties();
+ Properties myProps2 = new Properties();
+ Enumeration e;
+ String nextKey;
+
+ myProps.setProperty("key1", "value1");
+ myProps.setProperty("key2", "value2");
+ myProps.setProperty("key3", "value3");
+ myProps.setProperty("<a>key4</a>", "\"value4");
+ myProps.setProperty("key5 ", "<h>value5</h>");
+ myProps.setProperty("<a>key6</a>", " <h>value6</h> ");
+ myProps.setProperty("<comment>key7</comment>", "value7");
+ myProps.setProperty(" key8 ", "<comment>value8</comment>");
+ myProps.setProperty("<key9>", "\u0027value9");
+ myProps.setProperty("key10\"", "<value10>");
+ myProps.setProperty("&key11&", "value11");
+ myProps.setProperty("key12", "&value12&");
+ myProps.setProperty("<a>&key13<</a>", "&&value13<b>&</b>");
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ //store in UTF-8 encoding
+ myProps.storeToXML(out, "comment");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2.loadFromXML(in);
+ in.close();
+ } catch (InvalidPropertiesFormatException ipfe) {
+ fail("InvalidPropertiesFormatException occurred reading file: "
+ + ipfe.getMessage());
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
+
+ e = myProps.propertyNames();
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ //store in ISO-8859-1 encoding
+ myProps.storeToXML(out, "comment", "ISO-8859-1");
+ out.close();
+ ByteArrayInputStream in = new ByteArrayInputStream(out
+ .toByteArray());
+ myProps2 = new Properties();
+ myProps2.loadFromXML(in);
+ in.close();
+ } catch (InvalidPropertiesFormatException ipfe) {
+ fail("InvalidPropertiesFormatException occurred reading file: "
+ + ipfe.getMessage());
+ } catch (IOException ioe) {
+ fail("IOException occurred reading/writing file : "
+ + ioe.getMessage());
+ }
+
+ e = myProps.propertyNames();
+ while (e.hasMoreElements()) {
+ nextKey = (String) e.nextElement();
+ assertTrue("Stored property list not equal to original", myProps2
+ .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+ }
+ }
+
+ /**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
@@ -358,4 +469,38 @@
ps.close();
return bout.toByteArray();
}
+
+ protected byte[] writePropertiesXMLUTF_8() throws IOException {
+ PrintStream ps = null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ps = new PrintStream(bout, true, "UTF-8");
+ ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ ps.println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
+ ps.println("<properties>");
+ ps.println("<comment>comment</comment>");
+ ps.println("<entry key=\"key4\">value4</entry>");
+ ps.println("<entry key=\"key3\">value3</entry>");
+ ps.println("<entry key=\"key2\">value2</entry>");
+ ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
+ ps.println("</properties>");
+ ps.close();
+ return bout.toByteArray();
+ }
+
+ protected byte[] writePropertiesXMLISO_8859_1() throws IOException {
+ PrintStream ps = null;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ps = new PrintStream(bout, true, "ISO-8859-1");
+ ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
+ ps.println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
+ ps.println("<properties>");
+ ps.println("<comment>comment</comment>");
+ ps.println("<entry key=\"key4\">value4</entry>");
+ ps.println("<entry key=\"key3\">value3</entry>");
+ ps.println("<entry key=\"key2\">value2</entry>");
+ ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
+ ps.println("</properties>");
+ ps.close();
+ return bout.toByteArray();
+ }
}