Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/util/xml/PlatformXmlPropertiesProvider.java
38918 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.util.xml;2627import java.io.*;28import java.util.*;29import java.nio.charset.*;30import java.util.Map.Entry;31import org.xml.sax.*;32import org.w3c.dom.*;33import javax.xml.parsers.*;34import javax.xml.transform.*;35import javax.xml.transform.dom.*;36import javax.xml.transform.stream.*;3738import sun.util.spi.XmlPropertiesProvider;3940/**41* A {@code XmlPropertiesProvider} implementation that uses the JAXP API42* for parsing.43*44* @author Michael McCloskey45* @since 1.346*/47public class PlatformXmlPropertiesProvider extends XmlPropertiesProvider {4849// XML loading and saving methods for Properties5051// The required DTD URI for exported properties52private static final String PROPS_DTD_URI =53"http://java.sun.com/dtd/properties.dtd";5455private static final String PROPS_DTD =56"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +57"<!-- DTD for properties -->" +58"<!ELEMENT properties ( comment?, entry* ) >"+59"<!ATTLIST properties" +60" version CDATA #FIXED \"1.0\">" +61"<!ELEMENT comment (#PCDATA) >" +62"<!ELEMENT entry (#PCDATA) >" +63"<!ATTLIST entry " +64" key CDATA #REQUIRED>";6566/**67* Version number for the format of exported properties files.68*/69private static final String EXTERNAL_XML_VERSION = "1.0";7071@Override72public void load(Properties props, InputStream in)73throws IOException, InvalidPropertiesFormatException74{75Document doc = null;76try {77doc = getLoadingDoc(in);78} catch (SAXException saxe) {79throw new InvalidPropertiesFormatException(saxe);80}81Element propertiesElement = doc.getDocumentElement();82String xmlVersion = propertiesElement.getAttribute("version");83if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)84throw new InvalidPropertiesFormatException(85"Exported Properties file format version " + xmlVersion +86" is not supported. This java installation can read" +87" versions " + EXTERNAL_XML_VERSION + " or older. You" +88" may need to install a newer version of JDK.");89importProperties(props, propertiesElement);90}9192static Document getLoadingDoc(InputStream in)93throws SAXException, IOException94{95DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();96dbf.setIgnoringElementContentWhitespace(true);97dbf.setValidating(true);98dbf.setCoalescing(true);99dbf.setIgnoringComments(true);100try {101DocumentBuilder db = dbf.newDocumentBuilder();102db.setEntityResolver(new Resolver());103db.setErrorHandler(new EH());104InputSource is = new InputSource(in);105return db.parse(is);106} catch (ParserConfigurationException x) {107throw new Error(x);108}109}110111static void importProperties(Properties props, Element propertiesElement) {112NodeList entries = propertiesElement.getChildNodes();113int numEntries = entries.getLength();114int start = numEntries > 0 &&115entries.item(0).getNodeName().equals("comment") ? 1 : 0;116for (int i=start; i<numEntries; i++) {117Element entry = (Element)entries.item(i);118if (entry.hasAttribute("key")) {119Node n = entry.getFirstChild();120String val = (n == null) ? "" : n.getNodeValue();121props.setProperty(entry.getAttribute("key"), val);122}123}124}125126@Override127public void store(Properties props, OutputStream os, String comment,128String encoding)129throws IOException130{131// fast-fail for unsupported charsets as UnsupportedEncodingException may132// not be thrown later (see JDK-8000621)133try {134Charset.forName(encoding);135} catch (IllegalCharsetNameException | UnsupportedCharsetException x) {136throw new UnsupportedEncodingException(encoding);137}138DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();139DocumentBuilder db = null;140try {141db = dbf.newDocumentBuilder();142} catch (ParserConfigurationException pce) {143assert(false);144}145Document doc = db.newDocument();146Element properties = (Element)147doc.appendChild(doc.createElement("properties"));148149if (comment != null) {150Element comments = (Element)properties.appendChild(151doc.createElement("comment"));152comments.appendChild(doc.createTextNode(comment));153}154155synchronized (props) {156for (Entry<Object, Object> e : props.entrySet()) {157final Object k = e.getKey();158final Object v = e.getValue();159if (k instanceof String && v instanceof String) {160Element entry = (Element)properties.appendChild(161doc.createElement("entry"));162entry.setAttribute("key", (String)k);163entry.appendChild(doc.createTextNode((String)v));164}165}166}167emitDocument(doc, os, encoding);168}169170static void emitDocument(Document doc, OutputStream os, String encoding)171throws IOException172{173TransformerFactory tf = TransformerFactory.newInstance();174Transformer t = null;175try {176t = tf.newTransformer();177t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI);178t.setOutputProperty(OutputKeys.INDENT, "yes");179t.setOutputProperty(OutputKeys.METHOD, "xml");180t.setOutputProperty(OutputKeys.ENCODING, encoding);181} catch (TransformerConfigurationException tce) {182assert(false);183}184DOMSource doms = new DOMSource(doc);185StreamResult sr = new StreamResult(os);186try {187t.transform(doms, sr);188} catch (TransformerException te) {189throw new IOException(te);190}191}192193private static class Resolver implements EntityResolver {194public InputSource resolveEntity(String pid, String sid)195throws SAXException196{197if (sid.equals(PROPS_DTD_URI)) {198InputSource is;199is = new InputSource(new StringReader(PROPS_DTD));200is.setSystemId(PROPS_DTD_URI);201return is;202}203throw new SAXException("Invalid system identifier: " + sid);204}205}206207private static class EH implements ErrorHandler {208public void error(SAXParseException x) throws SAXException {209throw x;210}211public void fatalError(SAXParseException x) throws SAXException {212throw x;213}214public void warning(SAXParseException x) throws SAXException {215throw x;216}217}218219}220221222