Sonar Fixes + Refactor scattered XML initializations to XMLHelper

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1870769 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2019-12-03 21:56:47 +00:00
parent dd3279df30
commit 08159e66a7
34 changed files with 600 additions and 763 deletions

View File

@ -30,7 +30,7 @@ import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellReference; import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ooxml.util.SAXHelper; import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor; import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
import org.apache.poi.xssf.model.SharedStrings; import org.apache.poi.xssf.model.SharedStrings;
@ -188,7 +188,7 @@ public class XLSX2CSV {
DataFormatter formatter = new DataFormatter(); DataFormatter formatter = new DataFormatter();
InputSource sheetSource = new InputSource(sheetInputStream); InputSource sheetSource = new InputSource(sheetInputStream);
try { try {
XMLReader sheetParser = SAXHelper.newXMLReader(); XMLReader sheetParser = XMLHelper.newXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler( ContentHandler handler = new XSSFSheetXMLHandler(
styles, null, strings, sheetHandler, formatter, false); styles, null, strings, sheetHandler, formatter, false);
sheetParser.setContentHandler(handler); sheetParser.setContentHandler(handler);

View File

@ -23,13 +23,13 @@ import java.util.Map;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ooxml.util.SAXHelper; import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.XLSX2CSV; import org.apache.poi.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler; import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@ -78,7 +78,7 @@ public class FromHowTo {
} }
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException, ParserConfigurationException { public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException, ParserConfigurationException {
XMLReader parser = SAXHelper.newXMLReader(); XMLReader parser = XMLHelper.newXMLReader();
ContentHandler handler = new SheetHandler(sst); ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler); parser.setContentHandler(handler);
return parser; return parser;

View File

@ -35,7 +35,7 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.poi.sl.draw.binding.CTCustomGeometry2D; import org.apache.poi.sl.draw.binding.CTCustomGeometry2D;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.StaxHelper; import org.apache.poi.util.XMLHelper;
/** /**
* *
@ -50,7 +50,7 @@ public class PresetGeometries extends LinkedHashMap<String, CustomGeometry> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void init(InputStream is) throws XMLStreamException, JAXBException { public void init(InputStream is) throws XMLStreamException, JAXBException {
XMLInputFactory staxFactory = StaxHelper.newXMLInputFactory(); XMLInputFactory staxFactory = XMLHelper.newXMLInputFactory();
XMLStreamReader streamReader = staxFactory.createXMLStreamReader(new StreamSource(is)); XMLStreamReader streamReader = staxFactory.createXMLStreamReader(new StreamSource(is));
try { try {
// ignore StartElement: // ignore StartElement:

View File

@ -17,8 +17,6 @@
package org.apache.poi.util; package org.apache.poi.util;
import java.util.function.Consumer;
import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLOutputFactory;
@ -26,50 +24,33 @@ import javax.xml.stream.XMLOutputFactory;
/** /**
* Provides handy methods for working with StAX parsers and readers * Provides handy methods for working with StAX parsers and readers
*
* @deprecated use {@link XMLHelper}
*/ */
@Deprecated
@Removal(version = "5.0.0")
public final class StaxHelper { public final class StaxHelper {
private static final POILogger logger = POILogFactory.getLogger(StaxHelper.class);
private StaxHelper() { private StaxHelper() {
} }
/** /**
* Creates a new StAX XMLInputFactory, with sensible defaults * Creates a new StAX XMLInputFactory, with sensible defaults
*/ */
@SuppressWarnings({"squid:S2755"})
public static XMLInputFactory newXMLInputFactory() { public static XMLInputFactory newXMLInputFactory() {
XMLInputFactory factory = XMLInputFactory.newInstance(); return XMLHelper.newXMLInputFactory();
trySet(XMLInputFactory.IS_NAMESPACE_AWARE, (n) -> factory.setProperty(n, true));
trySet(XMLInputFactory.IS_VALIDATING, (n) -> factory.setProperty(n, false));
trySet(XMLInputFactory.SUPPORT_DTD, (n) -> factory.setProperty(n, false));
trySet(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, (n) -> factory.setProperty(n, false));
return factory;
} }
/** /**
* Creates a new StAX XMLOutputFactory, with sensible defaults * Creates a new StAX XMLOutputFactory, with sensible defaults
*/ */
public static XMLOutputFactory newXMLOutputFactory() { public static XMLOutputFactory newXMLOutputFactory() {
XMLOutputFactory factory = XMLOutputFactory.newInstance(); return XMLHelper.newXMLOutputFactory();
trySet(XMLOutputFactory.IS_REPAIRING_NAMESPACES, (n) -> factory.setProperty(n, true));
return factory;
} }
/** /**
* Creates a new StAX XMLEventFactory, with sensible defaults * Creates a new StAX XMLEventFactory, with sensible defaults
*/ */
public static XMLEventFactory newXMLEventFactory() { public static XMLEventFactory newXMLEventFactory() {
// this method seems safer on Android than getFactory() return XMLHelper.newXMLEventFactory();
return XMLEventFactory.newInstance();
}
private static void trySet(String name, Consumer<String> securityFeature) {
try {
securityFeature.accept(name);
} catch (Exception e) {
logger.log(POILogger.WARN, "StAX Property unsupported", name, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set StAX property because outdated StAX parser in classpath", name, ame);
}
} }
} }

View File

@ -17,19 +17,71 @@
package org.apache.poi.util; package org.apache.poi.util;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
/** /**
* Helper methods for working with javax.xml classes. * Helper methods for working with javax.xml classes.
*/ */
@Internal
public final class XMLHelper { public final class XMLHelper {
static final String FEATURE_LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
static final String FEATURE_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities";
static final String FEATURE_EXTERNAL_ENTITIES = "http://xml.org/sax/features/external-general-entities";
static final String PROPERTY_ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
static final String PROPERTY_SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
static final String METHOD_ENTITY_EXPANSION_XERCES = "setEntityExpansionLimit";
static final String[] SECURITY_MANAGERS = {
//"com.sun.org.apache.xerces.internal.util.SecurityManager",
"org.apache.xerces.util.SecurityManager"
};
private static POILogger logger = POILogFactory.getLogger(XMLHelper.class); private static POILogger logger = POILogFactory.getLogger(XMLHelper.class);
private static long lastLog;
// DocumentBuilderFactory.newDocumentBuilder is thread-safe
// see https://stackoverflow.com/questions/12455602/is-documentbuilder-thread-safe
private static final DocumentBuilderFactory documentBuilderFactory = getDocumentBuilderFactory();
private static final SAXParserFactory saxFactory = getSaxParserFactory();
@FunctionalInterface @FunctionalInterface
private interface SecurityFeature { private interface SecurityFeature {
void accept(String name) throws ParserConfigurationException; void accept(String name, boolean value) throws ParserConfigurationException, SAXException, TransformerException;
}
@FunctionalInterface
private interface SecurityProperty {
void accept(String name, Object value) throws SAXException;
}
private XMLHelper() {
} }
/** /**
@ -40,26 +92,225 @@ public final class XMLHelper {
@SuppressWarnings({"squid:S2755"}) @SuppressWarnings({"squid:S2755"})
public static DocumentBuilderFactory getDocumentBuilderFactory() { public static DocumentBuilderFactory getDocumentBuilderFactory() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
// this doesn't appear to work, and we still need to limit
// entity expansions to 1 in trySetXercesSecurityManager
factory.setExpandEntityReferences(false); factory.setExpandEntityReferences(false);
trySet(XMLConstants.FEATURE_SECURE_PROCESSING, (n) -> factory.setFeature(n, true)); factory.setValidating(false);
trySet(XMLConstants.ACCESS_EXTERNAL_SCHEMA, (n) -> factory.setAttribute(n, "")); trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySet(XMLConstants.ACCESS_EXTERNAL_DTD, (n) -> factory.setAttribute(n, "")); trySet(factory::setAttribute, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
trySet("http://xml.org/sax/features/external-general-entities", (n) -> factory.setFeature(n, false)); trySet(factory::setAttribute, XMLConstants.ACCESS_EXTERNAL_DTD, "");
trySet("http://xml.org/sax/features/external-parameter-entities", (n) -> factory.setFeature(n, false)); trySet(factory::setFeature, FEATURE_EXTERNAL_ENTITIES, false);
trySet("http://apache.org/xml/features/nonvalidating/load-external-dtd", (n) -> factory.setFeature(n, false)); trySet(factory::setFeature, FEATURE_PARAMETER_ENTITIES, false);
trySet("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", (n) -> factory.setFeature(n, false)); trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
trySet("http://apache.org/xml/features/disallow-doctype-decl", (n) -> factory.setFeature(n, true)); trySet(factory::setFeature, FEATURE_LOAD_DTD_GRAMMAR, false);
trySet("XIncludeAware", (n) -> factory.setXIncludeAware(false)); trySet(factory::setFeature, FEATURE_DISALLOW_DOCTYPE_DECL, true);
trySet((n, b) -> factory.setXIncludeAware(b), "XIncludeAware", false);
Object manager = getXercesSecurityManager();
if (manager == null || !trySet(factory::setAttribute, PROPERTY_SECURITY_MANAGER, manager)) {
// separate old version of Xerces not found => use the builtin way of setting the property
// Note: when entity_expansion_limit==0, there is no limit!
trySet(factory::setAttribute, PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
}
return factory; return factory;
} }
private static void trySet(String name, SecurityFeature feature) { /**
* Creates a new document builder, with sensible defaults
*
* @throws IllegalStateException If creating the DocumentBuilder fails, e.g.
* due to {@link ParserConfigurationException}.
*/
public static DocumentBuilder newDocumentBuilder() {
try { try {
feature.accept(name); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
} catch (Exception e) { documentBuilder.setEntityResolver(XMLHelper::ignoreEntity);
logger.log(POILogger.WARN, "SAX Feature unsupported", name, e); documentBuilder.setErrorHandler(new DocHelperErrorHandler());
} catch (AbstractMethodError ame) { return documentBuilder;
logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", name, ame); } catch (ParserConfigurationException e) {
throw new IllegalStateException("cannot create a DocumentBuilder", e);
} }
} }
public static SAXParserFactory getSaxParserFactory() {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySet(factory::setFeature, FEATURE_LOAD_DTD_GRAMMAR, false);
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
return factory;
} catch (RuntimeException | Error re) { // NOSONAR
// this also catches NoClassDefFoundError, which may be due to a local class path issue
// This may occur if the code is run inside a web container or a restricted JVM
// See bug 61170: https://bz.apache.org/bugzilla/show_bug.cgi?id=61170
logThrowable(re, "Failed to create SAXParserFactory", "-");
throw re;
} catch (Exception e) {
logThrowable(e, "Failed to create SAXParserFactory", "-");
throw new RuntimeException("Failed to create SAXParserFactory", e);
}
}
/**
* Creates a new SAX XMLReader, with sensible defaults
*/
public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
xmlReader.setEntityResolver(XMLHelper::ignoreEntity);
trySet(xmlReader::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
Object manager = getXercesSecurityManager();
if (manager == null || !trySet(xmlReader::setProperty, PROPERTY_SECURITY_MANAGER, manager)) {
// separate old version of Xerces not found => use the builtin way of setting the property
trySet(xmlReader::setProperty, PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
}
return xmlReader;
}
/**
* Creates a new StAX XMLInputFactory, with sensible defaults
*/
@SuppressWarnings({"squid:S2755"})
public static XMLInputFactory newXMLInputFactory() {
XMLInputFactory factory = XMLInputFactory.newInstance();
trySet(factory::setProperty, XMLInputFactory.IS_NAMESPACE_AWARE, true);
trySet(factory::setProperty, XMLInputFactory.IS_VALIDATING, false);
trySet(factory::setProperty, XMLInputFactory.SUPPORT_DTD, false);
trySet(factory::setProperty, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
return factory;
}
/**
* Creates a new StAX XMLOutputFactory, with sensible defaults
*/
public static XMLOutputFactory newXMLOutputFactory() {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
trySet(factory::setProperty, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
return factory;
}
/**
* Creates a new StAX XMLEventFactory, with sensible defaults
*/
public static XMLEventFactory newXMLEventFactory() {
// this method seems safer on Android than getFactory()
return XMLEventFactory.newInstance();
}
public static TransformerFactory getTransformerFactory() {
TransformerFactory factory = TransformerFactory.newInstance();
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
return factory;
}
public static Transformer newTransformer() throws TransformerConfigurationException {
Transformer serializer = getTransformerFactory().newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
serializer.setOutputProperty(OutputKeys.INDENT, "no");
serializer.setOutputProperty(OutputKeys.METHOD, "xml");
return serializer;
}
public static SchemaFactory getSchemaFactory() {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySet(factory::setProperty, XMLConstants.ACCESS_EXTERNAL_DTD, "");
trySet(factory::setProperty, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
return factory;
}
private static Object getXercesSecurityManager() {
// Try built-in JVM one first, standalone if not
for (String securityManagerClassName : SECURITY_MANAGERS) {
try {
Object mgr = Class.forName(securityManagerClassName).newInstance();
Method setLimit = mgr.getClass().getMethod(METHOD_ENTITY_EXPANSION_XERCES, Integer.TYPE);
setLimit.invoke(mgr, 1);
// Stop once one can be setup without error
return mgr;
} catch (ClassNotFoundException ignored) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
logThrowable(e, "SAX Feature unsupported", securityManagerClassName);
}
}
return null;
}
@SuppressWarnings("UnusedReturnValue")
private static boolean trySet(SecurityFeature feature, String name, boolean value) {
try {
feature.accept(name, value);
return true;
} catch (Exception e) {
logThrowable(e, "SAX Feature unsupported", name);
} catch (AbstractMethodError ame) {
logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
private static boolean trySet(SecurityProperty property, String name, Object value) {
try {
property.accept(name, value);
return true;
} catch (Exception e) {
logThrowable(e, "SAX Feature unsupported", name);
} catch (AbstractMethodError ame) {
logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
private static void logThrowable(Throwable t, String message, String name) {
if (System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, message + " [log suppressed for 5 minutes]", name, t);
lastLog = System.currentTimeMillis();
}
}
private static class DocHelperErrorHandler implements ErrorHandler {
public void warning(SAXParseException exception) {
printError(POILogger.WARN, exception);
}
public void error(SAXParseException exception) {
printError(POILogger.ERROR, exception);
}
public void fatalError(SAXParseException exception) throws SAXException {
printError(POILogger.FATAL, exception);
throw exception;
}
/**
* Prints the error message.
*/
private void printError(int type, SAXParseException ex) {
String systemId = ex.getSystemId();
if (systemId != null) {
int index = systemId.lastIndexOf('/');
if (index != -1) {
systemId = systemId.substring(index + 1);
}
}
String message = (systemId == null ? "" : systemId) +
':' + ex.getLineNumber() +
':' + ex.getColumnNumber() +
':' + ex.getMessage();
logger.log(type, message, ex);
}
}
private static InputSource ignoreEntity(String publicId, String systemId) {
return new InputSource(new StringReader(""));
}
} }

View File

@ -16,24 +16,33 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.ooxml.dev; package org.apache.poi.ooxml.dev;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import java.io.BufferedOutputStream;
import org.apache.poi.ooxml.util.DocumentHelper; import java.io.File;
import org.apache.poi.ooxml.util.TransformerHelper; import java.io.FileOutputStream;
import org.apache.poi.openxml4j.opc.internal.ZipHelper; import java.io.IOException;
import org.apache.poi.openxml4j.util.ZipSecureFile; import java.io.OutputStream;
import org.apache.poi.util.IOUtils;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.XMLHelper;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/** /**
* Reads a zipped OOXML file and produces a copy with the included * Reads a zipped OOXML file and produces a copy with the included
* pretty-printed XML files. * pretty-printed XML files.
@ -42,6 +51,8 @@ import java.util.zip.ZipOutputStream;
* use different formatting of the XML. * use different formatting of the XML.
*/ */
public class OOXMLPrettyPrint { public class OOXMLPrettyPrint {
private static final String XML_INDENT_AMOUNT = "{http://xml.apache.org/xslt}indent-amount";
private final DocumentBuilder documentBuilder; private final DocumentBuilder documentBuilder;
public OOXMLPrettyPrint() { public OOXMLPrettyPrint() {
@ -109,13 +120,11 @@ public class OOXMLPrettyPrint {
} }
private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException { private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException {
TransformerFactory transformerFactory = TransformerHelper.getFactory(); Transformer transformer = XMLHelper.newTransformer();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
if (indent > 0) { if (indent > 0) {
// set properties to indent the resulting XML nicely // set properties to indent the resulting XML nicely
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indent)); transformer.setOutputProperty(XML_INDENT_AMOUNT, Integer.toString(indent));
} }
Result result = new StreamResult(outputStream); Result result = new StreamResult(outputStream);
Source source = new DOMSource(document); Source source = new DOMSource(document);

View File

@ -19,66 +19,24 @@ package org.apache.poi.ooxml.util;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.events.Namespace; import javax.xml.stream.events.Namespace;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.XMLHelper;
import org.apache.poi.util.POILogger; import org.w3c.dom.Document;
import org.w3c.dom.*; import org.w3c.dom.Element;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public final class DocumentHelper { public final class DocumentHelper {
private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class); // must only be used to create empty documents, do not use it for parsing!
private static long lastLog; private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
private DocumentHelper() {} private DocumentHelper() {}
private static class DocHelperErrorHandler implements ErrorHandler {
public void warning(SAXParseException exception) {
printError(POILogger.WARN, exception);
}
public void error(SAXParseException exception) {
printError(POILogger.ERROR, exception);
}
public void fatalError(SAXParseException exception) throws SAXException {
printError(POILogger.FATAL, exception);
throw exception;
}
/** Prints the error message. */
private void printError(int type, SAXParseException ex) {
StringBuilder sb = new StringBuilder();
String systemId = ex.getSystemId();
if (systemId != null) {
int index = systemId.lastIndexOf('/');
if (index != -1)
systemId = systemId.substring(index + 1);
sb.append(systemId);
}
sb.append(':');
sb.append(ex.getLineNumber());
sb.append(':');
sb.append(ex.getColumnNumber());
sb.append(": ");
sb.append(ex.getMessage());
logger.log(type, sb.toString(), ex);
}
}
/** /**
* Creates a new document builder, with sensible defaults * Creates a new document builder, with sensible defaults
* *
@ -86,80 +44,14 @@ public final class DocumentHelper {
* due to {@link ParserConfigurationException}. * due to {@link ParserConfigurationException}.
*/ */
public static DocumentBuilder newDocumentBuilder() { public static DocumentBuilder newDocumentBuilder() {
try { return XMLHelper.newDocumentBuilder();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
documentBuilder.setErrorHandler(new DocHelperErrorHandler());
return documentBuilder;
} catch (ParserConfigurationException e) {
throw new IllegalStateException("cannot create a DocumentBuilder", e);
}
}
static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
static {
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false);
//this doesn't appear to work, and we still need to limit
//entity expansions to 1 in trySetXercesSecurityManager
documentBuilderFactory.setExpandEntityReferences(false);
trySetFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySetFeature(documentBuilderFactory, POIXMLConstants.FEATURE_DISALLOW_DOCTYPE_DECL, true);
trySetFeature(documentBuilderFactory, POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR, false);
trySetFeature(documentBuilderFactory, POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD, false);
trySetXercesSecurityManager(documentBuilderFactory);
}
private static void trySetFeature(@SuppressWarnings("SameParameterValue") DocumentBuilderFactory dbf, String feature, boolean enabled) {
try {
dbf.setFeature(feature, enabled);
} catch (Exception e) {
logger.log(POILogger.WARN, "DocumentBuilderFactory Feature unsupported", feature, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set DocumentBuilderFactory feature because outdated XML parser in classpath", feature, ame);
}
}
private static void trySetXercesSecurityManager(@SuppressWarnings("SameParameterValue") DocumentBuilderFactory dbf) {
// 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, 1);
dbf.setAttribute(POIXMLConstants.PROPERTY_SECURITY_MANAGER, mgr);
// Stop once one can be setup without error
return;
} catch (ClassNotFoundException e) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "DocumentBuilderFactory Security Manager could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
}
// separate old version of Xerces not found => use the builtin way of setting the property
// Note: when entity_expansion_limit==0, there is no limit!
try {
dbf.setAttribute(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
} catch (Throwable e) {
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "DocumentBuilderFactory Entity Expansion Limit could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
} }
/** /**
* Parses the given stream via the default (sensible) * Parses the given stream via the default (sensible)
* DocumentBuilder * DocumentBuilder
* @param inp Stream to read the XML data from * @param inp Stream to read the XML data from
* @return the parsed Document * @return the parsed Document
*/ */
public static Document readDocument(InputStream inp) throws IOException, SAXException { public static Document readDocument(InputStream inp) throws IOException, SAXException {
return newDocumentBuilder().parse(inp); return newDocumentBuilder().parse(inp);
@ -175,9 +67,6 @@ public final class DocumentHelper {
return newDocumentBuilder().parse(inp); 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 * Creates a new DOM Document
*/ */

View File

@ -1,26 +0,0 @@
/* ====================================================================
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.ooxml.util;
public class POIXMLConstants {
public static final String FEATURE_LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
public static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
public static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
public static final String PROPERTY_ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
public static final String PROPERTY_SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
}

View File

@ -17,120 +17,25 @@
package org.apache.poi.ooxml.util; package org.apache.poi.ooxml.util;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.Removal;
import org.apache.poi.util.POILogger; import org.apache.poi.util.XMLHelper;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
/** /**
* Provides handy methods for working with SAX parsers and readers * Provides handy methods for working with SAX parsers and readers
* @deprecated use {@link XMLHelper}
*/ */
@Deprecated
@Removal(version = "5.0.0")
public final class SAXHelper { public final class SAXHelper {
private static final POILogger logger = POILogFactory.getLogger(SAXHelper.class);
private static long lastLog;
private SAXHelper() {}
/** /**
* Creates a new SAX XMLReader, with sensible defaults * Creates a new SAX XMLReader, with sensible defaults
*/ */
public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException { public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader(); return XMLHelper.newXMLReader();
xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER);
trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING);
trySetXercesSecurityManager(xmlReader);
return xmlReader;
}
static final EntityResolver IGNORING_ENTITY_RESOLVER = (publicId, systemId) -> new InputSource(new StringReader(""));
private static final SAXParserFactory saxFactory;
static {
try {
saxFactory = SAXParserFactory.newInstance();
saxFactory.setValidating(false);
saxFactory.setNamespaceAware(true);
trySetSAXFeature(saxFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySetSAXFeature(saxFactory, POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR, false);
trySetSAXFeature(saxFactory, POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD, false);
} catch (RuntimeException | Error re) { // NOSONAR
// this also catches NoClassDefFoundError, which may be due to a local class path issue
// This may occur if the code is run inside a web container
// or a restricted JVM
// See bug 61170: https://bz.apache.org/bugzilla/show_bug.cgi?id=61170
logger.log(POILogger.WARN, "Failed to create SAXParserFactory", re);
throw re;
} catch (Exception e) {
logger.log(POILogger.WARN, "Failed to create SAXParserFactory", e);
throw new RuntimeException("Failed to create SAXParserFactory", e);
}
}
private static void trySetSAXFeature(@SuppressWarnings("SameParameterValue") SAXParserFactory spf,
String feature, boolean flag) {
try {
spf.setFeature(feature, flag);
} 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 trySetSAXFeature(XMLReader xmlReader, @SuppressWarnings("SameParameterValue") String feature) {
try {
xmlReader.setFeature(feature, true);
} 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(XMLReader xmlReader) {
// 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, 1);
xmlReader.setProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER, mgr);
// Stop once one can be setup without error
return;
} catch (ClassNotFoundException e) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
// throttle the log somewhat as it can spam the log otherwise
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
}
// separate old version of Xerces not found => use the builtin way of setting the property
try {
xmlReader.setProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
} catch (SAXException e) { // NOSONAR - also catch things like NoClassDefError here
// throttle the log somewhat as it can spam the log otherwise
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
} }
} }

View File

@ -17,33 +17,20 @@
package org.apache.poi.ooxml.util; package org.apache.poi.ooxml.util;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import javax.xml.XMLConstants;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
public final class TransformerHelper { import org.apache.poi.util.Removal;
private static POILogger logger = POILogFactory.getLogger(TransformerHelper.class); import org.apache.poi.util.XMLHelper;
/**
* @deprecated use {@link XMLHelper}
*/
@Removal(version = "5.0.0")
@Deprecated
public final class TransformerHelper {
private TransformerHelper() {} private TransformerHelper() {}
static final TransformerFactory transformerFactory = TransformerFactory.newInstance();
static {
trySetFeature(transformerFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
}
public static TransformerFactory getFactory() { public static TransformerFactory getFactory() {
return transformerFactory; return XMLHelper.getTransformerFactory();
}
private static void trySetFeature(TransformerFactory tf, String feature, boolean enabled) {
try {
tf.setFeature(feature, enabled);
} catch (Exception e) {
logger.log(POILogger.WARN, "TransformerFactory Feature unsupported", feature, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set TransformerFactory feature because outdated XML parser in classpath", feature, ame);
}
} }
} }

View File

@ -30,7 +30,8 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import org.apache.poi.ooxml.util.TransformerHelper; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.XMLHelper;
import org.w3c.dom.Document; import org.w3c.dom.Document;
public final class StreamHelper { public final class StreamHelper {
@ -39,10 +40,6 @@ public final class StreamHelper {
// Do nothing // Do nothing
} }
private static synchronized Transformer getIdentityTransformer() throws TransformerException {
return TransformerHelper.getFactory().newTransformer();
}
/** /**
* Save the document object in the specified output stream. * Save the document object in the specified output stream.
* *
@ -56,7 +53,7 @@ public final class StreamHelper {
public static boolean saveXmlInStream(Document xmlContent, public static boolean saveXmlInStream(Document xmlContent,
OutputStream outStream) { OutputStream outStream) {
try { try {
Transformer trans = getIdentityTransformer(); Transformer trans = XMLHelper.newTransformer();
Source xmlSource = new DOMSource(xmlContent); Source xmlSource = new DOMSource(xmlContent);
// prevent close of stream by transformer: // prevent close of stream by transformer:
Result outputTarget = new StreamResult(new FilterOutputStream( Result outputTarget = new StreamResult(new FilterOutputStream(
@ -97,14 +94,10 @@ public final class StreamHelper {
*/ */
public static boolean copyStream(InputStream inStream, OutputStream outStream) { public static boolean copyStream(InputStream inStream, OutputStream outStream) {
try { try {
byte[] buffer = new byte[1024]; IOUtils.copy(inStream, outStream);
int bytesRead; return true;
while ((bytesRead = inStream.read(buffer)) >= 0) {
outStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) { } catch (Exception e) {
return false; return false;
} }
return true;
} }
} }

View File

@ -96,7 +96,7 @@ public class TSPTimeStampService implements TimeStampService {
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings({"unchecked","squid:S2647"})
public byte[] timeStamp(byte[] data, RevocationData revocationData) public byte[] timeStamp(byte[] data, RevocationData revocationData)
throws Exception { throws Exception {
// digest the message // digest the message

View File

@ -18,18 +18,19 @@ package org.apache.poi.xssf.eventusermodel;
import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML; import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PushbackInputStream; import java.io.PushbackInputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.util.Removal; import org.apache.poi.util.Removal;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.SharedStrings; import org.apache.poi.xssf.model.SharedStrings;
import org.apache.poi.xssf.usermodel.XSSFRelation; import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFRichTextString;
@ -173,7 +174,7 @@ public class ReadOnlySharedStringsTable extends DefaultHandler implements Shared
pis.unread(emptyTest); pis.unread(emptyTest);
InputSource sheetSource = new InputSource(pis); InputSource sheetSource = new InputSource(pis);
try { try {
XMLReader sheetParser = SAXHelper.newXMLReader(); XMLReader sheetParser = XMLHelper.newXMLReader();
sheetParser.setContentHandler(this); sheetParser.setContentHandler(this);
sheetParser.parse(sheetSource); sheetParser.parse(sheetSource);
} catch(ParserConfigurationException e) { } catch(ParserConfigurationException e) {

View File

@ -16,7 +16,6 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xssf.eventusermodel; package org.apache.poi.xssf.eventusermodel;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -30,6 +29,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@ -42,7 +43,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.ooxml.util.SAXHelper; import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.CommentsTable; import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.StylesTable;
@ -253,7 +254,7 @@ public class XSSFReader {
XMLSheetRefReader xmlSheetRefReader = new XMLSheetRefReader(); XMLSheetRefReader xmlSheetRefReader = new XMLSheetRefReader();
XMLReader xmlReader; XMLReader xmlReader;
try { try {
xmlReader = SAXHelper.newXMLReader(); xmlReader = XMLHelper.newXMLReader();
} catch (ParserConfigurationException | SAXException e) { } catch (ParserConfigurationException | SAXException e) {
throw new POIXMLException(e); throw new POIXMLException(e);
} }

View File

@ -16,7 +16,6 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xssf.extractor; package org.apache.poi.xssf.extractor;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
@ -24,6 +23,8 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.ooxml.POIXMLProperties; import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.POIXMLProperties.CoreProperties; import org.apache.poi.ooxml.POIXMLProperties.CoreProperties;
import org.apache.poi.ooxml.POIXMLProperties.CustomProperties; import org.apache.poi.ooxml.POIXMLProperties.CustomProperties;
@ -34,12 +35,15 @@ import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.ooxml.util.SAXHelper; import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.model.*; import org.apache.poi.xssf.model.Comments;
import org.apache.poi.xssf.model.SharedStrings;
import org.apache.poi.xssf.model.Styles;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFComment; import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.usermodel.XSSFShape; import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSimpleShape; import org.apache.poi.xssf.usermodel.XSSFSimpleShape;
@ -244,7 +248,7 @@ public class XSSFEventBasedExcelExtractor extends POIXMLTextExtractor
InputSource sheetSource = new InputSource(sheetInputStream); InputSource sheetSource = new InputSource(sheetInputStream);
try { try {
XMLReader sheetParser = SAXHelper.newXMLReader(); XMLReader sheetParser = XMLHelper.newXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler( ContentHandler handler = new XSSFSheetXMLHandler(
styles, comments, strings, sheetContentsExtractor, formatter, formulasNotResults); styles, comments, strings, sheetContentsExtractor, formatter, formulasNotResults);
sheetParser.setContentHandler(handler); sheetParser.setContentHandler(handler);

View File

@ -28,7 +28,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Vector; import java.util.Vector;
import javax.xml.XMLConstants;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
@ -40,12 +39,12 @@ import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import javax.xml.validation.Validator;
import org.apache.poi.ooxml.util.DocumentHelper; import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.TransformerHelper;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFMap; import org.apache.poi.xssf.usermodel.XSSFMap;
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFRow;
@ -225,7 +224,7 @@ public class XSSFExportToXml implements Comparator<String>{
//Output the XML //Output the XML
//set up a transformer //set up a transformer
Transformer trans = TransformerHelper.getFactory().newTransformer(); Transformer trans = XMLHelper.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes"); trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty(OutputKeys.ENCODING, encoding); trans.setOutputProperty(OutputKeys.ENCODING, encoding);
@ -250,10 +249,7 @@ public class XSSFExportToXml implements Comparator<String>{
@SuppressWarnings({"squid:S2755"}) @SuppressWarnings({"squid:S2755"})
private boolean isValid(Document xml) throws SAXException{ private boolean isValid(Document xml) throws SAXException{
try { try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); SchemaFactory factory = XMLHelper.getSchemaFactory();
trySet(XMLConstants.FEATURE_SECURE_PROCESSING, (n) -> factory.setFeature(n, true));
trySet(XMLConstants.ACCESS_EXTERNAL_DTD, (n) -> factory.setProperty(n,""));
trySet(XMLConstants.ACCESS_EXTERNAL_SCHEMA, (n) -> factory.setProperty(n,""));
Source source = new DOMSource(map.getSchema()); Source source = new DOMSource(map.getSchema());
Schema schema = factory.newSchema(source); Schema schema = factory.newSchema(source);
@ -407,7 +403,7 @@ public class XSSFExportToXml implements Comparator<String>{
String[] rightTokens = rightXpath.split("/"); String[] rightTokens = rightXpath.split("/");
String samePath = ""; String samePath = "";
int minLength = leftTokens.length< rightTokens.length? leftTokens.length : rightTokens.length; int minLength = Math.min(leftTokens.length, rightTokens.length);
Node localComplexTypeRootNode = xmlSchema; Node localComplexTypeRootNode = xmlSchema;

View File

@ -25,22 +25,24 @@ import java.nio.charset.StandardCharsets;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import org.apache.poi.ooxml.util.TransformerHelper; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ss.usermodel.DifferentialStyleProvider; import org.apache.poi.ss.usermodel.DifferentialStyleProvider;
import org.apache.poi.ss.usermodel.TableStyle; import org.apache.poi.ss.usermodel.TableStyle;
import org.apache.poi.ss.usermodel.TableStyleType; import org.apache.poi.ss.usermodel.TableStyleType;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.StylesTable;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/** /**
* Table style names defined in the OOXML spec. * Table style names defined in the OOXML spec.
* The actual styling is defined in presetTableStyles.xml * The actual styling is defined in presetTableStyles.xml
@ -440,9 +442,8 @@ public enum XSSFBuiltinTableStyle {
} }
private static String writeToString(Node node) throws IOException, TransformerException { private static String writeToString(Node node) throws IOException, TransformerException {
TransformerFactory tf = TransformerHelper.getFactory();
try (StringWriter sw = new StringWriter()){ try (StringWriter sw = new StringWriter()){
Transformer transformer = tf.newTransformer(); Transformer transformer = XMLHelper.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node), new StreamResult(sw)); transformer.transform(new DOMSource(node), new StreamResult(sw));
return sw.toString(); return sw.toString();

View File

@ -1,73 +0,0 @@
/* ====================================================================
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.ooxml.util;
import org.junit.Test;
import org.xml.sax.InputSource;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
public class TestDocumentHelper {
@Test
public void testDocumentBuilder() throws Exception {
DocumentBuilder documentBuilder = DocumentHelper.newDocumentBuilder();
assertNotSame(documentBuilder, DocumentHelper.newDocumentBuilder());
assertTrue(documentBuilder.isNamespaceAware());
assertFalse(documentBuilder.isValidating());
documentBuilder.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyDocumentBuilders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<DocumentBuilder>> futures = new ArrayList<>();
for(int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(DocumentHelper::newDocumentBuilder));
}
HashSet<DocumentBuilder> dbs = new HashSet<>();
for(CompletableFuture<DocumentBuilder> future : futures) {
DocumentBuilder documentBuilder = future.get(10, TimeUnit.SECONDS);
assertTrue(documentBuilder.isNamespaceAware());
dbs.add(documentBuilder);
}
assertEquals(limit, dbs.size());
}
@Test
public void testDocumentBuilderFactory() throws Exception {
try {
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_DISALLOW_DOCTYPE_DECL));
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
} catch(AbstractMethodError e) {
// ignore exceptions from old parsers that don't support this API (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
}
}

View File

@ -1,85 +0,0 @@
/* ====================================================================
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.ooxml.util;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.XMLReader;
public class TestSAXHelper {
@Test
public void testXMLReader() throws Exception {
XMLReader reader = SAXHelper.newXMLReader();
assertNotSame(reader, SAXHelper.newXMLReader());
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
assertEquals(SAXHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertEquals("1", reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER));
} catch(SAXNotRecognizedException e) {
// ignore exceptions from old parsers that don't support these features
// (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyXMLReaders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<XMLReader>> futures = new ArrayList<>();
for(int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(() -> {
try {
return SAXHelper.newXMLReader();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
HashSet<XMLReader> readers = new HashSet<>();
for(CompletableFuture<XMLReader> future : futures) {
XMLReader reader = future.get(10, TimeUnit.SECONDS);
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
} catch (SAXNotRecognizedException e) {
// can happen for older XML Parsers, e.g. we have a CI Job which runs with Xerces XML Parser
assertTrue("Had Exception about not-recognized SAX feature: " + e + " which is only expected" +
" for Xerces XML Parser, but had parser: " + reader,
reader.getClass().getName().contains("org.apache.xerces"));
}
readers.add(reader);
}
assertEquals(limit, readers.size());
}
}

View File

@ -17,7 +17,15 @@
package org.apache.poi.openxml4j.opc; package org.apache.poi.openxml4j.opc;
import org.apache.poi.ooxml.util.POIXMLConstants; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.internal.ContentType; import org.apache.poi.openxml4j.opc.internal.ContentType;
@ -25,19 +33,13 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/** /**
* Tests for content type (ContentType class). * Tests for content type (ContentType class).
*/ */
public final class TestContentType { public final class TestContentType {
private static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
@Rule @Rule
public ExpectedException exception = ExpectedException.none(); public ExpectedException exception = ExpectedException.none();
@ -242,7 +244,7 @@ public final class TestContentType {
public static boolean isOldXercesActive() { public static boolean isOldXercesActive() {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try { try {
dbf.setFeature(POIXMLConstants.FEATURE_DISALLOW_DOCTYPE_DECL, true); dbf.setFeature(FEATURE_DISALLOW_DOCTYPE_DECL, true);
return false; return false;
} catch (Exception|AbstractMethodError ignored) {} } catch (Exception|AbstractMethodError ignored) {}
return true; return true;

View File

@ -32,15 +32,13 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FormulaError; import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.util.XMLHelper; import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.MapInfo; import org.apache.poi.xssf.model.MapInfo;
@ -48,8 +46,6 @@ import org.apache.poi.xssf.usermodel.XSSFMap;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; import org.xml.sax.SAXParseException;
@ -401,7 +397,7 @@ public final class TestXSSFExportToXML {
String xmlData = os.toString("UTF-8"); String xmlData = os.toString("UTF-8");
assertNotNull(xmlData); assertNotNull(xmlData);
assertTrue(!xmlData.isEmpty()); assertFalse(xmlData.isEmpty());
String a = xmlData.split("<A>")[1].split("</A>")[0].trim(); String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
String a_b = a.split("<B>")[1].split("</B>")[0].trim(); String a_b = a.split("<B>")[1].split("</B>")[0].trim();
@ -505,23 +501,11 @@ public final class TestXSSFExportToXML {
} }
} }
private void parseXML(String xmlData) throws IOException, SAXException, ParserConfigurationException { private void parseXML(String xmlData) throws IOException, SAXException {
DocumentBuilderFactory docBuilderFactory = XMLHelper.getDocumentBuilderFactory(); DocumentBuilder docBuilder = XMLHelper.newDocumentBuilder();
docBuilderFactory.setNamespaceAware(true);
docBuilderFactory.setValidating(false);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.setEntityResolver(new DummyEntityResolver());
docBuilder.parse(new ByteArrayInputStream(xmlData.getBytes(StandardCharsets.UTF_8))); docBuilder.parse(new ByteArrayInputStream(xmlData.getBytes(StandardCharsets.UTF_8)));
} }
private static class DummyEntityResolver implements EntityResolver {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
return null;
}
}
@Test @Test
public void testExportDataTypes() throws Exception { public void testExportDataTypes() throws Exception {
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) { try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {

View File

@ -59,7 +59,6 @@ import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLProperties; import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.util.DocumentHelper; import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@ -84,32 +83,7 @@ import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.functions.Function; import org.apache.poi.ss.formula.functions.Function;
import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.IgnoredErrorType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellAddress; import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
@ -118,6 +92,7 @@ import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.NullOutputStream; import org.apache.poi.util.NullOutputStream;
import org.apache.poi.util.TempFile; import org.apache.poi.util.TempFile;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.SXSSFITestDataProvider;
import org.apache.poi.xssf.XLSBUnsupportedException; import org.apache.poi.xssf.XLSBUnsupportedException;
import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFITestDataProvider;
@ -1946,7 +1921,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
File testFile = XSSFTestDataSamples.getSampleFile("54764.xlsx"); File testFile = XSSFTestDataSamples.getSampleFile("54764.xlsx");
ZipFile zip = new ZipFile(testFile); ZipFile zip = new ZipFile(testFile);
ZipArchiveEntry ze = zip.getEntry("xl/sharedStrings.xml"); ZipArchiveEntry ze = zip.getEntry("xl/sharedStrings.xml");
XMLReader reader = SAXHelper.newXMLReader(); XMLReader reader = XMLHelper.newXMLReader();
try { try {
reader.parse(new InputSource(zip.getInputStream(ze))); reader.parse(new InputSource(zip.getInputStream(ze)));
fail("should have thrown SAXParseException"); fail("should have thrown SAXParseException");

View File

@ -20,9 +20,7 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
@ -92,12 +90,8 @@ public class ExcelToFoConverter extends AbstractExcelConverter
DOMSource domSource = new DOMSource( doc ); DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File(args[1]) ); StreamResult streamResult = new StreamResult( new File(args[1]) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument // TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" ); Transformer serializer = XMLHelper.newTransformer();
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
serializer.setOutputProperty( OutputKeys.METHOD, "xml" );
serializer.transform( domSource, streamResult ); serializer.transform( domSource, streamResult );
} }
@ -113,8 +107,7 @@ public class ExcelToFoConverter extends AbstractExcelConverter
final HSSFWorkbook workbook = AbstractExcelUtils.loadXls( xlsFile ); final HSSFWorkbook workbook = AbstractExcelUtils.loadXls( xlsFile );
try { try {
ExcelToFoConverter excelToHtmlConverter = new ExcelToFoConverter( ExcelToFoConverter excelToHtmlConverter = new ExcelToFoConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder() XMLHelper.newDocumentBuilder().newDocument() );
.newDocument() );
excelToHtmlConverter.processWorkbook( workbook ); excelToHtmlConverter.processWorkbook( workbook );
return excelToHtmlConverter.getDocument(); return excelToHtmlConverter.getDocument();
} finally { } finally {

View File

@ -27,7 +27,6 @@ import java.util.Map;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
@ -85,11 +84,8 @@ public class ExcelToHtmlConverter extends AbstractExcelConverter {
DOMSource domSource = new DOMSource( doc ); DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File(args[1]) ); StreamResult streamResult = new StreamResult( new File(args[1]) );
TransformerFactory tf = TransformerFactory.newInstance(); Transformer serializer = XMLHelper.newTransformer();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument // TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
serializer.setOutputProperty( OutputKeys.METHOD, "html" ); serializer.setOutputProperty( OutputKeys.METHOD, "html" );
serializer.transform( domSource, streamResult ); serializer.transform( domSource, streamResult );
} }
@ -133,8 +129,7 @@ public class ExcelToHtmlConverter extends AbstractExcelConverter {
*/ */
public static Document process( HSSFWorkbook workbook ) throws IOException, ParserConfigurationException { public static Document process( HSSFWorkbook workbook ) throws IOException, ParserConfigurationException {
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter( ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder() XMLHelper.newDocumentBuilder().newDocument() );
.newDocument() );
excelToHtmlConverter.processWorkbook( workbook ); excelToHtmlConverter.processWorkbook( workbook );
return excelToHtmlConverter.getDocument(); return excelToHtmlConverter.getDocument();
} }

View File

@ -24,9 +24,7 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
@ -86,17 +84,14 @@ public class WordToFoConverter extends AbstractWordConverter
DOMSource domSource = new DOMSource( doc ); DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File( args[1] ) ); StreamResult streamResult = new StreamResult( new File( args[1] ) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument // TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" ); Transformer serializer = XMLHelper.newTransformer();
serializer.setOutputProperty( OutputKeys.INDENT, "yes" );
serializer.transform( domSource, streamResult ); serializer.transform( domSource, streamResult );
} }
static Document process( File docFile ) throws Exception static Document process( File docFile ) throws Exception
{ {
final DocumentBuilder docBuild = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder(); final DocumentBuilder docBuild = XMLHelper.newDocumentBuilder();
try (final HWPFDocumentCore hwpfDocument = WordToFoUtils.loadDoc( docFile )) { try (final HWPFDocumentCore hwpfDocument = WordToFoUtils.loadDoc( docFile )) {
WordToFoConverter wordToFoConverter = new WordToFoConverter(docBuild.newDocument()); WordToFoConverter wordToFoConverter = new WordToFoConverter(docBuild.newDocument());
wordToFoConverter.processDocument(hwpfDocument); wordToFoConverter.processDocument(hwpfDocument);

View File

@ -30,7 +30,6 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
@ -154,18 +153,15 @@ public class WordToHtmlConverter extends AbstractWordConverter
DOMSource domSource = new DOMSource( doc ); DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File(args[1]) ); StreamResult streamResult = new StreamResult( new File(args[1]) );
TransformerFactory tf = TransformerFactory.newInstance(); Transformer serializer = XMLHelper.newTransformer();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument // TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "yes" );
serializer.setOutputProperty( OutputKeys.METHOD, "html" ); serializer.setOutputProperty( OutputKeys.METHOD, "html" );
serializer.transform( domSource, streamResult ); serializer.transform( domSource, streamResult );
} }
static Document process( File docFile ) throws IOException, ParserConfigurationException static Document process( File docFile ) throws IOException, ParserConfigurationException
{ {
final DocumentBuilder docBuild = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder(); final DocumentBuilder docBuild = XMLHelper.newDocumentBuilder();
try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( docFile )) { try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( docFile )) {
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(docBuild.newDocument()); WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(docBuild.newDocument());
wordToHtmlConverter.processDocument(wordDocument); wordToHtmlConverter.processDocument(wordDocument);

View File

@ -76,7 +76,7 @@ public class WordToTextConverter extends AbstractWordConverter
throws Exception throws Exception
{ {
WordToTextConverter wordToTextConverter = new WordToTextConverter( WordToTextConverter wordToTextConverter = new WordToTextConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
wordToTextConverter.processDocument( wordDocument ); wordToTextConverter.processDocument( wordDocument );
return wordToTextConverter.getText(); return wordToTextConverter.getText();
} }
@ -105,11 +105,8 @@ public class WordToTextConverter extends AbstractWordConverter
DOMSource domSource = new DOMSource( doc ); DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File( args[1] ) ); StreamResult streamResult = new StreamResult( new File( args[1] ) );
TransformerFactory tf = TransformerFactory.newInstance(); Transformer serializer = XMLHelper.newTransformer();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument // TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
serializer.setOutputProperty( OutputKeys.METHOD, "text" ); serializer.setOutputProperty( OutputKeys.METHOD, "text" );
serializer.transform( domSource, streamResult ); serializer.transform( domSource, streamResult );
} }
@ -117,7 +114,7 @@ public class WordToTextConverter extends AbstractWordConverter
private static Document process( File docFile ) throws IOException, ParserConfigurationException { private static Document process( File docFile ) throws IOException, ParserConfigurationException {
try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( docFile )) { try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( docFile )) {
WordToTextConverter wordToTextConverter = new WordToTextConverter( WordToTextConverter wordToTextConverter = new WordToTextConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument()); XMLHelper.newDocumentBuilder().newDocument());
wordToTextConverter.processDocument(wordDocument); wordToTextConverter.processDocument(wordDocument);
return wordToTextConverter.getDocument(); return wordToTextConverter.getDocument();
} }
@ -141,8 +138,7 @@ public class WordToTextConverter extends AbstractWordConverter
public WordToTextConverter() throws ParserConfigurationException public WordToTextConverter() throws ParserConfigurationException
{ {
this.textDocumentFacade = new TextDocumentFacade( this.textDocumentFacade = new TextDocumentFacade(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder() XMLHelper.newDocumentBuilder().newDocument() );
.newDocument() );
} }
/** /**

View File

@ -16,26 +16,26 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.hssf.converter; package org.apache.poi.hssf.converter;
import org.apache.poi.POIDataSamples; import static org.junit.Assert.assertNotNull;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.XMLHelper; import java.io.File;
import org.junit.Test; import java.io.StringWriter;
import org.junit.runner.RunWith; import java.util.ArrayList;
import org.junit.runners.Parameterized; import java.util.Arrays;
import java.util.List;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FilenameFilter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertNotNull; import org.apache.poi.POIDataSamples;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.XMLHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class TestExcelConverterSuite public class TestExcelConverterSuite
@ -53,15 +53,7 @@ public class TestExcelConverterSuite
List<Object[]> files = new ArrayList<>(); List<Object[]> files = new ArrayList<>();
File directory = POIDataSamples.getDocumentInstance().getFile( File directory = POIDataSamples.getDocumentInstance().getFile(
"../spreadsheet" ); "../spreadsheet" );
for ( final File child : directory.listFiles( new FilenameFilter() for ( final File child : directory.listFiles((dir,name) -> name.endsWith( ".xls" ) && !failingFiles.contains( name ))) {
{
@Override
public boolean accept( File dir, String name )
{
return name.endsWith( ".xls" ) && !failingFiles.contains( name );
}
} ) )
{
files.add(new Object[] { child }); files.add(new Object[] { child });
} }
@ -84,16 +76,12 @@ public class TestExcelConverterSuite
} }
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter( ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
excelToHtmlConverter.processWorkbook( workbook ); excelToHtmlConverter.processWorkbook( workbook );
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance() Transformer transformer = XMLHelper.newTransformer();
.newTransformer();
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
transformer.transform( transformer.transform(
new DOMSource( excelToHtmlConverter.getDocument() ), new DOMSource( excelToHtmlConverter.getDocument() ),
new StreamResult( stringWriter ) ); new StreamResult( stringWriter ) );
@ -113,7 +101,7 @@ public class TestExcelConverterSuite
} }
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter( ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
excelToHtmlConverter.processWorkbook( workbook ); excelToHtmlConverter.processWorkbook( workbook );
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();

View File

@ -18,17 +18,17 @@ package org.apache.poi.hwpf.converter;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.transform.OutputKeys; import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FilenameFilter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.hwpf.HWPFDocumentCore; import org.apache.poi.hwpf.HWPFDocumentCore;
@ -55,15 +55,7 @@ public class TestWordToConverterSuite
List<Object[]> files = new ArrayList<>(); List<Object[]> files = new ArrayList<>();
File directory = POIDataSamples.getDocumentInstance().getFile( File directory = POIDataSamples.getDocumentInstance().getFile(
"../document" ); "../document" );
for ( final File child : directory.listFiles( new FilenameFilter() for ( final File child : directory.listFiles((dir,name) -> name.endsWith( ".doc" ) && !failingFiles.contains( name ))) {
{
@Override
public boolean accept( File dir, String name )
{
return name.endsWith( ".doc" ) && !failingFiles.contains( name );
}
} ) )
{
files.add(new Object[] { child }); files.add(new Object[] { child });
} }
@ -83,15 +75,12 @@ public class TestWordToConverterSuite
} }
WordToFoConverter wordToFoConverter = new WordToFoConverter( WordToFoConverter wordToFoConverter = new WordToFoConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
wordToFoConverter.processDocument( hwpfDocument ); wordToFoConverter.processDocument( hwpfDocument );
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance() Transformer transformer = XMLHelper.newTransformer();
.newTransformer();
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
transformer.setOutputProperty( OutputKeys.INDENT, "false" );
transformer.transform( transformer.transform(
new DOMSource( wordToFoConverter.getDocument() ), new DOMSource( wordToFoConverter.getDocument() ),
new StreamResult( stringWriter ) ); new StreamResult( stringWriter ) );
@ -111,7 +100,7 @@ public class TestWordToConverterSuite
} }
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter( WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
wordToHtmlConverter.processDocument( hwpfDocument ); wordToHtmlConverter.processDocument( hwpfDocument );
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
@ -140,7 +129,7 @@ public class TestWordToConverterSuite
} }
WordToTextConverter wordToTextConverter = new WordToTextConverter( WordToTextConverter wordToTextConverter = new WordToTextConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
wordToTextConverter.processDocument( wordDocument ); wordToTextConverter.processDocument( wordDocument );
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();

View File

@ -22,9 +22,7 @@ import static org.apache.poi.POITestCase.assertContains;
import java.io.StringWriter; import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
@ -45,14 +43,12 @@ public class TestWordToFoConverter
.getDocumentInstance().openResourceAsStream( sampleFileName ) ); .getDocumentInstance().openResourceAsStream( sampleFileName ) );
WordToFoConverter wordToFoConverter = new WordToFoConverter( WordToFoConverter wordToFoConverter = new WordToFoConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() ); XMLHelper.newDocumentBuilder().newDocument() );
wordToFoConverter.processDocument( hwpfDocument ); wordToFoConverter.processDocument( hwpfDocument );
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance() Transformer transformer = XMLHelper.newTransformer();
.newTransformer();
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
transformer.transform( transformer.transform(
new DOMSource( wordToFoConverter.getDocument() ), new DOMSource( wordToFoConverter.getDocument() ),
new StreamResult( stringWriter ) ); new StreamResult( stringWriter ) );

View File

@ -16,22 +16,22 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.hwpf.converter; package org.apache.poi.hwpf.converter;
import static org.apache.poi.POITestCase.assertContains;
import static org.junit.Assert.assertFalse;
import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.util.XMLHelper; import org.apache.poi.util.XMLHelper;
import org.junit.Test; import org.junit.Test;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import static org.apache.poi.POITestCase.assertContains;
import static org.junit.Assert.assertFalse;
/** /**
* Test cases for {@link WordToHtmlConverter} * Test cases for {@link WordToHtmlConverter}
*/ */
@ -45,7 +45,7 @@ public class TestWordToHtmlConverter {
HWPFDocument hwpfDocument = new HWPFDocument(POIDataSamples HWPFDocument hwpfDocument = new HWPFDocument(POIDataSamples
.getDocumentInstance().openResourceAsStream(sampleFileName)); .getDocumentInstance().openResourceAsStream(sampleFileName));
Document newDocument = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument(); Document newDocument = XMLHelper.newDocumentBuilder().newDocument();
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter( WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
newDocument); newDocument);
@ -58,10 +58,7 @@ public class TestWordToHtmlConverter {
StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance() Transformer transformer = XMLHelper.newTransformer();
.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
transformer.setOutputProperty(OutputKeys.METHOD, "html"); transformer.setOutputProperty(OutputKeys.METHOD, "html");
transformer.transform( transformer.transform(
new DOMSource(wordToHtmlConverter.getDocument()), new DOMSource(wordToHtmlConverter.getDocument()),

View File

@ -899,7 +899,7 @@ public class TestBugs{
@Test @Test
public void test59322() throws Exception { public void test59322() throws Exception {
try(HWPFDocument doc = HWPFTestDataSamples.openSampleFile("59322.doc")) { try(HWPFDocument doc = HWPFTestDataSamples.openSampleFile("59322.doc")) {
Document document = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument(); Document document = XMLHelper.newDocumentBuilder().newDocument();
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document); WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);
wordToHtmlConverter.processDocument(doc); wordToHtmlConverter.processDocument(doc);
assertNotNull(document); assertNotNull(document);

View File

@ -1,64 +0,0 @@
/* ====================================================================
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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import org.junit.Test;
/**
* Unit test for StaxHelper
*/
public class TestStaxHelper {
/**
* test that newXMLInputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLInputFactory() throws XMLStreamException {
XMLInputFactory factory = StaxHelper.newXMLInputFactory();
assertEquals(true, factory.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE));
assertEquals(false, factory.getProperty(XMLInputFactory.IS_VALIDATING));
assertEquals(false, factory.getProperty(XMLInputFactory.SUPPORT_DTD));
assertEquals(false, factory.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES));
}
/**
* test that newXMLOutputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLOutputFactory() {
XMLOutputFactory factory = StaxHelper.newXMLOutputFactory();
assertEquals(true, factory.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES));
}
/**
* test that newXMLEventFactory returns a factory
*/
@Test
public void testNewXMLEventFactory() {
assertNotNull(StaxHelper.newXMLEventFactory());
}
}

View File

@ -0,0 +1,161 @@
/* ====================================================================
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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.XMLReader;
public class TestXMLHelper {
@Test
public void testDocumentBuilder() throws Exception {
DocumentBuilder documentBuilder = XMLHelper.newDocumentBuilder();
assertNotSame(documentBuilder, XMLHelper.newDocumentBuilder());
assertTrue(documentBuilder.isNamespaceAware());
assertFalse(documentBuilder.isValidating());
documentBuilder.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyDocumentBuilders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<DocumentBuilder>> futures = new ArrayList<>();
for (int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(XMLHelper::newDocumentBuilder));
}
HashSet<DocumentBuilder> dbs = new HashSet<>();
for (CompletableFuture<DocumentBuilder> future : futures) {
DocumentBuilder documentBuilder = future.get(10, TimeUnit.SECONDS);
assertTrue(documentBuilder.isNamespaceAware());
dbs.add(documentBuilder);
}
assertEquals(limit, dbs.size());
}
@Test
public void testDocumentBuilderFactory() throws Exception {
try {
DocumentBuilderFactory dbf = XMLHelper.getDocumentBuilderFactory();
assertTrue(dbf.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertTrue(dbf.getFeature(XMLHelper.FEATURE_DISALLOW_DOCTYPE_DECL));
assertFalse(dbf.getFeature(XMLHelper.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(dbf.getFeature(XMLHelper.FEATURE_LOAD_EXTERNAL_DTD));
} catch (AbstractMethodError e) {
// ignore exceptions from old parsers that don't support this API (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
}
@Test
public void testXMLReader() throws Exception {
XMLReader reader = XMLHelper.newXMLReader();
assertNotSame(reader, XMLHelper.newXMLReader());
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertFalse(reader.getFeature(XMLHelper.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(reader.getFeature(XMLHelper.FEATURE_LOAD_EXTERNAL_DTD));
// assertEquals(XMLHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
assertNotNull(reader.getProperty(XMLHelper.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertEquals("1", reader.getProperty(XMLHelper.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertNotNull(reader.getProperty(XMLHelper.PROPERTY_SECURITY_MANAGER));
} catch (SAXNotRecognizedException e) {
// ignore exceptions from old parsers that don't support these features
// (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyXMLReaders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<XMLReader>> futures = new ArrayList<>();
for (int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(() -> {
try {
return XMLHelper.newXMLReader();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
HashSet<XMLReader> readers = new HashSet<>();
for (CompletableFuture<XMLReader> future : futures) {
XMLReader reader = future.get(10, TimeUnit.SECONDS);
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
} catch (SAXNotRecognizedException e) {
// can happen for older XML Parsers, e.g. we have a CI Job which runs with Xerces XML Parser
assertTrue("Had Exception about not-recognized SAX feature: " + e + " which is only expected" +
" for Xerces XML Parser, but had parser: " + reader,
reader.getClass().getName().contains("org.apache.xerces"));
}
readers.add(reader);
}
assertEquals(limit, readers.size());
}
/**
* test that newXMLInputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLInputFactory() {
XMLInputFactory factory = XMLHelper.newXMLInputFactory();
assertTrue((boolean)factory.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE));
assertFalse((boolean)factory.getProperty(XMLInputFactory.IS_VALIDATING));
assertFalse((boolean)factory.getProperty(XMLInputFactory.SUPPORT_DTD));
assertFalse((boolean)factory.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES));
}
/**
* test that newXMLOutputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLOutputFactory() {
XMLOutputFactory factory = XMLHelper.newXMLOutputFactory();
assertTrue((boolean)factory.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES));
}
/**
* test that newXMLEventFactory returns a factory
*/
@Test
public void testNewXMLEventFactory() {
assertNotNull(XMLHelper.newXMLEventFactory());
}
}