123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
- package org.apache.poi.ooxml;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Iterator;
-
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
- import org.apache.poi.openxml4j.opc.PackagePart;
- import org.apache.poi.openxml4j.opc.PackagePartName;
- import org.apache.poi.openxml4j.opc.PackageRelationship;
- import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
- import org.apache.poi.openxml4j.opc.PackagingURIHelper;
- import org.apache.poi.util.Internal;
- import org.apache.xmlbeans.XmlException;
-
- /**
- * Represents a descriptor of a OOXML relation.
- */
- public abstract class POIXMLRelation {
-
- @Internal
- public interface NoArgConstructor {
- POIXMLDocumentPart init();
- }
-
- @Internal
- public interface PackagePartConstructor {
- POIXMLDocumentPart init(PackagePart part) throws IOException, XmlException;
- }
-
- @Internal
- public interface ParentPartConstructor {
- POIXMLDocumentPart init(POIXMLDocumentPart parent, PackagePart part) throws IOException, XmlException;
- }
-
- private static final Logger LOGGER = LogManager.getLogger(POIXMLRelation.class);
-
- /**
- * Describes the content stored in a part.
- */
- private final String _type;
-
- /**
- * The kind of connection between a source part and a target part in a package.
- */
- private final String _relation;
-
- /**
- * The path component of a pack URI.
- */
- private final String _defaultName;
-
- /**
- * Constructors or factory method to construct instances of this relationship
- */
- private final NoArgConstructor noArgConstructor;
- private final PackagePartConstructor packagePartConstructor;
- private final ParentPartConstructor parentPartConstructor;
-
- /**
- * Instantiates a POIXMLRelation.
- *
- * @param type content type
- * @param rel relationship
- * @param defaultName default item name
- * @param noArgConstructor method used to construct instances of this relationship from scratch
- * @param packagePartConstructor method used to construct instances of this relationship with a package part
- */
- protected POIXMLRelation(String type, String rel, String defaultName,
- NoArgConstructor noArgConstructor,
- PackagePartConstructor packagePartConstructor,
- ParentPartConstructor parentPartConstructor) {
- _type = type;
- _relation = rel;
- _defaultName = defaultName;
- this.noArgConstructor = noArgConstructor;
- this.packagePartConstructor = packagePartConstructor;
- this.parentPartConstructor = parentPartConstructor;
- }
-
- /**
- * Instantiates a POIXMLRelation.
- *
- * @param type content type
- * @param rel relationship
- * @param defaultName default item name
- */
- protected POIXMLRelation(String type, String rel, String defaultName) {
- this(type, rel, defaultName, null, null, null);
- }
- /**
- * Return the content type. Content types define a media type, a subtype, and an
- * optional set of parameters, as defined in RFC 2616.
- *
- * @return the content type
- */
- public String getContentType() {
- return _type;
- }
-
- /**
- * Return the relationship, the kind of connection between a source part and a target part in a package.
- * Relationships make the connections between parts directly discoverable without looking at the content
- * in the parts, and without altering the parts themselves.
- *
- * @return the relationship
- */
- public String getRelation() {
- return _relation;
- }
-
- /**
- * Return the default part name. Part names are used to refer to a part in the context of a
- * package, typically as part of a URI.
- *
- * @return the default part name
- */
- public String getDefaultFileName() {
- return _defaultName;
- }
-
- /**
- * Returns the filename for the nth one of these, e.g. /xl/comments4.xml
- *
- * @param index the suffix for the document type
- * @return the filename including the suffix
- */
- public String getFileName(int index) {
- if(! _defaultName.contains("#")) {
- // Generic filename in all cases
- return getDefaultFileName();
- }
- return _defaultName.replace("#", Integer.toString(index));
- }
-
- /**
- * Returns the index of the filename within the package for the given part.
- * e.g. 4 for /xl/comments4.xml
- *
- * @param part the part to read the suffix from
- * @return the suffix
- */
- public Integer getFileNameIndex(POIXMLDocumentPart part) {
- String regex = _defaultName.replace("#", "(\\d+)");
- return Integer.valueOf(part.getPackagePart().getPartName().getName().replaceAll(regex, "$1"));
- }
-
- /**
- * @return the constructor method used to construct instances of this relationship from scratch
- *
- * @since 4.1.2
- */
- public NoArgConstructor getNoArgConstructor() {
- return noArgConstructor;
- }
-
- /**
- * @return the constructor method used to construct instances of this relationship with a package part
- *
- * @since 4.1.2
- */
- public PackagePartConstructor getPackagePartConstructor() {
- return packagePartConstructor;
- }
-
- /**
- * @return the constructor method used to construct instances of this relationship with a package part
- *
- * @since 4.1.2
- */
- public ParentPartConstructor getParentPartConstructor() {
- return parentPartConstructor;
- }
-
- /**
- * Fetches the InputStream to read the contents, based
- * of the specified core part, for which we are defined
- * as a suitable relationship
- *
- * @since 3.16-beta3
- */
- public InputStream getContents(PackagePart corePart) throws IOException, InvalidFormatException {
- PackageRelationshipCollection prc =
- corePart.getRelationshipsByType(getRelation());
- Iterator<PackageRelationship> it = prc.iterator();
- if(it.hasNext()) {
- PackageRelationship rel = it.next();
- PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
- PackagePart part = corePart.getPackage().getPart(relName);
- if (part == null) {
- throw new IllegalArgumentException("Could not read part " + relName + " from " + corePart);
- }
- return part.getInputStream();
- }
- LOGGER.atWarn().log("No part {} found", getDefaultFileName());
- return null;
- }
- }
|