mirror of https://github.com/apache/poi.git
Re-instate two dev-tools that we lost in some refactoring,
at least OOXMLPrettyPrint is still very useful for comparing ooxml-files git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849813 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ae3d6944db
commit
7de8c2eaec
|
@ -0,0 +1,145 @@
|
|||
/* ====================================================================
|
||||
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.dev;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.openxml4j.opc.PackageAccess;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
|
||||
/**
|
||||
* Prints out the contents of a OOXML container.
|
||||
* Useful for seeing what parts are defined, and how
|
||||
* they're all related to each other.
|
||||
*/
|
||||
public class OOXMLLister implements Closeable {
|
||||
private final OPCPackage container;
|
||||
private final PrintStream disp;
|
||||
|
||||
public OOXMLLister(OPCPackage container) {
|
||||
this(container, System.out);
|
||||
}
|
||||
public OOXMLLister(OPCPackage container, PrintStream disp) {
|
||||
this.container = container;
|
||||
this.disp = disp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures out how big a given PackagePart is.
|
||||
*
|
||||
* @param part the PackagePart
|
||||
* @return the size of the PackagePart
|
||||
*
|
||||
* @throws IOException if the part can't be read
|
||||
*/
|
||||
public static long getSize(PackagePart part) throws IOException {
|
||||
try (InputStream in = part.getInputStream()) {
|
||||
byte[] b = new byte[8192];
|
||||
long size = 0;
|
||||
int read = 0;
|
||||
|
||||
while (read > -1) {
|
||||
read = in.read(b);
|
||||
if (read > 0) {
|
||||
size += read;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays information on all the different
|
||||
* parts of the OOXML file container.
|
||||
* @throws InvalidFormatException if the package relations are invalid
|
||||
* @throws IOException if the package can't be read
|
||||
*/
|
||||
public void displayParts() throws InvalidFormatException, IOException {
|
||||
ArrayList<PackagePart> parts = container.getParts();
|
||||
for (PackagePart part : parts) {
|
||||
disp.println(part.getPartName());
|
||||
disp.println("\t" + part.getContentType());
|
||||
|
||||
if(! part.getPartName().toString().equals("/docProps/core.xml")) {
|
||||
disp.println("\t" + getSize(part) + " bytes");
|
||||
}
|
||||
|
||||
if(! part.isRelationshipPart()) {
|
||||
disp.println("\t" + part.getRelationships().size() + " relations");
|
||||
for(PackageRelationship rel : part.getRelationships()) {
|
||||
displayRelation(rel, "\t ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Displays information on all the different
|
||||
* relationships between different parts
|
||||
* of the OOXML file container.
|
||||
*/
|
||||
public void displayRelations() {
|
||||
PackageRelationshipCollection rels =
|
||||
container.getRelationships();
|
||||
for (PackageRelationship rel : rels) {
|
||||
displayRelation(rel, "");
|
||||
}
|
||||
}
|
||||
|
||||
private void displayRelation(PackageRelationship rel, String indent) {
|
||||
disp.println(indent+"Relationship:");
|
||||
disp.println(indent+"\tFrom: "+ rel.getSourceURI());
|
||||
disp.println(indent+"\tTo: " + rel.getTargetURI());
|
||||
disp.println(indent+"\tID: " + rel.getId());
|
||||
disp.println(indent+"\tMode: " + rel.getTargetMode());
|
||||
disp.println(indent+"\tType: " + rel.getRelationshipType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
container.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, InvalidFormatException {
|
||||
if(args.length == 0) {
|
||||
System.err.println("Use:");
|
||||
System.err.println("\tjava OOXMLLister <filename>");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File f = new File(args[0]);
|
||||
if(! f.exists()) {
|
||||
System.err.println("Error, file not found!");
|
||||
System.err.println("\t" + f);
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
try (OOXMLLister lister = new OOXMLLister(
|
||||
OPCPackage.open(f.toString(), PackageAccess.READ)
|
||||
)) {
|
||||
lister.disp.println(f + "\n");
|
||||
lister.displayParts();
|
||||
lister.disp.println();
|
||||
lister.displayRelations();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/* ====================================================================
|
||||
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.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.DocumentBuilderFactory;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Reads a zipped OOXML file and produces a copy with the included
|
||||
* pretty-printed XML files.
|
||||
*
|
||||
* This is useful for comparing OOXML files produced by different tools as the often
|
||||
* use different formatting of the XML.
|
||||
*/
|
||||
public class OOXMLPrettyPrint {
|
||||
private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
private final DocumentBuilder documentBuilder;
|
||||
|
||||
public OOXMLPrettyPrint() throws ParserConfigurationException {
|
||||
// allow files with much lower inflation rate here as there is no risk of Zip Bomb attacks in this developer tool
|
||||
ZipSecureFile.setMinInflateRatio(0.00001);
|
||||
|
||||
documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if(args.length <= 1 || args.length % 2 != 0) {
|
||||
System.err.println("Use:");
|
||||
System.err.println("\tjava OOXMLPrettyPrint [<filename> <outfilename>] ...");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
for(int i = 0;i < args.length;i+=2) {
|
||||
File f = new File(args[i]);
|
||||
if(! f.exists()) {
|
||||
System.err.println("Error, file not found!");
|
||||
System.err.println("\t" + f);
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
handleFile(f, new File(args[i+1]));
|
||||
}
|
||||
System.out.println("Done.");
|
||||
}
|
||||
|
||||
private static void handleFile(File file, File outFile) throws ZipException,
|
||||
IOException, ParserConfigurationException {
|
||||
System.out.println("Reading zip-file " + file + " and writing pretty-printed XML to " + outFile);
|
||||
|
||||
try (ZipSecureFile zipFile = ZipHelper.openZipFile(file)) {
|
||||
try (ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)))) {
|
||||
new OOXMLPrettyPrint().handle(zipFile, out);
|
||||
}
|
||||
} finally {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private void handle(ZipSecureFile file, ZipOutputStream out) throws IOException {
|
||||
Enumeration<? extends ZipArchiveEntry> entries = file.getEntries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipArchiveEntry entry = entries.nextElement();
|
||||
|
||||
String name = entry.getName();
|
||||
out.putNextEntry(new ZipEntry(name));
|
||||
try {
|
||||
if(name.endsWith(".xml") || name.endsWith(".rels")) {
|
||||
Document document = documentBuilder.parse(new InputSource(file.getInputStream(entry)));
|
||||
document.setXmlStandalone(true);
|
||||
pretty(document, out, 2);
|
||||
} else {
|
||||
System.out.println("Not pretty-printing non-XML file " + name);
|
||||
IOUtils.copy(file.getInputStream(entry), out);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IOException("While handling entry " + name, e);
|
||||
} finally {
|
||||
out.closeEntry();
|
||||
}
|
||||
System.out.print(".");
|
||||
}
|
||||
}
|
||||
|
||||
private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException {
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
if (indent > 0) {
|
||||
// set properties to indent the resulting XML nicely
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indent));
|
||||
}
|
||||
Result result = new StreamResult(outputStream);
|
||||
Source source = new DOMSource(document);
|
||||
transformer.transform(source, result);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue