123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
-
- package org.apache.poi.util;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.reflect.Method;
-
- import javax.xml.XMLConstants;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.ParserConfigurationException;
- import javax.xml.stream.events.Namespace;
-
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.xml.sax.SAXException;
-
- public final class DocumentHelper {
- private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class);
-
- private DocumentHelper() {}
-
- /**
- * Creates a new document builder, with sensible defaults
- */
- public static synchronized DocumentBuilder newDocumentBuilder() {
- try {
- DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
- documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
- return documentBuilder;
- } catch (ParserConfigurationException e) {
- throw new IllegalStateException("cannot create a DocumentBuilder", e);
- }
- }
-
- private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- static {
- documentBuilderFactory.setNamespaceAware(true);
- documentBuilderFactory.setValidating(false);
- trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
- trySetXercesSecurityManager(documentBuilderFactory);
- }
-
- private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
- try {
- documentBuilderFactory.setFeature(feature, enabled);
- } catch (Exception e) {
- logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e);
- } catch (AbstractMethodError ame) {
- logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
- }
- }
-
- private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) {
- // Try built-in JVM one first, standalone if not
- for (String securityManagerClassName : new String[] {
- "com.sun.org.apache.xerces.internal.util.SecurityManager",
- "org.apache.xerces.util.SecurityManager"
- }) {
- try {
- Object mgr = Class.forName(securityManagerClassName).newInstance();
- Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
- setLimit.invoke(mgr, 4096);
- documentBuilderFactory.setAttribute("http://apache.org/xml/properties/security-manager", mgr);
- // Stop once one can be setup without error
- return;
- } catch (Exception e) {
- logger.log(POILogger.WARN, "SAX Security Manager could not be setup", e);
- }
- }
- }
-
- /**
- * Parses the given stream via the default (sensible)
- * DocumentBuilder
- * @param inp Stream to read the XML data from
- * @return the parsed Document
- */
- public static Document readDocument(InputStream inp) throws IOException, SAXException {
- return newDocumentBuilder().parse(inp);
- }
-
- // must only be used to create empty documents, do not use it for parsing!
- private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
-
- /**
- * Creates a new DOM Document
- */
- public static synchronized Document createDocument() {
- return documentBuilderSingleton.newDocument();
- }
-
- /**
- * Adds a namespace declaration attribute to the given element.
- */
- public static void addNamespaceDeclaration(Element element, String namespacePrefix, String namespaceURI) {
- element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
- XMLConstants.XMLNS_ATTRIBUTE + ':' + namespacePrefix,
- namespaceURI);
- }
-
- /**
- * Adds a namespace declaration attribute to the given element.
- */
- public static void addNamespaceDeclaration(Element element, Namespace namespace) {
- addNamespaceDeclaration(element, namespace.getPrefix(), namespace.getNamespaceURI());
- }
-
- }
|