From 780b078c8504719e04c26a22c1bd846f8b521022 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Tue, 24 Sep 2019 20:52:37 +0000 Subject: [PATCH] add TransformerHelper git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1867496 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/ooxml/dev/OOXMLPrettyPrint.java | 36 +++------ .../poi/ooxml/util/TransformerHelper.java | 49 ++++++++++++ .../poi/openxml4j/opc/StreamHelper.java | 74 +++++++++---------- .../poi/xssf/extractor/XSSFExportToXml.java | 5 +- .../xssf/usermodel/XSSFBuiltinTableStyle.java | 3 +- 5 files changed, 101 insertions(+), 66 deletions(-) create mode 100644 src/ooxml/java/org/apache/poi/ooxml/util/TransformerHelper.java diff --git a/src/ooxml/java/org/apache/poi/ooxml/dev/OOXMLPrettyPrint.java b/src/ooxml/java/org/apache/poi/ooxml/dev/OOXMLPrettyPrint.java index 6cf5eb2cfb..8e8b9571d1 100644 --- a/src/ooxml/java/org/apache/poi/ooxml/dev/OOXMLPrettyPrint.java +++ b/src/ooxml/java/org/apache/poi/ooxml/dev/OOXMLPrettyPrint.java @@ -16,35 +16,24 @@ ==================================================================== */ package org.apache.poi.ooxml.dev; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipOutputStream; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.ParserConfigurationException; -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.TransformerFactory; -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.ooxml.util.TransformerHelper; import org.apache.poi.openxml4j.opc.internal.ZipHelper; import org.apache.poi.openxml4j.util.ZipSecureFile; 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.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + /** * Reads a zipped OOXML file and produces a copy with the included * pretty-printed XML files. @@ -82,8 +71,7 @@ public class OOXMLPrettyPrint { System.out.println("Done."); } - private static void handleFile(File file, File outFile) throws ZipException, - IOException, ParserConfigurationException { + private static void handleFile(File file, File outFile) throws IOException { System.out.println("Reading zip-file " + file + " and writing pretty-printed XML to " + outFile); try (ZipSecureFile zipFile = ZipHelper.openZipFile(file)) { @@ -121,7 +109,7 @@ public class OOXMLPrettyPrint { } private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException { - TransformerFactory transformerFactory = TransformerFactory.newInstance(); + TransformerFactory transformerFactory = TransformerHelper.getFactory(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); if (indent > 0) { diff --git a/src/ooxml/java/org/apache/poi/ooxml/util/TransformerHelper.java b/src/ooxml/java/org/apache/poi/ooxml/util/TransformerHelper.java new file mode 100644 index 0000000000..37422c6c91 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/ooxml/util/TransformerHelper.java @@ -0,0 +1,49 @@ +/* ==================================================================== + 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.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; + +import javax.xml.XMLConstants; +import javax.xml.transform.TransformerFactory; + +public final class TransformerHelper { + private static POILogger logger = POILogFactory.getLogger(TransformerHelper.class); + + private TransformerHelper() {} + + static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + static { + trySetFeature(transformerFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true); + } + + public static TransformerFactory getFactory() { + return transformerFactory; + } + + 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); + } + } +} diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java index 78861db115..3c4dc6a238 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java @@ -27,10 +27,10 @@ import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import org.apache.poi.ooxml.util.TransformerHelper; import org.w3c.dom.Document; public final class StreamHelper { @@ -38,12 +38,10 @@ public final class StreamHelper { private StreamHelper() { // Do nothing } - - private static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); - - private static synchronized Transformer getIdentityTransformer() throws TransformerException { - return transformerFactory.newTransformer(); - } + + private static synchronized Transformer getIdentityTransformer() throws TransformerException { + return TransformerHelper.getFactory().newTransformer(); + } /** * Save the document object in the specified output stream. @@ -55,38 +53,38 @@ public final class StreamHelper { * @return true if the xml is successfully written in the stream, * else false. */ - public static boolean saveXmlInStream(Document xmlContent, - OutputStream outStream) { - try { - Transformer trans = getIdentityTransformer(); - Source xmlSource = new DOMSource(xmlContent); - // prevent close of stream by transformer: - Result outputTarget = new StreamResult(new FilterOutputStream( - outStream) { - @Override - public void write(byte[] b, int off, int len) - throws IOException { - out.write(b, off, len); - } + public static boolean saveXmlInStream(Document xmlContent, + OutputStream outStream) { + try { + Transformer trans = getIdentityTransformer(); + Source xmlSource = new DOMSource(xmlContent); + // prevent close of stream by transformer: + Result outputTarget = new StreamResult(new FilterOutputStream( + outStream) { + @Override + public void write(byte[] b, int off, int len) + throws IOException { + out.write(b, off, len); + } - @Override - public void close() throws IOException { - out.flush(); // only flush, don't close! - } - }); - // xmlContent.setXmlStandalone(true); - trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - // don't indent xml documents, the indent will cause errors in calculating the xml signature - // because of different handling of linebreaks in Windows/Unix - // see https://stackoverflow.com/questions/36063375 - trans.setOutputProperty(OutputKeys.INDENT, "no"); - trans.setOutputProperty(OutputKeys.STANDALONE, "yes"); - trans.transform(xmlSource, outputTarget); - } catch (TransformerException e) { - return false; - } - return true; - } + @Override + public void close() throws IOException { + out.flush(); // only flush, don't close! + } + }); + // xmlContent.setXmlStandalone(true); + trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + // don't indent xml documents, the indent will cause errors in calculating the xml signature + // because of different handling of linebreaks in Windows/Unix + // see https://stackoverflow.com/questions/36063375 + trans.setOutputProperty(OutputKeys.INDENT, "no"); + trans.setOutputProperty(OutputKeys.STANDALONE, "yes"); + trans.transform(xmlSource, outputTarget); + } catch (TransformerException e) { + return false; + } + return true; + } /** * Copy the input stream into the output stream. diff --git a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java index 53984fec28..65cb5a981c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java +++ b/src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java @@ -33,13 +33,13 @@ import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; +import org.apache.poi.ooxml.util.TransformerHelper; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ooxml.util.DocumentHelper; @@ -218,8 +218,7 @@ public class XSSFExportToXml implements Comparator{ //Output the XML //set up a transformer - TransformerFactory transfac = TransformerFactory.newInstance(); - Transformer trans = transfac.newTransformer(); + Transformer trans = TransformerHelper.getFactory().newTransformer(); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.setOutputProperty(OutputKeys.INDENT, "yes"); trans.setOutputProperty(OutputKeys.ENCODING, encoding); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBuiltinTableStyle.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBuiltinTableStyle.java index 616e1198bf..36a3840223 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBuiltinTableStyle.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFBuiltinTableStyle.java @@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets; import java.util.EnumMap; import java.util.Map; +import org.apache.poi.ooxml.util.TransformerHelper; import org.apache.poi.ss.usermodel.DifferentialStyleProvider; import org.apache.poi.ss.usermodel.TableStyle; import org.apache.poi.ss.usermodel.TableStyleType; @@ -439,7 +440,7 @@ public enum XSSFBuiltinTableStyle { } private static String writeToString(Node node) throws IOException, TransformerException { - TransformerFactory tf = TransformerFactory.newInstance(); + TransformerFactory tf = TransformerHelper.getFactory(); try (StringWriter sw = new StringWriter()){ Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); -- 2.39.5