You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2009/01/29 13:44:35 UTC
svn commit: r738842 [3/7] - in /poi/trunk: ./ legal/ maven/
src/documentation/content/xdocs/ src/documentation/content/xdocs/oxml4j/
src/documentation/content/xdocs/spreadsheet/
src/examples/src/org/apache/poi/xssf/eventusermodel/examples/ src/ooxml/ja...
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,509 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+
+/**
+ * An immutable Open Packaging Convention compliant part name.
+ *
+ * @author Julien Chable
+ * @version 0.1
+ *
+ * @see http://www.ietf.org/rfc/rfc3986.txt
+ */
+public final class PackagePartName implements Comparable<PackagePartName> {
+
+ /**
+ * Part name stored as an URI.
+ */
+ private URI partNameURI;
+
+ /*
+ * URI Characters definition (RFC 3986)
+ */
+
+ /**
+ * Reserved characters for sub delimitations.
+ */
+ private static String[] RFC3986_PCHAR_SUB_DELIMS = { "!", "$", "&", "'",
+ "(", ")", "*", "+", ",", ";", "=" };
+
+ /**
+ * Unreserved character (+ ALPHA & DIGIT).
+ */
+ private static String[] RFC3986_PCHAR_UNRESERVED_SUP = { "-", ".", "_", "~" };
+
+ /**
+ * Authorized reserved characters for pChar.
+ */
+ private static String[] RFC3986_PCHAR_AUTHORIZED_SUP = { ":", "@" };
+
+ /**
+ * Flag to know if this part name is from a relationship part name.
+ */
+ private boolean isRelationship;
+
+ /**
+ * Constructor. Makes a ValidPartName object from a java.net.URI
+ *
+ * @param uri
+ * The URI to validate and to transform into ValidPartName.
+ * @param checkConformance
+ * Flag to specify if the contructor have to validate the OPC
+ * conformance. Must be always <code>true</code> except for
+ * special URI like '/' which is needed for internal use by
+ * OpenXML4J but is not valid.
+ * @throws InvalidFormatException
+ * Throw if the specified part name is not conform to Open
+ * Packaging Convention specifications.
+ * @see java.net.URI
+ */
+ PackagePartName(URI uri, boolean checkConformance)
+ throws InvalidFormatException {
+ if (checkConformance) {
+ throwExceptionIfInvalidPartUri(uri);
+ } else {
+ if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(uri)) {
+ throw new OpenXML4JRuntimeException(
+ "OCP conformance must be check for ALL part name except special cases : ['/']");
+ }
+ }
+ this.partNameURI = uri;
+ this.isRelationship = isRelationshipPartURI(this.partNameURI);
+ }
+
+ /**
+ * Constructor. Makes a ValidPartName object from a String part name.
+ *
+ * @param partName
+ * Part name to valid and to create.
+ * @param checkConformance
+ * Flag to specify if the contructor have to validate the OPC
+ * conformance. Must be always <code>true</code> except for
+ * special URI like '/' which is needed for internal use by
+ * OpenXML4J but is not valid.
+ * @throws InvalidFormatException
+ * Throw if the specified part name is not conform to Open
+ * Packaging Convention specifications.
+ */
+ PackagePartName(String partName, boolean checkConformance)
+ throws InvalidFormatException {
+ URI partURI;
+ try {
+ partURI = new URI(partName);
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(
+ "partName argmument is not a valid OPC part name !");
+ }
+
+ if (checkConformance) {
+ throwExceptionIfInvalidPartUri(partURI);
+ } else {
+ if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(partURI)) {
+ throw new OpenXML4JRuntimeException(
+ "OCP conformance must be check for ALL part name except special cases : ['/']");
+ }
+ }
+ this.partNameURI = partURI;
+ this.isRelationship = isRelationshipPartURI(this.partNameURI);
+ }
+
+ /**
+ * Check if the specified part name is a relationship part name.
+ *
+ * @param partUri
+ * The URI to check.
+ * @return <code>true</code> if this part name respect the relationship
+ * part naming convention else <code>false</code>.
+ */
+ private boolean isRelationshipPartURI(URI partUri) {
+ if (partUri == null)
+ throw new IllegalArgumentException("partUri");
+
+ return partUri.getPath().matches(
+ "^.*/" + PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME + "/.*\\"
+ + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME
+ + "$");
+ }
+
+ /**
+ * Know if this part name is a relationship part name.
+ *
+ * @return <code>true</code> if this part name respect the relationship
+ * part naming convention else <code>false</code>.
+ */
+ public boolean isRelationshipPartURI() {
+ return this.isRelationship;
+ }
+
+ /**
+ * Throws an exception (of any kind) if the specified part name does not
+ * follow the Open Packaging Convention specifications naming rules.
+ *
+ * @param partUri
+ * The part name to check.
+ * @throws Exception
+ * Throws if the part name is invalid.
+ */
+ private static void throwExceptionIfInvalidPartUri(URI partUri)
+ throws InvalidFormatException {
+ if (partUri == null)
+ throw new IllegalArgumentException("partUri");
+ // Check if the part name URI is empty [M1.1]
+ throwExceptionIfEmptyURI(partUri);
+
+ // Check if the part name URI is absolute
+ throwExceptionIfAbsoluteUri(partUri);
+
+ // Check if the part name URI starts with a forward slash [M1.4]
+ throwExceptionIfPartNameNotStartsWithForwardSlashChar(partUri);
+
+ // Check if the part name URI ends with a forward slash [M1.5]
+ throwExceptionIfPartNameEndsWithForwardSlashChar(partUri);
+
+ // Check if the part name does not have empty segments. [M1.3]
+ // Check if a segment ends with a dot ('.') character. [M1.9]
+ throwExceptionIfPartNameHaveInvalidSegments(partUri);
+ }
+
+ /**
+ * Throws an exception if the specified URI is empty. [M1.1]
+ *
+ * @param partURI
+ * Part URI to check.
+ * @throws InvalidFormatException
+ * If the specified URI is empty.
+ */
+ private static void throwExceptionIfEmptyURI(URI partURI)
+ throws InvalidFormatException {
+ if (partURI == null)
+ throw new IllegalArgumentException("partURI");
+
+ String uriPath = partURI.getPath();
+ if (uriPath.length() == 0
+ || ((uriPath.length() == 1) && (uriPath.charAt(0) == PackagingURIHelper.FORWARD_SLASH_CHAR)))
+ throw new InvalidFormatException(
+ "A part name shall not be empty [M1.1]: "
+ + partURI.getPath());
+ }
+
+ /**
+ * Throws an exception if the part name has empty segments. [M1.3]
+ *
+ * Throws an exception if a segment any characters other than pchar
+ * characters. [M1.6]
+ *
+ * Throws an exception if a segment contain percent-encoded forward slash
+ * ('/'), or backward slash ('\') characters. [M1.7]
+ *
+ * Throws an exception if a segment contain percent-encoded unreserved
+ * characters. [M1.8]
+ *
+ * Throws an exception if the specified part name's segments end with a dot
+ * ('.') character. [M1.9]
+ *
+ * Throws an exception if a segment doesn't include at least one non-dot
+ * character. [M1.10]
+ *
+ * @param partUri
+ * The part name to check.
+ * @throws InvalidFormatException
+ * if the specified URI contain an empty segments or if one the
+ * segments contained in the part name, ends with a dot ('.')
+ * character.
+ */
+ private static void throwExceptionIfPartNameHaveInvalidSegments(URI partUri)
+ throws InvalidFormatException {
+ if (partUri == null || "".equals(partUri)) {
+ throw new IllegalArgumentException("partUri");
+ }
+
+ // Split the URI into several part and analyze each
+ String[] segments = partUri.toASCIIString().split("/");
+ if (segments.length <= 1 || !segments[0].equals(""))
+ throw new InvalidFormatException(
+ "A part name shall not have empty segments [M1.3]: "
+ + partUri.getPath());
+
+ for (int i = 1; i < segments.length; ++i) {
+ String seg = segments[i];
+ if (seg == null || "".equals(seg)) {
+ throw new InvalidFormatException(
+ "A part name shall not have empty segments [M1.3]: "
+ + partUri.getPath());
+ }
+
+ if (seg.endsWith(".")) {
+ throw new InvalidFormatException(
+ "A segment shall not end with a dot ('.') character [M1.9]: "
+ + partUri.getPath());
+ }
+
+ if ("".equals(seg.replaceAll("\\\\.", ""))) {
+ // Normally will never been invoked with the previous
+ // implementation rule [M1.9]
+ throw new InvalidFormatException(
+ "A segment shall include at least one non-dot character. [M1.10]: "
+ + partUri.getPath());
+ }
+
+ /*
+ * Check for rule M1.6, M1.7, M1.8
+ */
+ checkPCharCompliance(seg);
+ }
+ }
+
+ /**
+ * Throws an exception if a segment any characters other than pchar
+ * characters. [M1.6]
+ *
+ * Throws an exception if a segment contain percent-encoded forward slash
+ * ('/'), or backward slash ('\') characters. [M1.7]
+ *
+ * Throws an exception if a segment contain percent-encoded unreserved
+ * characters. [M1.8]
+ *
+ * @param segment
+ * The segment to check
+ */
+ private static void checkPCharCompliance(String segment)
+ throws InvalidFormatException {
+ boolean errorFlag;
+ for (int i = 0; i < segment.length(); ++i) {
+ char c = segment.charAt(i);
+ errorFlag = true;
+
+ /* Check rule M1.6 */
+
+ // Check for digit or letter
+ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
+ || (c >= '0' && c <= '9')) {
+ errorFlag = false;
+ } else {
+ // Check "-", ".", "_", "~"
+ for (int j = 0; j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) {
+ if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) {
+ errorFlag = false;
+ break;
+ }
+ }
+
+ // Check ":", "@"
+ for (int j = 0; errorFlag
+ && j < RFC3986_PCHAR_AUTHORIZED_SUP.length; ++j) {
+ if (c == RFC3986_PCHAR_AUTHORIZED_SUP[j].charAt(0)) {
+ errorFlag = false;
+ }
+ }
+
+ // Check "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
+ for (int j = 0; errorFlag
+ && j < RFC3986_PCHAR_SUB_DELIMS.length; ++j) {
+ if (c == RFC3986_PCHAR_SUB_DELIMS[j].charAt(0)) {
+ errorFlag = false;
+ }
+ }
+ }
+
+ if (errorFlag && c == '%') {
+ // We certainly found an encoded character, check for length
+ // now ( '%' HEXDIGIT HEXDIGIT)
+ if (((segment.length() - i) < 2)) {
+ throw new InvalidFormatException("The segment " + segment
+ + " contain invalid encoded character !");
+ }
+
+ // If not percent encoded character error occur then reset the
+ // flag -> the character is valid
+ errorFlag = false;
+
+ // Decode the encoded character
+ char decodedChar = (char) Integer.parseInt(segment.substring(
+ i + 1, i + 3), 16);
+ i += 2;
+
+ /* Check rule M1.7 */
+ if (decodedChar == '/' || decodedChar == '\\')
+ throw new InvalidFormatException(
+ "A segment shall not contain percent-encoded forward slash ('/'), or backward slash ('\') characters. [M1.7]");
+
+ /* Check rule M1.8 */
+
+ // Check for unreserved character like define in RFC3986
+ if ((decodedChar >= 'A' && decodedChar <= 'Z')
+ || (decodedChar >= 'a' && decodedChar <= 'z')
+ || (decodedChar >= '0' && decodedChar <= '9'))
+ errorFlag = true;
+
+ // Check for unreserved character "-", ".", "_", "~"
+ for (int j = 0; !errorFlag
+ && j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) {
+ if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) {
+ errorFlag = true;
+ break;
+ }
+ }
+ if (errorFlag)
+ throw new InvalidFormatException(
+ "A segment shall not contain percent-encoded unreserved characters. [M1.8]");
+ }
+
+ if (errorFlag)
+ throw new InvalidFormatException(
+ "A segment shall not hold any characters other than pchar characters. [M1.6]");
+ }
+ }
+
+ /**
+ * Throws an exception if the specified part name doesn't start with a
+ * forward slash character '/'. [M1.4]
+ *
+ * @param partUri
+ * The part name to check.
+ * @throws InvalidFormatException
+ * If the specified part name doesn't start with a forward slash
+ * character '/'.
+ */
+ private static void throwExceptionIfPartNameNotStartsWithForwardSlashChar(
+ URI partUri) throws InvalidFormatException {
+ String uriPath = partUri.getPath();
+ if (uriPath.length() > 0
+ && uriPath.charAt(0) != PackagingURIHelper.FORWARD_SLASH_CHAR)
+ throw new InvalidFormatException(
+ "A part name shall start with a forward slash ('/') character [M1.4]: "
+ + partUri.getPath());
+ }
+
+ /**
+ * Throws an exception if the specified part name ends with a forwar slash
+ * character '/'. [M1.5]
+ *
+ * @param partUri
+ * The part name to check.
+ * @throws InvalidFormatException
+ * If the specified part name ends with a forwar slash character
+ * '/'.
+ */
+ private static void throwExceptionIfPartNameEndsWithForwardSlashChar(
+ URI partUri) throws InvalidFormatException {
+ String uriPath = partUri.getPath();
+ if (uriPath.length() > 0
+ && uriPath.charAt(uriPath.length() - 1) == PackagingURIHelper.FORWARD_SLASH_CHAR)
+ throw new InvalidFormatException(
+ "A part name shall not have a forward slash as the last character [M1.5]: "
+ + partUri.getPath());
+ }
+
+ /**
+ * Throws an exception if the specified URI is absolute.
+ *
+ * @param partUri
+ * The URI to check.
+ * @throws InvalidFormatException
+ * Throws if the specified URI is absolute.
+ */
+ private static void throwExceptionIfAbsoluteUri(URI partUri)
+ throws InvalidFormatException {
+ if (partUri.isAbsolute())
+ throw new InvalidFormatException("Absolute URI forbidden: "
+ + partUri);
+ }
+
+ /**
+ * Compare two part name following the rule M1.12 :
+ *
+ * Part name equivalence is determined by comparing part names as
+ * case-insensitive ASCII strings. Packages shall not contain equivalent
+ * part names and package implementers shall neither create nor recognize
+ * packages with equivalent part names. [M1.12]
+ */
+ public int compareTo(PackagePartName otherPartName) {
+ if (otherPartName == null)
+ return -1;
+ return this.partNameURI.toASCIIString().toLowerCase().compareTo(
+ otherPartName.partNameURI.toASCIIString().toLowerCase());
+ }
+
+ /**
+ * Retrieves the extension of the part name if any. If there is no extension
+ * returns an empty String. Example : '/document/content.xml' => 'xml'
+ *
+ * @return The extension of the part name.
+ */
+ public String getExtension() {
+ String fragment = this.partNameURI.getPath();
+ if (fragment.length() > 0) {
+ int i = fragment.lastIndexOf(".");
+ if (i > -1)
+ return fragment.substring(i + 1);
+ }
+ return "";
+ }
+
+ /**
+ * Get this part name.
+ *
+ * @return The name of this part name.
+ */
+ public String getName() {
+ return this.partNameURI.toASCIIString();
+ }
+
+ /**
+ * Part name equivalence is determined by comparing part names as
+ * case-insensitive ASCII strings. Packages shall not contain equivalent
+ * part names and package implementers shall neither create nor recognize
+ * packages with equivalent part names. [M1.12]
+ */
+ @Override
+ public boolean equals(Object otherPartName) {
+ if (otherPartName == null
+ || !(otherPartName instanceof PackagePartName))
+ return false;
+ return this.partNameURI.toASCIIString().toLowerCase().equals(
+ ((PackagePartName) otherPartName).partNameURI.toASCIIString()
+ .toLowerCase());
+ }
+
+ @Override
+ public int hashCode() {
+ return this.partNameURI.toASCIIString().toLowerCase().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ /* Getters and setters */
+
+ /**
+ * Part name property getter.
+ *
+ * @return This part name URI.
+ */
+ public URI getURI() {
+ return this.partNameURI;
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,227 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import java.util.Date;
+
+import org.apache.poi.openxml4j.util.Nullable;
+
+/**
+ * Represents the core properties of an OPC package.
+ *
+ * @author Julien Chable
+ * @version 1.0
+ * @see org.apache.poi.openxml4j.opc.Package
+ */
+public interface PackageProperties {
+
+ /**
+ * Dublin Core Terms URI.
+ */
+ public final static String NAMESPACE_DCTERMS = "http://purl.org/dc/terms/";
+
+ /**
+ * Dublin Core namespace URI.
+ */
+ public final static String NAMESPACE_DC = "http://purl.org/dc/elements/1.1/";
+
+ /* Getters and setters */
+
+ /**
+ * Set the category of the content of this package.
+ */
+ public abstract Nullable<String> getCategoryProperty();
+
+ /**
+ * Set the category of the content of this package.
+ */
+ public abstract void setCategoryProperty(String category);
+
+ /**
+ * Set the status of the content.
+ */
+ public abstract Nullable<String> getContentStatusProperty();
+
+ /**
+ * Get the status of the content.
+ */
+ public abstract void setContentStatusProperty(String contentStatus);
+
+ /**
+ * Get the type of content represented, generally defined by a specific use
+ * and intended audience.
+ */
+ public abstract Nullable<String> getContentTypeProperty();
+
+ /**
+ * Set the type of content represented, generally defined by a specific use
+ * and intended audience.
+ */
+ public abstract void setContentTypeProperty(String contentType);
+
+ /**
+ * Get the date of creation of the resource.
+ */
+ public abstract Nullable<Date> getCreatedProperty();
+
+ /**
+ * Set the date of creation of the resource.
+ */
+ public abstract void setCreatedProperty(String created);
+
+ /**
+ * Set the date of creation of the resource.
+ */
+ public abstract void setCreatedProperty(Nullable<Date> created);
+
+ /**
+ * Get the entity primarily responsible for making the content of the
+ * resource.
+ */
+ public abstract Nullable<String> getCreatorProperty();
+
+ /**
+ * Set the entity primarily responsible for making the content of the
+ * resource.
+ */
+ public abstract void setCreatorProperty(String creator);
+
+ /**
+ * Get the explanation of the content of the resource.
+ */
+ public abstract Nullable<String> getDescriptionProperty();
+
+ /**
+ * Set the explanation of the content of the resource.
+ */
+ public abstract void setDescriptionProperty(String description);
+
+ /**
+ * Get an unambiguous reference to the resource within a given context.
+ */
+ public abstract Nullable<String> getIdentifierProperty();
+
+ /**
+ * Set an unambiguous reference to the resource within a given context.
+ */
+ public abstract void setIdentifierProperty(String identifier);
+
+ /**
+ * Get a delimited set of keywords to support searching and indexing. This
+ * is typically a list of terms that are not available elsewhere in the
+ * properties
+ */
+ public abstract Nullable<String> getKeywordsProperty();
+
+ /**
+ * Set a delimited set of keywords to support searching and indexing. This
+ * is typically a list of terms that are not available elsewhere in the
+ * properties
+ */
+ public abstract void setKeywordsProperty(String keywords);
+
+ /**
+ * Get the language of the intellectual content of the resource.
+ */
+ public abstract Nullable<String> getLanguageProperty();
+
+ /**
+ * Set the language of the intellectual content of the resource.
+ */
+ public abstract void setLanguageProperty(String language);
+
+ /**
+ * Get the user who performed the last modification.
+ */
+ public abstract Nullable<String> getLastModifiedByProperty();
+
+ /**
+ * Set the user who performed the last modification.
+ */
+ public abstract void setLastModifiedByProperty(String lastModifiedBy);
+
+ /**
+ * Get the date and time of the last printing.
+ */
+ public abstract Nullable<Date> getLastPrintedProperty();
+
+ /**
+ * Set the date and time of the last printing.
+ */
+ public abstract void setLastPrintedProperty(String lastPrinted);
+
+ /**
+ * Set the date and time of the last printing.
+ */
+ public abstract void setLastPrintedProperty(Nullable<Date> lastPrinted);
+
+ /**
+ * Get the date on which the resource was changed.
+ */
+ public abstract Nullable<Date> getModifiedProperty();
+
+ /**
+ * Set the date on which the resource was changed.
+ */
+ public abstract void setModifiedProperty(String modified);
+
+ /**
+ * Set the date on which the resource was changed.
+ */
+ public abstract void setModifiedProperty(Nullable<Date> modified);
+
+ /**
+ * Get the revision number.
+ */
+ public abstract Nullable<String> getRevisionProperty();
+
+ /**
+ * Set the revision number.
+ */
+ public abstract void setRevisionProperty(String revision);
+
+ /**
+ * Get the topic of the content of the resource.
+ */
+ public abstract Nullable<String> getSubjectProperty();
+
+ /**
+ * Set the topic of the content of the resource.
+ */
+ public abstract void setSubjectProperty(String subject);
+
+ /**
+ * Get the name given to the resource.
+ */
+ public abstract Nullable<String> getTitleProperty();
+
+ /**
+ * Set the name given to the resource.
+ */
+ public abstract void setTitleProperty(String title);
+
+ /**
+ * Get the version number.
+ */
+ public abstract Nullable<String> getVersionProperty();
+
+ /**
+ * Set the version number.
+ */
+ public abstract void setVersionProperty(String version);
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,227 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+ * A part relationship.
+ *
+ * @author Julien Chable
+ * @version 1.0
+ */
+public final class PackageRelationship {
+
+ private static URI containerRelationshipPart;
+
+ static {
+ try {
+ containerRelationshipPart = new URI("/_rels/.rels");
+ } catch (URISyntaxException e) {
+ // Do nothing
+ }
+ }
+
+ /* XML markup */
+
+ public static final String ID_ATTRIBUTE_NAME = "Id";
+
+ public static final String RELATIONSHIPS_TAG_NAME = "Relationships";
+
+ public static final String RELATIONSHIP_TAG_NAME = "Relationship";
+
+ public static final String TARGET_ATTRIBUTE_NAME = "Target";
+
+ public static final String TARGET_MODE_ATTRIBUTE_NAME = "TargetMode";
+
+ public static final String TYPE_ATTRIBUTE_NAME = "Type";
+
+ /* End XML markup */
+
+ /**
+ * L'ID de la relation.
+ */
+ private String id;
+
+ /**
+ * R�f�rence vers le package.
+ */
+ private Package container;
+
+ /**
+ * Type de relation.
+ */
+ private String relationshipType;
+
+ /**
+ * Partie source de cette relation.
+ */
+ private PackagePart source;
+
+ /**
+ * Le mode de ciblage [Internal|External]
+ */
+ private TargetMode targetMode;
+
+ /**
+ * URI de la partie cible.
+ */
+ private URI targetUri;
+
+ /**
+ * Constructor.
+ *
+ * @param packageParent
+ * @param sourcePart
+ * @param targetUri
+ * @param targetMode
+ * @param relationshipType
+ * @param id
+ */
+ public PackageRelationship(Package pkg, PackagePart sourcePart,
+ URI targetUri, TargetMode targetMode, String relationshipType,
+ String id) {
+ if (pkg == null)
+ throw new IllegalArgumentException("pkg");
+ if (targetUri == null)
+ throw new IllegalArgumentException("targetUri");
+ if (relationshipType == null)
+ throw new IllegalArgumentException("relationshipType");
+ if (id == null)
+ throw new IllegalArgumentException("id");
+
+ this.container = pkg;
+ this.source = sourcePart;
+ this.targetUri = targetUri;
+ this.targetMode = targetMode;
+ this.relationshipType = relationshipType;
+ this.id = id;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof PackageRelationship)) {
+ return false;
+ }
+ PackageRelationship rel = (PackageRelationship) obj;
+ return (this.id == rel.id
+ && this.relationshipType == rel.relationshipType
+ && (rel.source != null ? rel.source.equals(this.source) : true)
+ && this.targetMode == rel.targetMode && this.targetUri
+ .equals(rel.targetUri));
+ }
+
+ @Override
+ public int hashCode() {
+ return this.id.hashCode() + this.relationshipType.hashCode()
+ + this.source.hashCode() + this.targetMode.hashCode()
+ + this.targetUri.hashCode();
+ }
+
+ /* Getters */
+
+ public URI getContainerPartRelationship() {
+ return containerRelationshipPart;
+ }
+
+ /**
+ * @return the container
+ */
+ public Package getPackage() {
+ return container;
+ }
+
+ /**
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @return the relationshipType
+ */
+ public String getRelationshipType() {
+ return relationshipType;
+ }
+
+ /**
+ * @return the source
+ */
+ public PackagePart getSource() {
+ return source;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public URI getSourceURI() {
+ if (source == null) {
+ return PackagingURIHelper.PACKAGE_ROOT_URI;
+ }
+ return source.partName.getURI();
+ }
+
+ /**
+ * public URI getSourceUri(){ }
+ *
+ * @return the targetMode
+ */
+ public TargetMode getTargetMode() {
+ return targetMode;
+ }
+
+ /**
+ * @return the targetUri
+ */
+ public URI getTargetURI() {
+ // If it's an external target, we don't
+ // need to apply our normal validation rules
+ if(targetMode == TargetMode.EXTERNAL) {
+ return targetUri;
+ }
+
+ // Internal target
+ // If it isn't absolute, resolve it relative
+ // to ourselves
+ if (!targetUri.toASCIIString().startsWith("/")) {
+ // So it's a relative part name, try to resolve it
+ return PackagingURIHelper.resolvePartUri(getSourceURI(), targetUri);
+ }
+ return targetUri;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(id == null ? "id=null" : "id=" + id);
+ sb.append(container == null ? " - container=null" : " - container="
+ + container.toString());
+ sb.append(relationshipType == null ? " - relationshipType=null"
+ : " - relationshipType=" + relationshipType.toString());
+ sb.append(source == null ? " - source=null" : " - source="
+ + getSourceURI().toASCIIString());
+ sb.append(targetUri == null ? " - target=null" : " - target="
+ + getTargetURI().toASCIIString());
+ sb.append(targetMode == null ? ",targetMode=null" : ",targetMode="
+ + targetMode.toString());
+ return sb.toString();
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,450 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.TreeMap;
+
+import org.apache.log4j.Logger;
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+
+/**
+ * Represents a collection of PackageRelationship elements that are owned by a
+ * given PackagePart or the Package.
+ *
+ * @author Julien Chable, CDubettier
+ * @version 0.1
+ */
+public final class PackageRelationshipCollection implements
+ Iterable<PackageRelationship> {
+
+ private static Logger logger = Logger.getLogger("org.openxml4j.opc");
+
+ /**
+ * Package relationships ordered by ID.
+ */
+ private TreeMap<String, PackageRelationship> relationshipsByID;
+
+ /**
+ * Package relationships ordered by type.
+ */
+ private TreeMap<String, PackageRelationship> relationshipsByType;
+
+ /**
+ * This relationshipPart.
+ */
+ private PackagePart relationshipPart;
+
+ /**
+ * Source part.
+ */
+ private PackagePart sourcePart;
+
+ /**
+ * This part name.
+ */
+ private PackagePartName partName;
+
+ /**
+ * Reference to the package.
+ */
+ private Package container;
+
+ /**
+ * Constructor.
+ */
+ PackageRelationshipCollection() {
+ relationshipsByID = new TreeMap<String, PackageRelationship>();
+ relationshipsByType = new TreeMap<String, PackageRelationship>();
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * This collection will contain only elements from the specified collection
+ * for which the type is compatible with the specified relationship type
+ * filter.
+ *
+ * @param coll
+ * Collection to import.
+ * @param filter
+ * Relationship type filter.
+ */
+ public PackageRelationshipCollection(PackageRelationshipCollection coll,
+ String filter) {
+ this();
+ for (PackageRelationship rel : coll.relationshipsByID.values()) {
+ if (filter == null || rel.getRelationshipType().equals(filter))
+ addRelationship(rel);
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ public PackageRelationshipCollection(Package container)
+ throws InvalidFormatException {
+ this(container, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @throws InvalidFormatException
+ * Throws if the format of the content part is invalid.
+ *
+ * @throws InvalidOperationException
+ * Throws if the specified part is a relationship part.
+ */
+ public PackageRelationshipCollection(PackagePart part)
+ throws InvalidFormatException {
+ this(part.container, part);
+ }
+
+ /**
+ * Constructor. Parse the existing package relationship part if one exists.
+ *
+ * @param container
+ * The parent package.
+ * @param part
+ * The part that own this relationships collection. If <b>null</b>
+ * then this part is considered as the package root.
+ * @throws InvalidFormatException
+ * If an error occurs during the parsing of the relatinships
+ * part fo the specified part.
+ */
+ public PackageRelationshipCollection(Package container, PackagePart part)
+ throws InvalidFormatException {
+ this();
+
+ if (container == null)
+ throw new IllegalArgumentException("container");
+
+ // Check if the specified part is not a relationship part
+ if (part != null && part.isRelationshipPart())
+ throw new IllegalArgumentException("part");
+
+ this.container = container;
+ this.sourcePart = part;
+ this.partName = getRelationshipPartName(part);
+ if ((container.getPackageAccess() != PackageAccess.WRITE)
+ && container.containPart(this.partName)) {
+ relationshipPart = container.getPart(this.partName);
+ parseRelationshipsPart(relationshipPart);
+ }
+ }
+
+ /**
+ * Get the relationship part name of the specified part.
+ *
+ * @param part
+ * The part .
+ * @return The relationship part name of the specified part. Be careful,
+ * only the correct name is returned, this method does not check if
+ * the part really exist in a package !
+ * @throws InvalidOperationException
+ * Throws if the specified part is a relationship part.
+ */
+ private static PackagePartName getRelationshipPartName(PackagePart part)
+ throws InvalidOperationException {
+ PackagePartName partName;
+ if (part == null) {
+ partName = PackagingURIHelper.PACKAGE_ROOT_PART_NAME;
+ } else {
+ partName = part.getPartName();
+ }
+ return PackagingURIHelper.getRelationshipPartName(partName);
+ }
+
+ /**
+ * Add the specified relationship to the collection.
+ *
+ * @param relPart
+ * The relationship to add.
+ */
+ public void addRelationship(PackageRelationship relPart) {
+ relationshipsByID.put(relPart.getId(), relPart);
+ relationshipsByType.put(relPart.getRelationshipType(), relPart);
+ }
+
+ /**
+ * Add a relationship to the collection.
+ *
+ * @param targetUri
+ * Target URI.
+ * @param targetMode
+ * The target mode : INTERNAL or EXTERNAL
+ * @param relationshipType
+ * Relationship type.
+ * @param id
+ * Relationship ID.
+ * @return The newly created relationship.
+ * @see PackageAccess
+ */
+ public PackageRelationship addRelationship(URI targetUri,
+ TargetMode targetMode, String relationshipType, String id) {
+
+ if (id == null) {
+ // Generate a unique ID is id parameter is null.
+ int i = 0;
+ do {
+ id = "rId" + ++i;
+ } while (relationshipsByID.get(id) != null);
+ }
+
+ PackageRelationship rel = new PackageRelationship(container,
+ sourcePart, targetUri, targetMode, relationshipType, id);
+ relationshipsByID.put(rel.getId(), rel);
+ relationshipsByType.put(rel.getRelationshipType(), rel);
+ return rel;
+ }
+
+ /**
+ * Remove a relationship by its ID.
+ *
+ * @param id
+ * The relationship ID to remove.
+ */
+ public void removeRelationship(String id) {
+ if (relationshipsByID != null && relationshipsByType != null) {
+ PackageRelationship rel = relationshipsByID.get(id);
+ if (rel != null) {
+ relationshipsByID.remove(rel.getId());
+ relationshipsByType.values().remove(rel);
+ }
+ }
+ }
+
+ /**
+ * Remove a relationship by its reference.
+ *
+ * @param rel
+ * The relationship to delete.
+ */
+ public void removeRelationship(PackageRelationship rel) {
+ if (rel == null)
+ throw new IllegalArgumentException("rel");
+
+ relationshipsByID.values().remove(rel);
+ relationshipsByType.values().remove(rel);
+ }
+
+ /**
+ * Retrieves a relationship by its index in the collection.
+ *
+ * @param index
+ * Must be a value between [0-relationships_count-1]
+ */
+ public PackageRelationship getRelationship(int index) {
+ if (index < 0 || index > relationshipsByID.values().size())
+ throw new IllegalArgumentException("index");
+
+ PackageRelationship retRel = null;
+ int i = 0;
+ for (PackageRelationship rel : relationshipsByID.values()) {
+ if (index == i++)
+ return rel;
+ }
+ return retRel;
+ }
+
+ /**
+ * Retrieves a package relationship based on its id.
+ *
+ * @param id
+ * ID of the package relationship to retrieve.
+ * @return The package relationship identified by the specified id.
+ */
+ public PackageRelationship getRelationshipByID(String id) {
+ return relationshipsByID.get(id);
+ }
+
+ /**
+ * Get the numbe rof relationships in the collection.
+ */
+ public int size() {
+ return relationshipsByID.values().size();
+ }
+
+ /**
+ * Parse the relationship part and add all relationship in this collection.
+ *
+ * @param relPart
+ * The package part to parse.
+ * @throws InvalidFormatException
+ * Throws if the relationship part is invalid.
+ */
+ private void parseRelationshipsPart(PackagePart relPart)
+ throws InvalidFormatException {
+ try {
+ SAXReader reader = new SAXReader();
+ logger.debug("Parsing relationship: " + relPart.getPartName());
+ Document xmlRelationshipsDoc = reader
+ .read(relPart.getInputStream());
+
+ // Browse default types
+ Element root = xmlRelationshipsDoc.getRootElement();
+
+ // Check OPC compliance M4.1 rule
+ boolean fCorePropertiesRelationship = false;
+
+ for (Iterator i = root
+ .elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i
+ .hasNext();) {
+ Element element = (Element) i.next();
+ // Relationship ID
+ String id = element.attribute(
+ PackageRelationship.ID_ATTRIBUTE_NAME).getValue();
+ // Relationship type
+ String type = element.attribute(
+ PackageRelationship.TYPE_ATTRIBUTE_NAME).getValue();
+
+ /* Check OPC Compliance */
+ // Check Rule M4.1
+ if (type.equals(PackageRelationshipTypes.CORE_PROPERTIES))
+ if (!fCorePropertiesRelationship)
+ fCorePropertiesRelationship = true;
+ else
+ throw new InvalidFormatException(
+ "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !");
+
+ /* End OPC Compliance */
+
+ // TargetMode (default value "Internal")
+ Attribute targetModeAttr = element
+ .attribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME);
+ TargetMode targetMode = TargetMode.INTERNAL;
+ if (targetModeAttr != null) {
+ targetMode = targetModeAttr.getValue().toLowerCase()
+ .equals("internal") ? TargetMode.INTERNAL
+ : TargetMode.EXTERNAL;
+ }
+
+ // Target converted in URI
+ URI target;
+ String value = "";
+ try {
+ value = element.attribute(
+ PackageRelationship.TARGET_ATTRIBUTE_NAME)
+ .getValue();
+
+ if (value.indexOf("\\") != -1) {
+ logger
+ .info("target contains \\ therefore not a valid URI"
+ + value + " replaced by /");
+ value = value.replaceAll("\\\\", "/");
+ // word can save external relationship with a \ instead
+ // of /
+ }
+
+ target = new URI(value);
+ } catch (URISyntaxException e) {
+ logger.error("Cannot convert " + value
+ + " in a valid relationship URI-> ignored", e);
+ continue;
+ }
+ addRelationship(target, targetMode, type, id);
+ }
+ } catch (Exception e) {
+ logger.error(e);
+ throw new InvalidFormatException(e.getMessage());
+ }
+ }
+
+ /**
+ * Retrieves all relations with the specified type.
+ *
+ * @param typeFilter
+ * Relationship type filter. If <b>null</b> then all
+ * relationships are returned.
+ * @return All relationships of the type specified by the filter.
+ */
+ public PackageRelationshipCollection getRelationships(String typeFilter) {
+ PackageRelationshipCollection coll = new PackageRelationshipCollection(
+ this, typeFilter);
+ return coll;
+ }
+
+ /**
+ * Get this collection's iterator.
+ */
+ public Iterator<PackageRelationship> iterator() {
+ return relationshipsByID.values().iterator();
+ }
+
+ /**
+ * Get an iterator of a collection with all relationship with the specified
+ * type.
+ *
+ * @param typeFilter
+ * Type filter.
+ * @return An iterator to a collection containing all relationships with the
+ * specified type contain in this collection.
+ */
+ public Iterator<PackageRelationship> iterator(String typeFilter) {
+ ArrayList<PackageRelationship> retArr = new ArrayList<PackageRelationship>();
+ for (PackageRelationship rel : relationshipsByID.values()) {
+ if (rel.getRelationshipType().equals(typeFilter))
+ retArr.add(rel);
+ }
+ return retArr.iterator();
+ }
+
+ /**
+ * Clear all relationships.
+ */
+ public void clear() {
+ relationshipsByID.clear();
+ relationshipsByType.clear();
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ if (relationshipsByID == null) {
+ str = "relationshipsByID=null";
+ } else {
+ str = relationshipsByID.size() + " relationship(s) = [";
+ }
+ if ((relationshipPart != null) && (relationshipPart.partName != null)) {
+ str = str + "," + relationshipPart.partName;
+ } else {
+ str = str + ",relationshipPart=null";
+ }
+
+ // Source of this relationship
+ if ((sourcePart != null) && (sourcePart.partName != null)) {
+ str = str + "," + sourcePart.partName;
+ } else {
+ str = str + ",sourcePart=null";
+ }
+ if (partName != null) {
+ str = str + "," + partName;
+ } else {
+ str = str + ",uri=null)";
+ }
+ return str + "]";
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,77 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+/**
+ * Relationship types.
+ *
+ * @author Julien Chable
+ * @version 0.2
+ */
+public interface PackageRelationshipTypes {
+
+ /**
+ * Core properties relationship type.
+ */
+ String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
+
+ /**
+ * Digital signature relationship type.
+ */
+ String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
+
+ /**
+ * Digital signature certificate relationship type.
+ */
+ String DIGITAL_SIGNATURE_CERTIFICATE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate";
+
+ /**
+ * Digital signature origin relationship type.
+ */
+ String DIGITAL_SIGNATURE_ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin";
+
+ /**
+ * Thumbnail relationship type.
+ */
+ String THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
+
+ /**
+ * Extended properties relationship type.
+ */
+ String EXTENDED_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
+
+ /**
+ * Core properties relationship type.
+ */
+ String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
+
+ /**
+ * Custom XML relationship type.
+ */
+ String CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
+
+ /**
+ * Image type.
+ */
+ String IMAGE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
+
+ /**
+ * Style type.
+ */
+ String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,623 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+
+/**
+ * Helper for part and pack URI.
+ *
+ * @author Julien Chable, CDubet, Kim Ung
+ * @version 0.1
+ */
+public final class PackagingURIHelper {
+
+ /**
+ * Package root URI.
+ */
+ private static URI packageRootUri;
+
+ /**
+ * Extension name of a relationship part.
+ */
+ public static final String RELATIONSHIP_PART_EXTENSION_NAME;
+
+ /**
+ * Segment name of a relationship part.
+ */
+ public static final String RELATIONSHIP_PART_SEGMENT_NAME;
+
+ /**
+ * Segment name of the package properties folder.
+ */
+ public static final String PACKAGE_PROPERTIES_SEGMENT_NAME;
+
+ /**
+ * Core package properties art name.
+ */
+ public static final String PACKAGE_CORE_PROPERTIES_NAME;
+
+ /**
+ * Forward slash URI separator.
+ */
+ public static final char FORWARD_SLASH_CHAR;
+
+ /**
+ * Forward slash URI separator.
+ */
+ public static final String FORWARD_SLASH_STRING;
+
+ /**
+ * Package relationships part URI
+ */
+ public static final URI PACKAGE_RELATIONSHIPS_ROOT_URI;
+
+ /**
+ * Package relationships part name.
+ */
+ public static final PackagePartName PACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
+
+ /**
+ * Core properties part URI.
+ */
+ public static final URI CORE_PROPERTIES_URI;
+
+ /**
+ * Core properties partname.
+ */
+ public static final PackagePartName CORE_PROPERTIES_PART_NAME;
+
+ /**
+ * Root package URI.
+ */
+ public static final URI PACKAGE_ROOT_URI;
+
+ /**
+ * Root package part name.
+ */
+ public static final PackagePartName PACKAGE_ROOT_PART_NAME;
+
+ /* Static initialization */
+ static {
+ RELATIONSHIP_PART_SEGMENT_NAME = "_rels";
+ RELATIONSHIP_PART_EXTENSION_NAME = ".rels";
+ FORWARD_SLASH_CHAR = '/';
+ FORWARD_SLASH_STRING = "/";
+ PACKAGE_PROPERTIES_SEGMENT_NAME = "docProps";
+ PACKAGE_CORE_PROPERTIES_NAME = "core.xml";
+
+ // Make URI
+ URI uriPACKAGE_ROOT_URI = null;
+ URI uriPACKAGE_RELATIONSHIPS_ROOT_URI = null;
+ URI uriPACKAGE_PROPERTIES_URI = null;
+ try {
+ uriPACKAGE_ROOT_URI = new URI("/");
+ uriPACKAGE_RELATIONSHIPS_ROOT_URI = new URI(FORWARD_SLASH_CHAR
+ + RELATIONSHIP_PART_SEGMENT_NAME + FORWARD_SLASH_CHAR
+ + RELATIONSHIP_PART_EXTENSION_NAME);
+ packageRootUri = new URI("/");
+ uriPACKAGE_PROPERTIES_URI = new URI(FORWARD_SLASH_CHAR
+ + PACKAGE_PROPERTIES_SEGMENT_NAME + FORWARD_SLASH_CHAR
+ + PACKAGE_CORE_PROPERTIES_NAME);
+ } catch (URISyntaxException e) {
+ // Should never happen in production as all data are fixed
+ }
+ PACKAGE_ROOT_URI = uriPACKAGE_ROOT_URI;
+ PACKAGE_RELATIONSHIPS_ROOT_URI = uriPACKAGE_RELATIONSHIPS_ROOT_URI;
+ CORE_PROPERTIES_URI = uriPACKAGE_PROPERTIES_URI;
+
+ // Make part name from previous URI
+ PackagePartName tmpPACKAGE_ROOT_PART_NAME = null;
+ PackagePartName tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = null;
+ PackagePartName tmpCORE_PROPERTIES_URI = null;
+ try {
+ tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = createPartName(PACKAGE_RELATIONSHIPS_ROOT_URI);
+ tmpCORE_PROPERTIES_URI = createPartName(CORE_PROPERTIES_URI);
+ tmpPACKAGE_ROOT_PART_NAME = new PackagePartName(PACKAGE_ROOT_URI,
+ false);
+ } catch (InvalidFormatException e) {
+ // Should never happen in production as all data are fixed
+ }
+ PACKAGE_RELATIONSHIPS_ROOT_PART_NAME = tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
+ CORE_PROPERTIES_PART_NAME = tmpCORE_PROPERTIES_URI;
+ PACKAGE_ROOT_PART_NAME = tmpPACKAGE_ROOT_PART_NAME;
+ }
+
+ /**
+ * Gets the URI for the package root.
+ *
+ * @return URI of the package root.
+ */
+ public static URI getPackageRootUri() {
+ return packageRootUri;
+ }
+
+ /**
+ * Know if the specified URI is a relationship part name.
+ *
+ * @param partUri
+ * URI to check.
+ * @return <i>true</i> if the URI <i>false</i>.
+ */
+ public static boolean isRelationshipPartURI(URI partUri) {
+ if (partUri == null)
+ throw new IllegalArgumentException("partUri");
+
+ return partUri.getPath().matches(
+ ".*" + RELATIONSHIP_PART_SEGMENT_NAME + ".*"
+ + RELATIONSHIP_PART_EXTENSION_NAME + "$");
+ }
+
+ /**
+ * Get file name from the specified URI.
+ */
+ public static String getFilename(URI uri) {
+ if (uri != null) {
+ String path = uri.getPath();
+ int len = path.length();
+ int num2 = len;
+ while (--num2 >= 0) {
+ char ch1 = path.charAt(num2);
+ if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR)
+ return path.substring(num2 + 1, len);
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Get the file name without the trailing extension.
+ */
+ public static String getFilenameWithoutExtension(URI uri) {
+ String filename = getFilename(uri);
+ int dotIndex = filename.lastIndexOf(".");
+ if (dotIndex == -1)
+ return filename;
+ return filename.substring(0, dotIndex);
+ }
+
+ /**
+ * Get the directory path from the specified URI.
+ */
+ public static URI getPath(URI uri) {
+ if (uri != null) {
+ String path = uri.getPath();
+ int len = path.length();
+ int num2 = len;
+ while (--num2 >= 0) {
+ char ch1 = path.charAt(num2);
+ if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) {
+ try {
+ return new URI(path.substring(0, num2));
+ } catch (URISyntaxException e) {
+ return null;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Combine les deux URI.
+ *
+ * @param prefix
+ * L'URI de pr�fixe.
+ * @param suffix
+ * L'URI de suffixe.
+ * @return
+ */
+ public static URI combine(URI prefix, URI suffix) {
+ URI retUri = null;
+ try {
+ retUri = new URI(combine(prefix.getPath(), suffix.getPath()));
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(
+ "Prefix and suffix can't be combine !");
+ }
+ return retUri;
+ }
+
+ /**
+ * Combine a string URI with a prefix and a suffix.
+ */
+ public static String combine(String prefix, String suffix) {
+ if (!prefix.endsWith("" + FORWARD_SLASH_CHAR)
+ && !suffix.startsWith("" + FORWARD_SLASH_CHAR))
+ return prefix + FORWARD_SLASH_CHAR + suffix;
+ else if ((!prefix.endsWith("" + FORWARD_SLASH_CHAR)
+ && suffix.startsWith("" + FORWARD_SLASH_CHAR) || (prefix
+ .endsWith("" + FORWARD_SLASH_CHAR) && !suffix.startsWith(""
+ + FORWARD_SLASH_CHAR))))
+ return prefix + suffix;
+ else
+ return "";
+ }
+
+ /**
+ * Fully relativize the source part URI against the target part URI.
+ *
+ * @param sourceURI
+ * The source part URI.
+ * @param targetURI
+ * The target part URI.
+ * @return A fully relativize part name URI ('word/media/image1.gif',
+ * '/word/document.xml' => 'media/image1.gif') else
+ * <code>null</code>.
+ */
+ public static URI relativizeURI(URI sourceURI, URI targetURI) {
+ StringBuilder retVal = new StringBuilder();
+ String[] segmentsSource = sourceURI.getPath().split("/", -1);
+ String[] segmentsTarget = targetURI.getPath().split("/", -1);
+
+ // If the source URI is empty
+ if (segmentsSource.length == 0) {
+ throw new IllegalArgumentException(
+ "Can't relativize an empty source URI !");
+ }
+
+ // If target URI is empty
+ if (segmentsTarget.length == 0) {
+ throw new IllegalArgumentException(
+ "Can't relativize an empty target URI !");
+ }
+
+ // If the source is the root, then the relativized
+ // form must actually be an absolute URI
+ if(sourceURI.toString().equals("/")) {
+ return targetURI;
+ }
+
+
+ // Relativize the source URI against the target URI.
+ // First up, figure out how many steps along we can go
+ // and still have them be the same
+ int segmentsTheSame = 0;
+ for (int i = 0; i < segmentsSource.length && i < segmentsTarget.length; i++) {
+ if (segmentsSource[i].equals(segmentsTarget[i])) {
+ // Match so far, good
+ segmentsTheSame++;
+ } else {
+ break;
+ }
+ }
+
+ // If we didn't have a good match or at least except a first empty element
+ if ((segmentsTheSame == 0 || segmentsTheSame == 1) &&
+ segmentsSource[0].equals("") && segmentsTarget[0].equals("")) {
+ for (int i = 0; i < segmentsSource.length - 2; i++) {
+ retVal.append("../");
+ }
+ for (int i = 0; i < segmentsTarget.length; i++) {
+ if (segmentsTarget[i].equals(""))
+ continue;
+ retVal.append(segmentsTarget[i]);
+ if (i != segmentsTarget.length - 1)
+ retVal.append("/");
+ }
+
+ try {
+ return new URI(retVal.toString());
+ } catch (Exception e) {
+ System.err.println(e);
+ return null;
+ }
+ }
+
+ // Special case for where the two are the same
+ if (segmentsTheSame == segmentsSource.length
+ && segmentsTheSame == segmentsTarget.length) {
+ retVal.append("");
+ } else {
+ // Matched for so long, but no more
+
+ // Do we need to go up a directory or two from
+ // the source to get here?
+ // (If it's all the way up, then don't bother!)
+ if (segmentsTheSame == 1) {
+ retVal.append("/");
+ } else {
+ for (int j = segmentsTheSame; j < segmentsSource.length - 1; j++) {
+ retVal.append("../");
+ }
+ }
+
+ // Now go from here on down
+ for (int j = segmentsTheSame; j < segmentsTarget.length; j++) {
+ if (retVal.length() > 0
+ && retVal.charAt(retVal.length() - 1) != '/') {
+ retVal.append("/");
+ }
+ retVal.append(segmentsTarget[j]);
+ }
+ }
+
+ try {
+ return new URI(retVal.toString());
+ } catch (Exception e) {
+ System.err.println(e);
+ return null;
+ }
+ }
+
+ /**
+ * Resolve a source uri against a target.
+ *
+ * @param sourcePartUri
+ * The source URI.
+ * @param targetUri
+ * The target URI.
+ * @return The resolved URI.
+ */
+ public static URI resolvePartUri(URI sourcePartUri, URI targetUri) {
+ if (sourcePartUri == null || sourcePartUri.isAbsolute()) {
+ throw new IllegalArgumentException("sourcePartUri invalid - "
+ + sourcePartUri);
+ }
+
+ if (targetUri == null || targetUri.isAbsolute()) {
+ throw new IllegalArgumentException("targetUri invalid - "
+ + targetUri);
+ }
+
+ return sourcePartUri.resolve(targetUri);
+ }
+
+ /**
+ * Get URI from a string path.
+ */
+ public static URI getURIFromPath(String path) {
+ URI retUri = null;
+ try {
+ retUri = new URI(path);
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException("path");
+ }
+ return retUri;
+ }
+
+ /**
+ * Get the source part URI from a specified relationships part.
+ *
+ * @param relationshipPartUri
+ * The relationship part use to retrieve the source part.
+ * @return The source part URI from the specified relationships part.
+ */
+ public static URI getSourcePartUriFromRelationshipPartUri(
+ URI relationshipPartUri) {
+ if (relationshipPartUri == null)
+ throw new IllegalArgumentException(
+ "Le param�tre relationshipPartUri ne doit pas �tre null !");
+
+ if (!isRelationshipPartURI(relationshipPartUri))
+ throw new IllegalArgumentException(
+ "L'URI ne doit pas �tre celle d'une partie de type relation.");
+
+ if (relationshipPartUri.compareTo(PACKAGE_RELATIONSHIPS_ROOT_URI) == 0)
+ return PACKAGE_ROOT_URI;
+
+ String filename = relationshipPartUri.getPath();
+ String filenameWithoutExtension = getFilenameWithoutExtension(relationshipPartUri);
+ filename = filename
+ .substring(0, ((filename.length() - filenameWithoutExtension
+ .length()) - RELATIONSHIP_PART_EXTENSION_NAME.length()));
+ filename = filename.substring(0, filename.length()
+ - RELATIONSHIP_PART_SEGMENT_NAME.length() - 1);
+ filename = combine(filename, filenameWithoutExtension);
+ return getURIFromPath(filename);
+ }
+
+ /**
+ * Create an OPC compliant part name by throwing an exception if the URI is
+ * not valid.
+ *
+ * @param partUri
+ * The part name URI to validate.
+ * @return A valid part name object, else <code>null</code>.
+ * @throws InvalidFormatException
+ * Throws if the specified URI is not OPC compliant.
+ */
+ public static PackagePartName createPartName(URI partUri)
+ throws InvalidFormatException {
+ if (partUri == null)
+ throw new IllegalArgumentException("partName");
+
+ return new PackagePartName(partUri, true);
+ }
+
+ /**
+ * Create an OPC compliant part name.
+ *
+ * @param partName
+ * The part name to validate.
+ * @return The correspondant part name if valid, else <code>null</code>.
+ * @throws InvalidFormatException
+ * Throws if the specified part name is not OPC compliant.
+ * @see #createPartName(URI)
+ */
+ public static PackagePartName createPartName(String partName)
+ throws InvalidFormatException {
+ URI partNameURI;
+ try {
+ partNameURI = new URI(partName);
+ } catch (URISyntaxException e) {
+ throw new InvalidFormatException(e.getMessage());
+ }
+ return createPartName(partNameURI);
+ }
+
+ /**
+ * Create an OPC compliant part name by resolving it using a base part.
+ *
+ * @param partName
+ * The part name to validate.
+ * @param relativePart
+ * The relative base part.
+ * @return The correspondant part name if valid, else <code>null</code>.
+ * @throws InvalidFormatException
+ * Throws if the specified part name is not OPC compliant.
+ * @see #createPartName(URI)
+ */
+ public static PackagePartName createPartName(String partName,
+ PackagePart relativePart) throws InvalidFormatException {
+ URI newPartNameURI;
+ try {
+ newPartNameURI = resolvePartUri(
+ relativePart.getPartName().getURI(), new URI(partName));
+ } catch (URISyntaxException e) {
+ throw new InvalidFormatException(e.getMessage());
+ }
+ return createPartName(newPartNameURI);
+ }
+
+ /**
+ * Create an OPC compliant part name by resolving it using a base part.
+ *
+ * @param partName
+ * The part name URI to validate.
+ * @param relativePart
+ * The relative base part.
+ * @return The correspondant part name if valid, else <code>null</code>.
+ * @throws InvalidFormatException
+ * Throws if the specified part name is not OPC compliant.
+ * @see #createPartName(URI)
+ */
+ public static PackagePartName createPartName(URI partName,
+ PackagePart relativePart) throws InvalidFormatException {
+ URI newPartNameURI = resolvePartUri(
+ relativePart.getPartName().getURI(), partName);
+ return createPartName(newPartNameURI);
+ }
+
+ /**
+ * Validate a part URI by returning a boolean.
+ * ([M1.1],[M1.3],[M1.4],[M1.5],[M1.6])
+ *
+ * (OPC Specifications 8.1.1 Part names) :
+ *
+ * Part Name Syntax
+ *
+ * The part name grammar is defined as follows:
+ *
+ * <i>part_name = 1*( "/" segment )
+ *
+ * segment = 1*( pchar )</i>
+ *
+ *
+ * (pchar is defined in RFC 3986)
+ *
+ * @param partUri
+ * The URI to validate.
+ * @return <b>true</b> if the URI is valid to the OPC Specifications, else
+ * <b>false</b>
+ *
+ * @see #createPartName(URI)
+ */
+ public static boolean isValidPartName(URI partUri) {
+ if (partUri == null)
+ throw new IllegalArgumentException("partUri");
+
+ try {
+ createPartName(partUri);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Decode a URI by converting all percent encoded character into a String
+ * character.
+ *
+ * @param uri
+ * The URI to decode.
+ * @return The specified URI in a String with converted percent encoded
+ * characters.
+ */
+ public static String decodeURI(URI uri) {
+ StringBuffer retVal = new StringBuffer();
+ String uriStr = uri.toASCIIString();
+ char c;
+ for (int i = 0; i < uriStr.length(); ++i) {
+ c = uriStr.charAt(i);
+ if (c == '%') {
+ // We certainly found an encoded character, check for length
+ // now ( '%' HEXDIGIT HEXDIGIT)
+ if (((uriStr.length() - i) < 2)) {
+ throw new IllegalArgumentException("The uri " + uriStr
+ + " contain invalid encoded character !");
+ }
+
+ // Decode the encoded character
+ char decodedChar = (char) Integer.parseInt(uriStr.substring(
+ i + 1, i + 3), 16);
+ retVal.append(decodedChar);
+ i += 2;
+ continue;
+ }
+ retVal.append(c);
+ }
+ return retVal.toString();
+ }
+
+ /**
+ * Build a part name where the relationship should be stored ((ex
+ * /word/document.xml -> /word/_rels/document.xml.rels)
+ *
+ * @param partName
+ * Source part URI
+ * @return the full path (as URI) of the relation file
+ * @throws InvalidOperationException
+ * Throws if the specified URI is a relationshp part.
+ */
+ public static PackagePartName getRelationshipPartName(
+ PackagePartName partName) {
+ if (partName == null)
+ throw new IllegalArgumentException("partName");
+
+ if (PackagingURIHelper.PACKAGE_ROOT_URI.getPath() == partName.getURI()
+ .getPath())
+ return PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
+
+ if (partName.isRelationshipPartURI())
+ throw new InvalidOperationException("Can't be a relationship part");
+
+ String fullPath = partName.getURI().getPath();
+ String filename = getFilename(partName.getURI());
+ fullPath = fullPath.substring(0, fullPath.length() - filename.length());
+ fullPath = combine(fullPath,
+ PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME);
+ fullPath = combine(fullPath, filename);
+ fullPath = fullPath
+ + PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME;
+
+ PackagePartName retPartName;
+ try {
+ retPartName = createPartName(fullPath);
+ } catch (InvalidFormatException e) {
+ // Should never happen in production as all data are fixed but in
+ // case of return null:
+ return null;
+ }
+ return retPartName;
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,166 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+
+public interface RelationshipSource {
+
+ /**
+ * 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
+ */
+ public abstract PackageRelationship addRelationship(
+ PackagePartName targetPartName, TargetMode targetMode,
+ String relationshipType);
+
+ /**
+ * Add a relationship to a part (except relationships part).
+ *
+ * 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.
+ *
+ * @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 InvalidFormatException
+ * If the URI point to a relationship part URI.
+ */
+ public abstract PackageRelationship addRelationship(
+ PackagePartName targetPartName, TargetMode targetMode,
+ String relationshipType, String id);
+
+ /**
+ * 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);
+
+ /**
+ * 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);
+
+ /**
+ * Delete all the relationships attached to this.
+ */
+ public abstract void clearRelationships();
+
+ /**
+ * Delete the relationship specified by its id.
+ *
+ * @param id
+ * The ID identified the part to delete.
+ */
+ public abstract void removeRelationship(String id);
+
+ /**
+ * Retrieve all the relationships attached to this.
+ *
+ * @return This part's relationships.
+ * @throws OpenXML4JException
+ */
+ public abstract PackageRelationshipCollection getRelationships()
+ throws InvalidFormatException, OpenXML4JException;
+
+ /**
+ * Retrieves a package relationship from its id.
+ *
+ * @param id
+ * ID of the package relationship to retrieve.
+ * @return The package relationship
+ */
+ public abstract PackageRelationship getRelationship(String 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.
+ */
+ public abstract PackageRelationshipCollection getRelationshipsByType(
+ String relationshipType) throws InvalidFormatException,
+ IllegalArgumentException, OpenXML4JException;
+
+ /**
+ * Knows if the part have any relationships.
+ *
+ * @return <b>true</b> if the part have at least one relationship else
+ * <b>false</b>.
+ */
+ public abstract boolean hasRelationships();
+
+ /**
+ * 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>
+ */
+ @SuppressWarnings("finally")
+ public abstract boolean isRelationshipExists(PackageRelationship rel);
+
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,77 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.dom4j.Document;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+
+public final class StreamHelper {
+
+ private StreamHelper() {
+ // Do nothing
+ }
+
+ /**
+ * Turning the DOM4j object in the specified output stream.
+ *
+ * @param xmlContent
+ * The XML document.
+ * @param outStream
+ * The OutputStream in which the XML document will be written.
+ * @return <b>true</b> if the xml is successfully written in the stream,
+ * else <b>false</b>.
+ */
+ public static boolean saveXmlInStream(Document xmlContent,
+ OutputStream outStream) {
+ try {
+ OutputFormat outformat = OutputFormat.createPrettyPrint();
+ outformat.setEncoding("UTF-8");
+ XMLWriter writer = new XMLWriter(outStream, outformat);
+ writer.write(xmlContent);
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Copy the input stream into the output stream.
+ *
+ * @param inStream
+ * The source stream.
+ * @param outStream
+ * The destination stream.
+ * @return <b>true</b> if the operation succeed, else return <b>false</b>.
+ */
+ public static boolean copyStream(InputStream inStream, OutputStream outStream) {
+ try {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inStream.read(buffer)) >= 0) {
+ outStream.write(buffer, 0, bytesRead);
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java
------------------------------------------------------------------------------
svn:executable = *
Added: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java?rev=738842&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java Thu Jan 29 12:44:31 2009
@@ -0,0 +1,32 @@
+/* ====================================================================
+ 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.openxml4j.opc;
+
+/**
+ * Specifies whether the target of a PackageRelationship is inside or outside a
+ * Package.
+ *
+ * @author Julien Chable
+ * @version 1.0
+ */
+public enum TargetMode {
+ /** The relationship references a resource that is external to the package. */
+ INTERNAL,
+ /** The relationship references a part that is inside the package. */
+ EXTERNAL
+}
Propchange: poi/trunk/src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java
------------------------------------------------------------------------------
svn:executable = *
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org