source: josm/trunk/src/org/openstreetmap/josm/tools/XmlUtils.java@ 14093

Last change on this file since 14093 was 13901, checked in by Don-vip, 6 years ago

add new XmlUtils class with more "safe factories" methods

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.io.IOException;
5import java.io.InputStream;
6
7import javax.xml.XMLConstants;
8import javax.xml.parsers.DocumentBuilder;
9import javax.xml.parsers.DocumentBuilderFactory;
10import javax.xml.parsers.ParserConfigurationException;
11import javax.xml.parsers.SAXParser;
12import javax.xml.parsers.SAXParserFactory;
13import javax.xml.stream.XMLInputFactory;
14import javax.xml.transform.TransformerConfigurationException;
15import javax.xml.transform.TransformerFactory;
16import javax.xml.validation.SchemaFactory;
17import javax.xml.validation.SchemaFactoryConfigurationError;
18
19import org.w3c.dom.Document;
20import org.xml.sax.InputSource;
21import org.xml.sax.SAXException;
22import org.xml.sax.helpers.DefaultHandler;
23
24/**
25 * XML utils, mainly used to construct safe factories.
26 * @since 13901
27 */
28public final class XmlUtils {
29
30 private XmlUtils() {
31 // Hide default constructor for utils classes
32 }
33
34 /**
35 * Returns the W3C XML Schema factory implementation. Robust method dealing with ContextClassLoader problems.
36 * @return the W3C XML Schema factory implementation
37 */
38 public static SchemaFactory newXmlSchemaFactory() {
39 try {
40 return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
41 } catch (SchemaFactoryConfigurationError e) {
42 Logging.debug(e);
43 // Can happen with icedtea-web. Use workaround from https://issues.apache.org/jira/browse/GERONIMO-6185
44 Thread currentThread = Thread.currentThread();
45 ClassLoader old = currentThread.getContextClassLoader();
46 currentThread.setContextClassLoader(null);
47 try {
48 return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
49 } finally {
50 currentThread.setContextClassLoader(old);
51 }
52 }
53 }
54
55 /**
56 * Returns a new secure DOM builder, supporting XML namespaces.
57 * @return a new secure DOM builder, supporting XML namespaces
58 * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration.
59 */
60 public static DocumentBuilder newSafeDOMBuilder() throws ParserConfigurationException {
61 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
62 builderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
63 builderFactory.setNamespaceAware(true);
64 builderFactory.setValidating(false);
65 return builderFactory.newDocumentBuilder();
66 }
67
68 /**
69 * Parse the content given {@link InputStream} as XML.
70 * This method uses a secure DOM builder, supporting XML namespaces.
71 *
72 * @param is The InputStream containing the content to be parsed.
73 * @return the result DOM document
74 * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration.
75 * @throws IOException if any IO errors occur.
76 * @throws SAXException for SAX errors.
77 */
78 public static Document parseSafeDOM(InputStream is) throws ParserConfigurationException, IOException, SAXException {
79 long start = System.currentTimeMillis();
80 Logging.debug("Starting DOM parsing of {0}", is);
81 Document result = newSafeDOMBuilder().parse(is);
82 if (Logging.isDebugEnabled()) {
83 Logging.debug("DOM parsing done in {0}", Utils.getDurationString(System.currentTimeMillis() - start));
84 }
85 return result;
86 }
87
88 /**
89 * Returns a new secure SAX parser, supporting XML namespaces.
90 * @return a new secure SAX parser, supporting XML namespaces
91 * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration.
92 * @throws SAXException for SAX errors.
93 */
94 public static SAXParser newSafeSAXParser() throws ParserConfigurationException, SAXException {
95 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
96 parserFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
97 parserFactory.setNamespaceAware(true);
98 return parserFactory.newSAXParser();
99 }
100
101 /**
102 * Parse the content given {@link org.xml.sax.InputSource} as XML using the specified {@link org.xml.sax.helpers.DefaultHandler}.
103 * This method uses a secure SAX parser, supporting XML namespaces.
104 *
105 * @param is The InputSource containing the content to be parsed.
106 * @param dh The SAX DefaultHandler to use.
107 * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration.
108 * @throws SAXException for SAX errors.
109 * @throws IOException if any IO errors occur.
110 */
111 public static void parseSafeSAX(InputSource is, DefaultHandler dh) throws ParserConfigurationException, SAXException, IOException {
112 long start = System.currentTimeMillis();
113 Logging.debug("Starting SAX parsing of {0} using {1}", is, dh);
114 newSafeSAXParser().parse(is, dh);
115 if (Logging.isDebugEnabled()) {
116 Logging.debug("SAX parsing done in {0}", Utils.getDurationString(System.currentTimeMillis() - start));
117 }
118 }
119
120 /**
121 * Returns a new secure {@link XMLInputFactory}.
122 * @return a new secure {@code XMLInputFactory}, for which external entities are not loaded
123 */
124 public static XMLInputFactory newSafeXMLInputFactory() {
125 XMLInputFactory factory = XMLInputFactory.newInstance();
126 // do not try to load external entities, nor validate the XML
127 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
128 factory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
129 factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
130 return factory;
131 }
132
133 /**
134 * Returns a new secure {@link TransformerFactory}.
135 * @return a new secure {@link TransformerFactory}
136 * @throws TransformerConfigurationException if the factory or the Transformers or Templates it creates cannot support this feature.
137 */
138 public static TransformerFactory newSafeTransformerFactory() throws TransformerConfigurationException {
139 TransformerFactory factory = TransformerFactory.newInstance();
140 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
141 return factory;
142 }
143}
Note: See TracBrowser for help on using the repository browser.