]> source.dussan.org Git - poi.git/commitdiff
[bug-62522] include partName in exception message
authorPJ Fanning <fanningpj@apache.org>
Fri, 6 Jul 2018 19:07:22 +0000 (19:07 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 6 Jul 2018 19:07:22 +0000 (19:07 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1835276 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java

index ac23a7cada4996a81710011bf1034c56f3808760..26ea1b0c7a0d389da7550e65551ffceddd434a6f 100644 (file)
@@ -43,433 +43,434 @@ import org.xml.sax.SAXException;
  */
 public abstract class ContentTypeManager {
 
-       /**
-        * Content type part name.
-        */
-       public static final String CONTENT_TYPES_PART_NAME = "[Content_Types].xml";
-
-       /**
-        * Content type namespace
-        */
-       public static final String TYPES_NAMESPACE_URI = PackageNamespaces.CONTENT_TYPES;
-
-       /* Xml elements in content type part */
-
-       private static final String TYPES_TAG_NAME = "Types";
-
-       private static final String DEFAULT_TAG_NAME = "Default";
-
-       private static final String EXTENSION_ATTRIBUTE_NAME = "Extension";
-
-       private static final String CONTENT_TYPE_ATTRIBUTE_NAME = "ContentType";
-
-       private static final String OVERRIDE_TAG_NAME = "Override";
-
-       private static final String PART_NAME_ATTRIBUTE_NAME = "PartName";
-
-       /**
-        * Reference to the package using this content type manager.
-        */
-       protected OPCPackage container;
-
-       /**
-        * Default content type tree. <Extension, ContentType>
-        */
-       private TreeMap<String, String> defaultContentType;
-
-       /**
-        * Override content type tree.
-        */
-       private TreeMap<PackagePartName, String> overrideContentType;
-
-       /**
-        * Constructor. Parses the content of the specified input stream.
-        *
-        * @param in
-        *            If different of <i>null</i> then the content types part is
-        *            retrieve and parse.
-        * @throws InvalidFormatException
-        *             If the content types part content is not valid.
-        */
-       public ContentTypeManager(InputStream in, OPCPackage pkg)
-                       throws InvalidFormatException {
-               this.container = pkg;
-               this.defaultContentType = new TreeMap<>();
-               if (in != null) {
-                       try {
-                               parseContentTypesFile(in);
-                       } catch (InvalidFormatException e) {
-                           InvalidFormatException ex = new InvalidFormatException("Can't read content types part !");
+    /**
+     * Content type part name.
+     */
+    public static final String CONTENT_TYPES_PART_NAME = "[Content_Types].xml";
+
+    /**
+     * Content type namespace
+     */
+    public static final String TYPES_NAMESPACE_URI = PackageNamespaces.CONTENT_TYPES;
+
+    /* Xml elements in content type part */
+
+    private static final String TYPES_TAG_NAME = "Types";
+
+    private static final String DEFAULT_TAG_NAME = "Default";
+
+    private static final String EXTENSION_ATTRIBUTE_NAME = "Extension";
+
+    private static final String CONTENT_TYPE_ATTRIBUTE_NAME = "ContentType";
+
+    private static final String OVERRIDE_TAG_NAME = "Override";
+
+    private static final String PART_NAME_ATTRIBUTE_NAME = "PartName";
+
+    /**
+     * Reference to the package using this content type manager.
+     */
+    protected OPCPackage container;
+
+    /**
+     * Default content type tree. <Extension, ContentType>
+     */
+    private TreeMap<String, String> defaultContentType;
+
+    /**
+     * Override content type tree.
+     */
+    private TreeMap<PackagePartName, String> overrideContentType;
+
+    /**
+     * Constructor. Parses the content of the specified input stream.
+     *
+     * @param in
+     *            If different of <i>null</i> then the content types part is
+     *            retrieve and parse.
+     * @throws InvalidFormatException
+     *             If the content types part content is not valid.
+     */
+    public ContentTypeManager(InputStream in, OPCPackage pkg)
+            throws InvalidFormatException {
+        this.container = pkg;
+        this.defaultContentType = new TreeMap<>();
+        if (in != null) {
+            try {
+                parseContentTypesFile(in);
+            } catch (InvalidFormatException e) {
+                InvalidFormatException ex = new InvalidFormatException("Can't read content types part !");
 
                 // here it is useful to add the cause to not loose the original stack-trace
                 ex.initCause(e);
-                       
+
                 throw ex;
-                       }
-               }
-       }
-
-       /**
-        * Build association extention-> content type (will be stored in
-        * [Content_Types].xml) for example ContentType="image/png" Extension="png"
-        * <p>
-        * [M2.8]: When adding a new part to a package, the package implementer
-        * shall ensure that a content type for that part is specified in the
-        * Content Types stream; the package implementer shall perform the steps
-        * described in &#167;9.1.2.3:
-        * </p><p>
-        * 1. Get the extension from the part name by taking the substring to the
-        * right of the rightmost occurrence of the dot character (.) from the
-        * rightmost segment.
-        * </p><p>
-        * 2. If a part name has no extension, a corresponding Override element
-        * shall be added to the Content Types stream.
-        * </p><p>
-        * 3. Compare the resulting extension with the values specified for the
-        * Extension attributes of the Default elements in the Content Types stream.
-        * The comparison shall be case-insensitive ASCII.
-        * </p><p>
-        * 4. If there is a Default element with a matching Extension attribute,
-        * then the content type of the new part shall be compared with the value of
-        * the ContentType attribute. The comparison might be case-sensitive and
-        * include every character regardless of the role it plays in the
-        * content-type grammar of RFC 2616, or it might follow the grammar of RFC
-        * 2616.
-        * </p><p>
-        * a. If the content types match, no further action is required.
-        * </p><p>
-        * b. If the content types do not match, a new Override element shall be
-        * added to the Content Types stream. .
-        * </p><p>
-        * 5. If there is no Default element with a matching Extension attribute, a
-        * new Default element or Override element shall be added to the Content
-        * Types stream.
-        * </p>
-        */
-       public void addContentType(PackagePartName partName, String contentType) {
-               boolean defaultCTExists = this.defaultContentType.containsValue(contentType);
-               String extension = partName.getExtension().toLowerCase(Locale.ROOT);
-               if ((extension.length() == 0)
-                               || (this.defaultContentType.containsKey(extension) && !defaultCTExists))
-                       this.addOverrideContentType(partName, contentType);
-               else if (!defaultCTExists)
-                       this.addDefaultContentType(extension, contentType);
-       }
-
-       /**
-        * Add an override content type for a specific part.
-        *
-        * @param partName
-        *            Name of the part.
-        * @param contentType
-        *            Content type of the part.
-        */
-       private void addOverrideContentType(PackagePartName partName,
-                       String contentType) {
-               if (overrideContentType == null)
-                       overrideContentType = new TreeMap<>();
-               overrideContentType.put(partName, contentType);
-       }
-
-       /**
-        * Add a content type associated with the specified extension.
-        *
-        * @param extension
-        *            The part name extension to bind to a content type.
-        * @param contentType
-        *            The content type associated with the specified extension.
-        */
-       private void addDefaultContentType(String extension, String contentType) {
-               // Remark : Originally the latest parameter was :
-               // contentType.toLowerCase(). Change due to a request ID 1996748.
-               defaultContentType.put(extension.toLowerCase(Locale.ROOT), contentType);
-       }
-
-       /**
+            }
+        }
+    }
+
+    /**
+     * Build association extention-> content type (will be stored in
+     * [Content_Types].xml) for example ContentType="image/png" Extension="png"
+     * <p>
+     * [M2.8]: When adding a new part to a package, the package implementer
+     * shall ensure that a content type for that part is specified in the
+     * Content Types stream; the package implementer shall perform the steps
+     * described in &#167;9.1.2.3:
+     * </p><p>
+     * 1. Get the extension from the part name by taking the substring to the
+     * right of the rightmost occurrence of the dot character (.) from the
+     * rightmost segment.
+     * </p><p>
+     * 2. If a part name has no extension, a corresponding Override element
+     * shall be added to the Content Types stream.
+     * </p><p>
+     * 3. Compare the resulting extension with the values specified for the
+     * Extension attributes of the Default elements in the Content Types stream.
+     * The comparison shall be case-insensitive ASCII.
+     * </p><p>
+     * 4. If there is a Default element with a matching Extension attribute,
+     * then the content type of the new part shall be compared with the value of
+     * the ContentType attribute. The comparison might be case-sensitive and
+     * include every character regardless of the role it plays in the
+     * content-type grammar of RFC 2616, or it might follow the grammar of RFC
+     * 2616.
+     * </p><p>
+     * a. If the content types match, no further action is required.
+     * </p><p>
+     * b. If the content types do not match, a new Override element shall be
+     * added to the Content Types stream. .
+     * </p><p>
+     * 5. If there is no Default element with a matching Extension attribute, a
+     * new Default element or Override element shall be added to the Content
+     * Types stream.
+     * </p>
+     */
+    public void addContentType(PackagePartName partName, String contentType) {
+        boolean defaultCTExists = this.defaultContentType.containsValue(contentType);
+        String extension = partName.getExtension().toLowerCase(Locale.ROOT);
+        if ((extension.length() == 0)
+                || (this.defaultContentType.containsKey(extension) && !defaultCTExists))
+            this.addOverrideContentType(partName, contentType);
+        else if (!defaultCTExists)
+            this.addDefaultContentType(extension, contentType);
+    }
+
+    /**
+     * Add an override content type for a specific part.
+     *
+     * @param partName
+     *            Name of the part.
+     * @param contentType
+     *            Content type of the part.
+     */
+    private void addOverrideContentType(PackagePartName partName,
+            String contentType) {
+        if (overrideContentType == null)
+            overrideContentType = new TreeMap<>();
+        overrideContentType.put(partName, contentType);
+    }
+
+    /**
+     * Add a content type associated with the specified extension.
+     *
+     * @param extension
+     *            The part name extension to bind to a content type.
+     * @param contentType
+     *            The content type associated with the specified extension.
+     */
+    private void addDefaultContentType(String extension, String contentType) {
+        // Remark : Originally the latest parameter was :
+        // contentType.toLowerCase(). Change due to a request ID 1996748.
+        defaultContentType.put(extension.toLowerCase(Locale.ROOT), contentType);
+    }
+
+    /**
+     * <p>
+     * Delete a content type based on the specified part name. If the specified
+     * part name is register with an override content type, then this content
+     * type is remove, else the content type is remove in the default content
+     * type list if it exists and if no part is associated with it yet.
+     * </p><p>
+     * Check rule M2.4: The package implementer shall require that the Content
+     * Types stream contain one of the following for every part in the package:
+     * One matching Default element One matching Override element Both a
+     * matching Default element and a matching Override element, in which case
+     * the Override element takes precedence.
+     * </p>
+     * @param partName
+     *            The part URI associated with the override content type to
+     *            delete.
+     * @exception InvalidOperationException
+     *                Throws if
+     */
+    public void removeContentType(PackagePartName partName)
+            throws InvalidOperationException {
+        if (partName == null)
+            throw new IllegalArgumentException("partName");
+
+        /* Override content type */
+        if (this.overrideContentType != null
+                && (this.overrideContentType.get(partName) != null)) {
+            // Remove the override definition for the specified part.
+            this.overrideContentType.remove(partName);
+            return;
+        }
+
+        /* Default content type */
+        String extensionToDelete = partName.getExtension();
+        boolean deleteDefaultContentTypeFlag = true;
+        if (this.container != null) {
+            try {
+                for (PackagePart part : this.container.getParts()) {
+                    if (!part.getPartName().equals(partName)
+                            && part.getPartName().getExtension()
+                                    .equalsIgnoreCase(extensionToDelete)) {
+                        deleteDefaultContentTypeFlag = false;
+                        break;
+                    }
+                }
+            } catch (InvalidFormatException e) {
+                throw new InvalidOperationException(e.getMessage());
+            }
+        }
+
+        // Remove the default content type, no other part use this content type.
+        if (deleteDefaultContentTypeFlag) {
+            this.defaultContentType.remove(extensionToDelete);
+        }
+
+        /*
+         * Check rule 2.4: The package implementer shall require that the
+         * Content Types stream contain one of the following for every part in
+         * the package: One matching Default element One matching Override
+         * element Both a matching Default element and a matching Override
+         * element, in which case the Override element takes precedence.
+         */
+        if (this.container != null) {
+            try {
+                for (PackagePart part : this.container.getParts()) {
+                    if (!part.getPartName().equals(partName)
+                            && this.getContentType(part.getPartName()) == null)
+                        throw new InvalidOperationException(
+                                "Rule M2.4 is not respected: Nor a default element or override element is associated with the part: "
+                                        + part.getPartName().getName());
+                }
+            } catch (InvalidFormatException e) {
+                throw new InvalidOperationException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Check if the specified content type is already register.
+     *
+     * @param contentType
+     *            The content type to check.
+     * @return <code>true</code> if the specified content type is already
+     *         register, then <code>false</code>.
+     */
+    public boolean isContentTypeRegister(String contentType) {
+        if (contentType == null)
+            throw new IllegalArgumentException("contentType");
+
+        return (this.defaultContentType.values().contains(contentType) || (this.overrideContentType != null && this.overrideContentType
+                .values().contains(contentType)));
+    }
+
+    /**
+     * Get the content type for the specified part, if any.
      * <p>
-        * Delete a content type based on the specified part name. If the specified
-        * part name is register with an override content type, then this content
-        * type is remove, else the content type is remove in the default content
-        * type list if it exists and if no part is associated with it yet.
-        * </p><p>
-        * Check rule M2.4: The package implementer shall require that the Content
-        * Types stream contain one of the following for every part in the package:
-        * One matching Default element One matching Override element Both a
-        * matching Default element and a matching Override element, in which case
-        * the Override element takes precedence.
-        * </p>
-        * @param partName
-        *            The part URI associated with the override content type to
-        *            delete.
-        * @exception InvalidOperationException
-        *                Throws if
-        */
-       public void removeContentType(PackagePartName partName)
-                       throws InvalidOperationException {
-               if (partName == null)
-                       throw new IllegalArgumentException("partName");
-
-               /* Override content type */
-               if (this.overrideContentType != null
-                               && (this.overrideContentType.get(partName) != null)) {
-                       // Remove the override definition for the specified part.
-                       this.overrideContentType.remove(partName);
-                       return;
-               }
-
-               /* Default content type */
-               String extensionToDelete = partName.getExtension();
-               boolean deleteDefaultContentTypeFlag = true;
-               if (this.container != null) {
-                       try {
-                               for (PackagePart part : this.container.getParts()) {
-                                       if (!part.getPartName().equals(partName)
-                                                       && part.getPartName().getExtension()
-                                                                       .equalsIgnoreCase(extensionToDelete)) {
-                                               deleteDefaultContentTypeFlag = false;
-                                               break;
-                                       }
-                               }
-                       } catch (InvalidFormatException e) {
-                               throw new InvalidOperationException(e.getMessage());
-                       }
-               }
-
-               // Remove the default content type, no other part use this content type.
-               if (deleteDefaultContentTypeFlag) {
-                       this.defaultContentType.remove(extensionToDelete);
-               }
-
-               /*
-                * Check rule 2.4: The package implementer shall require that the
-                * Content Types stream contain one of the following for every part in
-                * the package: One matching Default element One matching Override
-                * element Both a matching Default element and a matching Override
-                * element, in which case the Override element takes precedence.
-                */
-               if (this.container != null) {
-                       try {
-                               for (PackagePart part : this.container.getParts()) {
-                                       if (!part.getPartName().equals(partName)
-                                                       && this.getContentType(part.getPartName()) == null)
-                                               throw new InvalidOperationException(
-                                                               "Rule M2.4 is not respected: Nor a default element or override element is associated with the part: "
-                                                                               + part.getPartName().getName());
-                               }
-                       } catch (InvalidFormatException e) {
-                               throw new InvalidOperationException(e.getMessage());
-                       }
-               }
-       }
-
-       /**
-        * Check if the specified content type is already register.
-        *
-        * @param contentType
-        *            The content type to check.
-        * @return <code>true</code> if the specified content type is already
-        *         register, then <code>false</code>.
-        */
-       public boolean isContentTypeRegister(String contentType) {
-               if (contentType == null)
-                       throw new IllegalArgumentException("contentType");
-
-               return (this.defaultContentType.values().contains(contentType) || (this.overrideContentType != null && this.overrideContentType
-                               .values().contains(contentType)));
-       }
-
-       /**
-        * Get the content type for the specified part, if any.
-        * <p>
-        * Rule [M2.9]: To get the content type of a part, the package implementer
-        * shall perform the steps described in &#167;9.1.2.4:
-        * </p><p>
-        * 1. Compare the part name with the values specified for the PartName
-        * attribute of the Override elements. The comparison shall be
-        * case-insensitive ASCII.
-        * </p><p>
-        * 2. If there is an Override element with a matching PartName attribute,
-        * return the value of its ContentType attribute. No further action is
-        * required.
-        * </p><p>
-        * 3. If there is no Override element with a matching PartName attribute,
-        * then a. Get the extension from the part name by taking the substring to
-        * the right of the rightmost occurrence of the dot character (.) from the
-        * rightmost segment. b. Check the Default elements of the Content Types
-        * stream, comparing the extension with the value of the Extension
-        * attribute. The comparison shall be case-insensitive ASCII.
-        * </p><p>
-        * 4. If there is a Default element with a matching Extension attribute,
-        * return the value of its ContentType attribute. No further action is
-        * required.
-        * </p><p>
-        * 5. If neither Override nor Default elements with matching attributes are
-        * found for the specified part name, the implementation shall not map this
-        * part name to a part.
-        * </p>
-        * @param partName
-        *            The URI part to check.
-        * @return The content type associated with the URI (in case of an override
-        *         content type) or the extension (in case of default content type),
-        *         else <code>null</code>.
-        *
-        * @exception OpenXML4JRuntimeException
-        *                Throws if the content type manager is not able to find the
-        *                content from an existing part.
-        */
-       public String getContentType(PackagePartName partName) {
-               if (partName == null)
-                       throw new IllegalArgumentException("partName");
-
-               if ((this.overrideContentType != null)
-                               && this.overrideContentType.containsKey(partName))
-                       return this.overrideContentType.get(partName);
-
-               String extension = partName.getExtension().toLowerCase(Locale.ROOT);
-               if (this.defaultContentType.containsKey(extension))
-                       return this.defaultContentType.get(extension);
-
-               /*
-                * [M2.4] : The package implementer shall require that the Content Types
-                * stream contain one of the following for every part in the package:
-                * One matching Default element, One matching Override element, Both a
-                * matching Default element and a matching Override element, in which
-                * case the Override element takes precedence.
-                */
-               if (this.container != null && this.container.getPart(partName) != null) {
-                       throw new OpenXML4JRuntimeException(
-                                       "Rule M2.4 exception : this error should NEVER happen! If you can provide the triggering file, then please raise a bug at https://bz.apache.org/bugzilla/enter_bug.cgi?product=POI and attach the file that triggers it, thanks!");
-               }
-               return null;
-       }
-
-       /**
-        * Clear all content types.
-        */
-       public void clearAll() {
-               this.defaultContentType.clear();
-               if (this.overrideContentType != null)
-                       this.overrideContentType.clear();
-       }
-
-       /**
-        * Clear all override content types.
-        *
-        */
-       public void clearOverrideContentTypes() {
-               if (this.overrideContentType != null)
-                       this.overrideContentType.clear();
-       }
-
-       /**
-        * Parse the content types part.
-        *
-        * @throws InvalidFormatException
-        *             Throws if the content type doesn't exist or the XML format is
-        *             invalid.
-        */
-       private void parseContentTypesFile(InputStream in)
-                       throws InvalidFormatException {
-               try {
-                       Document xmlContentTypetDoc = DocumentHelper.readDocument(in);
-
-                       // Default content types
-                       NodeList defaultTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagNameNS(TYPES_NAMESPACE_URI, DEFAULT_TAG_NAME);
-                       int defaultTypeCount = defaultTypes.getLength();
-                       for (int i = 0; i < defaultTypeCount; i++) {
+     * Rule [M2.9]: To get the content type of a part, the package implementer
+     * shall perform the steps described in &#167;9.1.2.4:
+     * </p><p>
+     * 1. Compare the part name with the values specified for the PartName
+     * attribute of the Override elements. The comparison shall be
+     * case-insensitive ASCII.
+     * </p><p>
+     * 2. If there is an Override element with a matching PartName attribute,
+     * return the value of its ContentType attribute. No further action is
+     * required.
+     * </p><p>
+     * 3. If there is no Override element with a matching PartName attribute,
+     * then a. Get the extension from the part name by taking the substring to
+     * the right of the rightmost occurrence of the dot character (.) from the
+     * rightmost segment. b. Check the Default elements of the Content Types
+     * stream, comparing the extension with the value of the Extension
+     * attribute. The comparison shall be case-insensitive ASCII.
+     * </p><p>
+     * 4. If there is a Default element with a matching Extension attribute,
+     * return the value of its ContentType attribute. No further action is
+     * required.
+     * </p><p>
+     * 5. If neither Override nor Default elements with matching attributes are
+     * found for the specified part name, the implementation shall not map this
+     * part name to a part.
+     * </p>
+     * @param partName
+     *            The URI part to check.
+     * @return The content type associated with the URI (in case of an override
+     *         content type) or the extension (in case of default content type),
+     *         else <code>null</code>.
+     *
+     * @exception OpenXML4JRuntimeException
+     *                Throws if the content type manager is not able to find the
+     *                content from an existing part.
+     */
+    public String getContentType(PackagePartName partName) {
+        if (partName == null)
+            throw new IllegalArgumentException("partName");
+
+        if ((this.overrideContentType != null)
+                && this.overrideContentType.containsKey(partName))
+            return this.overrideContentType.get(partName);
+
+        String extension = partName.getExtension().toLowerCase(Locale.ROOT);
+        if (this.defaultContentType.containsKey(extension))
+            return this.defaultContentType.get(extension);
+
+        /*
+         * [M2.4] : The package implementer shall require that the Content Types
+         * stream contain one of the following for every part in the package:
+         * One matching Default element, One matching Override element, Both a
+         * matching Default element and a matching Override element, in which
+         * case the Override element takes precedence.
+         */
+        if (this.container != null && this.container.getPart(partName) != null) {
+            throw new OpenXML4JRuntimeException(
+                    "Rule M2.4 exception : Part \'" + partName +
+                            "\' not found - this error should NEVER happen! If you can provide the triggering file, then please raise a bug at https://bz.apache.org/bugzilla/enter_bug.cgi?product=POI and attach the file that triggers it, thanks!");
+        }
+        return null;
+    }
+
+    /**
+     * Clear all content types.
+     */
+    public void clearAll() {
+        this.defaultContentType.clear();
+        if (this.overrideContentType != null)
+            this.overrideContentType.clear();
+    }
+
+    /**
+     * Clear all override content types.
+     *
+     */
+    public void clearOverrideContentTypes() {
+        if (this.overrideContentType != null)
+            this.overrideContentType.clear();
+    }
+
+    /**
+     * Parse the content types part.
+     *
+     * @throws InvalidFormatException
+     *             Throws if the content type doesn't exist or the XML format is
+     *             invalid.
+     */
+    private void parseContentTypesFile(InputStream in)
+            throws InvalidFormatException {
+        try {
+            Document xmlContentTypetDoc = DocumentHelper.readDocument(in);
+
+            // Default content types
+            NodeList defaultTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagNameNS(TYPES_NAMESPACE_URI, DEFAULT_TAG_NAME);
+            int defaultTypeCount = defaultTypes.getLength();
+            for (int i = 0; i < defaultTypeCount; i++) {
                 Element element = (Element) defaultTypes.item(i);
-                               String extension = element.getAttribute(EXTENSION_ATTRIBUTE_NAME);
-                               String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME);
-                               addDefaultContentType(extension, contentType);
-                       }
+                String extension = element.getAttribute(EXTENSION_ATTRIBUTE_NAME);
+                String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME);
+                addDefaultContentType(extension, contentType);
+            }
 
-                       // Overriden content types
+            // Overriden content types
             NodeList overrideTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagNameNS(TYPES_NAMESPACE_URI, OVERRIDE_TAG_NAME);
             int overrideTypeCount = overrideTypes.getLength();
             for (int i = 0; i < overrideTypeCount; i++) {
-                               Element element = (Element) overrideTypes.item(i);
-                               URI uri = new URI(element.getAttribute(PART_NAME_ATTRIBUTE_NAME));
-                               PackagePartName partName = PackagingURIHelper.createPartName(uri);
-                               String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME);
-                               addOverrideContentType(partName, contentType);
-                       }
-               } catch (URISyntaxException | IOException | SAXException e) {
-                       throw new InvalidFormatException(e.getMessage());
+                Element element = (Element) overrideTypes.item(i);
+                URI uri = new URI(element.getAttribute(PART_NAME_ATTRIBUTE_NAME));
+                PackagePartName partName = PackagingURIHelper.createPartName(uri);
+                String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME);
+                addOverrideContentType(partName, contentType);
+            }
+        } catch (URISyntaxException | IOException | SAXException e) {
+            throw new InvalidFormatException(e.getMessage());
         }
-       }
-
-       /**
-        * Save the contents type part.
-        *
-        * @param outStream
-        *            The output stream use to save the XML content of the content
-        *            types part.
-        * @return <b>true</b> if the operation success, else <b>false</b>.
-        */
-       public boolean save(OutputStream outStream) {
-               Document xmlOutDoc = DocumentHelper.createDocument();
-
-               // Building namespace
-               Element typesElem = xmlOutDoc.createElementNS(TYPES_NAMESPACE_URI, TYPES_TAG_NAME);
+    }
+
+    /**
+     * Save the contents type part.
+     *
+     * @param outStream
+     *            The output stream use to save the XML content of the content
+     *            types part.
+     * @return <b>true</b> if the operation success, else <b>false</b>.
+     */
+    public boolean save(OutputStream outStream) {
+        Document xmlOutDoc = DocumentHelper.createDocument();
+
+        // Building namespace
+        Element typesElem = xmlOutDoc.createElementNS(TYPES_NAMESPACE_URI, TYPES_TAG_NAME);
         xmlOutDoc.appendChild(typesElem);
 
-               // Adding default types
-               for (Entry<String, String> entry : defaultContentType.entrySet()) {
-                       appendDefaultType(typesElem, entry);
-               }
-
-               // Adding specific types if any exist
-               if (overrideContentType != null) {
-                       for (Entry<PackagePartName, String> entry : overrideContentType
-                                       .entrySet()) {
-                               appendSpecificTypes(typesElem, entry);
-                       }
-               }
-               xmlOutDoc.normalize();
-
-               // Save content in the specified output stream
-               return this.saveImpl(xmlOutDoc, outStream);
-       }
-
-       /**
-        * Use to append specific type XML elements, use by the save() method.
-        *
-        * @param root
-        *            XML parent element use to append this override type element.
-        * @param entry
-        *            The values to append.
-        * @see #save(java.io.OutputStream)
-        */
-       private void appendSpecificTypes(Element root,
-                       Entry<PackagePartName, String> entry) {
+        // Adding default types
+        for (Entry<String, String> entry : defaultContentType.entrySet()) {
+            appendDefaultType(typesElem, entry);
+        }
+
+        // Adding specific types if any exist
+        if (overrideContentType != null) {
+            for (Entry<PackagePartName, String> entry : overrideContentType
+                    .entrySet()) {
+                appendSpecificTypes(typesElem, entry);
+            }
+        }
+        xmlOutDoc.normalize();
+
+        // Save content in the specified output stream
+        return this.saveImpl(xmlOutDoc, outStream);
+    }
+
+    /**
+     * Use to append specific type XML elements, use by the save() method.
+     *
+     * @param root
+     *            XML parent element use to append this override type element.
+     * @param entry
+     *            The values to append.
+     * @see #save(java.io.OutputStream)
+     */
+    private void appendSpecificTypes(Element root,
+            Entry<PackagePartName, String> entry) {
         Element specificType = root.getOwnerDocument().createElementNS(TYPES_NAMESPACE_URI, OVERRIDE_TAG_NAME);
         specificType.setAttribute(PART_NAME_ATTRIBUTE_NAME, entry.getKey().getName());
         specificType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue());
         root.appendChild(specificType);
-       }
-
-       /**
-        * Use to append default types XML elements, use by the save() method.
-        *
-        * @param root
-        *            XML parent element use to append this default type element.
-        * @param entry
-        *            The values to append.
-        * @see #save(java.io.OutputStream)
-        */
-       private void appendDefaultType(Element root, Entry<String, String> entry) {
+    }
+
+    /**
+     * Use to append default types XML elements, use by the save() method.
+     *
+     * @param root
+     *            XML parent element use to append this default type element.
+     * @param entry
+     *            The values to append.
+     * @see #save(java.io.OutputStream)
+     */
+    private void appendDefaultType(Element root, Entry<String, String> entry) {
         Element defaultType = root.getOwnerDocument().createElementNS(TYPES_NAMESPACE_URI, DEFAULT_TAG_NAME);
         defaultType.setAttribute(EXTENSION_ATTRIBUTE_NAME, entry.getKey());
         defaultType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue());
         root.appendChild(defaultType);
-       }
-
-       /**
-        * Specific implementation of the save method. Call by the save() method,
-        * call before exiting.
-        *
-        * @param out
-        *            The output stream use to write the content type XML.
-        */
-       public abstract boolean saveImpl(Document content, OutputStream out);
+    }
+
+    /**
+     * Specific implementation of the save method. Call by the save() method,
+     * call before exiting.
+     *
+     * @param out
+     *            The output stream use to write the content type XML.
+     */
+    public abstract boolean saveImpl(Document content, OutputStream out);
 }