Source Code Cross Referenced for XmlSupport.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » prefs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util.prefs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2002-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.util.prefs;
027
028        import java.util.*;
029        import java.io.*;
030        import javax.xml.parsers.*;
031        import javax.xml.transform.*;
032        import javax.xml.transform.dom.*;
033        import javax.xml.transform.stream.*;
034        import org.xml.sax.*;
035        import org.w3c.dom.*;
036
037        /**
038         * XML Support for java.util.prefs. Methods to import and export preference
039         * nodes and subtrees.
040         *
041         * @author  Josh Bloch and Mark Reinhold
042         * @version 1.17, 05/05/07
043         * @see     Preferences
044         * @since   1.4
045         */
046        class XmlSupport {
047            // The required DTD URI for exported preferences
048            private static final String PREFS_DTD_URI = "http://java.sun.com/dtd/preferences.dtd";
049
050            // The actual DTD corresponding to the URI
051            private static final String PREFS_DTD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
052                    +
053
054                    "<!-- DTD for preferences -->"
055                    +
056
057                    "<!ELEMENT preferences (root) >"
058                    + "<!ATTLIST preferences"
059                    + " EXTERNAL_XML_VERSION CDATA \"0.0\"  >"
060                    +
061
062                    "<!ELEMENT root (map, node*) >"
063                    + "<!ATTLIST root"
064                    + "          type (system|user) #REQUIRED >"
065                    +
066
067                    "<!ELEMENT node (map, node*) >"
068                    + "<!ATTLIST node"
069                    + "          name CDATA #REQUIRED >"
070                    +
071
072                    "<!ELEMENT map (entry*) >"
073                    + "<!ATTLIST map"
074                    + "  MAP_XML_VERSION CDATA \"0.0\"  >"
075                    + "<!ELEMENT entry EMPTY >"
076                    + "<!ATTLIST entry"
077                    + "          key CDATA #REQUIRED"
078                    + "          value CDATA #REQUIRED >";
079            /**
080             * Version number for the format exported preferences files.
081             */
082            private static final String EXTERNAL_XML_VERSION = "1.0";
083
084            /*
085             * Version number for the internal map files.
086             */
087            private static final String MAP_XML_VERSION = "1.0";
088
089            /**
090             * Export the specified preferences node and, if subTree is true, all
091             * subnodes, to the specified output stream.  Preferences are exported as
092             * an XML document conforming to the definition in the Preferences spec.
093             *
094             * @throws IOException if writing to the specified output stream
095             *         results in an <tt>IOException</tt>.
096             * @throws BackingStoreException if preference data cannot be read from
097             *         backing store.
098             * @throws IllegalStateException if this node (or an ancestor) has been
099             *         removed with the {@link #removeNode()} method.
100             */
101            static void export(OutputStream os, final Preferences p,
102                    boolean subTree) throws IOException, BackingStoreException {
103                if (((AbstractPreferences) p).isRemoved())
104                    throw new IllegalStateException("Node has been removed");
105                Document doc = createPrefsDoc("preferences");
106                Element preferences = doc.getDocumentElement();
107                preferences.setAttribute("EXTERNAL_XML_VERSION",
108                        EXTERNAL_XML_VERSION);
109                Element xmlRoot = (Element) preferences.appendChild(doc
110                        .createElement("root"));
111                xmlRoot.setAttribute("type", (p.isUserNode() ? "user"
112                        : "system"));
113
114                // Get bottom-up list of nodes from p to root, excluding root
115                List ancestors = new ArrayList();
116
117                for (Preferences kid = p, dad = kid.parent(); dad != null; kid = dad, dad = kid
118                        .parent()) {
119                    ancestors.add(kid);
120                }
121                Element e = xmlRoot;
122                for (int i = ancestors.size() - 1; i >= 0; i--) {
123                    e.appendChild(doc.createElement("map"));
124                    e = (Element) e.appendChild(doc.createElement("node"));
125                    e.setAttribute("name", ((Preferences) ancestors.get(i))
126                            .name());
127                }
128                putPreferencesInXml(e, doc, p, subTree);
129
130                writeDoc(doc, os);
131            }
132
133            /**
134             * Put the preferences in the specified Preferences node into the
135             * specified XML element which is assumed to represent a node
136             * in the specified XML document which is assumed to conform to 
137             * PREFS_DTD.  If subTree is true, create children of the specified
138             * XML node conforming to all of the children of the specified
139             * Preferences node and recurse.
140             *
141             * @throws BackingStoreException if it is not possible to read
142             *         the preferences or children out of the specified
143             *         preferences node.
144             */
145            private static void putPreferencesInXml(Element elt, Document doc,
146                    Preferences prefs, boolean subTree)
147                    throws BackingStoreException {
148                Preferences[] kidsCopy = null;
149                String[] kidNames = null;
150
151                // Node is locked to export its contents and get a 
152                // copy of children, then lock is released,
153                // and, if subTree = true, recursive calls are made on children
154                synchronized (((AbstractPreferences) prefs).lock) {
155                    // Check if this node was concurrently removed. If yes
156                    // remove it from XML Document and return.
157                    if (((AbstractPreferences) prefs).isRemoved()) {
158                        elt.getParentNode().removeChild(elt);
159                        return;
160                    }
161                    // Put map in xml element            
162                    String[] keys = prefs.keys();
163                    Element map = (Element) elt.appendChild(doc
164                            .createElement("map"));
165                    for (int i = 0; i < keys.length; i++) {
166                        Element entry = (Element) map.appendChild(doc
167                                .createElement("entry"));
168                        entry.setAttribute("key", keys[i]);
169                        // NEXT STATEMENT THROWS NULL PTR EXC INSTEAD OF ASSERT FAIL
170                        entry.setAttribute("value", prefs.get(keys[i], null));
171                    }
172                    // Recurse if appropriate
173                    if (subTree) {
174                        /* Get a copy of kids while lock is held */
175                        kidNames = prefs.childrenNames();
176                        kidsCopy = new Preferences[kidNames.length];
177                        for (int i = 0; i < kidNames.length; i++)
178                            kidsCopy[i] = prefs.node(kidNames[i]);
179                    }
180                    // release lock
181                }
182
183                if (subTree) {
184                    for (int i = 0; i < kidNames.length; i++) {
185                        Element xmlKid = (Element) elt.appendChild(doc
186                                .createElement("node"));
187                        xmlKid.setAttribute("name", kidNames[i]);
188                        putPreferencesInXml(xmlKid, doc, kidsCopy[i], subTree);
189                    }
190                }
191            }
192
193            /**
194             * Import preferences from the specified input stream, which is assumed
195             * to contain an XML document in the format described in the Preferences
196             * spec.
197             *
198             * @throws IOException if reading from the specified output stream
199             *         results in an <tt>IOException</tt>.
200             * @throws InvalidPreferencesFormatException Data on input stream does not
201             *         constitute a valid XML document with the mandated document type.
202             */
203            static void importPreferences(InputStream is) throws IOException,
204                    InvalidPreferencesFormatException {
205                try {
206                    Document doc = loadPrefsDoc(is);
207                    String xmlVersion = doc.getDocumentElement().getAttribute(
208                            "EXTERNAL_XML_VERSION");
209                    if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
210                        throw new InvalidPreferencesFormatException(
211                                "Exported preferences file format version "
212                                        + xmlVersion
213                                        + " is not supported. This java installation can read"
214                                        + " versions " + EXTERNAL_XML_VERSION
215                                        + " or older. You may need"
216                                        + " to install a newer version of JDK.");
217
218                    Element xmlRoot = (Element) doc.getDocumentElement()
219                            .getChildNodes().item(0);
220                    Preferences prefsRoot = (xmlRoot.getAttribute("type")
221                            .equals("user") ? Preferences.userRoot()
222                            : Preferences.systemRoot());
223                    ImportSubtree(prefsRoot, xmlRoot);
224                } catch (SAXException e) {
225                    throw new InvalidPreferencesFormatException(e);
226                }
227            }
228
229            /**
230             * Create a new prefs XML document.
231             */
232            private static Document createPrefsDoc(String qname) {
233                try {
234                    DOMImplementation di = DocumentBuilderFactory.newInstance()
235                            .newDocumentBuilder().getDOMImplementation();
236                    DocumentType dt = di.createDocumentType(qname, null,
237                            PREFS_DTD_URI);
238                    return di.createDocument(null, qname, dt);
239                } catch (ParserConfigurationException e) {
240                    throw new AssertionError(e);
241                }
242            }
243
244            /**
245             * Load an XML document from specified input stream, which must
246             * have the requisite DTD URI.
247             */
248            private static Document loadPrefsDoc(InputStream in)
249                    throws SAXException, IOException {
250                DocumentBuilderFactory dbf = DocumentBuilderFactory
251                        .newInstance();
252                dbf.setIgnoringElementContentWhitespace(true);
253                dbf.setValidating(true);
254                dbf.setCoalescing(true);
255                dbf.setIgnoringComments(true);
256                try {
257                    DocumentBuilder db = dbf.newDocumentBuilder();
258                    db.setEntityResolver(new Resolver());
259                    db.setErrorHandler(new EH());
260                    return db.parse(new InputSource(in));
261                } catch (ParserConfigurationException e) {
262                    throw new AssertionError(e);
263                }
264            }
265
266            /**
267             * Write XML document to the specified output stream.
268             */
269            private static final void writeDoc(Document doc, OutputStream out)
270                    throws IOException {
271                try {
272                    TransformerFactory tf = TransformerFactory.newInstance();
273                    try {
274                        tf.setAttribute("indent-number", new Integer(2));
275                    } catch (IllegalArgumentException iae) {
276                        //Ignore the IAE. Should not fail the writeout even the
277                        //transformer provider does not support "indent-number".
278                    }
279                    Transformer t = tf.newTransformer();
280                    t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc
281                            .getDoctype().getSystemId());
282                    t.setOutputProperty(OutputKeys.INDENT, "yes");
283                    //Transformer resets the "indent" info if the "result" is a StreamResult with  
284                    //an OutputStream object embedded, creating a Writer object on top of that
285                    //OutputStream object however works.
286                    t.transform(new DOMSource(doc), new StreamResult(
287                            new BufferedWriter(new OutputStreamWriter(out,
288                                    "UTF-8"))));
289                } catch (TransformerException e) {
290                    throw new AssertionError(e);
291                }
292            }
293
294            /**
295             * Recursively traverse the specified preferences node and store
296             * the described preferences into the system or current user
297             * preferences tree, as appropriate.
298             */
299            private static void ImportSubtree(Preferences prefsNode,
300                    Element xmlNode) {
301                NodeList xmlKids = xmlNode.getChildNodes();
302                int numXmlKids = xmlKids.getLength();
303                /*
304                 * We first lock the node, import its contents and get
305                 * child nodes. Then we unlock the node and go to children
306                 * Since some of the children might have been concurrently
307                 * deleted we check for this. 
308                 */
309                Preferences[] prefsKids;
310                /* Lock the node */
311                synchronized (((AbstractPreferences) prefsNode).lock) {
312                    //If removed, return silently 
313                    if (((AbstractPreferences) prefsNode).isRemoved())
314                        return;
315
316                    // Import any preferences at this node
317                    Element firstXmlKid = (Element) xmlKids.item(0);
318                    ImportPrefs(prefsNode, firstXmlKid);
319                    prefsKids = new Preferences[numXmlKids - 1];
320
321                    // Get involved children 
322                    for (int i = 1; i < numXmlKids; i++) {
323                        Element xmlKid = (Element) xmlKids.item(i);
324                        prefsKids[i - 1] = prefsNode.node(xmlKid
325                                .getAttribute("name"));
326                    }
327                } // unlocked the node
328                // import children
329                for (int i = 1; i < numXmlKids; i++)
330                    ImportSubtree(prefsKids[i - 1], (Element) xmlKids.item(i));
331            }
332
333            /**
334             * Import the preferences described by the specified XML element
335             * (a map from a preferences document) into the specified
336             * preferences node.
337             */
338            private static void ImportPrefs(Preferences prefsNode, Element map) {
339                NodeList entries = map.getChildNodes();
340                for (int i = 0, numEntries = entries.getLength(); i < numEntries; i++) {
341                    Element entry = (Element) entries.item(i);
342                    prefsNode.put(entry.getAttribute("key"), entry
343                            .getAttribute("value"));
344                }
345            }
346
347            /**
348             * Export the specified Map<String,String> to a map document on
349             * the specified OutputStream as per the prefs DTD.  This is used
350             * as the internal (undocumented) format for FileSystemPrefs.
351             *
352             * @throws IOException if writing to the specified output stream
353             *         results in an <tt>IOException</tt>.
354             */
355            static void exportMap(OutputStream os, Map map) throws IOException {
356                Document doc = createPrefsDoc("map");
357                Element xmlMap = doc.getDocumentElement();
358                xmlMap.setAttribute("MAP_XML_VERSION", MAP_XML_VERSION);
359
360                for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
361                    Map.Entry e = (Map.Entry) i.next();
362                    Element xe = (Element) xmlMap.appendChild(doc
363                            .createElement("entry"));
364                    xe.setAttribute("key", (String) e.getKey());
365                    xe.setAttribute("value", (String) e.getValue());
366                }
367
368                writeDoc(doc, os);
369            }
370
371            /**
372             * Import Map from the specified input stream, which is assumed
373             * to contain a map document as per the prefs DTD.  This is used
374             * as the internal (undocumented) format for FileSystemPrefs.  The
375             * key-value pairs specified in the XML document will be put into
376             * the specified Map.  (If this Map is empty, it will contain exactly
377             * the key-value pairs int the XML-document when this method returns.)
378             *
379             * @throws IOException if reading from the specified output stream
380             *         results in an <tt>IOException</tt>.
381             * @throws InvalidPreferencesFormatException Data on input stream does not
382             *         constitute a valid XML document with the mandated document type.
383             */
384            static void importMap(InputStream is, Map m) throws IOException,
385                    InvalidPreferencesFormatException {
386                try {
387                    Document doc = loadPrefsDoc(is);
388                    Element xmlMap = doc.getDocumentElement();
389                    // check version
390                    String mapVersion = xmlMap.getAttribute("MAP_XML_VERSION");
391                    if (mapVersion.compareTo(MAP_XML_VERSION) > 0)
392                        throw new InvalidPreferencesFormatException(
393                                "Preferences map file format version "
394                                        + mapVersion
395                                        + " is not supported. This java installation can read"
396                                        + " versions " + MAP_XML_VERSION
397                                        + " or older. You may need"
398                                        + " to install a newer version of JDK.");
399
400                    NodeList entries = xmlMap.getChildNodes();
401                    for (int i = 0, numEntries = entries.getLength(); i < numEntries; i++) {
402                        Element entry = (Element) entries.item(i);
403                        m.put(entry.getAttribute("key"), entry
404                                .getAttribute("value"));
405                    }
406                } catch (SAXException e) {
407                    throw new InvalidPreferencesFormatException(e);
408                }
409            }
410
411            private static class Resolver implements  EntityResolver {
412                public InputSource resolveEntity(String pid, String sid)
413                        throws SAXException {
414                    if (sid.equals(PREFS_DTD_URI)) {
415                        InputSource is;
416                        is = new InputSource(new StringReader(PREFS_DTD));
417                        is.setSystemId(PREFS_DTD_URI);
418                        return is;
419                    }
420                    throw new SAXException("Invalid system identifier: " + sid);
421                }
422            }
423
424            private static class EH implements  ErrorHandler {
425                public void error(SAXParseException x) throws SAXException {
426                    throw x;
427                }
428
429                public void fatalError(SAXParseException x) throws SAXException {
430                    throw x;
431                }
432
433                public void warning(SAXParseException x) throws SAXException {
434                    throw x;
435                }
436            }
437        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.