diff -r 6dcea85ad8ba -r 75acc009e9d8 src/share/classes/java/util/prefs/XmlSupport.java --- a/src/share/classes/java/util/prefs/XmlSupport.java Mon Jun 22 18:07:11 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,421 +0,0 @@ -/* - * Copyright 2002-2006 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package java.util.prefs; - -import java.util.*; -import java.io.*; -import javax.xml.parsers.*; -import javax.xml.transform.*; -import javax.xml.transform.dom.*; -import javax.xml.transform.stream.*; -import org.xml.sax.*; -import org.w3c.dom.*; - -/** - * XML Support for java.util.prefs. Methods to import and export preference - * nodes and subtrees. - * - * @author Josh Bloch and Mark Reinhold - * @see Preferences - * @since 1.4 - */ -class XmlSupport { - // The required DTD URI for exported preferences - private static final String PREFS_DTD_URI = - "http://java.sun.com/dtd/preferences.dtd"; - - // The actual DTD corresponding to the URI - private static final String PREFS_DTD = - "" + - - "" + - - "" + - "" + - - "" + - "" + - - "" + - "" + - - "" + - "" + - "" + - "" ; - /** - * Version number for the format exported preferences files. - */ - private static final String EXTERNAL_XML_VERSION = "1.0"; - - /* - * Version number for the internal map files. - */ - private static final String MAP_XML_VERSION = "1.0"; - - /** - * Export the specified preferences node and, if subTree is true, all - * subnodes, to the specified output stream. Preferences are exported as - * an XML document conforming to the definition in the Preferences spec. - * - * @throws IOException if writing to the specified output stream - * results in an IOException. - * @throws BackingStoreException if preference data cannot be read from - * backing store. - * @throws IllegalStateException if this node (or an ancestor) has been - * removed with the {@link #removeNode()} method. - */ - static void export(OutputStream os, final Preferences p, boolean subTree) - throws IOException, BackingStoreException { - if (((AbstractPreferences)p).isRemoved()) - throw new IllegalStateException("Node has been removed"); - Document doc = createPrefsDoc("preferences"); - Element preferences = doc.getDocumentElement() ; - preferences.setAttribute("EXTERNAL_XML_VERSION", EXTERNAL_XML_VERSION); - Element xmlRoot = (Element) - preferences.appendChild(doc.createElement("root")); - xmlRoot.setAttribute("type", (p.isUserNode() ? "user" : "system")); - - // Get bottom-up list of nodes from p to root, excluding root - List ancestors = new ArrayList(); - - for (Preferences kid = p, dad = kid.parent(); dad != null; - kid = dad, dad = kid.parent()) { - ancestors.add(kid); - } - Element e = xmlRoot; - for (int i=ancestors.size()-1; i >= 0; i--) { - e.appendChild(doc.createElement("map")); - e = (Element) e.appendChild(doc.createElement("node")); - e.setAttribute("name", ((Preferences)ancestors.get(i)).name()); - } - putPreferencesInXml(e, doc, p, subTree); - - writeDoc(doc, os); - } - - /** - * Put the preferences in the specified Preferences node into the - * specified XML element which is assumed to represent a node - * in the specified XML document which is assumed to conform to - * PREFS_DTD. If subTree is true, create children of the specified - * XML node conforming to all of the children of the specified - * Preferences node and recurse. - * - * @throws BackingStoreException if it is not possible to read - * the preferences or children out of the specified - * preferences node. - */ - private static void putPreferencesInXml(Element elt, Document doc, - Preferences prefs, boolean subTree) throws BackingStoreException - { - Preferences[] kidsCopy = null; - String[] kidNames = null; - - // Node is locked to export its contents and get a - // copy of children, then lock is released, - // and, if subTree = true, recursive calls are made on children - synchronized (((AbstractPreferences)prefs).lock) { - // Check if this node was concurrently removed. If yes - // remove it from XML Document and return. - if (((AbstractPreferences)prefs).isRemoved()) { - elt.getParentNode().removeChild(elt); - return; - } - // Put map in xml element - String[] keys = prefs.keys(); - Element map = (Element) elt.appendChild(doc.createElement("map")); - for (int i=0; iIOException. - * @throws InvalidPreferencesFormatException Data on input stream does not - * constitute a valid XML document with the mandated document type. - */ - static void importPreferences(InputStream is) - throws IOException, InvalidPreferencesFormatException - { - try { - Document doc = loadPrefsDoc(is); - String xmlVersion = - doc.getDocumentElement().getAttribute("EXTERNAL_XML_VERSION"); - if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) - throw new InvalidPreferencesFormatException( - "Exported preferences 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."); - - Element xmlRoot = (Element) doc.getDocumentElement(). - getChildNodes().item(0); - Preferences prefsRoot = - (xmlRoot.getAttribute("type").equals("user") ? - Preferences.userRoot() : Preferences.systemRoot()); - ImportSubtree(prefsRoot, xmlRoot); - } catch(SAXException e) { - throw new InvalidPreferencesFormatException(e); - } - } - - /** - * Create a new prefs XML document. - */ - private static Document createPrefsDoc( String qname ) { - try { - DOMImplementation di = DocumentBuilderFactory.newInstance(). - newDocumentBuilder().getDOMImplementation(); - DocumentType dt = di.createDocumentType(qname, null, PREFS_DTD_URI); - return di.createDocument(null, qname, dt); - } catch(ParserConfigurationException e) { - throw new AssertionError(e); - } - } - - /** - * Load an XML document from specified input stream, which must - * have the requisite DTD URI. - */ - private static Document loadPrefsDoc(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()); - return db.parse(new InputSource(in)); - } catch (ParserConfigurationException e) { - throw new AssertionError(e); - } - } - - /** - * Write XML document to the specified output stream. - */ - private static final void writeDoc(Document doc, OutputStream out) - throws IOException - { - try { - TransformerFactory tf = TransformerFactory.newInstance(); - try { - tf.setAttribute("indent-number", new Integer(2)); - } catch (IllegalArgumentException iae) { - //Ignore the IAE. Should not fail the writeout even the - //transformer provider does not support "indent-number". - } - Transformer t = tf.newTransformer(); - t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); - t.setOutputProperty(OutputKeys.INDENT, "yes"); - //Transformer resets the "indent" info if the "result" is a StreamResult with - //an OutputStream object embedded, creating a Writer object on top of that - //OutputStream object however works. - t.transform(new DOMSource(doc), - new StreamResult(new BufferedWriter(new OutputStreamWriter(out, "UTF-8")))); - } catch(TransformerException e) { - throw new AssertionError(e); - } - } - - /** - * Recursively traverse the specified preferences node and store - * the described preferences into the system or current user - * preferences tree, as appropriate. - */ - private static void ImportSubtree(Preferences prefsNode, Element xmlNode) { - NodeList xmlKids = xmlNode.getChildNodes(); - int numXmlKids = xmlKids.getLength(); - /* - * We first lock the node, import its contents and get - * child nodes. Then we unlock the node and go to children - * Since some of the children might have been concurrently - * deleted we check for this. - */ - Preferences[] prefsKids; - /* Lock the node */ - synchronized (((AbstractPreferences)prefsNode).lock) { - //If removed, return silently - if (((AbstractPreferences)prefsNode).isRemoved()) - return; - - // Import any preferences at this node - Element firstXmlKid = (Element) xmlKids.item(0); - ImportPrefs(prefsNode, firstXmlKid); - prefsKids = new Preferences[numXmlKids - 1]; - - // Get involved children - for (int i=1; i < numXmlKids; i++) { - Element xmlKid = (Element) xmlKids.item(i); - prefsKids[i-1] = prefsNode.node(xmlKid.getAttribute("name")); - } - } // unlocked the node - // import children - for (int i=1; i < numXmlKids; i++) - ImportSubtree(prefsKids[i-1], (Element)xmlKids.item(i)); - } - - /** - * Import the preferences described by the specified XML element - * (a map from a preferences document) into the specified - * preferences node. - */ - private static void ImportPrefs(Preferences prefsNode, Element map) { - NodeList entries = map.getChildNodes(); - for (int i=0, numEntries = entries.getLength(); i < numEntries; i++) { - Element entry = (Element) entries.item(i); - prefsNode.put(entry.getAttribute("key"), - entry.getAttribute("value")); - } - } - - /** - * Export the specified Map to a map document on - * the specified OutputStream as per the prefs DTD. This is used - * as the internal (undocumented) format for FileSystemPrefs. - * - * @throws IOException if writing to the specified output stream - * results in an IOException. - */ - static void exportMap(OutputStream os, Map map) throws IOException { - Document doc = createPrefsDoc("map"); - Element xmlMap = doc.getDocumentElement( ) ; - xmlMap.setAttribute("MAP_XML_VERSION", MAP_XML_VERSION); - - for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) { - Map.Entry e = (Map.Entry) i.next(); - Element xe = (Element) - xmlMap.appendChild(doc.createElement("entry")); - xe.setAttribute("key", (String) e.getKey()); - xe.setAttribute("value", (String) e.getValue()); - } - - writeDoc(doc, os); - } - - /** - * Import Map from the specified input stream, which is assumed - * to contain a map document as per the prefs DTD. This is used - * as the internal (undocumented) format for FileSystemPrefs. The - * key-value pairs specified in the XML document will be put into - * the specified Map. (If this Map is empty, it will contain exactly - * the key-value pairs int the XML-document when this method returns.) - * - * @throws IOException if reading from the specified output stream - * results in an IOException. - * @throws InvalidPreferencesFormatException Data on input stream does not - * constitute a valid XML document with the mandated document type. - */ - static void importMap(InputStream is, Map m) - throws IOException, InvalidPreferencesFormatException - { - try { - Document doc = loadPrefsDoc(is); - Element xmlMap = doc.getDocumentElement(); - // check version - String mapVersion = xmlMap.getAttribute("MAP_XML_VERSION"); - if (mapVersion.compareTo(MAP_XML_VERSION) > 0) - throw new InvalidPreferencesFormatException( - "Preferences map file format version " + mapVersion + - " is not supported. This java installation can read" + - " versions " + MAP_XML_VERSION + " or older. You may need" + - " to install a newer version of JDK."); - - NodeList entries = xmlMap.getChildNodes(); - for (int i=0, numEntries=entries.getLength(); i