From: Andreas Beeker Date: Sun, 10 Jan 2016 20:44:17 +0000 (+0000) Subject: #54916 - POI does not always read all the slides in pptx files X-Git-Tag: REL_3_14_FINAL~89 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c47f6763971f3ab1a563c92d460f5cb48c4c0728;p=poi.git #54916 - POI does not always read all the slides in pptx files git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1723966 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index a23dbdd7cc..a196797645 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -259,12 +259,22 @@ public class TestAllFiles { // non-TNEF files EXPECTED_FAILURES.add("ddf/Container.dat"); EXPECTED_FAILURES.add("ddf/47143.dat"); + + // sheet cloning errors + EXPECTED_FAILURES.add("spreadsheet/47813.xlsx"); + EXPECTED_FAILURES.add("spreadsheet/56450.xls"); + EXPECTED_FAILURES.add("spreadsheet/57231_MixedGasReport.xls"); + EXPECTED_FAILURES.add("spreadsheet/OddStyleRecord.xls"); + EXPECTED_FAILURES.add("spreadsheet/WithChartSheet.xlsx"); + EXPECTED_FAILURES.add("spreadsheet/chart_sheet.xlsx"); } private static final Set IGNORED = new HashSet(); static { // need JDK8+ - https://bugs.openjdk.java.net/browse/JDK-8038081 IGNORED.add("slideshow/42474-2.ppt"); + // OPC handler works / XSSF handler fails + IGNORED.add("spreadsheet/57181.xlsm"); } @Parameters(name="{index}: {0} using {1}") diff --git a/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java b/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java index 64e9805cb9..243679d03d 100644 --- a/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java +++ b/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java @@ -29,6 +29,7 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.util.RecordFormatException; public abstract class SpreadsheetHandler extends AbstractFileHandler { public void handleWorkbook(Workbook wb, String extension) throws IOException { @@ -54,6 +55,10 @@ public abstract class SpreadsheetHandler extends AbstractFileHandler { assertNotNull(read); readContent(read); + + modifyContent(read); + + read.close(); } private ByteArrayOutputStream writeToArray(Workbook wb) @@ -88,4 +93,25 @@ public abstract class SpreadsheetHandler extends AbstractFileHandler { } } } + + private void modifyContent(Workbook wb) { + for (int i=wb.getNumberOfSheets()-1; i>=0; i--) { + try { + wb.cloneSheet(i); + } catch (RecordFormatException e) { + if (e.getCause() instanceof CloneNotSupportedException) { + // ignore me + continue; + } + throw e; + } catch (RuntimeException e) { + if ("Could not find 'internal references' EXTERNALBOOK".equals(e.getMessage())) { + continue; + } else if ("CountryRecord not found".equals(e.getMessage())) { + continue; + } + throw e; + } + } + } } \ No newline at end of file diff --git a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java index 4de2dbd8eb..cf893949f0 100644 --- a/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/XSSFFileHandler.java @@ -68,6 +68,8 @@ public class XSSFFileHandler extends SpreadsheetHandler { exportToXML(wb); checkXSSFReader(OPCPackage.open(new ByteArrayInputStream(bytes))); + + wb.close(); } diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index 1abf91be0a..41bee52d48 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -20,11 +20,9 @@ import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; @@ -56,9 +54,39 @@ public class POIXMLDocumentPart { private String coreDocumentRel = PackageRelationshipTypes.CORE_DOCUMENT; private PackagePart packagePart; - private PackageRelationship packageRel; private POIXMLDocumentPart parent; - private Map relations = new LinkedHashMap(); + private Map relations = new LinkedHashMap(); + + /** + * The RelationPart is a cached relationship between the document, which contains the RelationPart, + * and one of its referenced child document parts. + * The child document parts may only belong to one parent, but it's often referenced by other + * parents too, having varying {@link PackageRelationship#getId() relationship ids} pointing to it. + */ + public static class RelationPart { + private final PackageRelationship relationship; + private final POIXMLDocumentPart documentPart; + + RelationPart(PackageRelationship relationship, POIXMLDocumentPart documentPart) { + this.relationship = relationship; + this.documentPart = documentPart; + } + + /** + * @return the cached relationship, which uniquely identifies this child document part within the parent + */ + public PackageRelationship getRelationship() { + return relationship; + } + + /** + * @return the child document part + */ + @SuppressWarnings("unchecked") + public T getDocumentPart() { + return (T)documentPart; + } + } /** * Counter that provides the amount of incoming relations from other parts @@ -86,47 +114,64 @@ public class POIXMLDocumentPart { public POIXMLDocumentPart(OPCPackage pkg) { this(pkg, PackageRelationshipTypes.CORE_DOCUMENT); } - + /** * Construct POIXMLDocumentPart representing a custom "core document" package part. */ public POIXMLDocumentPart(OPCPackage pkg, String coreDocumentRel) { + this(getPartFromOPCPackage(pkg, 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) { - throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699"); - } - } - if (coreRel == null) { - throw new POIXMLException("OOXML file structure broken/invalid - no core document found!"); - } - - this.packagePart = pkg.getPart(coreRel); - this.packageRel = coreRel; } - + /** * Creates new POIXMLDocumentPart - called by client code to create new parts from scratch. * * @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean) */ - public POIXMLDocumentPart(){ + public POIXMLDocumentPart() { } /** * Creates an POIXMLDocumentPart representing the given package part and relationship. - * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an exisiting file. + * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file. * - * @param part - The package part that holds xml data represenring this sheet. + * @param part - The package part that holds xml data representing this sheet. + * @see #read(POIXMLFactory, java.util.Map) + * + * @since POI 3.14-Beta1 + */ + public POIXMLDocumentPart(PackagePart part) { + this(null, part); + } + + /** + * Creates an POIXMLDocumentPart representing the given package part, relationship and parent + * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file. + * + * @param parent - Parent part + * @param part - The package part that holds xml data representing this sheet. + * @see #read(POIXMLFactory, java.util.Map) + * + * @since POI 3.14-Beta1 + */ + public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part) { + this.packagePart = part; + this.parent = parent; + } + + /** + * Creates an POIXMLDocumentPart representing the given package part and relationship. + * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file. + * + * @param part - The package part that holds xml data representing this sheet. * @param rel - the relationship of the given package part - * @see #read(POIXMLFactory, java.util.Map) + * @see #read(POIXMLFactory, java.util.Map) + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 */ + @Deprecated public POIXMLDocumentPart(PackagePart part, PackageRelationship rel){ - this.packagePart = part; - this.packageRel = rel; + this(null, part); } /** @@ -137,17 +182,18 @@ public class POIXMLDocumentPart { * @param part - The package part that holds xml data represenring this sheet. * @param rel - the relationship of the given package part * @see #read(POIXMLFactory, java.util.Map) + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 */ + @Deprecated public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel){ - this.packagePart = part; - this.packageRel = rel; - this.parent = parent; + this(parent, part); } /** * When you open something like a theme, call this to * re-base the XML Document onto the core child of the - * current core document + * current core document */ protected final void rebase(OPCPackage pkg) throws InvalidFormatException { PackageRelationshipCollection cores = @@ -158,8 +204,7 @@ public class POIXMLDocumentPart { " but found " + cores.size() + " parts of the right type" ); } - packageRel = cores.getRelationship(0); - packagePart = packagePart.getRelatedPart(packageRel); + packagePart = packagePart.getRelatedPart(cores.getRelationship(0)); } /** @@ -175,9 +220,28 @@ public class POIXMLDocumentPart { * Provides access to the PackageRelationship that identifies this POIXMLDocumentPart * * @return the PackageRelationship that identifies this POIXMLDocumentPart + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 */ - public final PackageRelationship getPackageRelationship(){ - return packageRel; + @Deprecated + @SuppressWarnings("resource") + public final PackageRelationship getPackageRelationship() { + if (this.parent != null) { + for (RelationPart rp : parent.getRelationParts()) { + if (rp.getDocumentPart() == this) { + return rp.getRelationship(); + } + } + } else { + OPCPackage pkg = getPackagePart().getPackage(); + String partName = getPackagePart().getPartName().getName(); + for (PackageRelationship rel : pkg.getRelationships()) { + if (rel.getTargetURI().toASCIIString().equals(partName)) { + return rel; + } + } + } + return null; } /** @@ -186,7 +250,21 @@ public class POIXMLDocumentPart { * @return child relations */ public final List getRelations(){ - return Collections.unmodifiableList(new ArrayList(relations.values())); + List l = new ArrayList(); + for (RelationPart rp : relations.values()) { + l.add(rp.getDocumentPart()); + } + return Collections.unmodifiableList(l); + } + + /** + * Returns the list of child relations for this POIXMLDocumentPart + * + * @return child relations + */ + public final List getRelationParts() { + List l = new ArrayList(relations.values()); + return Collections.unmodifiableList(l); } /** @@ -195,13 +273,14 @@ public class POIXMLDocumentPart { * {@link POIXMLDocumentPart} to the {@link PackagePart} of the target * {@link POIXMLDocumentPart} with a {@link PackageRelationship#getId()} * matching the given parameter value. - * + * * @param id * The relation id to look for * @return the target part of the relation, or null, if none exists */ public final POIXMLDocumentPart getRelationById(String id) { - return relations.get(id); + RelationPart rp = relations.get(id); + return (rp == null) ? null : rp.getDocumentPart(); } /** @@ -209,7 +288,7 @@ public class POIXMLDocumentPart { * {@link PackageRelationship}, that sources from the {@link PackagePart} of * this {@link POIXMLDocumentPart} to the {@link PackagePart} of the given * parameter value. - * + * * @param part * The {@link POIXMLDocumentPart} for which the according * relation-id shall be found. @@ -217,12 +296,9 @@ public class POIXMLDocumentPart { * parts are not related. */ public final String getRelationId(POIXMLDocumentPart part) { - Iterator> iter = relations.entrySet().iterator(); - while (iter.hasNext()) - { - Entry entry = iter.next(); - if (entry.getValue() == part) { - return entry.getKey(); + for (RelationPart rp : relations.values()) { + if (rp.getDocumentPart() == part) { + return rp.getRelationship().getId(); } } return null; @@ -232,10 +308,66 @@ public class POIXMLDocumentPart { * Add a new child POIXMLDocumentPart * * @param part the child to add + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public final void addRelation(String id,POIXMLDocumentPart part) { + PackageRelationship pr = part.getPackagePart().getRelationship(id); + addRelation(pr, part); + } + + /** + * Add a new child POIXMLDocumentPart + * + * @param relId the preferred relation id, when null the next free relation id will be used + * @param relationshipType the package relationship type + * @param part the child to add + * + * @since 3.14-Beta1 + */ + public final RelationPart addRelation(String relId, POIXMLRelation relationshipType, POIXMLDocumentPart part) { + PackageRelationship pr = findExistingRelation(part); + if (pr == null) { + PackagePartName ppn = part.getPackagePart().getPartName(); + String relType = relationshipType.getRelation(); + pr = packagePart.addRelationship(ppn, TargetMode.INTERNAL, relType, relId); + } + addRelation(pr, part); + return new RelationPart(pr, part); + } + + /** + * Add a new child POIXMLDocumentPart + * + * @param pr the relationship of the child + * @param part the child to add */ - public final void addRelation(String id,POIXMLDocumentPart part){ - relations.put(id,part); + private void addRelation(PackageRelationship pr, POIXMLDocumentPart part) { + relations.put(pr.getId(), new RelationPart(pr,part)); part.incrementRelationCounter(); + + } + + /** + * Check if the new part was already added before via PackagePart.addRelationship() + * + * @param part + * @return + */ + private PackageRelationship findExistingRelation(POIXMLDocumentPart part) { + String ppn = part.getPackagePart().getPartName().getName(); + try { + for (PackageRelationship pr : packagePart.getRelationships()) { + PackagePart pp = packagePart.getRelatedPart(pr); + if (ppn.equals(pp.getPartName().getName())) { + return pr; + } + } + } catch (InvalidFormatException e) { + throw new POIXMLException("invalid package relationships", e); + } + return null; } /** @@ -249,7 +381,7 @@ public class POIXMLDocumentPart { /** * Remove the relation to the specified part in this package and remove the * part, if it is no longer needed and flag is set to true. - * + * * @param part * The related part, to which the relation shall be removed. * @param removeUnusedParts @@ -331,7 +463,8 @@ public class POIXMLDocumentPart { commit(); alreadySaved.add(this.getPackagePart()); - for(POIXMLDocumentPart p : relations.values()){ + for(RelationPart rp : relations.values()){ + POIXMLDocumentPart p = rp.getDocumentPart(); if (!alreadySaved.contains(p.getPackagePart())) { p.onSave(alreadySaved); } @@ -339,10 +472,10 @@ public class POIXMLDocumentPart { } /** - * Ensure that a memory based package part does not have lingering data from previous - * commit() calls. - * - * Note: This is overwritten for some objects, as *PictureData seem to store the actual content + * Ensure that a memory based package part does not have lingering data from previous + * commit() calls. + * + * Note: This is overwritten for some objects, as *PictureData seem to store the actual content * in the part directly without keeping a copy like all others therefore we need to handle them differently. */ protected void prepareForCommit() { @@ -364,7 +497,7 @@ public class POIXMLDocumentPart { * create nor recognize packages with equivalent part names. */ public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){ - return createRelationship(descriptor, factory, -1, false); + return createRelationship(descriptor, factory, -1, false).getDocumentPart(); } /** @@ -380,7 +513,7 @@ public class POIXMLDocumentPart { * create nor recognize packages with equivalent part names. */ public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){ - return createRelationship(descriptor, factory, idx, false); + return createRelationship(descriptor, factory, idx, false).getDocumentPart(); } /** @@ -396,7 +529,7 @@ public class POIXMLDocumentPart { * equivalent part names and package implementers shall neither * create nor recognize packages with equivalent part names. */ - protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){ + protected final RelationPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){ try { PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx)); PackageRelationship rel = null; @@ -406,14 +539,14 @@ public class POIXMLDocumentPart { rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation()); } POIXMLDocumentPart doc = factory.newDocumentPart(descriptor); - doc.packageRel = rel; doc.packagePart = part; doc.parent = this; - if(!noRelation) { + if (!noRelation) { /* only add to relations, if according relationship is being created. */ - addRelation(rel.getId(),doc); + addRelation(rel,doc); } - return doc; + + return new RelationPart(rel,doc); } catch (PartAlreadyExistsException pae) { // Return the specific exception so the user knows // that the name is already taken @@ -432,42 +565,55 @@ public class POIXMLDocumentPart { * @param context context map containing already visited noted keyed by targetURI */ protected void read(POIXMLFactory factory, Map context) throws OpenXML4JException { + PackagePart pp = getPackagePart(); + // add mapping a second time, in case of initial caller hasn't done so + POIXMLDocumentPart otherChild = context.put(pp, this); + if (otherChild != null && otherChild != this) { + throw new POIXMLException("Unique PackagePart-POIXMLDocumentPart relation broken!"); + } + + if (!pp.hasRelationships()) return; + PackageRelationshipCollection rels = packagePart.getRelationships(); + List readLater = new ArrayList(); + + // scan breadth-first, so parent-relations are hopefully the shallowest element for (PackageRelationship rel : rels) { if(rel.getTargetMode() == TargetMode.INTERNAL){ URI uri = rel.getTargetURI(); - PackagePart p; + // check for internal references (e.g. '#Sheet1!A1') + PackagePartName relName; if(uri.getRawFragment() != null) { - /* - * For internal references (e.g. '#Sheet1!A1') the package part is null - */ - p = null; + relName = PackagingURIHelper.createPartName(uri.getPath()); } else { - PackagePartName relName = PackagingURIHelper.createPartName(uri); - p = packagePart.getPackage().getPart(relName); - if(p == null) { - logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI()); - continue; - } + relName = PackagingURIHelper.createPartName(uri); } - if (!context.containsKey(p)) { - POIXMLDocumentPart childPart = factory.createDocumentPart(this, rel, p); - childPart.parent = this; - addRelation(rel.getId(),childPart); - if(p != null){ - context.put(p, childPart); - if(p.hasRelationships()) childPart.read(factory, context); - } + final PackagePart p = packagePart.getPackage().getPart(relName); + if (p == null) { + logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI()); + continue; } - else { - addRelation(rel.getId(),context.get(p)); + + POIXMLDocumentPart childPart = context.get(p); + if (childPart == null) { + childPart = factory.createDocumentPart(this, p); + childPart.parent = this; + // already add child to context, so other children can reference it + context.put(p, childPart); + readLater.add(childPart); } + + addRelation(rel,childPart); } } + + for (POIXMLDocumentPart childPart : readLater) { + childPart.read(factory, context); + } } - + /** * Get the PackagePart that is the target of a relationship from this Part. * @@ -511,4 +657,28 @@ public class POIXMLDocumentPart { public static void _invokeOnDocumentRead(POIXMLDocumentPart part) throws IOException { part.onDocumentRead(); } + + /** + * Retrieves the core document part + * + * @since POI 3.14-Beta1 + */ + private static PackagePart getPartFromOPCPackage(OPCPackage pkg, String coreDocumentRel) { + PackageRelationship coreRel = pkg.getRelationshipsByType(coreDocumentRel).getRelationship(0); + + if (coreRel != null) { + PackagePart pp = pkg.getPart(coreRel); + if (pp == null) { + throw new POIXMLException("OOXML file structure broken/invalid - core document '"+coreRel.getTargetURI()+"' not found."); + } + return pp; + } + + coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0); + if (coreRel != null) { + throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699"); + } + + throw new POIXMLException("OOXML file structure broken/invalid - no core document found!"); + } } diff --git a/src/ooxml/java/org/apache/poi/POIXMLFactory.java b/src/ooxml/java/org/apache/poi/POIXMLFactory.java index 6eebbd9c2e..af58bd1296 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLFactory.java +++ b/src/ooxml/java/org/apache/poi/POIXMLFactory.java @@ -16,16 +16,25 @@ ==================================================================== */ package org.apache.poi; -import org.apache.poi.openxml4j.opc.PackageRelationship; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import org.apache.poi.POIXMLDocumentPart.RelationPart; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; /** * Defines a factory API that enables sub-classes to create instances of POIXMLDocumentPart - * - * @author Yegor Kozlov */ public abstract class POIXMLFactory { + private static final POILogger LOGGER = POILogFactory.getLogger(POIXMLFactory.class); + private static final Class[] PARENT_PART = {POIXMLDocumentPart.class, PackagePart.class}; + private static final Class[] ORPHAN_PART = {PackagePart.class}; + /** * Create a POIXMLDocumentPart from existing package part and relation. This method is called * from {@link POIXMLDocument#load(POIXMLFactory)} when parsing a document @@ -34,8 +43,62 @@ public abstract class POIXMLFactory { * @param rel the package part relationship * @param part the PackagePart representing the created instance * @return A new instance of a POIXMLDocumentPart. + * + * @since by POI 3.14-Beta1 */ - public abstract POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part); + public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackagePart part) { + PackageRelationship rel = getPackageRelationship(parent, part); + POIXMLRelation descriptor = getDescriptor(rel.getRelationshipType()); + + if (descriptor == null || descriptor.getRelationClass() == null) { + LOGGER.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType()); + return new POIXMLDocumentPart(parent, part); + } + + Class cls = descriptor.getRelationClass(); + try { + try { + return createDocumentPart(cls, PARENT_PART, new Object[]{parent, part}); + } catch (NoSuchMethodException e) { + return createDocumentPart(cls, ORPHAN_PART, new Object[]{part}); + } + } catch (Exception e) { + throw new POIXMLException(e); + } + } + + /** + * Need to delegate instantiation to sub class because of constructor visibility + * @since POI 3.14-Beta1 + */ + protected abstract POIXMLDocumentPart createDocumentPart + (Class cls, Class[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException; + + /** + * returns the descriptor for the given relationship type + * + * @return the descriptor or null if type is unknown + * + * @since POI 3.14-Beta1 + */ + protected abstract POIXMLRelation getDescriptor(String relationshipType); + + /** + * Create a POIXMLDocumentPart from existing package part and relation. This method is called + * from {@link POIXMLDocument#load(POIXMLFactory)} when parsing a document + * + * @param parent parent part + * @param rel the package part relationship + * @param part the PackagePart representing the created instance + * @return A new instance of a POIXMLDocumentPart. + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public final POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part) { + return createDocumentPart(parent, part); + } /** * Create a new POIXMLDocumentPart using the supplied descriptor. This method is used when adding new parts @@ -44,5 +107,33 @@ public abstract class POIXMLFactory { * @param descriptor describes the object to create * @return A new instance of a POIXMLDocumentPart. */ - public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor); + public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor) { + Class cls = descriptor.getRelationClass(); + try { + return createDocumentPart(cls, null, null); + } catch (Exception e) { + throw new POIXMLException(e); + } + } + + /** + * Retrieves the package relationship of the child part within the parent + * + * @since POI 3.14-Beta1 + */ + protected PackageRelationship getPackageRelationship(POIXMLDocumentPart parent, PackagePart part) { + try { + String partName = part.getPartName().getName(); + for (PackageRelationship pr : parent.getPackagePart().getRelationships()) { + String packName = pr.getTargetURI().toASCIIString(); + if (packName.equalsIgnoreCase(partName)) { + return pr; + } + } + } catch (InvalidFormatException e) { + throw new POIXMLException("error while determining package relations", e); + } + + throw new POIXMLException("package part isn't a child of the parent document."); + } } diff --git a/src/ooxml/java/org/apache/poi/POIXMLRelation.java b/src/ooxml/java/org/apache/poi/POIXMLRelation.java index 8766dfff72..68b4174eb6 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLRelation.java +++ b/src/ooxml/java/org/apache/poi/POIXMLRelation.java @@ -117,7 +117,7 @@ public abstract class POIXMLRelation { */ public Integer getFileNameIndex(POIXMLDocumentPart part) { String regex = _defaultName.replace("#", "(\\d+)"); - return Integer.parseInt(part.getPackageRelationship().getTargetURI().getPath().replaceAll(regex, "$1")); + return Integer.valueOf(part.getPackagePart().getPartName().getName().replaceAll(regex, "$1")); } /** diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java index 7d4741b219..90ee15e298 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java @@ -55,7 +55,7 @@ public final class PackageRelationship { /* End XML markup */ /** - * L'ID de la relation. + * Relation id. */ private String id; @@ -65,22 +65,22 @@ public final class PackageRelationship { private OPCPackage container; /** - * Type de relation. + * Relationship type */ private String relationshipType; /** - * Partie source de cette relation. + * Part of this relationship source */ private PackagePart source; /** - * Le mode de ciblage [Internal|External] + * Targeting mode [Internal|External] */ private TargetMode targetMode; /** - * URI de la partie cible. + * Target URI */ private URI targetUri; diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java index 6a872c4499..4ee9ee5ebf 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFBaseContents.java @@ -53,10 +53,21 @@ public class XDGFBaseContents extends XDGFXMLDocumentPart { protected Map _shapes = new HashMap(); protected List _connections = new ArrayList(); - public XDGFBaseContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { - super(part, rel, document); + /** + * @since POI 3.14-Beta1 + */ + public XDGFBaseContents(PackagePart part, XDGFDocument document) { + super(part, document); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XDGFBaseContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { + this(part, document); + } + @Internal public PageContentsType getXmlObject() { return _pageContents; diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java index 6bfa0c50c3..83ac58ce05 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFFactory.java @@ -18,69 +18,52 @@ package org.apache.poi.xdgf.usermodel; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLFactory; import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; +/** + * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type + */ public class XDGFFactory extends POIXMLFactory { - private static final POILogger logger = POILogFactory - .getLogger(XDGFFactory.class); - - private XDGFDocument _document; + private final XDGFDocument document; public XDGFFactory(XDGFDocument document) { - _document = document; + this.document = document; } - @Override - public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, - PackageRelationship rel, PackagePart part) { - POIXMLRelation descriptor = XDGFRelation.getInstance(rel - .getRelationshipType()); - if (descriptor == null || descriptor.getRelationClass() == null) { - logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " - + rel.getRelationshipType()); - return new POIXMLDocumentPart(part, rel); - } - - try { - Class cls = descriptor - .getRelationClass(); - try { - Constructor constructor = cls - .getDeclaredConstructor(POIXMLDocumentPart.class, - PackagePart.class, PackageRelationship.class, - XDGFDocument.class); - return constructor.newInstance(parent, part, rel, _document); - } catch (NoSuchMethodException e) { - Constructor constructor = cls - .getDeclaredConstructor(PackagePart.class, - PackageRelationship.class, XDGFDocument.class); - return constructor.newInstance(part, rel, _document); - } - } catch (Exception e) { - throw new POIXMLException(e); - } + /** + * @since POI 3.14-Beta1 + */ + protected POIXMLRelation getDescriptor(String relationshipType) { + return XDGFRelation.getInstance(relationshipType); } + /** + * @since POI 3.14-Beta1 + */ @Override - public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor) { - try { - Class cls = descriptor - .getRelationClass(); - Constructor constructor = cls - .getDeclaredConstructor(); - return constructor.newInstance(); - } catch (Exception e) { - throw new POIXMLException(e); + protected POIXMLDocumentPart createDocumentPart + (Class cls, Class[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Class[] cl; + Object[] vals; + if (classes == null) { + cl = new Class[]{XDGFDocument.class}; + vals = new Object[]{document}; + } else { + cl = new Class[classes.length+1]; + System.arraycopy(classes, 0, cl, 0, classes.length); + cl[classes.length] = XDGFDocument.class; + vals = new Object[values.length+1]; + System.arraycopy(values, 0, vals, 0, values.length); + vals[values.length] = document; } + + Constructor constructor = cls.getDeclaredConstructor(cl); + return constructor.newInstance(vals); } - } diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java index a56d1dd1df..335a32289a 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasterContents.java @@ -34,11 +34,22 @@ public class XDGFMasterContents extends XDGFBaseContents { protected XDGFMaster _master; - public XDGFMasterContents(PackagePart part, PackageRelationship rel, - XDGFDocument document) { - super(part, rel, document); + /** + * @since POI 3.14-Beta1 + */ + public XDGFMasterContents(PackagePart part, XDGFDocument document) { + super(part, document); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XDGFMasterContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { + this(part, document); + } + + @Override protected void onDocumentRead() { diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java index fb576ad843..9fa90b8327 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFMasters.java @@ -46,10 +46,21 @@ public class XDGFMasters extends XDGFXMLDocumentPart { // key: id of master protected Map _masters = new HashMap(); - public XDGFMasters(PackagePart part, PackageRelationship rel, XDGFDocument document) { - super(part, rel, document); + /** + * @since POI 3.14-Beta1 + */ + public XDGFMasters(PackagePart part, XDGFDocument document) { + super(part, document); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XDGFMasters(PackagePart part, PackageRelationship rel, XDGFDocument document) { + this(part, document); + } + @Internal protected MastersType getXmlObject() { return _mastersObject; @@ -72,16 +83,19 @@ public class XDGFMasters extends XDGFXMLDocumentPart { } // create the masters - for (POIXMLDocumentPart part: getRelations()) { + for (RelationPart rp : getRelationParts()) { + POIXMLDocumentPart part = rp.getDocumentPart(); - String relId = part.getPackageRelationship().getId(); + String relId = rp.getRelationship().getId(); MasterType settings = masterSettings.get(relId); - if (settings == null) + if (settings == null) { throw new POIXMLException("Master relationship for " + relId + " not found"); + } - if (!(part instanceof XDGFMasterContents)) + if (!(part instanceof XDGFMasterContents)) { throw new POIXMLException("Unexpected masters relationship for " + relId + ": " + part); + } XDGFMasterContents contents = (XDGFMasterContents)part; contents.onDocumentRead(); diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java index 70458a5b5a..e1965f3c25 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPageContents.java @@ -35,10 +35,21 @@ public class XDGFPageContents extends XDGFBaseContents { protected Map _masters = new HashMap(); protected XDGFPage _page; - public XDGFPageContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { - super(part, rel, document); + /** + * @since POI 3.14-Beta1 + */ + public XDGFPageContents(PackagePart part, XDGFDocument document) { + super(part, document); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XDGFPageContents(PackagePart part, PackageRelationship rel, XDGFDocument document) { + this(part, document); + } + @Override protected void onDocumentRead() { try { diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java index ced70aacfb..a2fc4c7a00 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPages.java @@ -45,10 +45,21 @@ public class XDGFPages extends XDGFXMLDocumentPart { // ordered by page number List _pages = new ArrayList(); - public XDGFPages(PackagePart part, PackageRelationship rel, XDGFDocument document) { - super(part, rel, document); + /** + * @since POI 3.14-Beta1 + */ + public XDGFPages(PackagePart part, XDGFDocument document) { + super(part, document); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XDGFPages(PackagePart part, PackageRelationship rel, XDGFDocument document) { + this(part, document); + } + @Internal PagesType getXmlObject() { return _pagesObject; diff --git a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java index afd4fce7fb..1733754874 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java +++ b/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFRelation.java @@ -65,12 +65,9 @@ public class XDGFRelation extends POIXMLRelation { "http://schemas.microsoft.com/visio/2010/relationships/windows", "/visio/windows.xml", null); - private XDGFRelation(String type, String rel, String defaultName, - Class cls) { + private XDGFRelation(String type, String rel, String defaultName, Class cls) { super(type, rel, defaultName, cls); - - if (cls != null && !_table.containsKey(rel)) - _table.put(rel, this); + _table.put(rel, this); } /** diff --git a/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java index a8c70d84c7..5e52646457 100644 --- a/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/xdgf/xml/XDGFXMLDocumentPart.java @@ -24,11 +24,21 @@ import org.apache.poi.xdgf.usermodel.XDGFDocument; public class XDGFXMLDocumentPart extends POIXMLDocumentPart { protected XDGFDocument _document; - - public XDGFXMLDocumentPart(PackagePart part, PackageRelationship rel, - XDGFDocument document) { - super(part, rel); + + /** + * @since POI 3.14-Beta1 + */ + public XDGFXMLDocumentPart(PackagePart part, XDGFDocument document) { + super(part); _document = document; } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XDGFXMLDocumentPart(PackagePart part, PackageRelationship rel, XDGFDocument document) { + this(part, document); + } } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java index 34b5bed19a..2084031b07 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java @@ -36,8 +36,6 @@ import org.apache.poi.POIXMLException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; -import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.apache.poi.sl.usermodel.Resources; @@ -132,9 +130,10 @@ implements SlideShow { Map masterMap = new HashMap(); Map shIdMap = new HashMap(); - for (POIXMLDocumentPart p : getRelations()) { + for (RelationPart rp : getRelationParts()) { + POIXMLDocumentPart p = rp.getDocumentPart(); if (p instanceof XSLFSlide) { - shIdMap.put(p.getPackageRelationship().getId(), (XSLFSlide) p); + shIdMap.put(rp.getRelationship().getId(), (XSLFSlide) p); } else if (p instanceof XSLFSlideMaster) { masterMap.put(getRelationId(p), (XSLFSlideMaster) p); } else if (p instanceof XSLFTableStyles){ @@ -218,19 +217,16 @@ implements SlideShow { } } - XSLFSlide slide = (XSLFSlide)createRelationship( - XSLFRelation.SLIDE, XSLFFactory.getInstance(), cnt); + RelationPart rp = createRelationship( + XSLFRelation.SLIDE, XSLFFactory.getInstance(), cnt, false); + XSLFSlide slide = (XSLFSlide)rp.getDocumentPart(); CTSlideIdListEntry slideId = slideList.addNewSldId(); slideId.setId(slideNumber); - slideId.setId2(slide.getPackageRelationship().getId()); + slideId.setId2(rp.getRelationship().getId()); layout.copyLayout(slide); - slide.addRelation(layout.getPackageRelationship().getId(), layout); - - PackagePartName ppName = layout.getPackagePart().getPartName(); - slide.getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, - layout.getPackageRelationship().getRelationshipType()); + slide.addRelation(null, XSLFRelation.SLIDE_LAYOUT, layout); _slides.add(slide); return slide; @@ -271,22 +267,13 @@ implements SlideShow { Integer slideIndex = XSLFRelation.SLIDE.getFileNameIndex(slide); - XSLFNotes notesSlide = (XSLFNotes) createRelationship(XSLFRelation.NOTES, XSLFFactory.getInstance(), slideIndex); - - notesSlide.addRelation(_notesMaster.getPackageRelationship().getId(), _notesMaster); - PackagePartName notesMasterPackagePartName = _notesMaster.getPackagePart().getPartName(); - notesSlide.getPackagePart().addRelationship(notesMasterPackagePartName, TargetMode.INTERNAL, - _notesMaster.getPackageRelationship().getRelationshipType()); - - slide.addRelation(notesSlide.getPackageRelationship().getId(), notesSlide); - PackagePartName notesSlidesPackagePartName = notesSlide.getPackagePart().getPartName(); - slide.getPackagePart().addRelationship(notesSlidesPackagePartName, TargetMode.INTERNAL, - notesSlide.getPackageRelationship().getRelationshipType()); - - notesSlide.addRelation(slide.getPackageRelationship().getId(), slide); - PackagePartName slidesPackagePartName = slide.getPackagePart().getPartName(); - notesSlide.getPackagePart().addRelationship(slidesPackagePartName, TargetMode.INTERNAL, - slide.getPackageRelationship().getRelationshipType()); + // add notes slide to presentation + XSLFNotes notesSlide = (XSLFNotes) createRelationship + (XSLFRelation.NOTES, XSLFFactory.getInstance(), slideIndex); + // link slide and notes slide with each other + slide.addRelation(null, XSLFRelation.NOTES, notesSlide); + notesSlide.addRelation(null, XSLFRelation.NOTES_MASTER, _notesMaster); + notesSlide.addRelation(null, XSLFRelation.SLIDE, slide); notesSlide.importContent(_notesMaster); @@ -297,15 +284,16 @@ implements SlideShow { * Create a notes master. */ public void createNotesMaster() { - - _notesMaster = (XSLFNotesMaster) createRelationship(XSLFRelation.NOTES_MASTER, - XSLFFactory.getInstance(), 1); + RelationPart rp = createRelationship + (XSLFRelation.NOTES_MASTER, XSLFFactory.getInstance(), 1, false); + _notesMaster = (XSLFNotesMaster)rp.getDocumentPart(); CTNotesMasterIdList notesMasterIdList = _presentation.addNewNotesMasterIdLst(); CTNotesMasterIdListEntry notesMasterId = notesMasterIdList.addNewNotesMasterId(); - notesMasterId.setId(_notesMaster.getPackageRelationship().getId()); + notesMasterId.setId(rp.getRelationship().getId()); Integer themeIndex = 1; + // TODO: check if that list can be replaced by idx = Math.max(idx,themeIdx) List themeIndexList = new ArrayList(); for (POIXMLDocumentPart p : getRelations()) { if (p instanceof XSLFTheme) { @@ -326,14 +314,11 @@ implements SlideShow { } } - XSLFTheme theme = (XSLFTheme) createRelationship(XSLFRelation.THEME, - XSLFFactory.getInstance(), themeIndex); + XSLFTheme theme = (XSLFTheme) createRelationship + (XSLFRelation.THEME, XSLFFactory.getInstance(), themeIndex); theme.importTheme(getSlides().get(0).getTheme()); - _notesMaster.addRelation(theme.getPackageRelationship().getId(), theme); - PackagePartName themePackagePartName = theme.getPackagePart().getPartName(); - _notesMaster.getPackagePart().addRelationship(themePackagePartName, TargetMode.INTERNAL, - theme.getPackageRelationship().getRelationshipType()); + _notesMaster.addRelation(null, XSLFRelation.THEME, theme); } /** @@ -436,7 +421,7 @@ implements SlideShow { if (relType == null) { throw new IllegalArgumentException("Picture type "+format+" is not supported."); } - img = (XSLFPictureData) createRelationship(relType, XSLFFactory.getInstance(), imageNumber + 1, true); + img = (XSLFPictureData) createRelationship(relType, XSLFFactory.getInstance(), imageNumber + 1, true).getDocumentPart(); img.setIndex(imageNumber); _pictures.add(img); try { diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java index db8df4e9fa..40b254c93a 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java @@ -55,20 +55,35 @@ public final class XSLFChart extends POIXMLDocumentPart { */ private CTChart chart; - /** - * Construct a chart from a package part. - * - * @param part the package part holding the chart data, - * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml - * @param rel the package relationship holding this chart, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart - */ - protected XSLFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + /** + * Construct a chart from a package part. + * + * @param part the package part holding the chart data, + * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml + * + * @since POI 3.14-Beta1 + */ + protected XSLFChart(PackagePart part) throws IOException, XmlException { + super(part); + + chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); + chart = chartSpace.getChart(); + } - chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); - chart = chartSpace.getChart(); - } + /** + * Construct a chart from a package part. + * + * @param part the package part holding the chart data, + * the content type must be application/vnd.openxmlformats-officedocument.drawingml.chart+xml + * @param rel the package relationship holding this chart, + * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSLFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } /** * Return the underlying CTChartSpace bean, the root element of the Chart part. diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java index dcbc78076e..52aa0f6ff2 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFCommentAuthors.java @@ -48,16 +48,30 @@ public class XSLFCommentAuthors extends POIXMLDocumentPart { * * @param part the package part holding the comment authors data, * the content type must be application/vnd.openxmlformats-officedocument.commentAuthors+xml - * @param rel the package relationship holding this comment authors, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors + * + * @since POI 3.14-Beta1 */ - XSLFCommentAuthors(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); - + XSLFCommentAuthors(PackagePart part) throws IOException, XmlException { + super(part); CmAuthorLstDocument doc = CmAuthorLstDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); _authors = doc.getCmAuthorLst(); } + + /** + * Construct a SpreadsheetML slide authors from a package part + * + * @param part the package part holding the comment authors data, + * the content type must be application/vnd.openxmlformats-officedocument.commentAuthors+xml + * @param rel the package relationship holding this comment authors, + * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + XSLFCommentAuthors(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } public CTCommentAuthorList getCTCommentAuthorsList() { return _authors; diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java index 8331289b4e..c2e1c732ff 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFComments.java @@ -48,16 +48,31 @@ public class XSLFComments extends POIXMLDocumentPart { * * @param part the package part holding the comments data, * the content type must be application/vnd.openxmlformats-officedocument.comments+xml - * @param rel the package relationship holding this comments, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments + * + * @since POI 3.14-Beta1 */ - XSLFComments(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + XSLFComments(PackagePart part) throws IOException, XmlException { + super(part); CmLstDocument doc = CmLstDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); _comments = doc.getCmLst(); } + + /** + * Construct a SpreadsheetML slide comments from a package part + * + * @param part the package part holding the comments data, + * the content type must be application/vnd.openxmlformats-officedocument.comments+xml + * @param rel the package relationship holding this comments, + * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments + * + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + XSLFComments(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } public CTCommentList getCTCommentsList() { return _comments; diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java index cb7f329181..897ebaec69 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFFactory.java @@ -19,27 +19,17 @@ package org.apache.poi.xslf.usermodel; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLFactory; import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.Beta; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - -import java.lang.reflect.Constructor; /** * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - * - * @author Yegor Kozlov */ -@Beta public final class XSLFFactory extends POIXMLFactory { - private static final POILogger logger = POILogFactory.getLogger(XSLFFactory.class); - private XSLFFactory(){ } @@ -50,32 +40,22 @@ public final class XSLFFactory extends POIXMLFactory { return inst; } + /** + * @since POI 3.14-Beta1 + */ @Override - public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part){ - POIXMLRelation descriptor = XSLFRelation.getInstance(rel.getRelationshipType()); - if(descriptor == null || descriptor.getRelationClass() == null){ - logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType()); - return new POIXMLDocumentPart(part, rel); - } - - try { - Class cls = descriptor.getRelationClass(); - Constructor constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class); - return constructor.newInstance(part, rel); - } catch (Exception e){ - throw new POIXMLException(e); - } + protected POIXMLRelation getDescriptor(String relationshipType) { + return XSLFRelation.getInstance(relationshipType); } + /** + * @since POI 3.14-Beta1 + */ @Override - public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){ - try { - Class cls = descriptor.getRelationClass(); - Constructor constructor = cls.getDeclaredConstructor(); - return constructor.newInstance(); - } catch (Exception e){ - throw new POIXMLException(e); - } + protected POIXMLDocumentPart createDocumentPart + (Class cls, Class[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor constructor = cls.getDeclaredConstructor(classes); + return constructor.newInstance(values); } - } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java index d69125e056..5c0ec58d25 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java @@ -53,9 +53,11 @@ implements Notes { * the content type must be application/vnd.openxmlformats-officedocument.notes+xml * @param rel the package relationship holding this notes, * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/notes + * + * @since POI 3.14-Beta1 */ - XSLFNotes(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + XSLFNotes(PackagePart part) throws IOException, XmlException { + super(part); NotesDocument doc = NotesDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); @@ -63,6 +65,14 @@ implements Notes { setCommonSlideData(_notes.getCSld()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + XSLFNotes(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } + private static CTNotesSlide prototype(){ CTNotesSlide ctNotes = CTNotesSlide.Factory.newInstance(); CTCommonSlideData cSld = ctNotes.addNewCSld(); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java index c93c9cc26e..6f955a45ed 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotesMaster.java @@ -59,14 +59,25 @@ import org.openxmlformats.schemas.presentationml.x2006.main.NotesMasterDocument; _slide = prototype(); } - protected XSLFNotesMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + /** + * @since POI 3.14-Beta1 + */ + protected XSLFNotesMaster(PackagePart part) throws IOException, XmlException { + super(part); NotesMasterDocument doc = NotesMasterDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); _slide = doc.getNotesMaster(); setCommonSlideData(_slide.getCSld()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSLFNotesMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } + private static CTNotesMaster prototype() { InputStream is = XSLFNotesMaster.class.getResourceAsStream("notesMaster.xml"); if (is == null) { diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java index 5cb8d6f333..935d12331e 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java @@ -64,15 +64,28 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture super(); } + /** + * Construct XSLFPictureData from a package part + * + * @param part the package part holding the drawing data + * + * @since POI 3.14-Beta1 + */ + public XSLFPictureData(PackagePart part) { + super(part); + } + /** * Construct XSLFPictureData from a package part * * @param part the package part holding the drawing data, * @param rel the package relationship holding this drawing, * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 */ + @Deprecated public XSLFPictureData(PackagePart part, PackageRelationship rel) { - super(part, rel); + this(part); } /** diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java index b2e3ff2bbc..5ea703ee69 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java @@ -221,7 +221,7 @@ public class XSLFRelation extends POIXMLRelation { null, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", null, - null + XSLFPictureData.class ); public static final XSLFRelation TABLE_STYLES = new XSLFRelation( @@ -233,8 +233,7 @@ public class XSLFRelation extends POIXMLRelation { private XSLFRelation(String type, String rel, String defaultName, Class cls) { super(type, rel, defaultName, cls); - - if(cls != null && !_table.containsKey(rel)) _table.put(rel, this); + _table.put(rel, this); } /** diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java index e8fa1da034..70ee99ccd3 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java @@ -72,9 +72,20 @@ implements XSLFShapeContainer, Sheet { public XSLFSheet() { super(); } + + /** + * @since POI 3.14-Beta1 + */ + public XSLFSheet(PackagePart part) { + super(part); + } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated public XSLFSheet(PackagePart part, PackageRelationship rel){ - super(part, rel); + this(part); } /** @@ -212,11 +223,9 @@ implements XSLFShapeContainer, Sheet { XSLFPictureData xPictureData = (XSLFPictureData)pictureData; PackagePart pic = xPictureData.getPackagePart(); - PackageRelationship rel = getPackagePart().addRelationship( - pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation()); - addRelation(rel.getId(), new XSLFPictureData(pic, rel)); + RelationPart rp = addRelation(null, XSLFRelation.IMAGES, new XSLFPictureData(pic)); - XSLFPictureShape sh = getDrawing().createPicture(rel.getId()); + XSLFPictureShape sh = getDrawing().createPicture(rp.getRelationship().getId()); new DrawPictureShape(sh).resize(); getShapes().add(sh); sh.setParent(this); @@ -550,17 +559,15 @@ implements XSLFShapeContainer, Sheet { } catch (InvalidFormatException e){ throw new POIXMLException(e); } - XSLFPictureData data = new XSLFPictureData(blipPart, null); + XSLFPictureData data = new XSLFPictureData(blipPart); XMLSlideShow ppt = getSlideShow(); XSLFPictureData pictureData = ppt.addPicture(data.getData(), data.getType()); PackagePart pic = pictureData.getPackagePart(); - PackageRelationship rel = getPackagePart().addRelationship( - pic.getPartName(), TargetMode.INTERNAL, blipRel.getRelationshipType()); - addRelation(rel.getId(), new XSLFPictureData(pic, rel)); - - return rel.getId(); + RelationPart rp = addRelation(blipId, XSLFRelation.IMAGES, new XSLFPictureData(pic)); + + return rp.getRelationship().getId(); } /** diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java index 491062163c..ebc69b76b9 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java @@ -66,11 +66,11 @@ implements Slide { * * @param part the package part holding the slide data, * the content type must be application/vnd.openxmlformats-officedocument.slide+xml - * @param rel the package relationship holding this slide, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide + * + * @since POI 3.14-Beta1 */ - XSLFSlide(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + XSLFSlide(PackagePart part) throws IOException, XmlException { + super(part); SldDocument doc = SldDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); @@ -78,7 +78,15 @@ implements Slide { setCommonSlideData(_slide.getCSld()); } - + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + XSLFSlide(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } + + private static CTSlide prototype(){ CTSlide ctSlide = CTSlide.Factory.newInstance(); CTCommonSlideData cSld = ctSlide.addNewCSld(); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java index 1d49b068e8..01e7c5488d 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java @@ -44,14 +44,24 @@ implements MasterSheet { _layout = CTSlideLayout.Factory.newInstance(); } - public XSLFSlideLayout(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + /** + * @since POI 3.14-Beta1 + */ + public XSLFSlideLayout(PackagePart part) throws IOException, XmlException { + super(part); SldLayoutDocument doc = SldLayoutDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); _layout = doc.getSldLayout(); setCommonSlideData(_layout.getCSld()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XSLFSlideLayout(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } public String getName() { return _layout.getCSld().getName(); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java index 34d282cd07..ae6c40936c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java @@ -69,14 +69,25 @@ import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; _slide = CTSlideMaster.Factory.newInstance(); } - protected XSLFSlideMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + /** + * @since POI 3.14-Beta1 + */ + protected XSLFSlideMaster(PackagePart part) throws IOException, XmlException { + super(part); SldMasterDocument doc = SldMasterDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); _slide = doc.getSldMaster(); setCommonSlideData(_slide.getCSld()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSLFSlideMaster(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } + @Override public CTSlideMaster getXmlObject() { return _slide; diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java index fce35efb59..76455d64df 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableStyles.java @@ -41,8 +41,11 @@ public class XSLFTableStyles extends POIXMLDocumentPart implements Iterableapplication/vnd.openxmlformats-officedocument.drawingml.chart+xml * @param rel the package relationship holding this chart, * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart + * + * @since POI 3.14-Beta1 */ - protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + protected XSSFChart(PackagePart part) throws IOException, XmlException { + super(part); chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace(); chart = chartSpace.getChart(); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } + + /** * Construct a new CTChartSpace bean. * By default, it's just an empty placeholder for chart objects. diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java index 65a9adbe18..03194ae02d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChartSheet.java @@ -51,10 +51,21 @@ public class XSSFChartSheet extends XSSFSheet { protected CTChartsheet chartsheet; - protected XSSFChartSheet(PackagePart part, PackageRelationship rel) { - super(part, rel); + /** + * @since POI 3.14-Beta1 + */ + protected XSSFChartSheet(PackagePart part) { + super(part); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFChartSheet(PackagePart part, PackageRelationship rel) { + this(part); + } + protected void read(InputStream is) throws IOException { //initialize the supeclass with a blank worksheet super.read(new ByteArrayInputStream(BLANK_WORKSHEET)); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java index 777c3befc1..3885770619 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDialogsheet.java @@ -17,6 +17,7 @@ package org.apache.poi.xssf.usermodel; +import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.ss.usermodel.Sheet; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; @@ -33,8 +34,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; public class XSSFDialogsheet extends XSSFSheet implements Sheet{ protected CTDialogsheet dialogsheet; - protected XSSFDialogsheet(XSSFSheet sheet) { - super(sheet.getPackagePart(), sheet.getPackageRelationship()); + protected XSSFDialogsheet(XSSFSheet sheet, PackageRelationship rel) { + super(sheet.getPackagePart(), rel); this.dialogsheet = CTDialogsheet.Factory.newInstance(); this.worksheet = CTWorksheet.Factory.newInstance(); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java index 64dfc5dd00..cf5455322f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java @@ -28,9 +28,7 @@ import javax.xml.namespace.QName; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.util.CellAddress; @@ -84,15 +82,25 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { * the content type must be application/vnd.openxmlformats-officedocument.drawing+xml * @param rel the package relationship holding this drawing, * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing + * + * @since POI 3.14-Beta1 */ - public XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + public XSSFDrawing(PackagePart part) throws IOException, XmlException { + super(part); XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS); //Removing root element options.setLoadReplaceDocumentElement(null); drawing = CTDrawing.Factory.parse(part.getInputStream(),options); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } + /** * Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects * @@ -199,9 +207,10 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { int chartNumber = getPackagePart().getPackage(). getPartsByContentType(XSSFRelation.CHART.getContentType()).size() + 1; - XSSFChart chart = (XSSFChart) createRelationship( - XSSFRelation.CHART, XSSFFactory.getInstance(), chartNumber); - String chartRelId = chart.getPackageRelationship().getId(); + RelationPart rp = createRelationship( + XSSFRelation.CHART, XSSFFactory.getInstance(), chartNumber, false); + XSSFChart chart = rp.getDocumentPart(); + String chartRelId = rp.getRelationship().getId(); XSSFGraphicFrame frame = createGraphicFrame(anchor); frame.setChart(chart, chartRelId); @@ -220,13 +229,13 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { * @param pictureIndex the index of the picture in the workbook collection of pictures, * {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} . */ + @SuppressWarnings("resource") protected PackageRelationship addPictureReference(int pictureIndex){ XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent(); XSSFPictureData data = wb.getAllPictures().get(pictureIndex); - PackagePartName ppName = data.getPackagePart().getPartName(); - PackageRelationship rel = getPackagePart().addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation()); - addRelation(rel.getId(),new XSSFPictureData(data.getPackagePart(), rel)); - return rel; + XSSFPictureData pic = new XSSFPictureData(data.getPackagePart(), null); + RelationPart rp = addRelation(null, XSSFRelation.IMAGES, pic); + return rp.getRelationship(); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java index 7855e42458..763b094f9a 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java @@ -18,26 +18,17 @@ package org.apache.poi.xssf.usermodel; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLFactory; import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; /** * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type - * - * @author Yegor Kozlov */ public final class XSSFFactory extends POIXMLFactory { - private static final POILogger logger = POILogFactory.getLogger(XSSFFactory.class); - - private XSSFFactory(){ - + private XSSFFactory() { } private static final XSSFFactory inst = new XSSFFactory(); @@ -46,32 +37,22 @@ public final class XSSFFactory extends POIXMLFactory { return inst; } + /** + * @since POI 3.14-Beta1 + */ @Override - public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part){ - POIXMLRelation descriptor = XSSFRelation.getInstance(rel.getRelationshipType()); - if(descriptor == null || descriptor.getRelationClass() == null){ - logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType()); - return new POIXMLDocumentPart(part, rel); - } - - try { - Class cls = descriptor.getRelationClass(); - Constructor constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class); - return constructor.newInstance(part, rel); - } catch (Exception e){ - throw new POIXMLException(e); - } + protected POIXMLRelation getDescriptor(String relationshipType) { + return XSSFRelation.getInstance(relationshipType); } + /** + * @since POI 3.14-Beta1 + */ @Override - public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){ - try { - Class cls = descriptor.getRelationClass(); - Constructor constructor = cls.getDeclaredConstructor(); - return constructor.newInstance(); - } catch (Exception e){ - throw new POIXMLException(e); - } + protected POIXMLDocumentPart createDocumentPart + (Class cls, Class[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor constructor = cls.getDeclaredConstructor(classes); + return constructor.newInstance(values); } - } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFMap.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFMap.java index b1f70dbca2..d4d148c87e 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFMap.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFMap.java @@ -21,6 +21,8 @@ import java.util.ArrayList; import java.util.List; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLDocumentPart.RelationPart; +import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.util.Internal; import org.apache.poi.xssf.model.MapInfo; import org.apache.poi.xssf.model.SingleXmlCells; @@ -97,15 +99,11 @@ public class XSSFMap { * @return the list of all Tables that provide a map rule to this mapping */ public List getRelatedTables() { - List tables = new ArrayList(); - int sheetNumber = mapInfo.getWorkbook().getNumberOfSheets(); - - for (int i = 0; i < sheetNumber; i++) { - XSSFSheet sheet = mapInfo.getWorkbook().getSheetAt(i); - for (POIXMLDocumentPart p : sheet.getRelations()) { - if (p.getPackageRelationship().getRelationshipType().equals(XSSFRelation.TABLE.getRelation())) { - XSSFTable table = (XSSFTable) p; + for (Sheet sheet : mapInfo.getWorkbook()) { + for (RelationPart rp : ((XSSFSheet)sheet).getRelationParts()) { + if (rp.getRelationship().getRelationshipType().equals(XSSFRelation.TABLE.getRelation())) { + XSSFTable table = rp.getDocumentPart(); if (table.mapsTo(ctMap.getID())) { tables.add(table); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java index 43599feb75..5c31d03224 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPictureData.java @@ -68,11 +68,21 @@ public class XSSFPictureData extends POIXMLDocumentPart implements PictureData { * @param part the package part holding the drawing data, * @param rel the package relationship holding this drawing, * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image + * + * @since POI 3.14-Beta1 */ - protected XSSFPictureData(PackagePart part, PackageRelationship rel) { - super(part, rel); + protected XSSFPictureData(PackagePart part) { + super(part); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFPictureData(PackagePart part, PackageRelationship rel) { + this(part); + } + /** * Gets the picture data as a byte array. *

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java index c6fb592056..5ba16075b2 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCache.java @@ -51,13 +51,23 @@ public class XSSFPivotCache extends POIXMLDocumentPart { * * @param part - The package part that holds xml data representing this pivot cache definition. * @param rel - the relationship of the given package part in the underlying OPC package + * + * @since POI 3.14-Beta1 */ @Beta - protected XSSFPivotCache(PackagePart part, PackageRelationship rel) throws IOException { - super(part, rel); + protected XSSFPivotCache(PackagePart part) throws IOException { + super(part); readFrom(part.getInputStream()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFPivotCache(PackagePart part, PackageRelationship rel) throws IOException { + this(part); + } + @Beta protected void readFrom(InputStream is) throws IOException { try { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java index f5c4fcad00..fd4c728c26 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheDefinition.java @@ -58,13 +58,23 @@ public class XSSFPivotCacheDefinition extends POIXMLDocumentPart{ * * @param part - The package part that holds xml data representing this pivot cache definition. * @param rel - the relationship of the given package part in the underlying OPC package + * + * @since POI 3.14-Beta1 */ @Beta - protected XSSFPivotCacheDefinition(PackagePart part, PackageRelationship rel) throws IOException { - super(part, rel); + protected XSSFPivotCacheDefinition(PackagePart part) throws IOException { + super(part); readFrom(part.getInputStream()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFPivotCacheDefinition(PackagePart part, PackageRelationship rel) throws IOException { + this(part); + } + @Beta public void readFrom(InputStream is) throws IOException { try { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java index a8fca93c5d..3464374972 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotCacheRecords.java @@ -48,13 +48,23 @@ public class XSSFPivotCacheRecords extends POIXMLDocumentPart { * * @param part - The package part that holds xml data representing this pivot cache records. * @param rel - the relationship of the given package part in the underlying OPC package + * + * @since POI 3.14-Beta1 */ @Beta - protected XSSFPivotCacheRecords(PackagePart part, PackageRelationship rel) throws IOException { - super(part, rel); + protected XSSFPivotCacheRecords(PackagePart part) throws IOException { + super(part); readFrom(part.getInputStream()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFPivotCacheRecords(PackagePart part, PackageRelationship rel) throws IOException { + this(part); + } + @Beta protected void readFrom(InputStream is) throws IOException { try { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java index bda2ccf695..5b61b01611 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPivotTable.java @@ -88,13 +88,23 @@ public class XSSFPivotTable extends POIXMLDocumentPart { * * @param part - The package part that holds xml data representing this pivot table. * @param rel - the relationship of the given package part in the underlying OPC package + * + * @since POI 3.14-Beta1 */ @Beta - protected XSSFPivotTable(PackagePart part, PackageRelationship rel) throws IOException { - super(part, rel); + protected XSSFPivotTable(PackagePart part) throws IOException { + super(part); readFrom(part.getInputStream()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFPivotTable(PackagePart part, PackageRelationship rel) throws IOException { + this(part); + } + @Beta public void readFrom(InputStream is) throws IOException { try { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java index fbe170f3fa..5a5a0a1bd9 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java @@ -347,8 +347,7 @@ public final class XSSFRelation extends POIXMLRelation { private XSSFRelation(String type, String rel, String defaultName, Class cls) { super(type, rel, defaultName, cls); - - if(cls != null && !_table.containsKey(rel)) _table.put(rel, this); + _table.put(rel, this); } /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 940be262d0..7c76f15f7a 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -162,16 +162,26 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { /** * Creates an XSSFSheet representing the given package part and relationship. - * Should only be called by XSSFWorkbook when reading in an exisiting file. + * Should only be called by XSSFWorkbook when reading in an existing file. * - * @param part - The package part that holds xml data represenring this sheet. + * @param part - The package part that holds xml data representing this sheet. * @param rel - the relationship of the given package part in the underlying OPC package + * + * @since POI 3.14-Beta1 */ - protected XSSFSheet(PackagePart part, PackageRelationship rel) { - super(part, rel); + protected XSSFSheet(PackagePart part) { + super(part); dataValidationHelper = new XSSFDataValidationHelper(this); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFSheet(PackagePart part, PackageRelationship rel) { + this(part); + } + /** * Returns the parent XSSFWorkbook * @@ -204,12 +214,13 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { initRows(worksheet); columnHelper = new ColumnHelper(worksheet); // Look for bits we're interested in - for(POIXMLDocumentPart p : getRelations()){ + for(RelationPart rp : getRelationParts()){ + POIXMLDocumentPart p = rp.getDocumentPart(); if(p instanceof CommentsTable) { sheetComments = (CommentsTable)p; } if(p instanceof XSSFTable) { - tables.put( p.getPackageRelationship().getId(), (XSSFTable)p ); + tables.put( rp.getRelationship().getId(), (XSSFTable)p ); } if(p instanceof XSSFPivotTable) { getWorkbook().getPivotTables().add((XSSFPivotTable) p); @@ -449,10 +460,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { CTDrawing ctDrawing = getCTDrawing(); if (ctDrawing != null) { // Search the referenced drawing in the list of the sheet's relations - for (POIXMLDocumentPart p : getRelations()){ + for (RelationPart rp : getRelationParts()){ + POIXMLDocumentPart p = rp.getDocumentPart(); if (p instanceof XSSFDrawing) { XSSFDrawing dr = (XSSFDrawing)p; - String drId = dr.getPackageRelationship().getId(); + String drId = rp.getRelationship().getId(); if (drId.equals(ctDrawing.getId())){ return dr; } @@ -478,8 +490,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { //drawingNumber = #drawings.size() + 1 int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size() + 1; - XSSFDrawing drawing = (XSSFDrawing)createRelationship(XSSFRelation.DRAWINGS, XSSFFactory.getInstance(), drawingNumber); - String relId = drawing.getPackageRelationship().getId(); + RelationPart rp = createRelationship(XSSFRelation.DRAWINGS, XSSFFactory.getInstance(), drawingNumber, false); + XSSFDrawing drawing = rp.getDocumentPart(); + String relId = rp.getRelationship().getId(); //add CT_Drawing element which indicates that this sheet contains drawing components built on the drawingML platform. //The relationship Id references the part containing the drawingML definitions. @@ -504,8 +517,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { if(autoCreate) { //drawingNumber = #drawings.size() + 1 int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.VML_DRAWINGS.getContentType()).size() + 1; - drawing = (XSSFVMLDrawing)createRelationship(XSSFRelation.VML_DRAWINGS, XSSFFactory.getInstance(), drawingNumber); - String relId = drawing.getPackageRelationship().getId(); + RelationPart rp = createRelationship(XSSFRelation.VML_DRAWINGS, XSSFFactory.getInstance(), drawingNumber, false); + drawing = rp.getDocumentPart(); + String relId = rp.getRelationship().getId(); //add CTLegacyDrawing element which indicates that this sheet contains drawing components built on the drawingML platform. //The relationship Id references the part containing the drawing definitions. @@ -514,10 +528,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } } else { //search the referenced drawing in the list of the sheet's relations - for(POIXMLDocumentPart p : getRelations()){ + for (RelationPart rp : getRelationParts()){ + POIXMLDocumentPart p = rp.getDocumentPart(); if(p instanceof XSSFVMLDrawing) { XSSFVMLDrawing dr = (XSSFVMLDrawing)p; - String drId = dr.getPackageRelationship().getId(); + String drId = rp.getRelationship().getId(); if(drId.equals(ctDrawing.getId())){ drawing = dr; break; @@ -3695,6 +3710,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { } + @SuppressWarnings("resource") @Override public XSSFAutoFilter setAutoFilter(CellRangeAddress range) { CTAutoFilter af = worksheet.getAutoFilter(); @@ -3735,8 +3751,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { // Table numbers need to be unique in the file, not just // unique within the sheet. Find the next one int tableNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.TABLE.getContentType()).size() + 1; - XSSFTable table = (XSSFTable)createRelationship(XSSFRelation.TABLE, XSSFFactory.getInstance(), tableNumber); - tbl.setId(table.getPackageRelationship().getId()); + RelationPart rp = createRelationship(XSSFRelation.TABLE, XSSFFactory.getInstance(), tableNumber, false); + XSSFTable table = rp.getDocumentPart(); + tbl.setId(rp.getRelationship().getId()); tables.put(tbl.getId(), table); @@ -3933,6 +3950,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { * including: pivotCacheDefinition, pivotCacheRecords * @return returns a pivotTable */ + @SuppressWarnings("resource") @Beta private XSSFPivotTable createPivotTable() { XSSFWorkbook wb = getWorkbook(); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java index e71a336456..c8a932bb98 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java @@ -62,12 +62,22 @@ public class XSSFTable extends POIXMLDocumentPart { ctTable = CTTable.Factory.newInstance(); } - public XSSFTable(PackagePart part, PackageRelationship rel) - throws IOException { - super(part, rel); + /** + * @since POI 3.14-Beta1 + */ + public XSSFTable(PackagePart part) throws IOException { + super(part); readFrom(part.getInputStream()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XSSFTable(PackagePart part, PackageRelationship rel) throws IOException { + this(part); + } + public void readFrom(InputStream is) throws IOException { try { TableDocument doc = TableDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java index 263dae0ddb..f074d0c190 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVBAPart.java @@ -35,11 +35,21 @@ public class XSSFVBAPart extends POIXMLDocumentPart { * * @param part the package part holding the VBA data, * @param rel the package relationship holding this part + * + * @since POI 3.14-Beta1 */ - protected XSSFVBAPart(PackagePart part, PackageRelationship rel) { - super(part, rel); + protected XSSFVBAPart(PackagePart part) { + super(part); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFVBAPart(PackagePart part, PackageRelationship rel) { + this(part); + } + /** * Like *PictureData, VBA objects store the actual content in the part * directly without keeping a copy like all others therefore we need to diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java index 96dfede0d2..6f8fccdc72 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFVMLDrawing.java @@ -110,12 +110,21 @@ public final class XSSFVMLDrawing extends POIXMLDocumentPart { * the content type must be application/vnd.openxmlformats-officedocument.drawing+xml * @param rel the package relationship holding this drawing, * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing + * + * @since POI 3.14-Beta1 */ - protected XSSFVMLDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { - super(part, rel); + protected XSSFVMLDrawing(PackagePart part) throws IOException, XmlException { + super(part); read(getPackagePart().getInputStream()); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + protected XSSFVMLDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { + this(part); + } protected void read(InputStream is) throws IOException, XmlException { XmlObject root = XmlObject.Factory.parse( 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 ae4fb23ed4..4f55feeb4f 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -338,17 +338,18 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { ThemesTable theme = null; Map shIdMap = new HashMap(); Map elIdMap = new HashMap(); - for(POIXMLDocumentPart p : getRelations()){ + for(RelationPart rp : getRelationParts()){ + POIXMLDocumentPart p = rp.getDocumentPart(); if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p; else if(p instanceof StylesTable) stylesSource = (StylesTable)p; else if(p instanceof ThemesTable) theme = (ThemesTable)p; else if(p instanceof CalculationChain) calcChain = (CalculationChain)p; else if(p instanceof MapInfo) mapInfo = (MapInfo)p; else if (p instanceof XSSFSheet) { - shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p); + shIdMap.put(rp.getRelationship().getId(), (XSSFSheet)p); } else if (p instanceof ExternalLinksTable) { - elIdMap.put(p.getPackageRelationship().getId(), (ExternalLinksTable)p); + elIdMap.put(rp.getRelationship().getId(), (ExternalLinksTable)p); } } boolean packageReadOnly = (getPackage().getPackageAccess() == PackageAccess.READ); @@ -492,7 +493,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { @Override public int addPicture(byte[] pictureData, int format) { int imageNumber = getAllPictures().size() + 1; - XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true); + XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true).getDocumentPart(); try { OutputStream out = img.getPackagePart().getOutputStream(); out.write(pictureData); @@ -521,7 +522,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { */ public int addPicture(InputStream is, int format) throws IOException { int imageNumber = getAllPictures().size() + 1; - XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true); + XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true).getDocumentPart(); OutputStream out = img.getPackagePart().getOutputStream(); IOUtils.copy(is, out); out.close(); @@ -546,6 +547,34 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { String clonedName = getUniqueSheetName(srcName); XSSFSheet clonedSheet = createSheet(clonedName); + + // copy sheet's relations + List rels = srcSheet.getRelationParts(); + // if the sheet being cloned has a drawing then rememebr it and re-create it too + XSSFDrawing dg = null; + for(RelationPart rp : rels) { + POIXMLDocumentPart r = rp.getDocumentPart(); + // do not copy the drawing relationship, it will be re-created + if(r instanceof XSSFDrawing) { + dg = (XSSFDrawing)r; + continue; + } + + addRelation(rp, clonedSheet); + } + + try { + for(PackageRelationship pr : srcSheet.getPackagePart().getRelationships()) { + if (pr.getTargetMode() == TargetMode.EXTERNAL) { + clonedSheet.getPackagePart().addExternalRelationship + (pr.getTargetURI().toASCIIString(), pr.getRelationshipType(), pr.getId()); + } + } + } catch (InvalidFormatException e) { + throw new POIXMLException("Failed to clone sheet", e); + } + + try { ByteArrayOutputStream out = new ByteArrayOutputStream(); srcSheet.write(out); @@ -565,23 +594,6 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { clonedSheet.setSelected(false); - // copy sheet's relations - List rels = srcSheet.getRelations(); - // if the sheet being cloned has a drawing then rememebr it and re-create tpoo - XSSFDrawing dg = null; - for(POIXMLDocumentPart r : rels) { - // do not copy the drawing relationship, it will be re-created - if(r instanceof XSSFDrawing) { - dg = (XSSFDrawing)r; - continue; - } - - PackageRelationship rel = r.getPackageRelationship(); - clonedSheet.getPackagePart().addRelationship( - rel.getTargetURI(), rel.getTargetMode(),rel.getRelationshipType()); - clonedSheet.addRelation(rel.getId(), r); - } - // clone the sheet drawing alongs with its relationships if (dg != null) { if(ct.isSetDrawing()) { @@ -596,20 +608,31 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { clonedDg = clonedSheet.createDrawingPatriarch(); // Clone drawing relations - List srcRels = srcSheet.createDrawingPatriarch().getRelations(); - for (POIXMLDocumentPart rel : srcRels) { - PackageRelationship relation = rel.getPackageRelationship(); - - clonedDg.addRelation(relation.getId(), rel); - - clonedDg - .getPackagePart() - .addRelationship(relation.getTargetURI(), relation.getTargetMode(), - relation.getRelationshipType(), relation.getId()); + List srcRels = srcSheet.createDrawingPatriarch().getRelationParts(); + for (RelationPart rp : srcRels) { + addRelation(rp, clonedDg); } } return clonedSheet; } + + /** + * @since 3.14-Beta1 + */ + private static void addRelation(RelationPart rp, POIXMLDocumentPart target) { + PackageRelationship rel = rp.getRelationship(); + if (rel.getTargetMode() == TargetMode.EXTERNAL) { + target.getPackagePart().addRelationship( + rel.getTargetURI(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId()); + } else { + XSSFRelation xssfRel = XSSFRelation.getInstance(rel.getRelationshipType()); + if (xssfRel == null) { + // Don't copy all relations blindly, but only the ones we know about + throw new POIXMLException("Can't clone sheet - unknown relation type found: "+rel.getRelationshipType()); + } + target.addRelation(rel.getId(), xssfRel, rp.getDocumentPart()); + } + } /** * Generate a valid sheet name based on the existing one. Used when cloning sheets. @@ -794,18 +817,21 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { break; } - XSSFSheet wrapper = (XSSFSheet)createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber); + RelationPart rp = createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber, false); + XSSFSheet wrapper = rp.getDocumentPart(); wrapper.sheet = sheet; - sheet.setId(wrapper.getPackageRelationship().getId()); + sheet.setId(rp.getRelationship().getId()); sheet.setSheetId(sheetNumber); - if(sheets.size() == 0) wrapper.setSelected(true); + if (sheets.isEmpty()) wrapper.setSelected(true); sheets.add(wrapper); return wrapper; } protected XSSFDialogsheet createDialogsheet(String sheetname, CTDialogsheet dialogsheet) { XSSFSheet sheet = createSheet(sheetname); - return new XSSFDialogsheet(sheet); + String sheetRelId = getRelationId(sheet); + PackageRelationship pr = getPackagePart().getRelationship(sheetRelId); + return new XSSFDialogsheet(sheet, pr); } private CTSheet addSheet(String sheetname) { diff --git a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java index d6f3e51599..e303fcf343 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java +++ b/src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java @@ -20,10 +20,9 @@ import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; import java.io.IOException; import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLDocumentPart.RelationPart; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.xwpf.usermodel.XWPFDocument; @@ -221,11 +220,9 @@ public class XWPFHeaderFooterPolicy { } private int getRelationIndex(XWPFRelation relation) { - List relations = doc.getRelations(); int i = 1; - for (Iterator it = relations.iterator(); it.hasNext(); ) { - POIXMLDocumentPart item = it.next(); - if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) { + for (RelationPart rp : doc.getRelationParts()) { + if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) { i++; } } @@ -287,17 +284,16 @@ public class XWPFHeaderFooterPolicy { private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) { CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewFooterReference(); ref.setType(type); - ref.setId(wrapper.getPackageRelationship().getId()); + ref.setId(doc.getRelationId(wrapper)); } private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) { CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewHeaderReference(); ref.setType(type); - ref.setId(wrapper.getPackageRelationship().getId()); + ref.setId(doc.getRelationId(wrapper)); } - - + public XWPFHeader getFirstPageHeader() { return firstPageHeader; } diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java index 3fecf9de48..a7cf4dca08 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java @@ -193,8 +193,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { headerFooterPolicy = new XWPFHeaderFooterPolicy(this); // Create for each XML-part in the Package a PartClass - for (POIXMLDocumentPart p : getRelations()) { - String relation = p.getPackageRelationship().getRelationshipType(); + for (RelationPart rp : getRelationParts()) { + POIXMLDocumentPart p = rp.getDocumentPart(); + String relation = rp.getRelationship().getRelationshipType(); if (relation.equals(XWPFRelation.STYLES.getRelation())) { this.styles = (XWPFStyles) p; this.styles.onDocumentRead(); @@ -257,8 +258,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } private void initFootnotes() throws XmlException, IOException { - for (POIXMLDocumentPart p : getRelations()) { - String relation = p.getPackageRelationship().getRelationshipType(); + for (RelationPart rp : getRelationParts()) { + POIXMLDocumentPart p = rp.getDocumentPart(); + String relation = rp.getRelationship().getRelationshipType(); if (relation.equals(XWPFRelation.FOOTNOTE.getRelation())) { this.footnotes = (XWPFFootnotes) p; this.footnotes.onDocumentRead(); @@ -723,11 +725,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { * @return i */ private int getRelationIndex(XWPFRelation relation) { - List relations = getRelations(); int i = 1; - for (Iterator it = relations.iterator(); it.hasNext(); ) { - POIXMLDocumentPart item = it.next(); - if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) { + for (RelationPart rp : getRelationParts()) { + if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) { i++; } } @@ -1313,16 +1313,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { * relationship to the already existing part and update * POIXMLDocumentPart data. */ - PackagePart picDataPart = xwpfPicData.getPackagePart(); // TODO add support for TargetMode.EXTERNAL relations. - TargetMode targetMode = TargetMode.INTERNAL; - PackagePartName partName = picDataPart.getPartName(); - String relation = relDesc.getRelation(); - PackageRelationship relShip = getPackagePart().addRelationship(partName, targetMode, relation); - String id = relShip.getId(); - addRelation(id, xwpfPicData); - pictures.add(xwpfPicData); - return id; + RelationPart rp = addRelation(null, XWPFRelation.IMAGES, xwpfPicData); + return rp.getRelationship().getId(); } else { /* Part already existed, get relation id and return it */ return getRelationId(xwpfPicData); diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java index 4fb02ce9b8..bc5bbe4c06 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFactory.java @@ -18,63 +18,42 @@ package org.apache.poi.xwpf.usermodel; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import org.apache.poi.POIXMLDocumentPart; -import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLFactory; import org.apache.poi.POIXMLRelation; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; -/** - * @author Yegor Kozlov - */ -public final class XWPFFactory extends POIXMLFactory { - - private static final POILogger logger = POILogFactory.getLogger(XWPFFactory.class); - private static final XWPFFactory inst = new XWPFFactory(); - - private XWPFFactory() { - - } - - public static XWPFFactory getInstance() { - return inst; - } - - @Override - public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part) { - POIXMLRelation descriptor = XWPFRelation.getInstance(rel.getRelationshipType()); - if (descriptor == null || descriptor.getRelationClass() == null) { - logger.log(POILogger.DEBUG, "using default POIXMLDocumentPart for " + rel.getRelationshipType()); - return new POIXMLDocumentPart(part, rel); - } - - try { - Class cls = descriptor.getRelationClass(); - try { - Constructor constructor = cls.getDeclaredConstructor(POIXMLDocumentPart.class, PackagePart.class, PackageRelationship.class); - return constructor.newInstance(parent, part, rel); - } catch (NoSuchMethodException e) { - Constructor constructor = cls.getDeclaredConstructor(PackagePart.class, PackageRelationship.class); - return constructor.newInstance(part, rel); - } - } catch (Exception e) { - throw new POIXMLException(e); - } - } - - @Override - public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor) { - try { - Class cls = descriptor.getRelationClass(); - Constructor constructor = cls.getDeclaredConstructor(); - return constructor.newInstance(); - } catch (Exception e) { - throw new POIXMLException(e); - } - } - -} +/** + * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type + */ +public final class XWPFFactory extends POIXMLFactory { + private XWPFFactory() { + + } + + private static final XWPFFactory inst = new XWPFFactory(); + + public static XWPFFactory getInstance() { + return inst; + } + + /** + * @since POI 3.14-Beta1 + */ + @Override + protected POIXMLRelation getDescriptor(String relationshipType) { + return XWPFRelation.getInstance(relationshipType); + } + + /** + * @since POI 3.14-Beta1 + */ + @Override + protected POIXMLDocumentPart createDocumentPart + (Class cls, Class[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor constructor = cls.getDeclaredConstructor(classes); + return constructor.newInstance(values); + } +} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java index 8268ff6505..dfe7462ce1 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java @@ -67,8 +67,19 @@ public class XWPFFooter extends XWPFHeaderFooter { cursor.dispose(); } + /** + * @since POI 3.14-Beta1 + */ + public XWPFFooter(POIXMLDocumentPart parent, PackagePart part) throws IOException { + super(parent, part); + } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated public XWPFFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { - super(parent, part, rel); + this(parent, part); } /** @@ -88,7 +99,7 @@ public class XWPFFooter extends XWPFHeaderFooter { protected void onDocumentRead() throws IOException { super.onDocumentRead(); FtrDocument ftrDocument = null; - InputStream is; + InputStream is = null; try { is = getPackagePart().getInputStream(); ftrDocument = FtrDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); @@ -117,6 +128,10 @@ public class XWPFFooter extends XWPFHeaderFooter { cursor.dispose(); } catch (Exception e) { throw new POIXMLException(e); + } finally { + if (is != null) { + is.close(); + } } } diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java index 1ecdc3d701..6408bf63be 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java @@ -48,14 +48,24 @@ public class XWPFFootnotes extends POIXMLDocumentPart { /** * Construct XWPFFootnotes from a package part - * - * @param part the package part holding the data of the footnotes, - * @param rel the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" - */ - public XWPFFootnotes(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { - super(part, rel); - } - + * + * @param part the package part holding the data of the footnotes, + * @param rel the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" + * + * @since POI 3.14-Beta1 + */ + public XWPFFootnotes(PackagePart part) throws IOException, OpenXML4JException { + super(part); + } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XWPFFootnotes(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { + this(part); + } + /** * Construct XWPFFootnotes from scratch for a new document. */ @@ -67,13 +77,18 @@ public class XWPFFootnotes extends POIXMLDocumentPart { */ @Override protected void onDocumentRead() throws IOException { - FootnotesDocument notesDoc; + FootnotesDocument notesDoc; + InputStream is = null; try { - InputStream is = getPackagePart().getInputStream(); + is = getPackagePart().getInputStream(); notesDoc = FootnotesDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); ctFootnotes = notesDoc.getFootnotes(); } catch (XmlException e) { throw new POIXMLException(); + } finally { + if (is != null) { + is.close(); + } } // Find our footnotes diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java index 0215727897..0af8df4bd0 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java @@ -47,8 +47,19 @@ public class XWPFHeader extends XWPFHeaderFooter { super(); } + /** + * @since POI 3.14-Beta1 + */ + public XWPFHeader(POIXMLDocumentPart parent, PackagePart part) throws IOException { + super(parent, part); + } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated public XWPFHeader(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { - super(parent, part, rel); + this(parent, part); } public XWPFHeader(XWPFDocument doc, CTHdrFtr hdrFtr) { @@ -91,7 +102,7 @@ public class XWPFHeader extends XWPFHeaderFooter { protected void onDocumentRead() throws IOException { super.onDocumentRead(); HdrDocument hdrDocument = null; - InputStream is; + InputStream is = null; try { is = getPackagePart().getInputStream(); hdrDocument = HdrDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); @@ -120,6 +131,10 @@ public class XWPFHeader extends XWPFHeaderFooter { cursor.dispose(); } catch (XmlException e) { throw new POIXMLException(e); + } finally { + if (is != null) { + is.close(); + } } } diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java index f5460dbd9c..068a35c02d 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java @@ -28,9 +28,7 @@ import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLRelation; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.util.IOUtils; import org.apache.poi.util.Internal; import org.apache.xmlbeans.XmlCursor; @@ -68,14 +66,25 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo readHdrFtr(); } - public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { - super(parent, part, rel); + /** + * @since by POI 3.14-Beta1 + */ + public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part) throws IOException { + super(parent, part); this.document = (XWPFDocument) getParent(); if (this.document == null) { throw new NullPointerException(); } } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException { + this(parent, part); + } @Override protected void onDocumentRead() throws IOException { @@ -271,16 +280,10 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo * relationship to the already existing part and update * POIXMLDocumentPart data. */ - PackagePart picDataPart = xwpfPicData.getPackagePart(); // TODO add support for TargetMode.EXTERNAL relations. - TargetMode targetMode = TargetMode.INTERNAL; - PackagePartName partName = picDataPart.getPartName(); - String relation = relDesc.getRelation(); - PackageRelationship relShip = getPackagePart().addRelationship(partName, targetMode, relation); - String id = relShip.getId(); - addRelation(id, xwpfPicData); + RelationPart rp = addRelation(null, XWPFRelation.IMAGES, xwpfPicData); pictures.add(xwpfPicData); - return id; + return rp.getRelationship().getId(); } else { /* Part already existed, get relation id and return it */ return getRelationId(xwpfPicData); diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java index 7b27e3aeb4..10b42f8f65 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java @@ -47,19 +47,29 @@ public class XWPFNumbering extends POIXMLDocumentPart { protected List nums = new ArrayList(); boolean isNew; private CTNumbering ctNumbering; - - /** - * create a new styles object with an existing document - */ - public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { - super(part, rel); - isNew = true; - } - - /** - * create a new XWPFNumbering object for use in a new document - */ - public XWPFNumbering() { + + /** + * create a new styles object with an existing document + * + * @since POI 3.14-Beta1 + */ + public XWPFNumbering(PackagePart part) throws IOException, OpenXML4JException { + super(part); + isNew = true; + } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { + this(part); + } + + /** + * create a new XWPFNumbering object for use in a new document + */ + public XWPFNumbering() { abstractNums = new ArrayList(); nums = new ArrayList(); isNew = true; @@ -83,12 +93,14 @@ public class XWPFNumbering extends POIXMLDocumentPart { for (CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()) { abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this)); } - isNew = false; - } catch (XmlException e) { - throw new POIXMLException(); - } - } - + isNew = false; + } catch (XmlException e) { + throw new POIXMLException(); + } finally { + is.close(); + } + } + /** * save and commit numbering */ diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java index 549ae813de..3c19b42a02 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java @@ -70,15 +70,23 @@ public class XWPFPictureData extends POIXMLDocumentPart { /** * Construct XWPFPictureData from a package part - * - * @param part the package part holding the drawing data, - * @param rel the package relationship holding this drawing, - * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image - */ - public XWPFPictureData(PackagePart part, PackageRelationship rel) { - super(part, rel); + * + * @param part the package part holding the drawing data, + * + * @since POI 3.14-Beta1 + */ + public XWPFPictureData(PackagePart part) { + super(part); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XWPFPictureData(PackagePart part, PackageRelationship rel) { + this(part); + } + @Override protected void onDocumentRead() throws IOException { super.onDocumentRead(); diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java index fae051e74f..59b97c3a45 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java @@ -208,13 +208,12 @@ public final class XWPFRelation extends POIXMLRelation { null, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", null, - null + XWPFPictureData.class ); private XWPFRelation(String type, String rel, String defaultName, Class cls) { super(type, rel, defaultName, cls); - - if (cls != null && !_table.containsKey(rel)) _table.put(rel, this); + _table.put(rel, this); } /** diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java index d0ee35a74c..ffa00cc0da 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java @@ -994,13 +994,13 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun { CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr(); cNvPicPr.addNewPicLocks().setNoChangeAspect(true); - - CTBlipFillProperties blipFill = pic.addNewBlipFill(); - CTBlip blip = blipFill.addNewBlip(); - blip.setEmbed(picData.getPackageRelationship().getId()); - blipFill.addNewStretch().addNewFillRect(); - - CTShapeProperties spPr = pic.addNewSpPr(); + + CTBlipFillProperties blipFill = pic.addNewBlipFill(); + CTBlip blip = blipFill.addNewBlip(); + blip.setEmbed(parent.getDocument().getRelationId(picData)); + blipFill.addNewStretch().addNewFillRect(); + + CTShapeProperties spPr = pic.addNewSpPr(); CTTransform2D xfrm = spPr.addNewXfrm(); CTPoint2D off = xfrm.addNewOff(); diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java index 66408c448f..fa4e6401f9 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java @@ -49,10 +49,21 @@ public class XWPFSettings extends POIXMLDocumentPart { private CTSettings ctSettings; - public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException { - super(part, rel); + /** + * @since POI 3.14-Beta1 + */ + public XWPFSettings(PackagePart part) throws IOException { + super(part); } + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException { + this(part); + } + public XWPFSettings() { super(); ctSettings = CTSettings.Factory.newInstance(); diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java index afe0c0f45d..55e1ca4755 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java @@ -61,13 +61,22 @@ public class XWPFStyles extends POIXMLDocumentPart { /** * Construct XWPFStyles from a package part * - * @param part the package part holding the data of the styles, - * @param rel the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" - */ - public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { - super(part, rel); - } - + * @param part the package part holding the data of the styles, + * + * @since POI 3.14-Beta1 + */ + public XWPFStyles(PackagePart part) throws IOException, OpenXML4JException { + super(part); + } + + /** + * @deprecated in POI 3.14, scheduled for removal in POI 3.16 + */ + @Deprecated + public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException { + this(part); + } + /** * Construct XWPFStyles from scratch for a new document. */ @@ -77,16 +86,18 @@ public class XWPFStyles extends POIXMLDocumentPart { /** * Read document */ - @Override - protected void onDocumentRead() throws IOException { - StylesDocument stylesDoc; - try { - InputStream is = getPackagePart().getInputStream(); + @Override + protected void onDocumentRead() throws IOException { + StylesDocument stylesDoc; + InputStream is = getPackagePart().getInputStream(); + try { stylesDoc = StylesDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); setStyles(stylesDoc.getStyles()); latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this); } catch (XmlException e) { throw new POIXMLException("Unable to read styles", e); + } finally { + is.close(); } } diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java index e037b35930..19bb7b9db8 100644 --- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java +++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertSame; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -34,7 +35,6 @@ import java.util.List; 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; @@ -71,14 +71,18 @@ public final class TestPOIXMLDocument { // } - @Override - public POIXMLDocumentPart createDocumentPart(POIXMLDocumentPart parent, PackageRelationship rel, PackagePart part){ - return new POIXMLDocumentPart(part, rel); + protected POIXMLRelation getDescriptor(String relationshipType) { + return null; } + /** + * @since POI 3.14-Beta1 + */ @Override - public POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor){ - throw new RuntimeException("not supported"); + protected POIXMLDocumentPart createDocumentPart + (Class cls, Class[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + return null; } } diff --git a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java index a0230b4375..ca46f295e5 100644 --- a/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java @@ -25,25 +25,20 @@ import static org.junit.Assert.fail; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; -import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.net.URI; import java.util.Collection; -import java.util.List; import javax.imageio.ImageIO; -import org.apache.poi.POIDataSamples; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLDocumentPart.RelationPart; import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.util.IOUtils; import org.apache.poi.xslf.usermodel.DrawingParagraph; import org.apache.poi.xslf.usermodel.DrawingTextBody; import org.apache.poi.xslf.usermodel.XMLSlideShow; @@ -109,7 +104,7 @@ public class TestXSLFBugs { XSLFSlide slide = ss.getSlides().get(0); // Check the relations from this - List rels = slide.getRelations(); + Collection rels = slide.getRelationParts(); // Should have 6 relations: // 1 external hyperlink (skipped from list) @@ -118,10 +113,10 @@ public class TestXSLFBugs { assertEquals(5, rels.size()); int layouts = 0; int hyperlinks = 0; - for(POIXMLDocumentPart p : rels) { - if(p.getPackageRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) { + for(RelationPart p : rels) { + if(p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) { hyperlinks++; - } else if(p instanceof XSLFSlideLayout) { + } else if(p.getDocumentPart() instanceof XSLFSlideLayout) { layouts++; } } @@ -129,9 +124,9 @@ public class TestXSLFBugs { assertEquals(4, hyperlinks); // Hyperlinks should all be to #_ftn1 or #ftnref1 - for(POIXMLDocumentPart p : rels) { - if(p.getPackageRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) { - URI target = p.getPackageRelationship().getTargetURI(); + for(RelationPart p : rels) { + if(p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) { + URI target = p.getRelationship().getTargetURI(); if(target.getFragment().equals("_ftn1") || target.getFragment().equals("_ftnref1")) { @@ -150,7 +145,6 @@ public class TestXSLFBugs { * rID2 -> slide3.xml */ @Test - @Ignore public void bug54916() throws Exception { XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("OverlappingRelations.pptx"); XSLFSlide slide; 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 92235c4399..17e1fa133e 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -44,6 +44,7 @@ import java.util.TreeMap; import org.apache.poi.EncryptedDocumentException; import org.apache.poi.POIDataSamples; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLDocumentPart.RelationPart; import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLProperties; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -55,6 +56,7 @@ 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.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.openxml4j.util.ZipSecureFile; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; @@ -221,9 +223,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals(1, wb1.getNumberOfSheets()); XSSFSheet sh = wb1.getSheetAt(0); XSSFDrawing drawing = sh.createDrawingPatriarch(); - List rels = drawing.getRelations(); + List rels = drawing.getRelationParts(); assertEquals(1, rels.size()); - assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment()); + assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment()); // And again, just to be sure XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1); @@ -231,9 +233,9 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals(1, wb2.getNumberOfSheets()); sh = wb2.getSheetAt(0); drawing = sh.createDrawingPatriarch(); - rels = drawing.getRelations(); + rels = drawing.getRelationParts(); assertEquals(1, rels.size()); - assertEquals("Sheet1!A1", rels.get(0).getPackageRelationship().getTargetURI().getFragment()); + assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment()); wb2.close(); } @@ -1262,12 +1264,20 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("51470.xlsx"); XSSFSheet sh0 = wb.getSheetAt(0); XSSFSheet sh1 = wb.cloneSheet(0); - List rels0 = sh0.getRelations(); - List rels1 = sh1.getRelations(); + List rels0 = sh0.getRelationParts(); + List rels1 = sh1.getRelationParts(); assertEquals(1, rels0.size()); assertEquals(1, rels1.size()); - assertEquals(rels0.get(0).getPackageRelationship(), rels1.get(0).getPackageRelationship()); + PackageRelationship pr0 = rels0.get(0).getRelationship(); + PackageRelationship pr1 = rels1.get(0).getRelationship(); + + assertEquals(pr0.getTargetMode(), pr1.getTargetMode()); + assertEquals(pr0.getTargetURI(), pr1.getTargetURI()); + POIXMLDocumentPart doc0 = rels0.get(0).getDocumentPart(); + POIXMLDocumentPart doc1 = rels1.get(0).getDocumentPart(); + + assertEquals(doc0, doc1); wb.close(); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java index 771c367f24..8bcce73e31 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.List; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLDocumentPart.RelationPart; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.FontUnderline; @@ -44,14 +45,15 @@ public class TestXSSFDrawing { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx"); XSSFSheet sheet = wb.getSheetAt(0); //the sheet has one relationship and it is XSSFDrawing - List rels = sheet.getRelations(); + List rels = sheet.getRelationParts(); assertEquals(1, rels.size()); - assertTrue(rels.get(0) instanceof XSSFDrawing); + RelationPart rp = rels.get(0); + assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - XSSFDrawing drawing = (XSSFDrawing)rels.get(0); + XSSFDrawing drawing = (XSSFDrawing)rp.getDocumentPart(); //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing assertSame(drawing, sheet.createDrawingPatriarch()); - String drawingId = drawing.getPackageRelationship().getId(); + String drawingId = rp.getRelationship().getId(); //there should be a relation to this drawing in the worksheet assertTrue(sheet.getCTWorksheet().isSetDrawing()); @@ -82,12 +84,13 @@ public class TestXSSFDrawing { XSSFDrawing dr2 = sheet.createDrawingPatriarch(); assertSame(dr1, dr2); - List rels = sheet.getRelations(); + List rels = sheet.getRelationParts(); assertEquals(1, rels.size()); - assertTrue(rels.get(0) instanceof XSSFDrawing); + RelationPart rp = rels.get(0); + assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - XSSFDrawing drawing = (XSSFDrawing)rels.get(0); - String drawingId = drawing.getPackageRelationship().getId(); + XSSFDrawing drawing = rp.getDocumentPart(); + String drawingId = rp.getRelationship().getId(); //there should be a relation to this drawing in the worksheet assertTrue(sheet.getCTWorksheet().isSetDrawing()); @@ -509,14 +512,15 @@ public class TestXSSFDrawing { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx"); XSSFSheet sheet = wb.getSheetAt(0); //the sheet has one relationship and it is XSSFDrawing - List rels = sheet.getRelations(); + List rels = sheet.getRelationParts(); assertEquals(1, rels.size()); - assertTrue(rels.get(0) instanceof XSSFDrawing); + RelationPart rp = rels.get(0); + assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - XSSFDrawing drawing = (XSSFDrawing)rels.get(0); + XSSFDrawing drawing = rp.getDocumentPart(); //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing assertSame(drawing, sheet.createDrawingPatriarch()); - String drawingId = drawing.getPackageRelationship().getId(); + String drawingId = rp.getRelationship().getId(); //there should be a relation to this drawing in the worksheet assertTrue(sheet.getCTWorksheet().isSetDrawing()); @@ -543,16 +547,17 @@ public class TestXSSFDrawing { XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithTextBox.xlsx"); XSSFSheet sheet = wb.getSheetAt(0); //the sheet has one relationship and it is XSSFDrawing - List rels = sheet.getRelations(); + List rels = sheet.getRelationParts(); assertEquals(1, rels.size()); + RelationPart rp = rels.get(0); - assertTrue(rels.get(0) instanceof XSSFDrawing); + assertTrue(rp.getDocumentPart() instanceof XSSFDrawing); - XSSFDrawing drawing = (XSSFDrawing)rels.get(0); + XSSFDrawing drawing = rp.getDocumentPart(); //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing assertSame(drawing, sheet.createDrawingPatriarch()); - String drawingId = drawing.getPackageRelationship().getId(); + String drawingId = rp.getRelationship().getId(); //there should be a relation to this drawing in the worksheet assertTrue(sheet.getCTWorksheet().isSetDrawing());