]> source.dussan.org Git - poi.git/commitdiff
fix some javadoc
authorPJ Fanning <fanningpj@apache.org>
Thu, 7 Jun 2018 08:37:28 +0000 (08:37 +0000)
committerPJ Fanning <fanningpj@apache.org>
Thu, 7 Jun 2018 08:37:28 +0000 (08:37 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1833106 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java

index bdf768d50db05fadf5f2a8eddc8e0e59b4bddc5b..1b04417ee2793b284d00dd870703a3a4a91ed545 100644 (file)
@@ -33,556 +33,561 @@ import org.apache.poi.openxml4j.opc.internal.ContentType;
  */
 public abstract class PackagePart implements RelationshipSource, Comparable<PackagePart> {
 
-       /**
-        * This part's container.
-        */
-       protected OPCPackage _container;
-
-       /**
-        * 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;
-
-       /**
-        * 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;
-
-       /**
-        * 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);
-    }
-
-       /**
-        * 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);
-       }
-
-       /**
-        * 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 (_relationships == null) {
-                       _relationships = new PackageRelationshipCollection();
-               }
-
-               URI targetURI;
-               try {
-                       targetURI = new URI(target);
-               } catch (URISyntaxException e) {
-                       throw new IllegalArgumentException("Invalid target - " + e);
-               }
-
-               return _relationships.addRelationship(targetURI, TargetMode.EXTERNAL,
-                               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).
-        * <p>
-        * 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.
-        * </p>
-        * @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();
-
-               if (targetPartName == 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.");
-               }
-
-               if (_relationships == null) {
-                       _relationships = new PackageRelationshipCollection();
-               }
-
-               return _relationships.addRelationship(targetPartName.getURI(),
-                               targetMode, relationshipType, id);
-       }
-
-       /**
-        * 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).
-        * <p>
-        * 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.
-        * </p>
-        * @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 (targetURI == null) {
-                       throw new IllegalArgumentException("targetPartName");
-               }
-               if (targetMode == null) {
-                       throw new IllegalArgumentException("targetMode");
-               }
-               if (relationshipType == null) {
-                       throw new IllegalArgumentException("relationshipType");
-               }
-
-               // Try to retrieve the target part
-
-               if (this._isRelationshipPart
-                               || PackagingURIHelper.isRelationshipPartURI(targetURI)) {
-                       throw new InvalidOperationException(
-                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");
-               }
-
-               if (_relationships == null) {
-                       _relationships = new PackageRelationshipCollection();
-               }
-
-               return _relationships.addRelationship(targetURI,
-                               targetMode, relationshipType, id);
-       }
-
-       /**
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships()
-        */
-       public void clearRelationships() {
-               if (_relationships != null) {
-                       _relationships.clear();
-               }
-       }
-
-       /**
-        * 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);
-       }
-
-       /**
-        * 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);
-       }
-
-       /**
-        * 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 <i>null</i> 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 <b>true</b> if the part have at least one relationship else
-        *         <b>false</b>.
-        * @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 <b>true</b> if the specified relationship exists in this part,
-        *         else returns <b>false</b>
-        * @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;
-       }
+    /**
+     * This part's container.
+     */
+    protected OPCPackage _container;
+
+    /**
+     * 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;
+
+    /**
+     * 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;
+
+    /**
+     * 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.
+     * @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));
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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 (_relationships == null) {
+            _relationships = new PackageRelationshipCollection();
+        }
+
+        URI targetURI;
+        try {
+            targetURI = new URI(target);
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException("Invalid target - " + e);
+        }
+
+        return _relationships.addRelationship(targetURI, TargetMode.EXTERNAL,
+                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).
+     * <p>
+     * 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.
+     * </p>
+     * @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();
+
+        if (targetPartName == 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.");
+        }
+
+        if (_relationships == null) {
+            _relationships = new PackageRelationshipCollection();
+        }
+
+        return _relationships.addRelationship(targetPartName.getURI(),
+                targetMode, relationshipType, id);
+    }
+
+    /**
+     * 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).
+     * <p>
+     * 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.
+     * </p>
+     * @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 (targetURI == null) {
+            throw new IllegalArgumentException("targetPartName");
+        }
+        if (targetMode == null) {
+            throw new IllegalArgumentException("targetMode");
+        }
+        if (relationshipType == null) {
+            throw new IllegalArgumentException("relationshipType");
+        }
+
+        // Try to retrieve the target part
+
+        if (this._isRelationshipPart
+                || PackagingURIHelper.isRelationshipPartURI(targetURI)) {
+            throw new InvalidOperationException(
+                    "Rule M1.25: The Relationships part shall not have relationships to any other part.");
+        }
+
+        if (_relationships == null) {
+            _relationships = new PackageRelationshipCollection();
+        }
+
+        return _relationships.addRelationship(targetURI,
+                targetMode, relationshipType, id);
+    }
+
+    /**
+     * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships()
+     */
+    public void clearRelationships() {
+        if (_relationships != null) {
+            _relationships.clear();
+        }
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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 <i>null</i> 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 <b>true</b> if the part have at least one relationship else
+     *         <b>false</b>.
+     * @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 <b>true</b> if the specified relationship exists in this part,
+     *         else returns <b>false</b>
+     * @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);
-                       }
-               }
-
-               // 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
-        *         <code>null</code>.
-        *
-        * @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 <i>MemoryPackagePart</i> 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);
-
-                       // 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 !");
-       }
-
-       /**
-        * 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
-        */
-
-       /**
-        * @return the uri
-        */
-       public PackagePartName getPartName() {
-               return _partName;
-       }
-
-       /**
-        * @return The Content Type of the part
-        */
-       public String getContentType() {
-               return _contentType.toString();
-       }
+    public PackagePart getRelatedPart(PackageRelationship rel) throws InvalidFormatException {
+        // Ensure this is one of ours
+        if(! isRelationshipExists(rel)) {
+            throw new IllegalArgumentException("Relationship " + rel + " doesn't start with this part " + _partName);
+        }
+        // Get the target URI, excluding any relative fragments
+        URI target = rel.getTargetURI();
+        if(target.getFragment() != null) {
+            String t = target.toString();
+            try {
+                target = new URI( t.substring(0, t.indexOf('#')) );
+            } catch(URISyntaxException e) {
+                throw new InvalidFormatException("Invalid target URI: " + target);
+            }
+        }
+
+        // Turn that into a name, and fetch
+        PackagePartName relName = PackagingURIHelper.createPartName(target);
+        PackagePart part = _container.getPart(relName);
+        if (part == null) {
+            throw new IllegalArgumentException("No part found for relationship " + rel);
+        }
+        return part;
+    }
+
+    /**
+     * Get the input stream of this part to read its content.
+     *
+     * @return The input stream of the content of this part, else
+     *         <code>null</code>.
+     *
+     * @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 <i>MemoryPackagePart</i> 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;
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /*
+     * Accessors
+     */
+
+    /**
+     * @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, including parameters, of the part
@@ -591,138 +596,142 @@ public abstract class PackagePart implements RelationshipSource, Comparable<Pack
         return _contentType;
     }
 
-       /**
-        * Set the content type.
-        *
-        * @param contentType
-        *            the contentType to set
-        *
-        * @throws InvalidFormatException
-        *             Throws if the content type is not valid.
-        * @throws InvalidOperationException
-        *             Throws if you try to change the content type whereas this
-        *             part is already attached to a package.
-        */
-       public void setContentType(String contentType)
-                       throws InvalidFormatException {
-               if (_container == null) {
-                       _contentType = new ContentType(contentType);
-               }
-               else {
-                   _container.unregisterPartAndContentType(_partName);
-                   _contentType = new ContentType(contentType);
-                   _container.registerPartAndContentType(this);
-               }
-       }
-
-       public OPCPackage getPackage() {
-               return _container;
-       }
-
-       /**
-        * @return true if this part is a relationship
-        */
-       public boolean isRelationshipPart() {
-               return this._isRelationshipPart;
-       }
-
-       /**
-        * @return true if this part has been logically deleted
-        */
-       public boolean isDeleted() {
-               return _isDeleted;
-       }
-
-       /**
-        * @param isDeleted
-        *            the isDeleted to set
-        */
-       public void setDeleted(boolean isDeleted) {
-               this._isDeleted = isDeleted;
-       }
-       
-       /**
-        * @return The length of the part in bytes, or -1 if not known
-        */
-       public long getSize() {
-          return -1;
-       }
-
-       @Override
-       public String toString() {
-               return "Name: " + this._partName + " - Content Type: "
-                               + this._contentType;
-       }
-
-       /**
-        * Compare based on the package part name, using a natural sort order
-        */
-       @Override
-       public int compareTo(PackagePart other)
-       {
-           // NOTE could also throw a NullPointerException() if desired
-           if (other == null)
-               return -1;
-
-           return PackagePartName.compare(this._partName, other._partName);
-       }
-
-       /*-------------- Abstract methods ------------- */
-
-       /**
-        * Abstract method that get the input stream of this part.
-        *
-        * @exception IOException
-        *                Throws if an IO Exception occur in the implementation
-        *                method.
-        */
-       protected abstract InputStream getInputStreamImpl() throws IOException;
-
-       /**
-        * Abstract method that get the output stream of this part.
-        */
-       protected abstract OutputStream getOutputStreamImpl();
-
-       /**
-        * 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.
-        * @throws OpenXML4JException
-        *             If any exception occur.
-        */
-       public abstract boolean save(OutputStream zos) throws OpenXML4JException;
-
-       /**
-        * Load the content of this part.
-        *
-        * @param ios
-        *            The input stream of the content to load.
-        * @return <b>true</b> if the content has been successfully loaded, else
-        *         <b>false</b>.
-        * @throws InvalidFormatException
-        *             Throws if the content format is invalid.
-        */
-       public abstract boolean load(InputStream ios) throws InvalidFormatException;
-
-       /**
-        * 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();
-
-       /**
-        * 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() {
-       }
+    /**
+     * Set the content type.
+     *
+     * @param contentType
+     *            the contentType to set
+     *
+     * @throws InvalidFormatException
+     *             Throws if the content type is not valid.
+     * @throws InvalidOperationException
+     *             Throws if you try to change the content type whereas this
+     *             part is already attached to a package.
+     */
+    public void setContentType(String contentType)
+            throws InvalidFormatException {
+        if (_container == null) {
+            _contentType = new ContentType(contentType);
+        }
+        else {
+            _container.unregisterPartAndContentType(_partName);
+            _contentType = new ContentType(contentType);
+            _container.registerPartAndContentType(this);
+        }
+    }
+
+    public OPCPackage getPackage() {
+        return _container;
+    }
+
+    /**
+     * @return true if this part is a relationship
+     */
+    public boolean isRelationshipPart() {
+        return this._isRelationshipPart;
+    }
+
+    /**
+     * @return true if this part has been logically deleted
+     */
+    public boolean isDeleted() {
+        return _isDeleted;
+    }
+
+    /**
+     * @param isDeleted
+     *            the isDeleted to set
+     */
+    public void setDeleted(boolean isDeleted) {
+        this._isDeleted = isDeleted;
+    }
+
+    /**
+     * @return The length of the part in bytes, or -1 if not known
+     */
+    public long getSize() {
+       return -1;
+    }
+
+    @Override
+    public String toString() {
+        return "Name: " + this._partName + " - Content Type: "
+                + this._contentType;
+    }
+
+    /**
+     * Compare based on the package part name, using a natural sort order
+     */
+    @Override
+    public int compareTo(PackagePart other)
+    {
+        // NOTE could also throw a NullPointerException() if desired
+        if (other == null)
+            return -1;
+
+        return PackagePartName.compare(this._partName, other._partName);
+    }
+
+    /*-------------- Abstract methods ------------- */
+
+    /**
+     * Method that gets the input stream for this part.
+     *
+     * @return input stream for this part
+     * @exception IOException
+     *                Throws if an IO Exception occur in the implementation
+     *                method.
+     */
+    protected abstract InputStream getInputStreamImpl() throws IOException;
+
+    /**
+     * Method that gets the output stream for this part.
+     *
+     * @return output stream for this part
+     */
+    protected abstract OutputStream getOutputStreamImpl();
+
+    /**
+     * 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;
+
+    /**
+     * Load the content of this part.
+     *
+     * @param ios
+     *            The input stream of the content to load.
+     * @return <b>true</b> if the content has been successfully loaded, else
+     *         <b>false</b>.
+     * @throws InvalidFormatException
+     *             Throws if the content format is invalid.
+     */
+    public abstract boolean load(InputStream ios) throws InvalidFormatException;
+
+    /**
+     * 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();
+
+    /**
+     * 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() {
+    }
 }