diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java index bdf768d50d..1b04417ee2 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java @@ -33,556 +33,561 @@ import org.apache.poi.openxml4j.opc.internal.ContentType; */ public abstract class PackagePart implements RelationshipSource, Comparable { - /** - * This part's container. - */ - protected OPCPackage _container; + /** + * This part's container. + */ + protected OPCPackage _container; - /** - * The part name. (required by the specification [M1.1]) - */ - protected PackagePartName _partName; + /** + * The part name. (required by the specification [M1.1]) + */ + protected PackagePartName _partName; - /** - * The type of content of this part. (required by the specification [M1.2]) - */ - protected ContentType _contentType; + /** + * The type of content of this part. (required by the specification [M1.2]) + */ + protected ContentType _contentType; - /** - * Flag to know if this part is a relationship. - */ - private boolean _isRelationshipPart; + /** + * Flag to know if this part is a relationship. + */ + private boolean _isRelationshipPart; - /** - * Flag to know if this part has been logically deleted. - */ - private boolean _isDeleted; + /** + * Flag to know if this part has been logically deleted. + */ + private boolean _isDeleted; - /** - * This part's relationships. - */ - private PackageRelationshipCollection _relationships; + /** + * This part's relationships. + */ + private PackageRelationshipCollection _relationships; - /** - * Constructor. - * - * @param pack - * Parent package. - * @param partName - * The part name, relative to the parent Package root. - * @param contentType - * The content type. - * @throws InvalidFormatException - * If the specified URI is not valid. - */ - protected PackagePart(OPCPackage pack, PackagePartName partName, - ContentType contentType) throws InvalidFormatException { - this(pack, partName, contentType, true); - } - - /** - * Constructor. - * - * @param pack - * Parent package. - * @param partName - * The part name, relative to the parent Package root. - * @param contentType - * The content type. - * @param loadRelationships - * Specify if the relationships will be loaded - * @throws InvalidFormatException - * If the specified URI is not valid. - */ - protected PackagePart(OPCPackage pack, PackagePartName partName, - ContentType contentType, boolean loadRelationships) - throws InvalidFormatException { - _partName = partName; - _contentType = contentType; - _container = pack; - - // Check if this part is a relationship part - _isRelationshipPart = this._partName.isRelationshipPartURI(); - - // Load relationships if any - if (loadRelationships) { - loadRelationships(); - } - } - - /** - * Constructor. - * - * @param pack - * Parent package. - * @param partName - * The part name, relative to the parent Package root. - * @param contentType - * The Multipurpose Internet Mail Extensions (MIME) content type - * of the part's data stream. - */ - public PackagePart(OPCPackage pack, PackagePartName partName, - String contentType) throws InvalidFormatException { - this(pack, partName, new ContentType(contentType)); - } - - /** - * Check if the new part was already added before via PackagePart.addRelationship() - * - * @param packagePart to find the relationship for - * @return The existing relationship, or null if there isn't yet one - */ - public PackageRelationship findExistingRelation(PackagePart packagePart) { - return _relationships.findExistingInternalRelation(packagePart); + /** + * Constructor. + * + * @param pack + * Parent package. + * @param partName + * The part name, relative to the parent Package root. + * @param contentType + * The content type. + * @throws InvalidFormatException + * If the specified URI is not valid. + */ + protected PackagePart(OPCPackage pack, PackagePartName partName, + ContentType contentType) throws InvalidFormatException { + this(pack, partName, contentType, true); } - /** - * Adds an external relationship to a part (except relationships part). - * - * The targets of external relationships are not subject to the same - * validity checks that internal ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target - * External target of the relationship - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, - * java.lang.String) - */ - public PackageRelationship addExternalRelationship(String target, - String relationshipType) { - return addExternalRelationship(target, relationshipType, null); - } + /** + * Constructor. + * + * @param pack + * Parent package. + * @param partName + * The part name, relative to the parent Package root. + * @param contentType + * The content type. + * @param loadRelationships + * Specify if the relationships will be loaded + * @throws InvalidFormatException + * If the specified URI is not valid. + */ + protected PackagePart(OPCPackage pack, PackagePartName partName, + ContentType contentType, boolean loadRelationships) + throws InvalidFormatException { + _partName = partName; + _contentType = contentType; + _container = pack; - /** - * Adds an external relationship to a part (except relationships part). - * - * The targets of external relationships are not subject to the same - * validity checks that internal ones are, as the contents is potentially - * any file, URL or similar. - * - * @param target - * External target of the relationship - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, - * java.lang.String) - */ - public PackageRelationship addExternalRelationship(String target, - String relationshipType, String id) { - if (target == null) { - throw new IllegalArgumentException("target is null for type " + relationshipType); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } + // Check if this part is a relationship part + _isRelationshipPart = this._partName.isRelationshipPartURI(); - if (_relationships == null) { - _relationships = new PackageRelationshipCollection(); - } + // Load relationships if any + if (loadRelationships) { + loadRelationships(); + } + } - URI targetURI; - try { - targetURI = new URI(target); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid target - " + e); - } + /** + * Constructor. + * + * @param pack + * Parent package. + * @param partName + * The part name, relative to the parent Package root. + * @param contentType + * The Multipurpose Internet Mail Extensions (MIME) content type + * of the part's data stream. + * @throws InvalidFormatException + * If the specified URI is not valid. + */ + public PackagePart(OPCPackage pack, PackagePartName partName, + String contentType) throws InvalidFormatException { + this(pack, partName, new ContentType(contentType)); + } - return _relationships.addRelationship(targetURI, TargetMode.EXTERNAL, - relationshipType, id); - } + /** + * Check if the new part was already added before via PackagePart.addRelationship() + * + * @param packagePart to find the relationship for + * @return The existing relationship, or null if there isn't yet one + */ + public PackageRelationship findExistingRelation(PackagePart packagePart) { + return _relationships.findExistingInternalRelation(packagePart); + } - /** - * Add a relationship to a part (except relationships part). - * - * @param targetPartName - * Name of the target part. This one must be relative to the - * source root directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String) - */ - public PackageRelationship addRelationship(PackagePartName targetPartName, - TargetMode targetMode, String relationshipType) { - return addRelationship(targetPartName, targetMode, relationshipType, - null); - } + /** + * Adds an external relationship to a part (except relationships part). + * + * The targets of external relationships are not subject to the same + * validity checks that internal ones are, as the contents is potentially + * any file, URL or similar. + * + * @param target + * External target of the relationship + * @param relationshipType + * Type of relationship. + * @return The newly created and added relationship + * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, + * java.lang.String) + */ + public PackageRelationship addExternalRelationship(String target, + String relationshipType) { + return addExternalRelationship(target, relationshipType, null); + } - /** - * Add a relationship to a part (except relationships part). - *

- * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - *

- * @param targetPartName - * Name of the target part. This one must be relative to the - * source root directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * - * @throws InvalidOperationException - * If a writing operation is done on a read only package or - * invalid nested relations are created. - * @throws IllegalArgumentException if targetPartName, targetMode - * or relationshipType are passed as null - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String) - */ - public PackageRelationship addRelationship(PackagePartName targetPartName, - TargetMode targetMode, String relationshipType, String id) { - _container.throwExceptionIfReadOnly(); + /** + * Adds an external relationship to a part (except relationships part). + * + * The targets of external relationships are not subject to the same + * validity checks that internal ones are, as the contents is potentially + * any file, URL or similar. + * + * @param target + * External target of the relationship + * @param relationshipType + * Type of relationship. + * @param id + * Relationship unique id. + * @return The newly created and added relationship + * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, + * java.lang.String) + */ + public PackageRelationship addExternalRelationship(String target, + String relationshipType, String id) { + if (target == null) { + throw new IllegalArgumentException("target is null for type " + relationshipType); + } + if (relationshipType == null) { + throw new IllegalArgumentException("relationshipType"); + } - if (targetPartName == null) { - throw new IllegalArgumentException("targetPartName"); - } - if (targetMode == null) { - throw new IllegalArgumentException("targetMode"); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } + if (_relationships == null) { + _relationships = new PackageRelationshipCollection(); + } - if (this._isRelationshipPart || targetPartName.isRelationshipPartURI()) { - throw new InvalidOperationException( - "Rule M1.25: The Relationships part shall not have relationships to any other part."); - } + URI targetURI; + try { + targetURI = new URI(target); + } catch (URISyntaxException e) { + throw new IllegalArgumentException("Invalid target - " + e); + } - if (_relationships == null) { - _relationships = new PackageRelationshipCollection(); - } + return _relationships.addRelationship(targetURI, TargetMode.EXTERNAL, + relationshipType, id); + } - return _relationships.addRelationship(targetPartName.getURI(), - targetMode, relationshipType, id); - } + /** + * Add a relationship to a part (except relationships part). + * + * @param targetPartName + * Name of the target part. This one must be relative to the + * source root directory of the part. + * @param targetMode + * Mode [Internal|External]. + * @param relationshipType + * Type of relationship. + * @return The newly created and added relationship + * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, + * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String) + */ + public PackageRelationship addRelationship(PackagePartName targetPartName, + TargetMode targetMode, String relationshipType) { + return addRelationship(targetPartName, targetMode, relationshipType, + null); + } - /** - * Add a relationship to a part (except relationships part). - * - * @param targetURI - * URI the target part. Must be relative to the source root - * directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @return The newly created and added relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String) - */ - public PackageRelationship addRelationship(URI targetURI, - TargetMode targetMode, String relationshipType) { - return addRelationship(targetURI, targetMode, relationshipType, null); - } + /** + * Add a relationship to a part (except relationships part). + *

+ * Check rule M1.25: The Relationships part shall not have relationships to + * any other part. Package implementers shall enforce this requirement upon + * the attempt to create such a relationship and shall treat any such + * relationship as invalid. + *

+ * @param targetPartName + * Name of the target part. This one must be relative to the + * source root directory of the part. + * @param targetMode + * Mode [Internal|External]. + * @param relationshipType + * Type of relationship. + * @param id + * Relationship unique id. + * @return The newly created and added relationship + * + * @throws InvalidOperationException + * If a writing operation is done on a read only package or + * invalid nested relations are created. + * @throws IllegalArgumentException if targetPartName, targetMode + * or relationshipType are passed as null + * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, + * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String) + */ + public PackageRelationship addRelationship(PackagePartName targetPartName, + TargetMode targetMode, String relationshipType, String id) { + _container.throwExceptionIfReadOnly(); - /** - * Add a relationship to a part (except relationships part). - *

- * Check rule M1.25: The Relationships part shall not have relationships to - * any other part. Package implementers shall enforce this requirement upon - * the attempt to create such a relationship and shall treat any such - * relationship as invalid. - *

- * @param targetURI - * URI of the target part. Must be relative to the source root - * directory of the part. - * @param targetMode - * Mode [Internal|External]. - * @param relationshipType - * Type of relationship. - * @param id - * Relationship unique id. - * @return The newly created and added relationship - * - * @throws InvalidOperationException - * If the URI point to a relationship part URI. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, - * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String) - */ - public PackageRelationship addRelationship(URI targetURI, - TargetMode targetMode, String relationshipType, String id) { - _container.throwExceptionIfReadOnly(); + if (targetPartName == null) { + throw new IllegalArgumentException("targetPartName"); + } + if (targetMode == null) { + throw new IllegalArgumentException("targetMode"); + } + if (relationshipType == null) { + throw new IllegalArgumentException("relationshipType"); + } - if (targetURI == null) { - throw new IllegalArgumentException("targetPartName"); - } - if (targetMode == null) { - throw new IllegalArgumentException("targetMode"); - } - if (relationshipType == null) { - throw new IllegalArgumentException("relationshipType"); - } + if (this._isRelationshipPart || targetPartName.isRelationshipPartURI()) { + throw new InvalidOperationException( + "Rule M1.25: The Relationships part shall not have relationships to any other part."); + } - // Try to retrieve the target part + if (_relationships == null) { + _relationships = new PackageRelationshipCollection(); + } - if (this._isRelationshipPart - || PackagingURIHelper.isRelationshipPartURI(targetURI)) { - throw new InvalidOperationException( - "Rule M1.25: The Relationships part shall not have relationships to any other part."); - } + return _relationships.addRelationship(targetPartName.getURI(), + targetMode, relationshipType, id); + } - if (_relationships == null) { - _relationships = new PackageRelationshipCollection(); - } + /** + * Add a relationship to a part (except relationships part). + * + * @param targetURI + * URI the target part. Must be relative to the source root + * directory of the part. + * @param targetMode + * Mode [Internal|External]. + * @param relationshipType + * Type of relationship. + * @return The newly created and added relationship + * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, + * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String) + */ + public PackageRelationship addRelationship(URI targetURI, + TargetMode targetMode, String relationshipType) { + return addRelationship(targetURI, targetMode, relationshipType, null); + } - return _relationships.addRelationship(targetURI, - targetMode, relationshipType, id); - } + /** + * Add a relationship to a part (except relationships part). + *

+ * Check rule M1.25: The Relationships part shall not have relationships to + * any other part. Package implementers shall enforce this requirement upon + * the attempt to create such a relationship and shall treat any such + * relationship as invalid. + *

+ * @param targetURI + * URI of the target part. Must be relative to the source root + * directory of the part. + * @param targetMode + * Mode [Internal|External]. + * @param relationshipType + * Type of relationship. + * @param id + * Relationship unique id. + * @return The newly created and added relationship + * + * @throws InvalidOperationException + * If the URI point to a relationship part URI. + * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName, + * org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String) + */ + public PackageRelationship addRelationship(URI targetURI, + TargetMode targetMode, String relationshipType, String id) { + _container.throwExceptionIfReadOnly(); - /** - * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships() - */ - public void clearRelationships() { - if (_relationships != null) { - _relationships.clear(); - } - } + if (targetURI == null) { + throw new IllegalArgumentException("targetPartName"); + } + if (targetMode == null) { + throw new IllegalArgumentException("targetMode"); + } + if (relationshipType == null) { + throw new IllegalArgumentException("relationshipType"); + } - /** - * Delete the relationship specified by its id. - * - * @param id - * The ID identified the part to delete. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#removeRelationship(java.lang.String) - */ - public void removeRelationship(String id) { - this._container.throwExceptionIfReadOnly(); - if (this._relationships != null) - this._relationships.removeRelationship(id); - } + // Try to retrieve the target part - /** - * Retrieve all the relationships attached to this part. - * - * @return This part's relationships. - * @throws InvalidOperationException - * Throws if the package is open en write only mode. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationships() - */ - public PackageRelationshipCollection getRelationships() - throws InvalidFormatException { - return getRelationshipsCore(null); - } + if (this._isRelationshipPart + || PackagingURIHelper.isRelationshipPartURI(targetURI)) { + throw new InvalidOperationException( + "Rule M1.25: The Relationships part shall not have relationships to any other part."); + } - /** - * Retrieves a package relationship from its id. - * - * @param id - * ID of the package relationship to retrieve. - * @return The package relationship - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String) - */ - public PackageRelationship getRelationship(String id) { - return this._relationships.getRelationshipByID(id); - } + if (_relationships == null) { + _relationships = new PackageRelationshipCollection(); + } - /** - * Retrieve all relationships attached to this part which have the specified - * type. - * - * @param relationshipType - * Relationship type filter. - * @return All relationships from this part that have the specified type. - * @throws InvalidFormatException - * If an error occurs while parsing the part. - * @throws InvalidOperationException - * If the package is open in write only mode. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationshipsByType(java.lang.String) - */ - public PackageRelationshipCollection getRelationshipsByType( - String relationshipType) throws InvalidFormatException { - _container.throwExceptionIfWriteOnly(); + return _relationships.addRelationship(targetURI, + targetMode, relationshipType, id); + } - return getRelationshipsCore(relationshipType); - } + /** + * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships() + */ + public void clearRelationships() { + if (_relationships != null) { + _relationships.clear(); + } + } - /** - * Implementation of the getRelationships method(). - * - * @param filter - * Relationship type filter. If null then the filter is - * disabled and return all the relationships. - * @return All relationships from this part that have the specified type. - * @throws InvalidFormatException - * Throws if an error occurs during parsing the relationships - * part. - * @throws InvalidOperationException - * Throws if the package is open en write only mode. - * @see #getRelationshipsByType(String) - */ - private PackageRelationshipCollection getRelationshipsCore(String filter) - throws InvalidFormatException { - this._container.throwExceptionIfWriteOnly(); - if (_relationships == null) { - this.throwExceptionIfRelationship(); - _relationships = new PackageRelationshipCollection(this); - } - return new PackageRelationshipCollection(_relationships, filter); - } + /** + * Delete the relationship specified by its id. + * + * @param id + * The ID identified the part to delete. + * @see org.apache.poi.openxml4j.opc.RelationshipSource#removeRelationship(java.lang.String) + */ + public void removeRelationship(String id) { + this._container.throwExceptionIfReadOnly(); + if (this._relationships != null) + this._relationships.removeRelationship(id); + } - /** - * Knows if the part have any relationships. - * - * @return true if the part have at least one relationship else - * false. - * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships() - */ - public boolean hasRelationships() { - return (!this._isRelationshipPart && (_relationships != null && _relationships - .size() > 0)); - } + /** + * Retrieve all the relationships attached to this part. + * + * @return This part's relationships. + * @throws InvalidOperationException + * Throws if the package is open en write only mode. + * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationships() + */ + public PackageRelationshipCollection getRelationships() + throws InvalidFormatException { + return getRelationshipsCore(null); + } - /** - * Checks if the specified relationship is part of this package part. - * - * @param rel - * The relationship to check. - * @return true if the specified relationship exists in this part, - * else returns false - * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship) - */ - public boolean isRelationshipExists(PackageRelationship rel) { - return rel != null && _relationships.getRelationshipByID(rel.getId()) != null; - } + /** + * Retrieves a package relationship from its id. + * + * @param id + * ID of the package relationship to retrieve. + * @return The package relationship + * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String) + */ + public PackageRelationship getRelationship(String id) { + return this._relationships.getRelationshipByID(id); + } + + /** + * Retrieve all relationships attached to this part which have the specified + * type. + * + * @param relationshipType + * Relationship type filter. + * @return All relationships from this part that have the specified type. + * @throws InvalidFormatException + * If an error occurs while parsing the part. + * @throws InvalidOperationException + * If the package is open in write only mode. + * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationshipsByType(java.lang.String) + */ + public PackageRelationshipCollection getRelationshipsByType( + String relationshipType) throws InvalidFormatException { + _container.throwExceptionIfWriteOnly(); + + return getRelationshipsCore(relationshipType); + } + + /** + * Implementation of the getRelationships method(). + * + * @param filter + * Relationship type filter. If null then the filter is + * disabled and return all the relationships. + * @return All relationships from this part that have the specified type. + * @throws InvalidFormatException + * Throws if an error occurs during parsing the relationships + * part. + * @throws InvalidOperationException + * Throws if the package is open en write only mode. + * @see #getRelationshipsByType(String) + */ + private PackageRelationshipCollection getRelationshipsCore(String filter) + throws InvalidFormatException { + this._container.throwExceptionIfWriteOnly(); + if (_relationships == null) { + this.throwExceptionIfRelationship(); + _relationships = new PackageRelationshipCollection(this); + } + return new PackageRelationshipCollection(_relationships, filter); + } + + /** + * Knows if the part have any relationships. + * + * @return true if the part have at least one relationship else + * false. + * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships() + */ + public boolean hasRelationships() { + return (!this._isRelationshipPart && (_relationships != null && _relationships + .size() > 0)); + } + + /** + * Checks if the specified relationship is part of this package part. + * + * @param rel + * The relationship to check. + * @return true if the specified relationship exists in this part, + * else returns false + * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship) + */ + public boolean isRelationshipExists(PackageRelationship rel) { + return rel != null && _relationships.getRelationshipByID(rel.getId()) != null; + } /** * Get the PackagePart that is the target of a relationship. * * @param rel A relationship from this part to another one * @return The target part of the relationship + * @throws InvalidFormatException + * If the specified URI is not valid. */ - public PackagePart getRelatedPart(PackageRelationship rel) throws InvalidFormatException { - // Ensure this is one of ours - if(! isRelationshipExists(rel)) { - throw new IllegalArgumentException("Relationship " + rel + " doesn't start with this part " + _partName); - } - // Get the target URI, excluding any relative fragments - URI target = rel.getTargetURI(); - if(target.getFragment() != null) { - String t = target.toString(); - try { - target = new URI( t.substring(0, t.indexOf('#')) ); - } catch(URISyntaxException e) { - throw new InvalidFormatException("Invalid target URI: " + target); - } - } + public PackagePart getRelatedPart(PackageRelationship rel) throws InvalidFormatException { + // Ensure this is one of ours + if(! isRelationshipExists(rel)) { + throw new IllegalArgumentException("Relationship " + rel + " doesn't start with this part " + _partName); + } + // Get the target URI, excluding any relative fragments + URI target = rel.getTargetURI(); + if(target.getFragment() != null) { + String t = target.toString(); + try { + target = new URI( t.substring(0, t.indexOf('#')) ); + } catch(URISyntaxException e) { + throw new InvalidFormatException("Invalid target URI: " + target); + } + } - // Turn that into a name, and fetch - PackagePartName relName = PackagingURIHelper.createPartName(target); - PackagePart part = _container.getPart(relName); - if (part == null) { - throw new IllegalArgumentException("No part found for relationship " + rel); - } - return part; - } + // Turn that into a name, and fetch + PackagePartName relName = PackagingURIHelper.createPartName(target); + PackagePart part = _container.getPart(relName); + if (part == null) { + throw new IllegalArgumentException("No part found for relationship " + rel); + } + return part; + } - /** - * Get the input stream of this part to read its content. - * - * @return The input stream of the content of this part, else - * null. - * - * @throws IOException If creating the input-stream fails. - */ - public InputStream getInputStream() throws IOException { - InputStream inStream = this.getInputStreamImpl(); - if (inStream == null) { - throw new IOException("Can't obtain the input stream from " - + _partName.getName()); - } - return inStream; - } + /** + * Get the input stream of this part to read its content. + * + * @return The input stream of the content of this part, else + * null. + * + * @throws IOException If creating the input-stream fails. + */ + public InputStream getInputStream() throws IOException { + InputStream inStream = this.getInputStreamImpl(); + if (inStream == null) { + throw new IOException("Can't obtain the input stream from " + + _partName.getName()); + } + return inStream; + } - /** - * Get the output stream of this part. If the part is originally embedded in - * Zip package, it'll be transform into a MemoryPackagePart in - * order to write inside (the standard Java API doesn't allow to write in - * the file) - * - * @see org.apache.poi.openxml4j.opc.internal.MemoryPackagePart - */ - public OutputStream getOutputStream() { - OutputStream outStream; - // If this part is a zip package part (read only by design) we convert - // this part into a MemoryPackagePart instance for write purpose. - if (this instanceof ZipPackagePart) { - // Delete logically this part - _container.removePart(this._partName); + /** + * Get the output stream of this part. If the part is originally embedded in + * Zip package, it'll be transform into a MemoryPackagePart in + * order to write inside (the standard Java API doesn't allow to write in + * the file) + * + * @return output stream for this part + * @see org.apache.poi.openxml4j.opc.internal.MemoryPackagePart + */ + public OutputStream getOutputStream() { + OutputStream outStream; + // If this part is a zip package part (read only by design) we convert + // this part into a MemoryPackagePart instance for write purpose. + if (this instanceof ZipPackagePart) { + // Delete logically this part + _container.removePart(this._partName); - // Create a memory part - PackagePart part = _container.createPart(this._partName, - this._contentType.toString(), false); - if (part == null) { - throw new InvalidOperationException( - "Can't create a temporary part !"); - } - part._relationships = this._relationships; - outStream = part.getOutputStreamImpl(); - } else { - outStream = this.getOutputStreamImpl(); - } - return outStream; - } + // Create a memory part + PackagePart part = _container.createPart(this._partName, + this._contentType.toString(), false); + if (part == null) { + throw new InvalidOperationException( + "Can't create a temporary part !"); + } + part._relationships = this._relationships; + outStream = part.getOutputStreamImpl(); + } else { + outStream = this.getOutputStreamImpl(); + } + return outStream; + } - /** - * Throws an exception if this package part is a relationship part. - * - * @throws InvalidOperationException - * If this part is a relationship part. - */ - private void throwExceptionIfRelationship() - throws InvalidOperationException { - if (this._isRelationshipPart) - throw new InvalidOperationException( - "Can do this operation on a relationship part !"); - } + /** + * Throws an exception if this package part is a relationship part. + * + * @throws InvalidOperationException + * If this part is a relationship part. + */ + private void throwExceptionIfRelationship() + throws InvalidOperationException { + if (this._isRelationshipPart) + throw new InvalidOperationException( + "Can do this operation on a relationship part !"); + } - /** - * Ensure the package relationships collection instance is built. - * - * @throws InvalidFormatException - * Throws if - */ - /* package */ void loadRelationships() throws InvalidFormatException { - if (this._relationships == null && !this._isRelationshipPart) { - this.throwExceptionIfRelationship(); - _relationships = new PackageRelationshipCollection(this); - } - } + /** + * Ensure the package relationships collection instance is built. + * + * @throws InvalidFormatException + * Throws if + */ + /* package */ void loadRelationships() throws InvalidFormatException { + if (this._relationships == null && !this._isRelationshipPart) { + this.throwExceptionIfRelationship(); + _relationships = new PackageRelationshipCollection(this); + } + } - /* - * Accessors - */ + /* + * Accessors + */ - /** - * @return the uri - */ - public PackagePartName getPartName() { - return _partName; - } + /** + * @return the uri + */ + public PackagePartName getPartName() { + return _partName; + } - /** - * @return The Content Type of the part - */ - public String getContentType() { - return _contentType.toString(); - } + /** + * @return The Content Type of the part + */ + public String getContentType() { + return _contentType.toString(); + } /** * @return The Content Type, including parameters, of the part @@ -591,138 +596,142 @@ public abstract class PackagePart implements RelationshipSource, Comparabletrue if the content has been successfully loaded, else - * false. - * @throws InvalidFormatException - * Throws if the content format is invalid. - */ - public abstract boolean load(InputStream ios) throws InvalidFormatException; + /** + * Save the content of this part and the associated relationships part (if + * this part own at least one relationship) into the specified output + * stream. + * + * @param zos + * Output stream to save this part. + * @return boolean flag that shows if the save succeeded + * @throws OpenXML4JException + * If any exception occur. + */ + public abstract boolean save(OutputStream zos) throws OpenXML4JException; - /** - * Close this part : flush this part, close the input stream and output - * stream. After this method call, the part must be available for packaging. - */ - public abstract void close(); + /** + * Load the content of this part. + * + * @param ios + * The input stream of the content to load. + * @return true if the content has been successfully loaded, else + * false. + * @throws InvalidFormatException + * Throws if the content format is invalid. + */ + public abstract boolean load(InputStream ios) throws InvalidFormatException; - /** - * Flush the content of this part. If the input stream and/or output stream - * as in a waiting state to read or write, the must to empty their - * respective buffer. - */ - public abstract void flush(); + /** + * Close this part : flush this part, close the input stream and output + * stream. After this method call, the part must be available for packaging. + */ + public abstract void close(); - /** - * Allows sub-classes to clean up before new data is added. - */ - public void clear() { - } + /** + * Flush the content of this part. If the input stream and/or output stream + * as in a waiting state to read or write, the must to empty their + * respective buffer. + */ + public abstract void flush(); + + /** + * Allows sub-classes to clean up before new data is added. + */ + public void clear() { + } }