From: Yegor Kozlov Date: Sun, 12 Jul 2009 07:18:42 +0000 (+0000) Subject: fixed XSSF and OpenXml4J to read/write relationships with targets starting with ... X-Git-Tag: REL_3_5-FINAL~85 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3601f7f8c60b971f77ef80f51c2e91bc28be59b0;p=poi.git fixed XSSF and OpenXml4J to read/write relationships with targets starting with '#' (internal locations), see Bugzilla 47504 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@793280 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index 09030222c2..76671d1e10 100755 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -19,6 +19,7 @@ package org.apache.poi; import java.io.IOException; import java.util.LinkedList; import java.util.List; +import java.net.URI; import org.apache.xmlbeans.XmlOptions; import org.apache.poi.util.POILogger; @@ -142,7 +143,7 @@ public class POIXMLDocumentPart { @Override public String toString(){ - return packagePart.toString(); + return packagePart == null ? null : packagePart.toString(); } /** @@ -231,17 +232,28 @@ public class POIXMLDocumentPart { PackageRelationshipCollection rels = packagePart.getRelationships(); for (PackageRelationship rel : rels) { if(rel.getTargetMode() == TargetMode.INTERNAL){ - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - PackagePart p = packagePart.getPackage().getPart(relName); - if(p == null) { - logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI()); - continue; + URI uri = rel.getTargetURI(); + + PackagePart p; + if(uri.getRawFragment() != null) { + /* + * For internal references (e.g. '#Sheet1!A1') the package part is null + */ + p = null; + } else { + PackagePartName relName = PackagingURIHelper.createPartName(uri); + p = packagePart.getPackage().getPart(relName); + if(p == null) { + logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI()); + continue; + } } + POIXMLDocumentPart childPart = factory.createDocumentPart(rel, p); childPart.parent = this; addRelation(childPart); - if(p.hasRelationships()) childPart.read(factory); + if(p != null && p.hasRelationships()) childPart.read(factory); } } } diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java index b59a78b74c..cfe0fb0a5d 100755 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java @@ -161,8 +161,12 @@ public final class ZipPartMarshaller implements PartMarshaller { PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External"); } else { - targetValue = PackagingURIHelper.relativizeURI( - sourcePartURI, rel.getTargetURI()).getPath(); + URI targetURI = rel.getTargetURI(); + targetValue = PackagingURIHelper.relativizeURI( + sourcePartURI, targetURI).getPath(); + if (targetURI.getRawFragment() != null) { + targetValue += "#" + targetURI.getRawFragment(); + } } relElem.addAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME, targetValue); diff --git a/src/ooxml/java/org/apache/poi/util/PackageHelper.java b/src/ooxml/java/org/apache/poi/util/PackageHelper.java index 78468d5b94..186d85acc3 100755 --- a/src/ooxml/java/org/apache/poi/util/PackageHelper.java +++ b/src/ooxml/java/org/apache/poi/util/PackageHelper.java @@ -22,6 +22,7 @@ import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.util.IOUtils; import java.io.*; +import java.net.URI; /** * Provides handy methods to work with OOXML packages @@ -83,11 +84,10 @@ public class PackageHelper { * Creates an empty file in the default temporary-file directory, */ public static File createTempFile() throws IOException { - File file = File.createTempFile("poi-ooxml-", ".tmp"); + File file = TempFile.createTempFile("poi-ooxml-", ".tmp"); //there is no way to pass an existing file to Package.create(file), //delete first, the file will be re-created in Packe.create(file) file.delete(); - file.deleteOnExit(); return file; } @@ -104,11 +104,18 @@ public class PackageHelper { //external relations don't have associated package parts continue; } else { - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - p = pkg.getPart(relName); + URI uri = rel.getTargetURI(); + + if(uri.getRawFragment() != null) { + part_tgt.addRelationship(uri, rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); + continue; + } else { + PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); + p = pkg.getPart(relName); + part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); + } } - part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); PackagePart dest; if(!tgt.containPart(p.getPartName())){ diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java index 5f667deba9..46597b7828 100755 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java @@ -35,6 +35,7 @@ import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; import org.apache.poi.openxml4j.opc.internal.FileHelper; +import org.apache.poi.util.TempFile; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; @@ -167,8 +168,10 @@ public final class TestPackage extends TestCase { coreOut = corePart.getOutputStream(); coreOut.write("".getBytes()); coreOut.close(); - - + + //add a relationship with internal target: "#Sheet1!A1" + corePart.addRelationship(new URI("#Sheet1!A1"), TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", "rId2"); + // Check things are as expected PackageRelationshipCollection coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT); @@ -181,11 +184,12 @@ public final class TestPackage extends TestCase { // Save and re-load pkg.close(); - FileOutputStream fout = new FileOutputStream(File.createTempFile("testCreatePackageWithCoreDocument", ".zip")); + File tmp = TempFile.createTempFile("testCreatePackageWithCoreDocument", ".zip"); + FileOutputStream fout = new FileOutputStream(tmp); fout.write(baos.toByteArray()); fout.close(); - pkg = OPCPackage.open(new ByteArrayInputStream(baos.toByteArray())); - + pkg = OPCPackage.open(tmp.getPath()); + //tmp.delete(); // Check still right coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT); @@ -193,8 +197,16 @@ public final class TestPackage extends TestCase { coreRel = coreRels.getRelationship(0); assertEquals("/", coreRel.getSourceURI().toString()); assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString()); - assertNotNull(pkg.getPart(coreRel)); - } + corePart = pkg.getPart(coreRel); + assertNotNull(corePart); + + PackageRelationshipCollection rels = corePart.getRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"); + assertEquals(1, rels.size()); + rel = rels.getRelationship(0); + assertEquals("Sheet1!A1", rel.getTargetURI().getRawFragment()); + + + } /** * Test package opening. diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java index a4ef876b47..6161f4264b 100755 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java @@ -17,9 +17,7 @@ package org.apache.poi.openxml4j.opc; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; +import java.io.*; import junit.framework.TestCase; @@ -254,4 +252,5 @@ public class TestRelationships extends TestCase { assertEquals("/docProps/core.xml", pkg.getRelationshipsByType("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties").getRelationship(0).getTargetURI().toString()); } + } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java b/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java index 6c37c7086f..e7d254119a 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java @@ -30,6 +30,7 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.util.TempFile; /** * Centralises logic for finding/opening sample files in the src/testcases/org/apache/poi/hssf/hssf/data folder. @@ -57,8 +58,7 @@ public class XSSFTestDataSamples { InputStream is = new ByteArrayInputStream(baos.toByteArray()); result = new HSSFWorkbook(is); } else if (wb instanceof XSSFWorkbook) { - File tmp = File.createTempFile("poi-ooxml-", ".xlsx"); - tmp.deleteOnExit(); + File tmp = TempFile.createTempFile("poi-ooxml-", ".xlsx"); FileOutputStream out = new FileOutputStream(tmp); wb.write(out); out.close(); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 9cb9b7f737..bda438994c 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -18,6 +18,7 @@ package org.apache.poi.xssf.usermodel; import java.io.File; +import java.util.List; import junit.framework.TestCase; @@ -28,6 +29,7 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; +import org.apache.poi.POIXMLDocumentPart; public class TestXSSFBugs extends BaseTestBugzillaIssues { @Override @@ -121,4 +123,24 @@ public class TestXSSFBugs extends BaseTestBugzillaIssues { ); assertNotNull(drw); } + public void test47504() { + XSSFWorkbook wb = getTestDataProvider().openSampleWorkbook("47504.xlsx"); + assertEquals(1, wb.getNumberOfSheets()); + XSSFSheet sh = wb.getSheetAt(0); + XSSFDrawing drawing = sh.createDrawingPatriarch(); + List rels = drawing.getRelations(); + assertEquals(1, rels.size()); + assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment()); + + // And again, just to be sure + wb = XSSFTestDataSamples.writeOutAndReadBack(wb); + assertEquals(1, wb.getNumberOfSheets()); + sh = wb.getSheetAt(0); + drawing = sh.createDrawingPatriarch(); + rels = drawing.getRelations(); + assertEquals(1, rels.size()); + assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment()); + + } + } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java index 749b92114b..6ab1edbf75 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java @@ -33,6 +33,7 @@ import org.apache.poi.openxml4j.opc.ContentTypes; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagingURIHelper; +import org.apache.poi.util.TempFile; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; @@ -74,7 +75,7 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook { assertEquals(0, workbook.getSheetAt(2).getFirstRowNum()); assertEquals(0, workbook.getSheetAt(2).getLastRowNum()); - File file = File.createTempFile("poi-", ".xlsx"); + File file = TempFile.createTempFile("poi-", ".xlsx"); OutputStream out = new FileOutputStream(file); workbook.write(out); out.close(); diff --git a/src/testcases/org/apache/poi/hssf/data/47504.xlsx b/src/testcases/org/apache/poi/hssf/data/47504.xlsx new file mode 100755 index 0000000000..8805a78ac5 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/47504.xlsx differ