diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index bfcdf5aa4..507b79199 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + New PackagePart method getRelatedPart(PackageRelationship) to simplify navigation of relations between OPC Parts 51832 - handle XLS files where the WRITEPROTECT record preceeds the FILEPASS one, rather than following as normal 51809 - correct GTE handling in COUNTIF Add HWPF API to update range text and delete bookmarks diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index 075c9c84f..fa41a5744 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -90,7 +90,7 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{ PackagePart[] parts = new PackagePart[partsC.size()]; int count = 0; for (PackageRelationship rel : partsC) { - parts[count] = getTargetPart(rel); + parts[count] = getPackagePart().getRelatedPart(rel); count++; } return parts; diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index 311573618..880af2765 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -61,23 +61,6 @@ public class POIXMLDocumentPart { private POIXMLDocumentPart parent; private Map relations = new LinkedHashMap(); - /** - * Get the PackagePart that is the target of a relationship. - * - * @param rel The relationship - * @param pkg The package to fetch from - * @return The target part - * @throws InvalidFormatException - */ - protected static PackagePart getTargetPart(OPCPackage pkg, PackageRelationship rel) - throws InvalidFormatException { - PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); - PackagePart part = pkg.getPart(relName); - if (part == null) { - throw new IllegalArgumentException("No part found for relationship " + rel); - } - return part; - } /** * Counter that provides the amount of incoming relations from other parts * to this part. @@ -159,7 +142,7 @@ public class POIXMLDocumentPart { ); } packageRel = cores.getRelationship(0); - packagePart = POIXMLDocument.getTargetPart(pkg, packageRel); + packagePart = packagePart.getRelatedPart(packageRel); } /** @@ -425,6 +408,18 @@ public class POIXMLDocumentPart { } } } + + /** + * Get the PackagePart that is the target of a relationship from this Part. + * + * @param rel The relationship + * @return The target part + * @throws InvalidFormatException + */ + protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException { + return getPackagePart().getRelatedPart(rel); + } + /** * Fired when a new package part is created @@ -440,17 +435,6 @@ public class POIXMLDocumentPart { } - /** - * Get the PackagePart that is the target of a relationship. - * - * @param rel The relationship - * @return The target part - * @throws InvalidFormatException - */ - protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException { - return getTargetPart(getPackagePart().getPackage(), rel); - } - /** * Fired when a package part is about to be removed from the package */ diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java index 36bcc37a3..6371c13ce 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java @@ -456,6 +456,38 @@ public abstract class PackagePart implements RelationshipSource { return false; } + /** + * Get the PackagePart that is the target of a relationship. + * + * @param rel A relationship from this part to another one + * @return The target part of the relationship + */ + public PackagePart getRelatedPart(PackageRelationship rel) throws InvalidFormatException { + // Ensure this is one of ours + if(! isRelationshipExists(rel)) { + throw new IllegalArgumentException("Relationship " + rel + " doesn't start with this part " + _partName); + } + + // Get the target URI, excluding any relative fragments + URI target = rel.getTargetURI(); + if(target.getFragment() != null) { + String t = target.toString(); + try { + target = new URI( t.substring(0, t.indexOf('#')) ); + } catch(URISyntaxException e) { + throw new InvalidFormatException("Invalid target URI: " + target); + } + } + + // Turn that into a name, and fetch + PackagePartName relName = PackagingURIHelper.createPartName(target); + PackagePart part = _container.getPart(relName); + if (part == null) { + throw new IllegalArgumentException("No part found for relationship " + rel); + } + return part; + } + /** * Get the input stream of this part to read its content. * diff --git a/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java index d2986dc3f..09dccdff1 100644 --- a/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java @@ -78,14 +78,15 @@ public class XSLFSlideShow extends POIXMLDocument { embedds = new LinkedList(); for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdList()) { - PackagePart slidePart = - getTargetPart(getCorePart().getRelationship(ctSlide.getId2())); + PackagePart corePart = getCorePart(); + PackagePart slidePart = corePart.getRelatedPart( + corePart.getRelationship(ctSlide.getId2())); for(PackageRelationship rel : slidePart.getRelationshipsByType(OLE_OBJECT_REL_TYPE)) - embedds.add(getTargetPart(rel)); // TODO: Add this reference to each slide as well + embedds.add(slidePart.getRelatedPart(rel)); // TODO: Add this reference to each slide as well for(PackageRelationship rel : slidePart.getRelationshipsByType(PACK_OBJECT_REL_TYPE)) - embedds.add(getTargetPart(rel)); + embedds.add(slidePart.getRelatedPart(rel)); } } public XSLFSlideShow(String file) throws OpenXML4JException, IOException, XmlException { @@ -129,8 +130,9 @@ public class XSLFSlideShow extends POIXMLDocument { public PackagePart getSlideMasterPart(CTSlideMasterIdListEntry master) throws IOException, XmlException { try { - return getTargetPart( - getCorePart().getRelationship(master.getId2()) + PackagePart corePart = getCorePart(); + return corePart.getRelatedPart( + corePart.getRelationship(master.getId2()) ); } catch(InvalidFormatException e) { throw new XmlException(e); @@ -150,9 +152,10 @@ public class XSLFSlideShow extends POIXMLDocument { public PackagePart getSlidePart(CTSlideIdListEntry slide) throws IOException, XmlException { try { - return getTargetPart( - getCorePart().getRelationship(slide.getId2()) - ); + PackagePart corePart = getCorePart(); + return corePart.getRelatedPart( + corePart.getRelationship(slide.getId2()) + ); } catch(InvalidFormatException e) { throw new XmlException(e); } @@ -192,7 +195,7 @@ public class XSLFSlideShow extends POIXMLDocument { } try { - return getTargetPart(notes.getRelationship(0)); + return slidePart.getRelatedPart(notes.getRelationship(0)); } catch(InvalidFormatException e) { throw new IllegalStateException(e); } @@ -236,7 +239,7 @@ public class XSLFSlideShow extends POIXMLDocument { } try { - PackagePart cPart = getTargetPart( + PackagePart cPart = slidePart.getRelatedPart( commentRels.getRelationship(0) ); CmLstDocument commDoc = diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 9b0c7219a..801128178 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -1333,12 +1333,13 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable embedds = new LinkedList(); // Get the embeddings for the workbook + PackagePart part = getPackagePart(); for (PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE)) { - embedds.add(getTargetPart(rel)); + embedds.add(part.getRelatedPart(rel)); } for (PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE)) { - embedds.add(getTargetPart(rel)); + embedds.add(part.getRelatedPart(rel)); } return embedds;