From 8c1b7df4bc119a1b6e93ebb1db51e21585107f31 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 19 Jul 2015 12:11:19 +0000 Subject: [PATCH] Bug 57484: Allow processing of non-OOXML core namespace packages git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691821 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/TestAllFiles.java | 12 +-- .../poi/stress/POIXMLDocumentHandler.java | 37 ++------- .../apache/poi/stress/XDGFFileHandler.java | 77 +++++++++++++++++++ .../java/org/apache/poi/POIXMLDocument.java | 9 +++ .../org/apache/poi/POIXMLDocumentPart.java | 17 +++- .../org/apache/poi/TestPOIXMLDocument.java | 34 ++++++++ 6 files changed, 145 insertions(+), 41 deletions(-) create mode 100644 src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index 85b058084..784b9baa2 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -103,12 +103,12 @@ public class TestAllFiles { HANDLERS.put(".vsd", new HDGFFileHandler()); // Visio - ooxml (currently unsupported) - HANDLERS.put(".vsdm", new NullFileHandler()); - HANDLERS.put(".vsdx", new NullFileHandler()); - HANDLERS.put(".vssm", new NullFileHandler()); - HANDLERS.put(".vssx", new NullFileHandler()); - HANDLERS.put(".vstm", new NullFileHandler()); - HANDLERS.put(".vstx", new NullFileHandler()); + HANDLERS.put(".vsdm", new XDGFFileHandler()); + HANDLERS.put(".vsdx", new XDGFFileHandler()); + HANDLERS.put(".vssm", new XDGFFileHandler()); + HANDLERS.put(".vssx", new XDGFFileHandler()); + HANDLERS.put(".vstm", new XDGFFileHandler()); + HANDLERS.put(".vstx", new XDGFFileHandler()); // POIFS HANDLERS.put(".ole2", new POIFSFileHandler()); diff --git a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java index 7b0821dcc..1a8cbf6a0 100644 --- a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java +++ b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java @@ -20,17 +20,10 @@ import static org.junit.Assert.assertNotNull; import java.io.IOException; import java.io.InputStream; -import java.util.List; import org.apache.poi.POIXMLDocument; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; -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.poifs.crypt.Decryptor; import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.junit.Ignore; -import org.junit.Test; public final class POIXMLDocumentHandler { protected void handlePOIXMLDocument(POIXMLDocument doc) throws Exception { @@ -44,33 +37,15 @@ public final class POIXMLDocumentHandler { protected static boolean isEncrypted(InputStream stream) throws IOException { if (POIFSFileSystem.hasPOIFSHeader(stream)) { POIFSFileSystem poifs = new POIFSFileSystem(stream); - if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { - return true; + try { + if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { + return true; + } + } finally { + poifs.close(); } throw new IOException("wrong file format or file extension for OO XML file"); } return false; } - - // a test-case to test this locally without executing the full TestAllFiles - @Ignore("POIXMLDocument cannot handle this Visio file currently...") - @Test - public void test() throws Exception { - OPCPackage pkg = OPCPackage.open("test-data/diagram/test.vsdx", PackageAccess.READ); - try { - handlePOIXMLDocument(new TestPOIXMLDocument(pkg)); - } finally { - pkg.close(); - } - } - - private final static class TestPOIXMLDocument extends POIXMLDocument { - public TestPOIXMLDocument(OPCPackage pkg) { - super(pkg); - } - - public List getAllEmbedds() throws OpenXML4JException { - return null; - } - } } diff --git a/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java new file mode 100644 index 000000000..3095cea12 --- /dev/null +++ b/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java @@ -0,0 +1,77 @@ +/* ==================================================================== + 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.stress; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.POIXMLDocument; +import org.apache.poi.openxml4j.exceptions.OpenXML4JException; +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.util.PackageHelper; +import org.junit.Test; + +public class XDGFFileHandler extends AbstractFileHandler { + @Override + public void handleFile(InputStream stream) throws Exception { + // ignore password protected files + if (POIXMLDocumentHandler.isEncrypted(stream)) return; + + TestXDGFXMLDocument doc = new TestXDGFXMLDocument(stream); + new POIXMLDocumentHandler().handlePOIXMLDocument(doc); + } + + @Override + public void handleExtracting(File file) throws Exception { + // TODO: extraction/actual operations not supported yet + } + + // a test-case to test this locally without executing the full TestAllFiles + @Test + public void test() throws Exception { + OPCPackage pkg = OPCPackage.open("test-data/diagram/test.vsdx", PackageAccess.READ); + try { + TestXDGFXMLDocument doc = new TestXDGFXMLDocument(pkg); + new POIXMLDocumentHandler().handlePOIXMLDocument(doc); + } finally { + pkg.close(); + } + } + + // TODO: Get rid of this when full visio ooxml support is added + private final static class TestXDGFXMLDocument extends POIXMLDocument { + + public static String CORE_DOCUMENT = "http://schemas.microsoft.com/visio/2010/relationships/document"; + + public TestXDGFXMLDocument(OPCPackage pkg) { + super(pkg, CORE_DOCUMENT); + } + + public TestXDGFXMLDocument(InputStream is) throws IOException { + this(PackageHelper.open(is)); + } + + public List getAllEmbedds() throws OpenXML4JException { + return new ArrayList(); + } + } +} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index 0e18ee112..0352d5c87 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -57,6 +57,15 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close protected POIXMLDocument(OPCPackage pkg) { super(pkg); + init(pkg); + } + + protected POIXMLDocument(OPCPackage pkg, String coreDocumentRel) { + super(pkg, coreDocumentRel); + init(pkg); + } + + private void init(OPCPackage pkg) { this.pkg = pkg; // Workaround for XMLBEANS-512 - ensure that when we parse diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index f051eb32a..857f0dad2 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -63,7 +63,7 @@ public class POIXMLDocumentPart { DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8"); } - + private String coreDocumentRel = PackageRelationshipTypes.CORE_DOCUMENT; private PackagePart packagePart; private PackageRelationship packageRel; private POIXMLDocumentPart parent; @@ -93,7 +93,16 @@ public class POIXMLDocumentPart { * Construct POIXMLDocumentPart representing a "core document" package part. */ public POIXMLDocumentPart(OPCPackage pkg) { - PackageRelationship coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0); + this(pkg, PackageRelationshipTypes.CORE_DOCUMENT); + } + + /** + * Construct POIXMLDocumentPart representing a custom "core document" package part. + */ + public POIXMLDocumentPart(OPCPackage pkg, String coreDocumentRel) { + this.coreDocumentRel = coreDocumentRel; + PackageRelationship coreRel = pkg.getRelationshipsByType(this.coreDocumentRel).getRelationship(0); + if (coreRel == null) { coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0); if (coreRel != null) { @@ -151,10 +160,10 @@ public class POIXMLDocumentPart { */ protected final void rebase(OPCPackage pkg) throws InvalidFormatException { PackageRelationshipCollection cores = - packagePart.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT); + packagePart.getRelationshipsByType(coreDocumentRel); if(cores.size() != 1) { throw new IllegalStateException( - "Tried to rebase using " + PackageRelationshipTypes.CORE_DOCUMENT + + "Tried to rebase using " + coreDocumentRel + " but found " + cores.size() + " parts of the right type" ); } diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java index 55f4093fb..2c41b18f7 100644 --- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java +++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java @@ -31,6 +31,7 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; import org.apache.poi.util.PackageHelper; import org.apache.poi.util.TempFile; @@ -44,6 +45,10 @@ public final class TestPOIXMLDocument extends TestCase { public OPCParser(OPCPackage pkg) { super(pkg); } + + public OPCParser(OPCPackage pkg, String coreDocumentRel) { + super(pkg, coreDocumentRel); + } @Override public List getAllEmbedds() { @@ -181,4 +186,33 @@ public final class TestPOIXMLDocument extends TestCase { part.onDocumentCreate(); //part.getTargetPart(null); } + + public void testVSDX() throws Exception { + OPCPackage open = PackageHelper.open(POIDataSamples.getDiagramInstance().openResourceAsStream("test.vsdx")); + + POIXMLDocument part = new OPCParser(open, PackageRelationshipTypes.VISIO_CORE_DOCUMENT); + + assertNotNull(part); + assertEquals(0, part.getRelationCounter()); + } + + public void testVSDXPart() throws Exception { + OPCPackage open = PackageHelper.open(POIDataSamples.getDiagramInstance().openResourceAsStream("test.vsdx")); + + POIXMLDocumentPart part = new POIXMLDocumentPart(open, PackageRelationshipTypes.VISIO_CORE_DOCUMENT); + + assertNotNull(part); + assertEquals(0, part.getRelationCounter()); + } + + public void testInvalidCoreRel() throws Exception { + OPCPackage open = PackageHelper.open(POIDataSamples.getDiagramInstance().openResourceAsStream("test.vsdx")); + + try { + new POIXMLDocumentPart(open, "somethingillegal"); + fail("Unknown core ref will throw exception"); + } catch (POIXMLException e) { + // expected here + } + } }