From ad93d569daec924390fa9346a1bf74eed52f5fa8 Mon Sep 17 00:00:00 2001
From: PJ Fanning
- * [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:
- *
- * 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.
- *
- * 2. If a part name has no extension, a corresponding Override element
- * shall be added to the Content Types stream.
- *
- * 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.
- *
- * 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.
- *
- * a. If the content types match, no further action is required.
- *
- * b. If the content types do not match, a new Override element shall be
- * added to the Content Types stream. .
- *
- * 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.
- *
+ * [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:
+ *
+ * 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.
+ *
+ * 2. If a part name has no extension, a corresponding Override element
+ * shall be added to the Content Types stream.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * a. If the content types match, no further action is required.
+ *
+ * b. If the content types do not match, a new Override element shall be
+ * added to the Content Types stream. .
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
- * 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.
- *
- * 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.
- *
- * Rule [M2.9]: To get the content type of a part, the package implementer
- * shall perform the steps described in §9.1.2.4:
- *
- * 1. Compare the part name with the values specified for the PartName
- * attribute of the Override elements. The comparison shall be
- * case-insensitive ASCII.
- *
- * 2. If there is an Override element with a matching PartName attribute,
- * return the value of its ContentType attribute. No further action is
- * required.
- *
- * 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.
- *
- * 4. If there is a Default element with a matching Extension attribute,
- * return the value of its ContentType attribute. No further action is
- * required.
- *
- * 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.
- * true
if the specified content type is already
+ * register, then false
.
+ */
+ 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.
* true
if the specified content type is already
- * register, then false
.
- */
- 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.
- * null
.
- *
- * @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:
+ *
+ * 1. Compare the part name with the values specified for the PartName + * attribute of the Override elements. The comparison shall be + * case-insensitive ASCII. + *
+ * 2. If there is an Override element with a matching PartName attribute, + * return the value of its ContentType attribute. No further action is + * required. + *
+ * 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. + *
+ * 4. If there is a Default element with a matching Extension attribute, + * return the value of its ContentType attribute. No further action is + * required. + *
+ * 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. + *
+ * @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), + * elsenull
.
+ *
+ * @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 true if the operation success, else false.
- */
- 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 true if the operation success, else false.
+ */
+ 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