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;
public class OOXMLPrettyPrint {
private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private final DocumentBuilder documentBuilder;
public OOXMLPrettyPrint() throws ParserConfigurationException {
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) {
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);
}
}