8000354: (props) Properties.storeToXML/loadFromXML need to allow for alternative implementations
Reviewed-by: mchung, forax
--- a/jdk/make/java/java/FILES_java.gmk Fri Oct 05 09:57:50 2012 -0700
+++ b/jdk/make/java/java/FILES_java.gmk Sat Oct 06 13:56:16 2012 +0100
@@ -236,6 +236,7 @@
java/util/Observer.java \
java/util/Properties.java \
java/util/InvalidPropertiesFormatException.java \
+ sun/util/spi/XmlPropertiesProvider.java \
java/util/PropertyPermission.java \
java/util/PropertyResourceBundle.java \
java/util/Random.java \
--- a/jdk/make/sun/util/Makefile Fri Oct 05 09:57:50 2012 -0700
+++ b/jdk/make/sun/util/Makefile Sat Oct 06 13:56:16 2012 +0100
@@ -41,3 +41,20 @@
#
include $(BUILDDIR)/common/Classes.gmk
+#
+# Rules for XML properties provider configuration file
+#
+SERVICEDIR = $(CLASSBINDIR)/META-INF/services
+FILES_copy = $(SERVICEDIR)/sun.util.spi.XmlPropertiesProvider
+
+copy-files: $(FILES_copy)
+
+$(SERVICEDIR)/%: $(SHARE_SRC)/classes/sun/util/xml/META-INF/services/%
+ $(install-file)
+
+build: copy-files
+
+clean::
+ $(RM) $(FILES_copy)
+
+
--- a/jdk/src/share/classes/java/util/Properties.java Fri Oct 05 09:57:50 2012 -0700
+++ b/jdk/src/share/classes/java/util/Properties.java Sat Oct 06 13:56:16 2012 +0100
@@ -34,7 +34,10 @@
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
-import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import sun.util.spi.XmlPropertiesProvider;
/**
* The {@code Properties} class represents a persistent set of
@@ -866,7 +869,7 @@
{
if (in == null)
throw new NullPointerException();
- XMLUtils.load(this, in);
+ XmlSupport.load(this, in);
in.close();
}
@@ -934,7 +937,7 @@
{
if (os == null)
throw new NullPointerException();
- XMLUtils.save(this, os, comment, encoding);
+ XmlSupport.save(this, os, comment, encoding);
}
/**
@@ -1113,59 +1116,82 @@
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
+ /**
+ * Supporting class for loading/storing properties in XML format.
+ *
+ * <p> The {@code load} and {@code store} methods defined here delegate to a
+ * system-wide {@code XmlPropertiesProvider}. On first invocation of either
+ * method then the system-wide provider is located as follows: </p>
+ *
+ * <ol>
+ * <li> If the system property {@code sun.util.spi.XmlPropertiesProvider}
+ * is defined then it is taken to be the full-qualified name of a concrete
+ * provider class. The class is loaded with the system class loader as the
+ * initiating loader. If it cannot be loaded or instantiated using a zero
+ * argument constructor then an unspecified error is thrown. </li>
+ *
+ * <li> If the system property is not defined then the service-provider
+ * loading facility defined by the {@link ServiceLoader} class is used to
+ * locate a provider with the system class loader as the initiating
+ * loader and {@code sun.util.spi.XmlPropertiesProvider} as the service
+ * type. If this process fails then an unspecified error is thrown. If
+ * there is more than one service provider installed then it is
+ * not specified as to which provider will be used. </li>
+ *
+ * <li> If the provider is not found by the above means then a system
+ * default provider will be instantiated and used. </li>
+ * </ol>
+ */
+ private static class XmlSupport {
- private static class XMLUtils {
- private static Method load = null;
- private static Method save = null;
- static {
+ private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) {
+ String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider");
+ if (cn == null)
+ return null;
try {
- // reference sun.util.xml.Utils reflectively
- // to allow the Properties class be compiled in
- // the absence of XML
- Class<?> c = Class.forName("sun.util.xml.XMLUtils", true, null);
- load = c.getMethod("load", Properties.class, InputStream.class);
- save = c.getMethod("save", Properties.class, OutputStream.class,
- String.class, String.class);
- } catch (ClassNotFoundException cnf) {
- throw new AssertionError(cnf);
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
+ Class<?> c = Class.forName(cn, true, cl);
+ return (XmlPropertiesProvider)c.newInstance();
+ } catch (ClassNotFoundException |
+ IllegalAccessException |
+ InstantiationException x) {
+ throw new ServiceConfigurationError(null, x);
}
}
- static void invoke(Method m, Object... args) throws IOException {
- try {
- m.invoke(null, args);
- } catch (IllegalAccessException e) {
- throw new AssertionError(e);
- } catch (InvocationTargetException e) {
- Throwable t = e.getCause();
- if (t instanceof RuntimeException)
- throw (RuntimeException)t;
+ private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) {
+ Iterator<XmlPropertiesProvider> iterator =
+ ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator();
+ return iterator.hasNext() ? iterator.next() : null;
+ }
- if (t instanceof IOException) {
- throw (IOException)t;
- } else {
- throw new AssertionError(t);
- }
- }
+ private static XmlPropertiesProvider loadProvider() {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<XmlPropertiesProvider>() {
+ public XmlPropertiesProvider run() {
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ XmlPropertiesProvider provider = loadProviderFromProperty(cl);
+ if (provider != null)
+ return provider;
+ provider = loadProviderAsService(cl);
+ if (provider != null)
+ return provider;
+ throw new InternalError("No fallback");
+ }});
}
+ private static final XmlPropertiesProvider PROVIDER = loadProvider();
+
static void load(Properties props, InputStream in)
throws IOException, InvalidPropertiesFormatException
{
- if (load == null)
- throw new InternalError("sun.util.xml.XMLUtils not found");
- invoke(load, props, in);
+ PROVIDER.load(props, in);
}
static void save(Properties props, OutputStream os, String comment,
String encoding)
throws IOException
{
- if (save == null)
- throw new InternalError("sun.util.xml.XMLUtils not found");
- invoke(save, props, os, comment, encoding);
+ PROVIDER.store(props, os, comment, encoding);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/spi/XmlPropertiesProvider.java Sat Oct 06 13:56:16 2012 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.spi;
+
+import java.util.Properties;
+import java.util.InvalidPropertiesFormatException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Service-provider class for loading and storing {@link Properites} in XML
+ * format.
+ *
+ * @see Properties#loadFromXML
+ * @see Properties#storeToXML
+ */
+
+public abstract class XmlPropertiesProvider {
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected XmlPropertiesProvider() {
+ // do nothing for now
+ }
+
+ /**
+ * Loads all of the properties represented by the XML document on the
+ * specified input stream into a properties table.
+ *
+ * @param props the properties table to populate
+ * @param in the input stream from which to read the XML document
+ * @throws IOException if reading from the specified input stream fails
+ * @throws InvalidPropertiesFormatException Data on input stream does not
+ * constitute a valid XML document with the mandated document type.
+ *
+ * @see Properties#loadFromXML
+ */
+ public abstract void load(Properties props, InputStream in)
+ throws IOException, InvalidPropertiesFormatException;
+
+ /**
+ * Emits an XML document representing all of the properties in a given
+ * table.
+ *
+ * @param props the properies to store
+ * @param out the output stream on which to emit the XML document.
+ * @param comment a description of the property list, can be @{code null}
+ * @param encoding the name of a supported character encoding
+ *
+ * @throws IOException if writing to the specified output stream fails
+ * @throws NullPointerException if {@code out} is null.
+ * @throws ClassCastException if this {@code Properties} object
+ * contains any keys or values that are not
+ * {@code Strings}.
+ *
+ * @see Properties#storeToXML
+ */
+ public abstract void store(Properties props, OutputStream out,
+ String comment, String encoding)
+ throws IOException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/xml/META-INF/services/sun.util.spi.XmlPropertiesProvider Sat Oct 06 13:56:16 2012 +0100
@@ -0,0 +1,1 @@
+sun.util.xml.PlatformXmlPropertiesProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/xml/PlatformXmlPropertiesProvider.java Sat Oct 06 13:56:16 2012 +0100
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.xml;
+
+import java.io.*;
+import java.util.*;
+import org.xml.sax.*;
+import org.w3c.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.*;
+
+import sun.util.spi.XmlPropertiesProvider;
+
+/**
+ * A {@code XmlPropertiesProvider} implementation that uses the JAXP API
+ * for parsing.
+ *
+ * @author Michael McCloskey
+ * @since 1.3
+ */
+public class PlatformXmlPropertiesProvider extends XmlPropertiesProvider {
+
+ // XML loading and saving methods for Properties
+
+ // The required DTD URI for exported properties
+ private static final String PROPS_DTD_URI =
+ "http://java.sun.com/dtd/properties.dtd";
+
+ private static final String PROPS_DTD =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<!-- DTD for properties -->" +
+ "<!ELEMENT properties ( comment?, entry* ) >"+
+ "<!ATTLIST properties" +
+ " version CDATA #FIXED \"1.0\">" +
+ "<!ELEMENT comment (#PCDATA) >" +
+ "<!ELEMENT entry (#PCDATA) >" +
+ "<!ATTLIST entry " +
+ " key CDATA #REQUIRED>";
+
+ /**
+ * Version number for the format of exported properties files.
+ */
+ private static final String EXTERNAL_XML_VERSION = "1.0";
+
+ @Override
+ public void load(Properties props, InputStream in)
+ throws IOException, InvalidPropertiesFormatException
+ {
+ Document doc = null;
+ try {
+ doc = getLoadingDoc(in);
+ } catch (SAXException saxe) {
+ throw new InvalidPropertiesFormatException(saxe);
+ }
+ Element propertiesElement = doc.getDocumentElement();
+ String xmlVersion = propertiesElement.getAttribute("version");
+ if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
+ throw new InvalidPropertiesFormatException(
+ "Exported Properties file format version " + xmlVersion +
+ " is not supported. This java installation can read" +
+ " versions " + EXTERNAL_XML_VERSION + " or older. You" +
+ " may need to install a newer version of JDK.");
+ importProperties(props, propertiesElement);
+ }
+
+ static Document getLoadingDoc(InputStream in)
+ throws SAXException, IOException
+ {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setIgnoringElementContentWhitespace(true);
+ dbf.setValidating(true);
+ dbf.setCoalescing(true);
+ dbf.setIgnoringComments(true);
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setEntityResolver(new Resolver());
+ db.setErrorHandler(new EH());
+ InputSource is = new InputSource(in);
+ return db.parse(is);
+ } catch (ParserConfigurationException x) {
+ throw new Error(x);
+ }
+ }
+
+ static void importProperties(Properties props, Element propertiesElement) {
+ NodeList entries = propertiesElement.getChildNodes();
+ int numEntries = entries.getLength();
+ int start = numEntries > 0 &&
+ entries.item(0).getNodeName().equals("comment") ? 1 : 0;
+ for (int i=start; i<numEntries; i++) {
+ Element entry = (Element)entries.item(i);
+ if (entry.hasAttribute("key")) {
+ Node n = entry.getFirstChild();
+ String val = (n == null) ? "" : n.getNodeValue();
+ props.setProperty(entry.getAttribute("key"), val);
+ }
+ }
+ }
+
+ @Override
+ public void store(Properties props, OutputStream os, String comment,
+ String encoding)
+ throws IOException
+ {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ DocumentBuilder db = null;
+ try {
+ db = dbf.newDocumentBuilder();
+ } catch (ParserConfigurationException pce) {
+ assert(false);
+ }
+ Document doc = db.newDocument();
+ Element properties = (Element)
+ doc.appendChild(doc.createElement("properties"));
+
+ if (comment != null) {
+ Element comments = (Element)properties.appendChild(
+ doc.createElement("comment"));
+ comments.appendChild(doc.createTextNode(comment));
+ }
+
+ synchronized (props) {
+ for (String key : props.stringPropertyNames()) {
+ Element entry = (Element)properties.appendChild(
+ doc.createElement("entry"));
+ entry.setAttribute("key", key);
+ entry.appendChild(doc.createTextNode(props.getProperty(key)));
+ }
+ }
+ emitDocument(doc, os, encoding);
+ }
+
+ static void emitDocument(Document doc, OutputStream os, String encoding)
+ throws IOException
+ {
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer t = null;
+ try {
+ t = tf.newTransformer();
+ t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI);
+ t.setOutputProperty(OutputKeys.INDENT, "yes");
+ t.setOutputProperty(OutputKeys.METHOD, "xml");
+ t.setOutputProperty(OutputKeys.ENCODING, encoding);
+ } catch (TransformerConfigurationException tce) {
+ assert(false);
+ }
+ DOMSource doms = new DOMSource(doc);
+ StreamResult sr = new StreamResult(os);
+ try {
+ t.transform(doms, sr);
+ } catch (TransformerException te) {
+ throw new IOException(te);
+ }
+ }
+
+ private static class Resolver implements EntityResolver {
+ public InputSource resolveEntity(String pid, String sid)
+ throws SAXException
+ {
+ if (sid.equals(PROPS_DTD_URI)) {
+ InputSource is;
+ is = new InputSource(new StringReader(PROPS_DTD));
+ is.setSystemId(PROPS_DTD_URI);
+ return is;
+ }
+ throw new SAXException("Invalid system identifier: " + sid);
+ }
+ }
+
+ private static class EH implements ErrorHandler {
+ public void error(SAXParseException x) throws SAXException {
+ throw x;
+ }
+ public void fatalError(SAXParseException x) throws SAXException {
+ throw x;
+ }
+ public void warning(SAXParseException x) throws SAXException {
+ throw x;
+ }
+ }
+
+}
--- a/jdk/src/share/classes/sun/util/xml/XMLUtils.java Fri Oct 05 09:57:50 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.util.xml;
-
-import java.io.*;
-import java.util.*;
-import org.xml.sax.*;
-import org.xml.sax.helpers.*;
-import org.w3c.dom.*;
-import javax.xml.parsers.*;
-import javax.xml.transform.*;
-import javax.xml.transform.dom.*;
-import javax.xml.transform.stream.*;
-
-/**
- * A class used to aid in Properties load and save in XML. Keeping this
- * code outside of Properties helps reduce the number of classes loaded
- * when Properties is loaded.
- *
- * @author Michael McCloskey
- * @since 1.3
- */
-public class XMLUtils {
-
- // XML loading and saving methods for Properties
-
- // The required DTD URI for exported properties
- private static final String PROPS_DTD_URI =
- "http://java.sun.com/dtd/properties.dtd";
-
- private static final String PROPS_DTD =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
- "<!-- DTD for properties -->" +
- "<!ELEMENT properties ( comment?, entry* ) >"+
- "<!ATTLIST properties" +
- " version CDATA #FIXED \"1.0\">" +
- "<!ELEMENT comment (#PCDATA) >" +
- "<!ELEMENT entry (#PCDATA) >" +
- "<!ATTLIST entry " +
- " key CDATA #REQUIRED>";
-
- /**
- * Version number for the format of exported properties files.
- */
- private static final String EXTERNAL_XML_VERSION = "1.0";
-
- public static void load(Properties props, InputStream in)
- throws IOException, InvalidPropertiesFormatException
- {
- Document doc = null;
- try {
- doc = getLoadingDoc(in);
- } catch (SAXException saxe) {
- throw new InvalidPropertiesFormatException(saxe);
- }
- Element propertiesElement = doc.getDocumentElement();
- String xmlVersion = propertiesElement.getAttribute("version");
- if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
- throw new InvalidPropertiesFormatException(
- "Exported Properties file format version " + xmlVersion +
- " is not supported. This java installation can read" +
- " versions " + EXTERNAL_XML_VERSION + " or older. You" +
- " may need to install a newer version of JDK.");
- importProperties(props, propertiesElement);
- }
-
- static Document getLoadingDoc(InputStream in)
- throws SAXException, IOException
- {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setIgnoringElementContentWhitespace(true);
- dbf.setValidating(true);
- dbf.setCoalescing(true);
- dbf.setIgnoringComments(true);
- try {
- DocumentBuilder db = dbf.newDocumentBuilder();
- db.setEntityResolver(new Resolver());
- db.setErrorHandler(new EH());
- InputSource is = new InputSource(in);
- return db.parse(is);
- } catch (ParserConfigurationException x) {
- throw new Error(x);
- }
- }
-
- static void importProperties(Properties props, Element propertiesElement) {
- NodeList entries = propertiesElement.getChildNodes();
- int numEntries = entries.getLength();
- int start = numEntries > 0 &&
- entries.item(0).getNodeName().equals("comment") ? 1 : 0;
- for (int i=start; i<numEntries; i++) {
- Element entry = (Element)entries.item(i);
- if (entry.hasAttribute("key")) {
- Node n = entry.getFirstChild();
- String val = (n == null) ? "" : n.getNodeValue();
- props.setProperty(entry.getAttribute("key"), val);
- }
- }
- }
-
- public static void save(Properties props, OutputStream os, String comment,
- String encoding)
- throws IOException
- {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- DocumentBuilder db = null;
- try {
- db = dbf.newDocumentBuilder();
- } catch (ParserConfigurationException pce) {
- assert(false);
- }
- Document doc = db.newDocument();
- Element properties = (Element)
- doc.appendChild(doc.createElement("properties"));
-
- if (comment != null) {
- Element comments = (Element)properties.appendChild(
- doc.createElement("comment"));
- comments.appendChild(doc.createTextNode(comment));
- }
-
- synchronized (props) {
- for (String key : props.stringPropertyNames()) {
- Element entry = (Element)properties.appendChild(
- doc.createElement("entry"));
- entry.setAttribute("key", key);
- entry.appendChild(doc.createTextNode(props.getProperty(key)));
- }
- }
- emitDocument(doc, os, encoding);
- }
-
- static void emitDocument(Document doc, OutputStream os, String encoding)
- throws IOException
- {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer t = null;
- try {
- t = tf.newTransformer();
- t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI);
- t.setOutputProperty(OutputKeys.INDENT, "yes");
- t.setOutputProperty(OutputKeys.METHOD, "xml");
- t.setOutputProperty(OutputKeys.ENCODING, encoding);
- } catch (TransformerConfigurationException tce) {
- assert(false);
- }
- DOMSource doms = new DOMSource(doc);
- StreamResult sr = new StreamResult(os);
- try {
- t.transform(doms, sr);
- } catch (TransformerException te) {
- IOException ioe = new IOException();
- ioe.initCause(te);
- throw ioe;
- }
- }
-
- private static class Resolver implements EntityResolver {
- public InputSource resolveEntity(String pid, String sid)
- throws SAXException
- {
- if (sid.equals(PROPS_DTD_URI)) {
- InputSource is;
- is = new InputSource(new StringReader(PROPS_DTD));
- is.setSystemId(PROPS_DTD_URI);
- return is;
- }
- throw new SAXException("Invalid system identifier: " + sid);
- }
- }
-
- private static class EH implements ErrorHandler {
- public void error(SAXParseException x) throws SAXException {
- throw x;
- }
- public void fatalError(SAXParseException x) throws SAXException {
- throw x;
- }
- public void warning(SAXParseException x) throws SAXException {
- throw x;
- }
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Properties/CustomProvider.java Sat Oct 06 13:56:16 2012 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8000354
+ * @summary Test
+ * @compile -XDignore.symbol.file CustomProvider.java MyXmlPropertiesProvider.java
+ * @run main/othervm -Dsun.util.spi.XmlPropertiesProvider=MyXmlPropertiesProvider CustomProvider
+ */
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Sanity test to verify that the property sun.util.spi.XmlPropertiesProvider
+ * can be used to specify a custom provider for loading/storing properties
+ * in XML format.
+ */
+public class CustomProvider {
+
+ public static void main(String[] args) throws IOException {
+ String provider = System.getProperty("sun.util.spi.XmlPropertiesProvider");
+ assertTrue(provider != null, "sun.util.spi.XmlPropertiesProvider not set");
+
+ OutputStream out = new ByteArrayOutputStream();
+ InputStream in = new ByteArrayInputStream(new byte[100]);
+
+ Properties props;
+
+ props = new Properties();
+ props.loadFromXML(in);
+
+ props = System.getProperties();
+ props.storeToXML(out, "comment");
+ props.storeToXML(out, "comment", "UTF-8");
+
+ // check that the provider's load and store methods have been invoked
+
+ assertTrue(MyXmlPropertiesProvider.createCount() == 1,
+ "Provider should only be created once");
+ assertTrue(MyXmlPropertiesProvider.loadCount() == 1,
+ "load method expected to be called once");
+ assertTrue(MyXmlPropertiesProvider.storeCount() == 2,
+ "store method expected to be called twice");
+ }
+
+ static void assertTrue(boolean b, String msg) {
+ if (!b) throw new RuntimeException(msg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Properties/LoadAndStoreXML.java Sat Oct 06 13:56:16 2012 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8000354
+ * @summary Basic test of storeToXML and loadToXML
+ */
+
+import java.io.*;
+import java.util.*;
+import java.security.*;
+
+public class LoadAndStoreXML {
+
+ /**
+ * Simple policy implementation that grants a set of permissions to
+ * all code sources and protection domains.
+ */
+ static class SimplePolicy extends Policy {
+ private final Permissions perms;
+
+ public SimplePolicy(Permission...permissions) {
+ perms = new Permissions();
+ for (Permission permission : permissions)
+ perms.add(permission);
+ }
+
+ @Override
+ public PermissionCollection getPermissions(CodeSource cs) {
+ return perms;
+ }
+
+ @Override
+ public PermissionCollection getPermissions(ProtectionDomain pd) {
+ return perms;
+ }
+
+ @Override
+ public boolean implies(ProtectionDomain pd, Permission p) {
+ return perms.implies(p);
+ }
+ }
+
+ /**
+ * Sanity test that properties saved with Properties#storeToXML can be
+ * read with Properties#loadFromXML.
+ */
+ static void test() throws IOException {
+ Properties props = new Properties();
+ props.put("k1", "foo");
+ props.put("k2", "bar");
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ props.storeToXML(out, "no comment");
+
+ Properties p = new Properties();
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ p.loadFromXML(in);
+
+ if (!p.equals(props)) {
+ System.err.println("stored: " + props);
+ System.err.println("loaded: " + p);
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ public static void main(String[] args) throws IOException {
+
+ // run test without security manager
+ test();
+
+ // re-run test with security manager
+ Policy orig = Policy.getPolicy();
+ Policy p = new SimplePolicy(new RuntimePermission("setSecurityManager"),
+ new PropertyPermission("line.separator", "read"));
+ Policy.setPolicy(p);
+ System.setSecurityManager(new SecurityManager());
+ try {
+ test();
+ } finally {
+ // turn off security manager and restore policy
+ System.setSecurityManager(null);
+ Policy.setPolicy(orig);
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Properties/MyXmlPropertiesProvider.java Sat Oct 06 13:56:16 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.*;
+import java.io.*;
+
+public class MyXmlPropertiesProvider
+ extends sun.util.spi.XmlPropertiesProvider
+{
+ private static int createCount;
+ private static int loadCount;
+ private static int storeCount;
+
+ static int createCount() { return createCount; }
+ static int loadCount() { return loadCount; }
+ static int storeCount() { return storeCount; }
+
+ public MyXmlPropertiesProvider() {
+ createCount++;
+ }
+
+ @Override
+ public void load(Properties props, InputStream in)
+ throws IOException, InvalidPropertiesFormatException
+ {
+ loadCount++;
+ }
+
+ @Override
+ public void store(Properties props, OutputStream out,
+ String comment, String encoding)
+ throws IOException
+ {
+ storeCount++;
+ }
+}