Home » openjdk-7 » java » util » [javadoc | source]

    1   /*
    2    * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.util;
   27   
   28   import java.io;
   29   import org.xml.sax;
   30   import org.xml.sax.helpers;
   31   import org.w3c.dom;
   32   import javax.xml.parsers;
   33   import javax.xml.transform;
   34   import javax.xml.transform.dom;
   35   import javax.xml.transform.stream;
   36   
   37   /**
   38    * A class used to aid in Properties load and save in XML. Keeping this
   39    * code outside of Properties helps reduce the number of classes loaded
   40    * when Properties is loaded.
   41    *
   42    * @author  Michael McCloskey
   43    * @since   1.3
   44    */
   45   class XMLUtils {
   46   
   47       // XML loading and saving methods for Properties
   48   
   49       // The required DTD URI for exported properties
   50       private static final String PROPS_DTD_URI =
   51       "http://java.sun.com/dtd/properties.dtd";
   52   
   53       private static final String PROPS_DTD =
   54       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
   55       "<!-- DTD for properties -->"                +
   56       "<!ELEMENT properties ( comment?, entry* ) >"+
   57       "<!ATTLIST properties"                       +
   58           " version CDATA #FIXED \"1.0\">"         +
   59       "<!ELEMENT comment (#PCDATA) >"              +
   60       "<!ELEMENT entry (#PCDATA) >"                +
   61       "<!ATTLIST entry "                           +
   62           " key CDATA #REQUIRED>";
   63   
   64       /**
   65        * Version number for the format of exported properties files.
   66        */
   67       private static final String EXTERNAL_XML_VERSION = "1.0";
   68   
   69       static void load(Properties props, InputStream in)
   70           throws IOException, InvalidPropertiesFormatException
   71       {
   72           Document doc = null;
   73           try {
   74               doc = getLoadingDoc(in);
   75           } catch (SAXException saxe) {
   76               throw new InvalidPropertiesFormatException(saxe);
   77           }
   78           Element propertiesElement = (Element)doc.getChildNodes().item(1);
   79           String xmlVersion = propertiesElement.getAttribute("version");
   80           if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
   81               throw new InvalidPropertiesFormatException(
   82                   "Exported Properties file format version " + xmlVersion +
   83                   " is not supported. This java installation can read" +
   84                   " versions " + EXTERNAL_XML_VERSION + " or older. You" +
   85                   " may need to install a newer version of JDK.");
   86           importProperties(props, propertiesElement);
   87       }
   88   
   89       static Document getLoadingDoc(InputStream in)
   90           throws SAXException, IOException
   91       {
   92           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
   93           dbf.setIgnoringElementContentWhitespace(true);
   94           dbf.setValidating(true);
   95           dbf.setCoalescing(true);
   96           dbf.setIgnoringComments(true);
   97           try {
   98               DocumentBuilder db = dbf.newDocumentBuilder();
   99               db.setEntityResolver(new Resolver());
  100               db.setErrorHandler(new EH());
  101               InputSource is = new InputSource(in);
  102               return db.parse(is);
  103           } catch (ParserConfigurationException x) {
  104               throw new Error(x);
  105           }
  106       }
  107   
  108       static void importProperties(Properties props, Element propertiesElement) {
  109           NodeList entries = propertiesElement.getChildNodes();
  110           int numEntries = entries.getLength();
  111           int start = numEntries > 0 &&
  112               entries.item(0).getNodeName().equals("comment") ? 1 : 0;
  113           for (int i=start; i<numEntries; i++) {
  114               Element entry = (Element)entries.item(i);
  115               if (entry.hasAttribute("key")) {
  116                   Node n = entry.getFirstChild();
  117                   String val = (n == null) ? "" : n.getNodeValue();
  118                   props.setProperty(entry.getAttribute("key"), val);
  119               }
  120           }
  121       }
  122   
  123       static void save(Properties props, OutputStream os, String comment,
  124                        String encoding)
  125           throws IOException
  126       {
  127           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  128           DocumentBuilder db = null;
  129           try {
  130               db = dbf.newDocumentBuilder();
  131           } catch (ParserConfigurationException pce) {
  132               assert(false);
  133           }
  134           Document doc = db.newDocument();
  135           Element properties =  (Element)
  136               doc.appendChild(doc.createElement("properties"));
  137   
  138           if (comment != null) {
  139               Element comments = (Element)properties.appendChild(
  140                   doc.createElement("comment"));
  141               comments.appendChild(doc.createTextNode(comment));
  142           }
  143   
  144           synchronized (props) {
  145               for (String key : props.stringPropertyNames()) {
  146                   Element entry = (Element)properties.appendChild(
  147                       doc.createElement("entry"));
  148                   entry.setAttribute("key", key);
  149                   entry.appendChild(doc.createTextNode(props.getProperty(key)));
  150               }
  151           }
  152           emitDocument(doc, os, encoding);
  153       }
  154   
  155       static void emitDocument(Document doc, OutputStream os, String encoding)
  156           throws IOException
  157       {
  158           TransformerFactory tf = TransformerFactory.newInstance();
  159           Transformer t = null;
  160           try {
  161               t = tf.newTransformer();
  162               t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI);
  163               t.setOutputProperty(OutputKeys.INDENT, "yes");
  164               t.setOutputProperty(OutputKeys.METHOD, "xml");
  165               t.setOutputProperty(OutputKeys.ENCODING, encoding);
  166           } catch (TransformerConfigurationException tce) {
  167               assert(false);
  168           }
  169           DOMSource doms = new DOMSource(doc);
  170           StreamResult sr = new StreamResult(os);
  171           try {
  172               t.transform(doms, sr);
  173           } catch (TransformerException te) {
  174               IOException ioe = new IOException();
  175               ioe.initCause(te);
  176               throw ioe;
  177           }
  178       }
  179   
  180       private static class Resolver implements EntityResolver {
  181           public InputSource resolveEntity(String pid, String sid)
  182               throws SAXException
  183           {
  184               if (sid.equals(PROPS_DTD_URI)) {
  185                   InputSource is;
  186                   is = new InputSource(new StringReader(PROPS_DTD));
  187                   is.setSystemId(PROPS_DTD_URI);
  188                   return is;
  189               }
  190               throw new SAXException("Invalid system identifier: " + sid);
  191           }
  192       }
  193   
  194       private static class EH implements ErrorHandler {
  195           public void error(SAXParseException x) throws SAXException {
  196               throw x;
  197           }
  198           public void fatalError(SAXParseException x) throws SAXException {
  199               throw x;
  200           }
  201           public void warning(SAXParseException x) throws SAXException {
  202               throw x;
  203           }
  204       }
  205   
  206   }

Home » openjdk-7 » java » util » [javadoc | source]