*/
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 §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 §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 §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 §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);
}