]> source.dussan.org Git - poi.git/commitdiff
Renamed Package (in org.apache.poi.openxml4j.opc) to OPCPackage so as to avoid clash...
authorJosh Micich <josh@apache.org>
Wed, 18 Mar 2009 18:54:01 +0000 (18:54 +0000)
committerJosh Micich <josh@apache.org>
Wed, 18 Mar 2009 18:54:01 +0000 (18:54 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@755699 13f79535-47bb-0310-9956-ffa450edef68

48 files changed:
src/examples/src/org/apache/poi/xssf/eventusermodel/examples/FromHowTo.java
src/ooxml/java/org/apache/poi/POIXMLDocument.java
src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/POIXMLProperties.java
src/ooxml/java/org/apache/poi/dev/OOXMLLister.java
src/ooxml/java/org/apache/poi/extractor/ExtractorFactory.java
src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/openxml4j/opc/Package.java
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackagePart.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePart.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/UnmarshallContext.java
src/ooxml/java/org/apache/poi/ss/usermodel/WorkbookFactory.java
src/ooxml/java/org/apache/poi/util/PackageHelper.java
src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java
src/ooxml/java/org/apache/poi/xslf/extractor/XSLFPowerPointExtractor.java
src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFReader.java
src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExcelExtractor.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/java/org/apache/poi/xwpf/extractor/XWPFWordExtractor.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/testcases/org/apache/poi/TestEmbeded.java
src/ooxml/testcases/org/apache/poi/TestXMLPropertiesTextExtractor.java
src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestListParts.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageThumbnail.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackagingURIHelper.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCComplianceCoreProperties.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/compliance/TestOPCCompliancePackageModel.java
src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xssf/XSSFTestDataSamples.java
src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFReader.java
src/ooxml/testcases/org/apache/poi/xssf/model/TestCommentsTable.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java

index 88668093df3ac1180f148b29b2eb72c7f3233b4d..fc6604c649569729cccd045c146c3793eaa27303 100644 (file)
@@ -22,7 +22,7 @@ import java.util.Iterator;
 import org.apache.poi.xssf.eventusermodel.XSSFReader;
 import org.apache.poi.xssf.model.SharedStringsTable;
 import org.apache.poi.xssf.usermodel.XSSFRichTextString;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.InputSource;
@@ -36,7 +36,7 @@ import org.xml.sax.helpers.XMLReaderFactory;
  */
 public class FromHowTo {
        public void processOneSheet(String filename) throws Exception {
-               Package pkg = Package.open(filename);
+               OPCPackage pkg = OPCPackage.open(filename);
                XSSFReader r = new XSSFReader( pkg );
                SharedStringsTable sst = r.getSharedStringsTable();
 
@@ -51,7 +51,7 @@ public class FromHowTo {
        }
 
        public void processAllSheets(String filename) throws Exception {
-               Package pkg = Package.open(filename);
+               OPCPackage pkg = OPCPackage.open(filename);
                XSSFReader r = new XSSFReader( pkg );
                SharedStringsTable sst = r.getSharedStringsTable();
                
index ef333d86dffde4d2db979c9f26a7c8495c1b86d5..f71ed7ba3e11ba4f71baa7a4a3eef78030a83ee9 100644 (file)
@@ -41,14 +41,14 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
     public static final String PACK_OBJECT_REL_TYPE="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
 
     /** The OPC Package */
-    private Package pkg;
+    private OPCPackage pkg;
 
     /**
      * The properties of the OPC package, opened as needed
      */
     private POIXMLProperties properties;
 
-    protected POIXMLDocument(Package pkg) {
+    protected POIXMLDocument(OPCPackage pkg) {
         super(pkg);
         this.pkg = pkg;
     }
@@ -58,15 +58,15 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
      *  in the event of a problem.
      * Works around shortcomings in java's this() constructor calls
      */
-    public static Package openPackage(String path) throws IOException {
+    public static OPCPackage openPackage(String path) throws IOException {
         try {
-            return Package.open(path);
+            return OPCPackage.open(path);
         } catch (InvalidFormatException e) {
             throw new IOException(e.toString());
         }
     }
 
-    public Package getPackage() {
+    public OPCPackage getPackage() {
         return this.pkg;
     }
 
@@ -92,7 +92,7 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
      * @return The target part
      * @throws InvalidFormatException
      */
-    protected static PackagePart getTargetPart(Package pkg, PackageRelationship rel) throws InvalidFormatException {
+    protected static PackagePart getTargetPart(OPCPackage pkg, PackageRelationship rel) throws InvalidFormatException {
         PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
         PackagePart part = pkg.getPart(relName);
         if (part == null) {
@@ -176,7 +176,7 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
      * there is no way to change or even save such an instance in a OutputStream.
      * The workaround is to create a copy via a temp file
      */
-    protected static Package ensureWriteAccess(Package pkg) throws IOException {
+    protected static OPCPackage ensureWriteAccess(OPCPackage pkg) throws IOException {
         if(pkg.getPackageAccess() == PackageAccess.READ){
             try {
                 return PackageHelper.clone(pkg);
index aa7f72df195cae81cc3ec8cc4bb7ebc8d0569804..a93215a3b90794a0dd533874186aab8e5e78907c 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-package org.apache.poi;\r
-\r
-import java.io.IOException;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-\r
-import org.apache.xmlbeans.XmlOptions;\r
-import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.POILogFactory;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.opc.*;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-\r
-/**\r
- * Represents an entry of a OOXML package.\r
- *\r
- * <p>\r
- * Each POIXMLDocumentPart keeps a reference to the underlying a {@link org.apache.poi.openxml4j.opc.PackagePart}.\r
- * </p>\r
- *\r
- * @author Yegor Kozlov\r
- */\r
-public class POIXMLDocumentPart {\r
-    private static POILogger logger = POILogFactory.getLogger(POIXMLDocumentPart.class);\r
-\r
-    public static final XmlOptions DEFAULT_XML_OPTIONS;\r
-    static {\r
-        DEFAULT_XML_OPTIONS = new XmlOptions();\r
-        DEFAULT_XML_OPTIONS.setSaveOuter();\r
-        DEFAULT_XML_OPTIONS.setUseDefaultNamespace();\r
-        DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces();\r
-    }\r
-\r
-    private PackagePart packagePart;\r
-    private PackageRelationship packageRel;\r
-    private POIXMLDocumentPart parent;\r
-    private List<POIXMLDocumentPart> relations;\r
-\r
-    /**\r
-     * Construct POIXMLDocumentPart representing a "core document" package part.\r
-     */\r
-    public POIXMLDocumentPart(Package pkg) {\r
-        try {\r
-            PackageRelationship coreRel = pkg.getRelationshipsByType(\r
-                    PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0);\r
-\r
-            this.relations = new LinkedList<POIXMLDocumentPart>();\r
-            this.packagePart = pkg.getPart(coreRel);\r
-            this.packageRel = coreRel;\r
-        } catch (OpenXML4JException e){\r
-            throw new POIXMLException(e);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Creates new POIXMLDocumentPart   - called by client code to create new parts from scratch.\r
-     *\r
-     * @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)\r
-     */\r
-    public POIXMLDocumentPart(){\r
-        this.relations = new LinkedList<POIXMLDocumentPart>();\r
-    }\r
-\r
-    /**\r
-     * Creates an POIXMLDocumentPart representing the given package part and relationship.\r
-     * Called by {@link #read(POIXMLFactory)} when reading in an exisiting file.\r
-     *\r
-     * @param part - The package part that holds xml data represenring this sheet.\r
-     * @param rel - the relationship of the given package part\r
-     * @see #read(POIXMLFactory)\r
-     */\r
-    public POIXMLDocumentPart(PackagePart part, PackageRelationship rel){\r
-        this.relations = new LinkedList<POIXMLDocumentPart>();\r
-        this.packagePart = part;\r
-        this.packageRel = rel;\r
-    }\r
-\r
-    /**\r
-     * Provides access to the underlying PackagePart\r
-     *\r
-     * @return the underlying PackagePart\r
-     */\r
-    public final PackagePart getPackagePart(){\r
-        return packagePart;\r
-    }\r
-\r
-    /**\r
-     * Provides access to the PackageRelationship that identifies this POIXMLDocumentPart\r
-     *\r
-     * @return the PackageRelationship that identifies this POIXMLDocumentPart\r
-     */\r
-    public final PackageRelationship getPackageRelationship(){\r
-        return packageRel;\r
-    }\r
-\r
-    /**\r
-     * Returns the list of child relations for this POIXMLDocumentPart\r
-     *\r
-     * @return child relations\r
-     */\r
-    public final List<POIXMLDocumentPart> getRelations(){\r
-        return relations;\r
-    }\r
-\r
-    /**\r
-     * Add a new child POIXMLDocumentPart\r
-     *\r
-     * @param part the child to add\r
-     */\r
-    protected final void addRelation(POIXMLDocumentPart part){\r
-        relations.add(part);\r
-    }\r
-\r
-    /**\r
-     * Remove the specified part in this package.\r
-     */\r
-    public final void removeRelation(POIXMLDocumentPart part){\r
-        getPackagePart().removeRelationship(part.getPackageRelationship().getId());\r
-        getPackagePart().getPackage().removePart(part.getPackagePart());\r
-        relations.remove(part);\r
-    }\r
-\r
-    /**\r
-     * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent.\r
-     *\r
-     * @return the parent POIXMLDocumentPart or <code>null</code> for the root element.\r
-     */\r
-    public final POIXMLDocumentPart getParent(){\r
-        return parent;\r
-    }\r
-\r
-    @Override\r
-    public String toString(){\r
-        return packagePart.toString();\r
-    }\r
-\r
-    /**\r
-     * Save the content in the underlying package part.\r
-     * Default implementation is empty meaning that the package part is left unmodified.\r
-     *\r
-     * Sub-classes should override and add logic to marshal the "model" into Ooxml4J.\r
-     *\r
-     * For example, the code saving a generic XML entry may look as follows:\r
-     * <pre><code>\r
-     * protected void commit() throws IOException {\r
-     *   PackagePart part = getPackagePart();\r
-     *   OutputStream out = part.getOutputStream();\r
-     *   XmlObject bean = getXmlBean(); //the "model" which holds changes in memory\r
-     *   bean.save(out, DEFAULT_XML_OPTIONS);\r
-     *   out.close();\r
-     * }\r
-     *  </code></pre>\r
-     *\r
-     */\r
-    protected void commit() throws IOException {\r
-\r
-    }\r
-\r
-    /**\r
-     * Save changes in the underlying OOXML package.\r
-     * Recursively fires {@link #commit()} for each package part\r
-     */\r
-    protected final void onSave() throws IOException{\r
-        commit();\r
-        for(POIXMLDocumentPart p : relations){\r
-            p.onSave();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Create a new child POIXMLDocumentPart\r
-     *\r
-     * @param descriptor the part descriptor\r
-     * @param factory the factory that will create an instance of the requested relation\r
-     * @return the created child POIXMLDocumentPart\r
-     */\r
-    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){\r
-        return createRelationship(descriptor, factory, -1, false);\r
-    }\r
-\r
-    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){\r
-        return createRelationship(descriptor, factory, idx, false);\r
-    }\r
-\r
-    /**\r
-     * Create a new child POIXMLDocumentPart\r
-     *\r
-     * @param descriptor the part descriptor\r
-     * @param factory the factory that will create an instance of the requested relation\r
-     * @param idx part number\r
-     * @param noRelation if true, then no relationship is added.\r
-     * @return the created child POIXMLDocumentPart\r
-     */\r
-    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){\r
-        try {\r
-\r
-            PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));\r
-            PackageRelationship rel = null;\r
-            if(!noRelation) rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());\r
-\r
-            PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());\r
-            POIXMLDocumentPart doc = factory.newDocumentPart(descriptor);\r
-            doc.packageRel = rel;\r
-            doc.packagePart = part;\r
-            doc.parent = this;\r
-            addRelation(doc);\r
-            return doc;\r
-        } catch (Exception e){\r
-            throw new POIXMLException(e);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Iterate through the underlying PackagePart and create child POIXMLFactory instances\r
-     * using the specified factory\r
-     *\r
-     * @param factory   the factory object that creates POIXMLFactory instances\r
-     */\r
-    protected final void read(POIXMLFactory factory) throws OpenXML4JException {\r
-        PackageRelationshipCollection rels = packagePart.getRelationships();\r
-        for (PackageRelationship rel : rels) {\r
-            if(rel.getTargetMode() == TargetMode.INTERNAL){\r
-                PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());\r
-                PackagePart p = packagePart.getPackage().getPart(relName);\r
-                if(p == null) {\r
-                    logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI());\r
-                    continue;\r
-                }\r
-                POIXMLDocumentPart childPart = factory.createDocumentPart(rel, p);\r
-                childPart.parent = this;\r
-                addRelation(childPart);\r
-\r
-                if(p.hasRelationships()) childPart.read(factory);\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Fired when a new package part is created\r
-     */\r
-    protected void onDocumentCreate() throws IOException {\r
-\r
-    }\r
-\r
-    /**\r
-     * Fired when a package part is read\r
-     */\r
-    protected void onDocumentRead() throws IOException{\r
-\r
-    }\r
-\r
-}\r
+/* ====================================================================
+   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;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.xmlbeans.XmlOptions;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.*;
+import org.apache.poi.openxml4j.opc.Package;
+
+/**
+ * Represents an entry of a OOXML package.
+ *
+ * <p>
+ * Each POIXMLDocumentPart keeps a reference to the underlying a {@link org.apache.poi.openxml4j.opc.PackagePart}.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+public class POIXMLDocumentPart {
+    private static POILogger logger = POILogFactory.getLogger(POIXMLDocumentPart.class);
+
+    public static final XmlOptions DEFAULT_XML_OPTIONS;
+    static {
+        DEFAULT_XML_OPTIONS = new XmlOptions();
+        DEFAULT_XML_OPTIONS.setSaveOuter();
+        DEFAULT_XML_OPTIONS.setUseDefaultNamespace();
+        DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces();
+    }
+
+    private PackagePart packagePart;
+    private PackageRelationship packageRel;
+    private POIXMLDocumentPart parent;
+    private List<POIXMLDocumentPart> relations;
+
+    /**
+     * Construct POIXMLDocumentPart representing a "core document" package part.
+     */
+    public POIXMLDocumentPart(OPCPackage pkg) {
+        PackageRelationship coreRel = pkg.getRelationshipsByType(
+                PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0);
+
+        this.relations = new LinkedList<POIXMLDocumentPart>();
+        this.packagePart = pkg.getPart(coreRel);
+        this.packageRel = coreRel;
+    }
+
+    /**
+     * Creates new POIXMLDocumentPart   - called by client code to create new parts from scratch.
+     *
+     * @see #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)
+     */
+    public POIXMLDocumentPart(){
+        this.relations = new LinkedList<POIXMLDocumentPart>();
+    }
+
+    /**
+     * Creates an POIXMLDocumentPart representing the given package part and relationship.
+     * Called by {@link #read(POIXMLFactory)} when reading in an exisiting file.
+     *
+     * @param part - The package part that holds xml data represenring this sheet.
+     * @param rel - the relationship of the given package part
+     * @see #read(POIXMLFactory)
+     */
+    public POIXMLDocumentPart(PackagePart part, PackageRelationship rel){
+        this.relations = new LinkedList<POIXMLDocumentPart>();
+        this.packagePart = part;
+        this.packageRel = rel;
+    }
+
+    /**
+     * Provides access to the underlying PackagePart
+     *
+     * @return the underlying PackagePart
+     */
+    public final PackagePart getPackagePart(){
+        return packagePart;
+    }
+
+    /**
+     * Provides access to the PackageRelationship that identifies this POIXMLDocumentPart
+     *
+     * @return the PackageRelationship that identifies this POIXMLDocumentPart
+     */
+    public final PackageRelationship getPackageRelationship(){
+        return packageRel;
+    }
+
+    /**
+     * Returns the list of child relations for this POIXMLDocumentPart
+     *
+     * @return child relations
+     */
+    public final List<POIXMLDocumentPart> getRelations(){
+        return relations;
+    }
+
+    /**
+     * Add a new child POIXMLDocumentPart
+     *
+     * @param part the child to add
+     */
+    protected final void addRelation(POIXMLDocumentPart part){
+        relations.add(part);
+    }
+
+    /**
+     * Remove the specified part in this package.
+     */
+    public final void removeRelation(POIXMLDocumentPart part){
+        getPackagePart().removeRelationship(part.getPackageRelationship().getId());
+        getPackagePart().getPackage().removePart(part.getPackagePart());
+        relations.remove(part);
+    }
+
+    /**
+     * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent.
+     *
+     * @return the parent POIXMLDocumentPart or <code>null</code> for the root element.
+     */
+    public final POIXMLDocumentPart getParent(){
+        return parent;
+    }
+
+    @Override
+    public String toString(){
+        return packagePart.toString();
+    }
+
+    /**
+     * Save the content in the underlying package part.
+     * Default implementation is empty meaning that the package part is left unmodified.
+     *
+     * Sub-classes should override and add logic to marshal the "model" into Ooxml4J.
+     *
+     * For example, the code saving a generic XML entry may look as follows:
+     * <pre><code>
+     * protected void commit() throws IOException {
+     *   PackagePart part = getPackagePart();
+     *   OutputStream out = part.getOutputStream();
+     *   XmlObject bean = getXmlBean(); //the "model" which holds changes in memory
+     *   bean.save(out, DEFAULT_XML_OPTIONS);
+     *   out.close();
+     * }
+     *  </code></pre>
+     *
+     */
+    protected void commit() throws IOException {
+
+    }
+
+    /**
+     * Save changes in the underlying OOXML package.
+     * Recursively fires {@link #commit()} for each package part
+     */
+    protected final void onSave() throws IOException{
+        commit();
+        for(POIXMLDocumentPart p : relations){
+            p.onSave();
+        }
+    }
+
+    /**
+     * Create a new child POIXMLDocumentPart
+     *
+     * @param descriptor the part descriptor
+     * @param factory the factory that will create an instance of the requested relation
+     * @return the created child POIXMLDocumentPart
+     */
+    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
+        return createRelationship(descriptor, factory, -1, false);
+    }
+
+    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
+        return createRelationship(descriptor, factory, idx, false);
+    }
+
+    /**
+     * Create a new child POIXMLDocumentPart
+     *
+     * @param descriptor the part descriptor
+     * @param factory the factory that will create an instance of the requested relation
+     * @param idx part number
+     * @param noRelation if true, then no relationship is added.
+     * @return the created child POIXMLDocumentPart
+     */
+    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){
+        try {
+
+            PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
+            PackageRelationship rel = null;
+            if(!noRelation) rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
+
+            PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
+            POIXMLDocumentPart doc = factory.newDocumentPart(descriptor);
+            doc.packageRel = rel;
+            doc.packagePart = part;
+            doc.parent = this;
+            addRelation(doc);
+            return doc;
+        } catch (Exception e){
+            throw new POIXMLException(e);
+        }
+    }
+
+    /**
+     * Iterate through the underlying PackagePart and create child POIXMLFactory instances
+     * using the specified factory
+     *
+     * @param factory   the factory object that creates POIXMLFactory instances
+     */
+    protected final void read(POIXMLFactory factory) throws OpenXML4JException {
+        PackageRelationshipCollection rels = packagePart.getRelationships();
+        for (PackageRelationship rel : rels) {
+            if(rel.getTargetMode() == TargetMode.INTERNAL){
+                PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
+                PackagePart p = packagePart.getPackage().getPart(relName);
+                if(p == null) {
+                    logger.log(POILogger.ERROR, "Skipped invalid entry " + rel.getTargetURI());
+                    continue;
+                }
+                POIXMLDocumentPart childPart = factory.createDocumentPart(rel, p);
+                childPart.parent = this;
+                addRelation(childPart);
+
+                if(p.hasRelationships()) childPart.read(factory);
+            }
+        }
+    }
+
+
+    /**
+     * Fired when a new package part is created
+     */
+    protected void onDocumentCreate() throws IOException {
+
+    }
+
+    /**
+     * Fired when a package part is read
+     */
+    protected void onDocumentRead() throws IOException{
+
+    }
+
+}
index 3d862be8886afbaaeb84e32804e5655bcd704b05..dcb6a9ce3fe0afdce31e5dff00a8eb7145d3c492 100644 (file)
@@ -18,23 +18,23 @@ package org.apache.poi;
 
 import java.io.IOException;
 
-import org.apache.xmlbeans.XmlException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
+import org.apache.xmlbeans.XmlException;
 
 /**
  * Wrapper around the two different kinds of OOXML properties 
  *  a document can have
  */
 public class POIXMLProperties {
-       private Package pkg;
+       private OPCPackage pkg;
        private CoreProperties core;
        private ExtendedProperties ext;
        private CustomProperties cust;
        
-       public POIXMLProperties(Package docPackage) throws IOException, OpenXML4JException, XmlException {
+       public POIXMLProperties(OPCPackage docPackage) throws IOException, OpenXML4JException, XmlException {
                this.pkg = docPackage;
                
                // Core properties
@@ -97,7 +97,7 @@ public class POIXMLProperties {
         * Writes out the ooxml properties into the supplied,
         *  new Package
         */
-       public void write(Package pkg) {
+       public void write(OPCPackage pkg) {
                // TODO
        }
        
index a55bc2632bdc1e2d65d431d8d7c2f86c6ace821f..ed5fec285597247d2361e7d14311f3a647345d28 100644 (file)
@@ -22,7 +22,7 @@ import java.io.InputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
 
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackageAccess;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
@@ -34,13 +34,13 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
  *  they're all related to each other.
  */
 public class OOXMLLister {
-       private Package container;
+       private OPCPackage container;
        private PrintStream disp;
        
-       public OOXMLLister(Package container) {
+       public OOXMLLister(OPCPackage container) {
                this(container, System.out);
        }
-       public OOXMLLister(Package container, PrintStream disp) {
+       public OOXMLLister(OPCPackage container, PrintStream disp) {
                this.container = container;
                this.disp = disp;
        }
@@ -122,7 +122,7 @@ public class OOXMLLister {
                }
                
                OOXMLLister lister = new OOXMLLister(
-                               Package.open(f.toString(), PackageAccess.READ)
+                               OPCPackage.open(f.toString(), PackageAccess.READ)
                );
                
                lister.disp.println(f.toString() + "\n");
index 7640db845ff0203a88b8d609bf195fdc618c4826..dc25f63a38d118657612690a6f683f555632c14f 100644 (file)
@@ -33,6 +33,11 @@ import org.apache.poi.hdgf.extractor.VisioTextExtractor;
 import org.apache.poi.hslf.extractor.PowerPointExtractor;
 import org.apache.poi.hssf.extractor.ExcelExtractor;
 import org.apache.poi.hwpf.extractor.WordExtractor;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.Entry;
@@ -41,14 +46,9 @@ import org.apache.poi.xslf.XSLFSlideShow;
 import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
 import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
 import org.apache.poi.xssf.usermodel.XSSFRelation;
-import org.apache.poi.xwpf.usermodel.XWPFRelation;
 import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
+import org.apache.poi.xwpf.usermodel.XWPFRelation;
 import org.apache.xmlbeans.XmlException;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
-import org.apache.poi.openxml4j.opc.PackagePart;
-import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 
 /**
  * Figures out the correct POITextExtractor for your supplied
@@ -67,7 +67,7 @@ public class ExtractorFactory {
                }
                if(POIXMLDocument.hasOOXMLHeader(inp)) {
                        inp.close();
-                       return createExtractor(Package.open(f.toString()));
+                       return createExtractor(OPCPackage.open(f.toString()));
                }
                throw new IllegalArgumentException("Your File was neither an OLE2 file, nor an OOXML file");
        }
@@ -83,12 +83,12 @@ public class ExtractorFactory {
                        return createExtractor(new POIFSFileSystem(inp));
                }
                if(POIXMLDocument.hasOOXMLHeader(inp)) {
-                       return createExtractor(Package.open(inp));
+                       return createExtractor(OPCPackage.open(inp));
                }
                throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
        }
        
-       public static POIXMLTextExtractor createExtractor(Package pkg) throws IOException, OpenXML4JException, XmlException {
+       public static POIXMLTextExtractor createExtractor(OPCPackage pkg) throws IOException, OpenXML4JException, XmlException {
                PackageRelationshipCollection core = 
                        pkg.getRelationshipsByType(CORE_DOCUMENT_REL);
                if(core.size() != 1) {
diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
new file mode 100644 (file)
index 0000000..4efe6bd
--- /dev/null
@@ -0,0 +1,1390 @@
+/* ====================================================================
+   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.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.openxml4j.opc.internal.ContentType;
+import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
+import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
+import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
+import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
+import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager;
+import org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller;
+import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller;
+import org.apache.poi.openxml4j.opc.internal.unmarshallers.PackagePropertiesUnmarshaller;
+import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext;
+import org.apache.poi.openxml4j.util.Nullable;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
+
+/**
+ * Represents a container that can store multiple data objects.
+ * 
+ * @author Julien Chable, CDubet
+ * @version 0.1
+ */
+public abstract class OPCPackage implements RelationshipSource {
+
+       /**
+        * Logger.
+        */
+    private static POILogger logger = POILogFactory.getLogger(OPCPackage.class);
+
+       /**
+        * Default package access.
+        */
+       protected static final PackageAccess defaultPackageAccess = PackageAccess.READ_WRITE;
+
+       /**
+        * Package access.
+        */
+       private PackageAccess packageAccess;
+
+       /**
+        * Package parts collection.
+        */
+       protected PackagePartCollection partList;
+
+       /**
+        * Package relationships.
+        */
+       protected PackageRelationshipCollection relationships;
+
+       /**
+        * Part marshallers by content type.
+        */
+       protected Hashtable<ContentType, PartMarshaller> partMarshallers;
+
+       /**
+        * Default part marshaller.
+        */
+       protected PartMarshaller defaultPartMarshaller;
+
+       /**
+        * Part unmarshallers by content type.
+        */
+       protected Hashtable<ContentType, PartUnmarshaller> partUnmarshallers;
+
+       /**
+        * Core package properties.
+        */
+       protected PackagePropertiesPart packageProperties;
+
+       /**
+        * Manage parts content types of this package.
+        */
+       protected ContentTypeManager contentTypeManager;
+
+       /**
+        * Flag if a modification is done to the document.
+        */
+       protected boolean isDirty = false;
+
+       /**
+        * File path of this package.
+        */
+       protected String originalPackagePath;
+
+       /**
+        * Output stream for writing this package.
+        */
+       protected OutputStream output;
+
+       /**
+        * Constructor.
+        * 
+        * @param access
+        *            Package access.
+        */
+       OPCPackage(PackageAccess access) {
+               if (getClass() != ZipPackage.class) {
+                       throw new IllegalArgumentException("PackageBase may not be subclassed");
+               }
+               init();
+               this.packageAccess = access;
+       }
+
+       /**
+        * Initialize the package instance.
+        */
+       private void init() {
+               this.partMarshallers = new Hashtable<ContentType, PartMarshaller>(5);
+               this.partUnmarshallers = new Hashtable<ContentType, PartUnmarshaller>(2);
+
+               try {
+                       // Add 'default' unmarshaller
+                       this.partUnmarshallers.put(new ContentType(
+                                       ContentTypes.CORE_PROPERTIES_PART),
+                                       new PackagePropertiesUnmarshaller());
+
+                       // Add default marshaller
+                       this.defaultPartMarshaller = new DefaultMarshaller();
+                       // TODO Delocalize specialized marshallers
+                       this.partMarshallers.put(new ContentType(
+                                       ContentTypes.CORE_PROPERTIES_PART),
+                                       new ZipPackagePropertiesMarshaller());
+               } catch (InvalidFormatException e) {
+                       // Should never happen
+                       throw new OpenXML4JRuntimeException(
+                                       "Package.init() : this exception should never happen, if you read this message please send a mail to the developers team.");
+               }
+       }
+
+
+       /**
+        * Open a package with read/write permission.
+        * 
+        * @param path
+        *            The document path.
+        * @return A Package object, else <b>null</b>.
+        * @throws InvalidFormatException
+        *             If the specified file doesn't exist, and a parsing error
+        *             occur.
+        */
+       public static OPCPackage open(String path) throws InvalidFormatException {
+               return open(path, defaultPackageAccess);
+       }
+
+       /**
+        * Open a package.
+        * 
+        * @param path
+        *            The document path.
+        * @param access
+        *            PackageBase access.
+        * @return A PackageBase object, else <b>null</b>.
+        * @throws InvalidFormatException
+        *             If the specified file doesn't exist, and a parsing error
+        *             occur.
+        */
+       public static OPCPackage open(String path, PackageAccess access)
+                       throws InvalidFormatException {
+               if (path == null || "".equals(path.trim())
+                               || (new File(path).exists() && new File(path).isDirectory()))
+                       throw new IllegalArgumentException("path");
+
+               OPCPackage pack = new ZipPackage(path, access);
+               if (pack.partList == null && access != PackageAccess.WRITE) {
+                       pack.getParts();
+               }
+               pack.originalPackagePath = new File(path).getAbsolutePath();
+               return pack;
+       }
+
+       /**
+        * Open a package.
+        * 
+        * Note - uses quite a bit more memory than {@link #open(String)}, which
+        * doesn't need to hold the whole zip file in memory, and can take advantage
+        * of native methods
+        * 
+        * @param in
+        *            The InputStream to read the package from
+        * @return A PackageBase object
+        */
+       public static OPCPackage open(InputStream in) throws InvalidFormatException,
+                       IOException {
+               OPCPackage pack = new ZipPackage(in, PackageAccess.READ);
+               if (pack.partList == null) {
+                       pack.getParts();
+               }
+               return pack;
+       }
+
+       /**
+        * Opens a package if it exists, else it creates one.
+        * 
+        * @param file
+        *            The file to open or to create.
+        * @return A newly created package if the specified file does not exist,
+        *         else the package extract from the file.
+        * @throws InvalidFormatException
+        *             Throws if the specified file exist and is not valid.
+        */
+       public static OPCPackage openOrCreate(File file) throws InvalidFormatException {
+               OPCPackage retPackage = null;
+               if (file.exists()) {
+                       retPackage = open(file.getAbsolutePath());
+               } else {
+                       retPackage = create(file);
+               }
+               return retPackage;
+       }
+
+       /**
+        * Creates a new package.
+        * 
+        * @param path
+        *            Path of the document.
+        * @return A newly created PackageBase ready to use.
+        */
+       public static OPCPackage create(String path) {
+               return create(new File(path));
+       }
+
+       /**
+        * Creates a new package.
+        * 
+        * @param file
+        *            Path of the document.
+        * @return A newly created PackageBase ready to use.
+        */
+       public static OPCPackage create(File file) {
+               if (file == null || (file.exists() && file.isDirectory()))
+                       throw new IllegalArgumentException("file");
+
+               if (file.exists()) {
+                       throw new InvalidOperationException(
+                                       "This package (or file) already exists : use the open() method or delete the file.");
+               }
+
+               // Creates a new package
+               OPCPackage pkg = null;
+               pkg = new ZipPackage();
+               pkg.originalPackagePath = file.getAbsolutePath();
+
+               configurePackage(pkg);
+               return pkg;
+       }
+
+       public static OPCPackage create(OutputStream output) {
+               OPCPackage pkg = null;
+               pkg = new ZipPackage();
+               pkg.originalPackagePath = null;
+               pkg.output = output;
+
+               configurePackage(pkg);
+               return pkg;
+       }
+
+       /**
+        * Configure the package.
+        * 
+        * @param pkg
+        */
+       private static void configurePackage(OPCPackage pkg) {
+               try {
+                       // Content type manager
+                       pkg.contentTypeManager = new ZipContentTypeManager(null, pkg);
+                       // Add default content types for .xml and .rels
+                       pkg.contentTypeManager
+                                       .addContentType(
+                                                       PackagingURIHelper
+                                                                       .createPartName(PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_URI),
+                                                       ContentTypes.RELATIONSHIPS_PART);
+                       pkg.contentTypeManager
+                                       .addContentType(PackagingURIHelper
+                                                       .createPartName("/default.xml"),
+                                                       ContentTypes.PLAIN_OLD_XML);
+
+                       // Init some PackageBase properties
+                       pkg.packageProperties = new PackagePropertiesPart(pkg,
+                                       PackagingURIHelper.CORE_PROPERTIES_PART_NAME);
+                       pkg.packageProperties.setCreatorProperty("Generated by OpenXML4J");
+                       pkg.packageProperties.setCreatedProperty(new Nullable<Date>(
+                                       new Date()));
+               } catch (InvalidFormatException e) {
+                       // Should never happen
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       /**
+        * Flush the package : save all.
+        * 
+        * @see #close()
+        */
+       public void flush() {
+               throwExceptionIfReadOnly();
+
+               if (this.packageProperties != null) {
+                       this.packageProperties.flush();
+               }
+
+               this.flushImpl();
+       }
+
+       /**
+        * Close the package and save its content.
+        * 
+        * @throws IOException
+        *             If an IO exception occur during the saving process.
+        */
+       public void close() throws IOException {
+               if (this.packageAccess == PackageAccess.READ) {
+                       logger
+                                       .log(POILogger.WARN, "The close() method is intended to SAVE a package. This package is open in READ ONLY mode, use the revert() method instead !");
+                       return;
+               }
+
+               // Save the content
+               ReentrantReadWriteLock l = new ReentrantReadWriteLock();
+               try {
+                       l.writeLock().lock();
+                       if (this.originalPackagePath != null
+                                       && !"".equals(this.originalPackagePath.trim())) {
+                               File targetFile = new File(this.originalPackagePath);
+                               if (!targetFile.exists()
+                                               || !(this.originalPackagePath
+                                                               .equalsIgnoreCase(targetFile.getAbsolutePath()))) {
+                                       // Case of a package created from scratch
+                                       save(targetFile);
+                               } else {
+                                       closeImpl();
+                               }
+                       } else if (this.output != null) {
+                               save(this.output);
+                       }
+               } finally {
+                       l.writeLock().unlock();
+               }
+
+               // Clear
+               this.contentTypeManager.clearAll();
+
+               // Call the garbage collector
+               Runtime.getRuntime().gc();
+       }
+
+       /**
+        * Close the package WITHOUT saving its content. Reinitialize this package
+        * and cancel all changes done to it.
+        */
+       public void revert() {
+               revertImpl();
+       }
+
+       /**
+        * Add a thumbnail to the package. This method is provided to make easier
+        * the addition of a thumbnail in a package. You can do the same work by
+        * using the traditionnal relationship and part mechanism.
+        * 
+        * @param path
+        *            The full path to the image file.
+        */
+       public void addThumbnail(String path) throws IOException {
+               // Check parameter
+               if ("".equals(path))
+                       throw new IllegalArgumentException("path");
+
+               // Get the filename from the path
+               String filename = path
+                               .substring(path.lastIndexOf(File.separatorChar) + 1);
+
+               // Create the thumbnail part name
+               String contentType = ContentTypes
+                               .getContentTypeFromFileExtension(filename);
+               PackagePartName thumbnailPartName = null;
+               try {
+                       thumbnailPartName = PackagingURIHelper.createPartName("/docProps/"
+                                       + filename);
+               } catch (InvalidFormatException e) {
+                       try {
+                               thumbnailPartName = PackagingURIHelper
+                                               .createPartName("/docProps/thumbnail"
+                                                               + path.substring(path.lastIndexOf(".") + 1));
+                       } catch (InvalidFormatException e2) {
+                               throw new InvalidOperationException(
+                                               "Can't add a thumbnail file named '" + filename + "'");
+                       }
+               }
+
+               // Check if part already exist
+               if (this.getPart(thumbnailPartName) != null)
+                       throw new InvalidOperationException(
+                                       "You already add a thumbnail named '" + filename + "'");
+
+               // Add the thumbnail part to this package.
+               PackagePart thumbnailPart = this.createPart(thumbnailPartName,
+                               contentType, false);
+
+               // Add the relationship between the package and the thumbnail part
+               this.addRelationship(thumbnailPartName, TargetMode.INTERNAL,
+                               PackageRelationshipTypes.THUMBNAIL);
+
+               // Copy file data to the newly created part
+               StreamHelper.copyStream(new FileInputStream(path), thumbnailPart
+                               .getOutputStream());
+       }
+
+       /**
+        * Throws an exception if the package access mode is in read only mode
+        * (PackageAccess.Read).
+        * 
+        * @throws InvalidOperationException
+        *             Throws if a writing operation is done on a read only package.
+        * @see org.apache.poi.openxml4j.opc.PackageAccess
+        */
+       void throwExceptionIfReadOnly() throws InvalidOperationException {
+               if (packageAccess == PackageAccess.READ)
+                       throw new InvalidOperationException(
+                                       "Operation not allowed, document open in read only mode!");
+       }
+
+       /**
+        * Throws an exception if the package access mode is in write only mode
+        * (PackageAccess.Write). This method is call when other methods need write
+        * right.
+        * 
+        * @throws InvalidOperationException
+        *             Throws if a read operation is done on a write only package.
+        * @see org.apache.poi.openxml4j.opc.PackageAccess
+        */
+       void throwExceptionIfWriteOnly() throws InvalidOperationException {
+               if (packageAccess == PackageAccess.WRITE)
+                       throw new InvalidOperationException(
+                                       "Operation not allowed, document open in write only mode!");
+       }
+
+       /**
+        * Retrieves or creates if none exists, core package property part.
+        * 
+        * @return The PackageProperties part of this package.
+        */
+       public PackageProperties getPackageProperties()
+                       throws InvalidFormatException {
+               this.throwExceptionIfWriteOnly();
+               // If no properties part has been found then we create one
+               if (this.packageProperties == null) {
+                       this.packageProperties = new PackagePropertiesPart(this,
+                                       PackagingURIHelper.CORE_PROPERTIES_PART_NAME);
+               }
+               return this.packageProperties;
+       }
+
+       /**
+        * Retrieve a part identified by its name.
+        * 
+        * @param partName
+        *            Part name of the part to retrieve.
+        * @return The part with the specified name, else <code>null</code>.
+        */
+       public PackagePart getPart(PackagePartName partName) {
+               throwExceptionIfWriteOnly();
+
+               if (partName == null)
+                       throw new IllegalArgumentException("partName");
+
+               // If the partlist is null, then we parse the package.
+               if (partList == null) {
+                       try {
+                               getParts();
+                       } catch (InvalidFormatException e) {
+                               return null;
+                       }
+               }
+               return getPartImpl(partName);
+       }
+
+       /**
+        * Retrieve parts by content type.
+        * 
+        * @param contentType
+        *            The content type criteria.
+        * @return All part associated to the specified content type.
+        */
+       public ArrayList<PackagePart> getPartsByContentType(String contentType) {
+               ArrayList<PackagePart> retArr = new ArrayList<PackagePart>();
+               for (PackagePart part : partList.values()) {
+                       if (part.getContentType().equals(contentType))
+                               retArr.add(part);
+               }
+               return retArr;
+       }
+
+       /**
+        * Retrieve parts by relationship type.
+        * 
+        * @param relationshipType
+        *            Relationship type.
+        * @return All parts which are the target of a relationship with the
+        *         specified type, if the method can't retrieve relationships from
+        *         the package, then return <code>null</code>.
+        */
+       public ArrayList<PackagePart> getPartsByRelationshipType(
+                       String relationshipType) {
+               if (relationshipType == null)
+                       throw new IllegalArgumentException("relationshipType");
+               ArrayList<PackagePart> retArr = new ArrayList<PackagePart>();
+               for (PackageRelationship rel : getRelationshipsByType(relationshipType)) {
+                       retArr.add(getPart(rel));
+               }
+               return retArr;
+       }
+
+       /**
+        * Get the target part from the specified relationship.
+        * 
+        * @param partRel
+        *            The part relationship uses to retrieve the part.
+        */
+       public PackagePart getPart(PackageRelationship partRel) {
+               PackagePart retPart = null;
+               ensureRelationships();
+               for (PackageRelationship rel : relationships) {
+                       if (rel.getRelationshipType().equals(partRel.getRelationshipType())) {
+                               try {
+                                       retPart = getPart(PackagingURIHelper.createPartName(rel
+                                                       .getTargetURI()));
+                               } catch (InvalidFormatException e) {
+                                       continue;
+                               }
+                               break;
+                       }
+               }
+               return retPart;
+       }
+
+       /**
+        * Load the parts of the archive if it has not been done yet The
+        * relationships of each part are not loaded
+        * 
+        * @return All this package's parts.
+        */
+       public ArrayList<PackagePart> getParts() throws InvalidFormatException {
+               throwExceptionIfWriteOnly();
+
+               // If the part list is null, we parse the package to retrieve all parts.
+               if (partList == null) {
+                       /* Variables use to validate OPC Compliance */
+
+                       // Ensure rule M4.1 -> A format consumer shall consider more than
+                       // one core properties relationship for a package to be an error
+                       boolean hasCorePropertiesPart = false;
+
+                       PackagePart[] parts = this.getPartsImpl();
+                       this.partList = new PackagePartCollection();
+                       for (PackagePart part : parts) {
+                               if (partList.containsKey(part.partName))
+                                       throw new InvalidFormatException(
+                                                       "A part with the name '"
+                                                                       + part.partName
+                                                                       + "' already exist : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");
+
+                               // Check OPC compliance rule M4.1
+                               if (part.getContentType().equals(
+                                               ContentTypes.CORE_PROPERTIES_PART)) {
+                                       if (!hasCorePropertiesPart)
+                                               hasCorePropertiesPart = true;
+                                       else
+                                               throw new InvalidFormatException(
+                                                               "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !");
+                               }
+
+                               PartUnmarshaller partUnmarshaller = partUnmarshallers
+                                               .get(part.contentType);
+
+                               if (partUnmarshaller != null) {
+                                       UnmarshallContext context = new UnmarshallContext(this,
+                                                       part.partName);
+                                       try {
+                                               PackagePart unmarshallPart = partUnmarshaller
+                                                               .unmarshall(context, part.getInputStream());
+                                               partList.put(unmarshallPart.partName, unmarshallPart);
+
+                                               // Core properties case
+                                               if (unmarshallPart instanceof PackagePropertiesPart)
+                                                       this.packageProperties = (PackagePropertiesPart) unmarshallPart;
+                                       } catch (IOException ioe) {
+                                               logger.log(POILogger.WARN, "Unmarshall operation : IOException for "
+                                                               + part.partName);
+                                               continue;
+                                       } catch (InvalidOperationException invoe) {
+                                               throw new InvalidFormatException(invoe.getMessage());
+                                       }
+                               } else {
+                                       try {
+                                               partList.put(part.partName, part);
+                                       } catch (InvalidOperationException e) {
+                                               throw new InvalidFormatException(e.getMessage());
+                                       }
+                               }
+                       }
+               }
+               return new ArrayList<PackagePart>(partList.values());
+       }
+
+       /**
+        * Create and add a part, with the specified name and content type, to the
+        * package.
+        * 
+        * @param partName
+        *            Part name.
+        * @param contentType
+        *            Part content type.
+        * @return The newly created part.
+        * @throws InvalidFormatException
+        *             If rule M1.12 is not verified : Packages shall not contain
+        *             equivalent part names and package implementers shall neither
+        *             create nor recognize packages with equivalent part names.
+        * @see #createPartImpl(PackagePartName, String, boolean) 
+        */
+       public PackagePart createPart(PackagePartName partName, String contentType) {
+               return this.createPart(partName, contentType, true);
+       }
+
+       /**
+        * Create and add a part, with the specified name and content type, to the
+        * package. For general purpose, prefer the overload version of this method
+        * without the 'loadRelationships' parameter.
+        * 
+        * @param partName
+        *            Part name.
+        * @param contentType
+        *            Part content type.
+        * @param loadRelationships
+        *            Specify if the existing relationship part, if any, logically
+        *            associated to the newly created part will be loaded.
+        * @return The newly created part.
+        * @throws InvalidFormatException
+        *             If rule M1.12 is not verified : Packages shall not contain
+        *             equivalent part names and package implementers shall neither
+        *             create nor recognize packages with equivalent part names.
+        * @see {@link#createPartImpl(URI, String)}
+        */
+       PackagePart createPart(PackagePartName partName, String contentType,
+                       boolean loadRelationships) {
+               throwExceptionIfReadOnly();
+               if (partName == null) {
+                       throw new IllegalArgumentException("partName");
+               }
+
+               if (contentType == null || contentType == "") {
+                       throw new IllegalArgumentException("contentType");
+               }
+
+               // Check if the specified part name already exists
+               if (partList.containsKey(partName)
+                               && !partList.get(partName).isDeleted()) {
+                       throw new InvalidOperationException(
+                                       "A part with the name '"
+                                                       + partName.getName()
+                                                       + "' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");
+               }
+
+               /* Check OPC compliance */
+
+               // Rule [M4.1]: The format designer shall specify and the format
+               // producer
+               // shall create at most one core properties relationship for a package.
+               // A format consumer shall consider more than one core properties
+               // relationship for a package to be an error. If present, the
+               // relationship shall target the Core Properties part.
+               if (contentType == ContentTypes.CORE_PROPERTIES_PART) {
+                       if (this.packageProperties != null)
+                               throw new InvalidOperationException(
+                                               "OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !");
+               }
+
+               /* End check OPC compliance */
+
+               PackagePart part = this.createPartImpl(partName, contentType,
+                               loadRelationships);
+               this.contentTypeManager.addContentType(partName, contentType);
+               this.partList.put(partName, part);
+               this.isDirty = true;
+               return part;
+       }
+
+       /**
+        * Add a part to the package.
+        * 
+        * @param partName
+        *            Part name of the part to create.
+        * @param contentType
+        *            type associated with the file
+        * @param content
+        *            the contents to add. In order to have faster operation in
+        *            document merge, the data are stored in memory not on a hard
+        *            disk
+        * 
+        * @return The new part.
+        * @see #createPart(PackagePartName, String)
+        */
+       public PackagePart createPart(PackagePartName partName, String contentType,
+                       ByteArrayOutputStream content) {
+               PackagePart addedPart = this.createPart(partName, contentType);
+               if (addedPart == null) {
+                       return null;
+               }
+               // Extract the zip entry content to put it in the part content
+               if (content != null) {
+                       try {
+                               OutputStream partOutput = addedPart.getOutputStream();
+                               if (partOutput == null) {
+                                       return null;
+                               }
+
+                               partOutput.write(content.toByteArray(), 0, content.size());
+                               partOutput.close();
+
+                       } catch (IOException ioe) {
+                               return null;
+                       }
+               } else {
+                       return null;
+               }
+               return addedPart;
+       }
+
+       /**
+        * Add the specified part to the package. If a part already exists in the
+        * package with the same name as the one specified, then we replace the old
+        * part by the specified part.
+        * 
+        * @param part
+        *            The part to add (or replace).
+        * @return The part added to the package, the same as the one specified.
+        * @throws InvalidFormatException
+        *             If rule M1.12 is not verified : Packages shall not contain
+        *             equivalent part names and package implementers shall neither
+        *             create nor recognize packages with equivalent part names.
+        */
+       protected PackagePart addPackagePart(PackagePart part) {
+               throwExceptionIfReadOnly();
+               if (part == null) {
+                       throw new IllegalArgumentException("part");
+               }
+
+               if (partList.containsKey(part.partName)) {
+                       if (!partList.get(part.partName).isDeleted()) {
+                               throw new InvalidOperationException(
+                                               "A part with the name '"
+                                                               + part.partName.getName()
+                                                               + "' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");
+                       }
+                       // If the specified partis flagged as deleted, we make it
+                       // available
+                       part.setDeleted(false);
+                       // and delete the old part to replace it thereafeter
+                       this.partList.remove(part.partName);
+               }
+               this.partList.put(part.partName, part);
+               this.isDirty = true;
+               return part;
+       }
+
+       /**
+        * Remove the specified part in this package. If this part is relationship
+        * part, then delete all relationships in the source part.
+        * 
+        * @param part
+        *            The part to remove. If <code>null</code>, skip the action.
+        * @see #removePart(PackagePartName)
+        */
+       public void removePart(PackagePart part) {
+               if (part != null) {
+                       removePart(part.getPartName());
+               }
+       }
+
+       /**
+        * Remove a part in this package. If this part is relationship part, then
+        * delete all relationships in the source part.
+        * 
+        * @param partName
+        *            The part name of the part to remove.
+        */
+       public void removePart(PackagePartName partName) {
+               throwExceptionIfReadOnly();
+               if (partName == null || !this.containPart(partName))
+                       throw new IllegalArgumentException("partName");
+
+               // Delete the specified part from the package.
+               if (this.partList.containsKey(partName)) {
+                       this.partList.get(partName).setDeleted(true);
+                       this.removePartImpl(partName);
+                       this.partList.remove(partName);
+               } else {
+                       this.removePartImpl(partName);
+               }
+
+               // Delete content type
+               this.contentTypeManager.removeContentType(partName);
+
+               // If this part is a relationship part, then delete all relationships of
+               // the source part.
+               if (partName.isRelationshipPartURI()) {
+                       URI sourceURI = PackagingURIHelper
+                                       .getSourcePartUriFromRelationshipPartUri(partName.getURI());
+                       PackagePartName sourcePartName;
+                       try {
+                               sourcePartName = PackagingURIHelper.createPartName(sourceURI);
+                       } catch (InvalidFormatException e) {
+                               logger
+                                               .log(POILogger.ERROR, "Part name URI '"
+                                                               + sourceURI
+                                                               + "' is not valid ! This message is not intended to be displayed !");
+                               return;
+                       }
+                       if (sourcePartName.getURI().equals(
+                                       PackagingURIHelper.PACKAGE_ROOT_URI)) {
+                               clearRelationships();
+                       } else if (containPart(sourcePartName)) {
+                               PackagePart part = getPart(sourcePartName);
+                               if (part != null)
+                                       part.clearRelationships();
+                       }
+               }
+
+               this.isDirty = true;
+       }
+
+       /**
+        * Remove a part from this package as well as its relationship part, if one
+        * exists, and all parts listed in the relationship part. Be aware that this
+        * do not delete relationships which target the specified part.
+        * 
+        * @param partName
+        *            The name of the part to delete.
+        * @throws InvalidFormatException
+        *             Throws if the associated relationship part of the specified
+        *             part is not valid.
+        */
+       public void removePartRecursive(PackagePartName partName)
+                       throws InvalidFormatException {
+               // Retrieves relationship part, if one exists
+               PackagePart relPart = this.partList.get(PackagingURIHelper
+                               .getRelationshipPartName(partName));
+               // Retrieves PackagePart object from the package
+               PackagePart partToRemove = this.partList.get(partName);
+
+               if (relPart != null) {
+                       PackageRelationshipCollection partRels = new PackageRelationshipCollection(
+                                       partToRemove);
+                       for (PackageRelationship rel : partRels) {
+                               PackagePartName partNameToRemove = PackagingURIHelper
+                                               .createPartName(PackagingURIHelper.resolvePartUri(rel
+                                                               .getSourceURI(), rel.getTargetURI()));
+                               removePart(partNameToRemove);
+                       }
+
+                       // Finally delete its relationship part if one exists
+                       this.removePart(relPart.partName);
+               }
+
+               // Delete the specified part
+               this.removePart(partToRemove.partName);
+       }
+
+       /**
+        * Delete the part with the specified name and its associated relationships
+        * part if one exists. Prefer the use of this method to delete a part in the
+        * package, compare to the remove() methods that don't remove associated
+        * relationships part.
+        * 
+        * @param partName
+        *            Name of the part to delete
+        */
+       public void deletePart(PackagePartName partName) {
+               if (partName == null)
+                       throw new IllegalArgumentException("partName");
+
+               // Remove the part
+               this.removePart(partName);
+               // Remove the relationships part
+               this.removePart(PackagingURIHelper.getRelationshipPartName(partName));
+       }
+
+       /**
+        * Delete the part with the specified name and all part listed in its
+        * associated relationships part if one exists. This process is recursively
+        * apply to all parts in the relationships part of the specified part.
+        * Prefer the use of this method to delete a part in the package, compare to
+        * the remove() methods that don't remove associated relationships part.
+        * 
+        * @param partName
+        *            Name of the part to delete
+        */
+       public void deletePartRecursive(PackagePartName partName) {
+               if (partName == null || !this.containPart(partName))
+                       throw new IllegalArgumentException("partName");
+
+               PackagePart partToDelete = this.getPart(partName);
+               // Remove the part
+               this.removePart(partName);
+               // Remove all relationship parts associated
+               try {
+                       for (PackageRelationship relationship : partToDelete
+                                       .getRelationships()) {
+                               PackagePartName targetPartName = PackagingURIHelper
+                                               .createPartName(PackagingURIHelper.resolvePartUri(
+                                                               partName.getURI(), relationship.getTargetURI()));
+                               this.deletePartRecursive(targetPartName);
+                       }
+               } catch (InvalidFormatException e) {
+                       logger.log(POILogger.WARN, "An exception occurs while deleting part '"
+                                       + partName.getName()
+                                       + "'. Some parts may remain in the package. - "
+                                       + e.getMessage());
+                       return;
+               }
+               // Remove the relationships part
+               PackagePartName relationshipPartName = PackagingURIHelper
+                               .getRelationshipPartName(partName);
+               if (relationshipPartName != null && containPart(relationshipPartName))
+                       this.removePart(relationshipPartName);
+       }
+
+       /**
+        * Check if a part already exists in this package from its name.
+        * 
+        * @param partName
+        *            Part name to check.
+        * @return <i>true</i> if the part is logically added to this package, else
+        *         <i>false</i>.
+        */
+       public boolean containPart(PackagePartName partName) {
+               return (this.getPart(partName) != null);
+       }
+
+       /**
+        * Add a relationship to the package (except relationships part).
+        * 
+        * Check rule M4.1 : The format designer shall specify and the format
+        * producer shall create at most one core properties relationship for a
+        * package. A format consumer shall consider more than one core properties
+        * relationship for a package to be an error. If present, the relationship
+        * shall target the Core Properties 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
+        *            Target part name.
+        * @param targetMode
+        *            Target mode, either Internal or External.
+        * @param relationshipType
+        *            Relationship type.
+        * @param relID
+        *            ID of the relationship.
+        * @see PackageRelationshipTypes
+        */
+       public PackageRelationship addRelationship(PackagePartName targetPartName,
+                       TargetMode targetMode, String relationshipType, String relID) {
+               /* Check OPC compliance */
+
+               // Check rule M4.1 : The format designer shall specify and the format
+               // producer
+               // shall create at most one core properties relationship for a package.
+               // A format consumer shall consider more than one core properties
+               // relationship for a package to be an error. If present, the
+               // relationship shall target the Core Properties part.
+               if (relationshipType.equals(PackageRelationshipTypes.CORE_PROPERTIES)
+                               && this.packageProperties != null)
+                       throw new InvalidOperationException(
+                                       "OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead.");
+
+               /*
+                * 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.
+                */
+               if (targetPartName.isRelationshipPartURI()) {
+                       throw new InvalidOperationException(
+                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");
+               }
+
+               /* End OPC compliance */
+
+               ensureRelationships();
+               PackageRelationship retRel = relationships.addRelationship(
+                               targetPartName.getURI(), targetMode, relationshipType, relID);
+               this.isDirty = true;
+               return retRel;
+       }
+
+       /**
+        * Add a package relationship.
+        * 
+        * @param targetPartName
+        *            Target part name.
+        * @param targetMode
+        *            Target mode, either Internal or External.
+        * @param relationshipType
+        *            Relationship type.
+        * @see PackageRelationshipTypes
+        */
+       public PackageRelationship addRelationship(PackagePartName targetPartName,
+                       TargetMode targetMode, String relationshipType) {
+               return this.addRelationship(targetPartName, targetMode,
+                               relationshipType, null);
+       }
+
+       /**
+        * 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) {
+               return addExternalRelationship(target, relationshipType, null);
+       }
+
+       /**
+        * 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) {
+               if (target == null) {
+                       throw new IllegalArgumentException("target");
+               }
+               if (relationshipType == null) {
+                       throw new IllegalArgumentException("relationshipType");
+               }
+
+               URI targetURI;
+               try {
+                       targetURI = new URI(target);
+               } catch (URISyntaxException e) {
+                       throw new IllegalArgumentException("Invalid target - " + e);
+               }
+
+               ensureRelationships();
+               PackageRelationship retRel = relationships.addRelationship(targetURI,
+                               TargetMode.EXTERNAL, relationshipType, id);
+               this.isDirty = true;
+               return retRel;
+       }
+
+       /**
+        * Delete a relationship from this package.
+        * 
+        * @param id
+        *            Id of the relationship to delete.
+        */
+       public void removeRelationship(String id) {
+               if (relationships != null) {
+                       relationships.removeRelationship(id);
+                       this.isDirty = true;
+               }
+       }
+
+       /**
+        * Retrieves all package relationships.
+        * 
+        * @return All package relationships of this package.
+        * @throws OpenXML4JException
+        * @see #getRelationshipsHelper(String)
+        */
+       public PackageRelationshipCollection getRelationships() {
+               return getRelationshipsHelper(null);
+       }
+
+       /**
+        * Retrieves all relationships with the specified type.
+        * 
+        * @param relationshipType
+        *            The filter specifying the relationship type.
+        * @return All relationships with the specified relationship type.
+        */
+       public PackageRelationshipCollection getRelationshipsByType(
+                       String relationshipType) {
+               throwExceptionIfWriteOnly();
+               if (relationshipType == null) {
+                       throw new IllegalArgumentException("relationshipType");
+               }
+               return getRelationshipsHelper(relationshipType);
+       }
+
+       /**
+        * Retrieves all relationships with specified id (normally just ine because
+        * a relationship id is supposed to be unique).
+        * 
+        * @param id
+        *            Id of the wanted relationship.
+        */
+       private PackageRelationshipCollection getRelationshipsHelper(String id) {
+               throwExceptionIfWriteOnly();
+               ensureRelationships();
+               return this.relationships.getRelationships(id);
+       }
+
+       /**
+        * Clear package relationships.
+        */
+       public void clearRelationships() {
+               if (relationships != null) {
+                       relationships.clear();
+                       this.isDirty = true;
+               }
+       }
+
+       /**
+        * Ensure that the relationships collection is not null.
+        */
+       public void ensureRelationships() {
+               if (this.relationships == null) {
+                       try {
+                               this.relationships = new PackageRelationshipCollection(this);
+                       } catch (InvalidFormatException e) {
+                               this.relationships = new PackageRelationshipCollection();
+                       }
+               }
+       }
+
+       /**
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String)
+        */
+       public PackageRelationship getRelationship(String id) {
+               return this.relationships.getRelationshipByID(id);
+       }
+
+       /**
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships()
+        */
+       public boolean hasRelationships() {
+               return (relationships.size() > 0);
+       }
+
+       /**
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship)
+        */
+       @SuppressWarnings("finally")
+       public boolean isRelationshipExists(PackageRelationship rel) {
+               try {
+                       for (PackageRelationship r : this.getRelationships()) {
+                               if (r == rel)
+                                       return true;
+                       }
+               } finally {
+                       return false;
+               }
+       }
+
+       /**
+        * Add a marshaller.
+        * 
+        * @param contentType
+        *            The content type to bind to the specified marshaller.
+        * @param marshaller
+        *            The marshaller to register with the specified content type.
+        */
+       public void addMarshaller(String contentType, PartMarshaller marshaller) {
+               try {
+                       partMarshallers.put(new ContentType(contentType), marshaller);
+               } catch (InvalidFormatException e) {
+                       logger.log(POILogger.WARN, "The specified content type is not valid: '"
+                                       + e.getMessage() + "'. The marshaller will not be added !");
+               }
+       }
+
+       /**
+        * Add an unmarshaller.
+        * 
+        * @param contentType
+        *            The content type to bind to the specified unmarshaller.
+        * @param unmarshaller
+        *            The unmarshaller to register with the specified content type.
+        */
+       public void addUnmarshaller(String contentType,
+                       PartUnmarshaller unmarshaller) {
+               try {
+                       partUnmarshallers.put(new ContentType(contentType), unmarshaller);
+               } catch (InvalidFormatException e) {
+                       logger.log(POILogger.WARN, "The specified content type is not valid: '"
+                                       + e.getMessage()
+                                       + "'. The unmarshaller will not be added !");
+               }
+       }
+
+       /**
+        * Remove a marshaller by its content type.
+        * 
+        * @param contentType
+        *            The content type associated with the marshaller to remove.
+        */
+       public void removeMarshaller(String contentType) {
+               partMarshallers.remove(contentType);
+       }
+
+       /**
+        * Remove an unmarshaller by its content type.
+        * 
+        * @param contentType
+        *            The content type associated with the unmarshaller to remove.
+        */
+       public void removeUnmarshaller(String contentType) {
+               partUnmarshallers.remove(contentType);
+       }
+
+       /* Accesseurs */
+
+       /**
+        * Get the package access mode.
+        * 
+        * @return the packageAccess The current package access.
+        */
+       public PackageAccess getPackageAccess() {
+               return packageAccess;
+       }
+
+       /**
+        * Validates the package compliance with the OPC specifications.
+        * 
+        * @return <b>true</b> if the package is valid else <b>false</b>
+        */
+       public boolean validatePackage(OPCPackage pkg) throws InvalidFormatException {
+               throw new InvalidOperationException("Not implemented yet !!!");
+       }
+
+       /**
+        * Save the document in the specified file.
+        * 
+        * @param targetFile
+        *            Destination file.
+        * @throws IOException
+        *             Throws if an IO exception occur.
+        * @see #save(OutputStream)
+        */
+       public void save(File targetFile) throws IOException {
+               if (targetFile == null)
+                       throw new IllegalArgumentException("targetFile");
+
+               this.throwExceptionIfReadOnly();
+               FileOutputStream fos = null;
+               try {
+                       fos = new FileOutputStream(targetFile);
+               } catch (FileNotFoundException e) {
+                       throw new IOException(e.getLocalizedMessage());
+               }
+               this.save(fos);
+       }
+
+       /**
+        * Save the document in the specified output stream.
+        * 
+        * @param outputStream
+        *            The stream to save the package.
+        * @see #saveImpl(OutputStream)
+        */
+       public void save(OutputStream outputStream) throws IOException {
+               throwExceptionIfReadOnly();
+               this.saveImpl(outputStream);
+       }
+
+       /**
+        * Core method to create a package part. This method must be implemented by
+        * the subclass.
+        * 
+        * @param partName
+        *            URI of the part to create.
+        * @param contentType
+        *            Content type of the part to create.
+        * @return The newly created package part.
+        */
+       protected abstract PackagePart createPartImpl(PackagePartName partName,
+                       String contentType, boolean loadRelationships);
+
+       /**
+        * Core method to delete a package part. This method must be implemented by
+        * the subclass.
+        * 
+        * @param partName
+        *            The URI of the part to delete.
+        */
+       protected abstract void removePartImpl(PackagePartName partName);
+
+       /**
+        * Flush the package but not save.
+        */
+       protected abstract void flushImpl();
+
+       /**
+        * Close the package and cause a save of the package.
+        * 
+        */
+       protected abstract void closeImpl() throws IOException;
+
+       /**
+        * Close the package without saving the document. Discard all changes made
+        * to this package.
+        */
+       protected abstract void revertImpl();
+
+       /**
+        * Save the package into the specified output stream.
+        * 
+        * @param outputStream
+        *            The output stream use to save this package.
+        */
+       protected abstract void saveImpl(OutputStream outputStream)
+                       throws IOException;
+
+       /**
+        * Get the package part mapped to the specified URI.
+        * 
+        * @param partName
+        *            The URI of the part to retrieve.
+        * @return The package part located by the specified URI, else <b>null</b>.
+        */
+       protected abstract PackagePart getPartImpl(PackagePartName partName);
+
+       /**
+        * Get all parts link to the package.
+        * 
+        * @return A list of the part owned by the package.
+        */
+       protected abstract PackagePart[] getPartsImpl()
+                       throws InvalidFormatException;
+}
index 918337178fa0e4311ad6bb229e5a1d3b13b4b0ae..0a41045614ed10658a56069e6431baf6427278ab 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-import java.util.ArrayList;\r
-import java.util.Date;\r
-import java.util.Hashtable;\r
-import java.util.concurrent.locks.ReentrantReadWriteLock;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;\r
-import org.apache.poi.openxml4j.opc.internal.ContentType;\r
-import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;\r
-import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;\r
-import org.apache.poi.openxml4j.opc.internal.PartMarshaller;\r
-import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;\r
-import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager;\r
-import org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller;\r
-import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller;\r
-import org.apache.poi.openxml4j.opc.internal.unmarshallers.PackagePropertiesUnmarshaller;\r
-import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext;\r
-import org.apache.poi.openxml4j.util.Nullable;\r
-import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.POILogFactory;\r
-\r
-/**\r
- * Represents a container that can store multiple data objects.\r
- * \r
- * @author Julien Chable, CDubet\r
- * @version 0.1\r
- */\r
-public abstract class Package implements RelationshipSource {\r
-\r
-       /**\r
-        * Logger.\r
-        */\r
-    private static POILogger logger = POILogFactory.getLogger(Package.class);\r
-\r
-       /**\r
-        * Default package access.\r
-        */\r
-       protected static final PackageAccess defaultPackageAccess = PackageAccess.READ_WRITE;\r
-\r
-       /**\r
-        * Package access.\r
-        */\r
-       private PackageAccess packageAccess;\r
-\r
-       /**\r
-        * Package parts collection.\r
-        */\r
-       protected PackagePartCollection partList;\r
-\r
-       /**\r
-        * Package relationships.\r
-        */\r
-       protected PackageRelationshipCollection relationships;\r
-\r
-       /**\r
-        * Part marshallers by content type.\r
-        */\r
-       protected Hashtable<ContentType, PartMarshaller> partMarshallers;\r
-\r
-       /**\r
-        * Default part marshaller.\r
-        */\r
-       protected PartMarshaller defaultPartMarshaller;\r
-\r
-       /**\r
-        * Part unmarshallers by content type.\r
-        */\r
-       protected Hashtable<ContentType, PartUnmarshaller> partUnmarshallers;\r
-\r
-       /**\r
-        * Core package properties.\r
-        */\r
-       protected PackagePropertiesPart packageProperties;\r
-\r
-       /**\r
-        * Manage parts content types of this package.\r
-        */\r
-       protected ContentTypeManager contentTypeManager;\r
-\r
-       /**\r
-        * Flag if a modification is done to the document.\r
-        */\r
-       protected boolean isDirty = false;\r
-\r
-       /**\r
-        * File path of this package.\r
-        */\r
-       protected String originalPackagePath;\r
-\r
-       /**\r
-        * Output stream for writing this package.\r
-        */\r
-       protected OutputStream output;\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param access\r
-        *            Package access.\r
-        */\r
-       protected Package(PackageAccess access) {\r
-               init();\r
-               this.packageAccess = access;\r
-       }\r
-\r
-       /**\r
-        * Initialize the package instance.\r
-        */\r
-       private void init() {\r
-               this.partMarshallers = new Hashtable<ContentType, PartMarshaller>(5);\r
-               this.partUnmarshallers = new Hashtable<ContentType, PartUnmarshaller>(2);\r
-\r
-               try {\r
-                       // Add 'default' unmarshaller\r
-                       this.partUnmarshallers.put(new ContentType(\r
-                                       ContentTypes.CORE_PROPERTIES_PART),\r
-                                       new PackagePropertiesUnmarshaller());\r
-\r
-                       // Add default marshaller\r
-                       this.defaultPartMarshaller = new DefaultMarshaller();\r
-                       // TODO Delocalize specialized marshallers\r
-                       this.partMarshallers.put(new ContentType(\r
-                                       ContentTypes.CORE_PROPERTIES_PART),\r
-                                       new ZipPackagePropertiesMarshaller());\r
-               } catch (InvalidFormatException e) {\r
-                       // Should never happpen\r
-                       throw new OpenXML4JRuntimeException(\r
-                                       "Package.init() : this exception should never happen, if you read this message please send a mail to the developers team.");\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Open a package with read/write permission.\r
-        * \r
-        * @param path\r
-        *            The document path.\r
-        * @return A Package object, else <b>null</b>.\r
-        * @throws InvalidFormatException\r
-        *             If the specified file doesn't exist, and a parsing error\r
-        *             occur.\r
-        */\r
-       public static Package open(String path) throws InvalidFormatException {\r
-               return open(path, defaultPackageAccess);\r
-       }\r
-\r
-       /**\r
-        * Open a package.\r
-        * \r
-        * @param path\r
-        *            The document path.\r
-        * @param access\r
-        *            Package access.\r
-        * @return A Package object, else <b>null</b>.\r
-        * @throws InvalidFormatException\r
-        *             If the specified file doesn't exist, and a parsing error\r
-        *             occur.\r
-        */\r
-       public static Package open(String path, PackageAccess access)\r
-                       throws InvalidFormatException {\r
-               if (path == null || "".equals(path.trim())\r
-                               || (new File(path).exists() && new File(path).isDirectory()))\r
-                       throw new IllegalArgumentException("path");\r
-\r
-               Package pack = new ZipPackage(path, access);\r
-               if (pack.partList == null && access != PackageAccess.WRITE) {\r
-                       pack.getParts();\r
-               }\r
-               pack.originalPackagePath = new File(path).getAbsolutePath();\r
-               return pack;\r
-       }\r
-\r
-       /**\r
-        * Open a package.\r
-        * \r
-        * Note - uses quite a bit more memory than {@link #open(String)}, which\r
-        * doesn't need to hold the whole zip file in memory, and can take advantage\r
-        * of native methods\r
-        * \r
-        * @param in\r
-        *            The InputStream to read the package from\r
-        * @return A Package object\r
-        */\r
-       public static Package open(InputStream in) throws InvalidFormatException,\r
-                       IOException {\r
-               Package pack = new ZipPackage(in, PackageAccess.READ);\r
-               if (pack.partList == null) {\r
-                       pack.getParts();\r
-               }\r
-               return pack;\r
-       }\r
-\r
-       /**\r
-        * Opens a package if it exists, else it creates one.\r
-        * \r
-        * @param file\r
-        *            The file to open or to create.\r
-        * @return A newly created package if the specified file does not exist,\r
-        *         else the package extract from the file.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the specified file exist and is not valid.\r
-        */\r
-       public static Package openOrCreate(File file) throws InvalidFormatException {\r
-               Package retPackage = null;\r
-               if (file.exists()) {\r
-                       retPackage = open(file.getAbsolutePath());\r
-               } else {\r
-                       retPackage = create(file);\r
-               }\r
-               return retPackage;\r
-       }\r
-\r
-       /**\r
-        * Creates a new package.\r
-        * \r
-        * @param path\r
-        *            Path of the document.\r
-        * @return A newly created Package ready to use.\r
-        */\r
-       public static Package create(String path) {\r
-               return create(new File(path));\r
-       }\r
-\r
-       /**\r
-        * Creates a new package.\r
-        * \r
-        * @param file\r
-        *            Path of the document.\r
-        * @return A newly created Package ready to use.\r
-        */\r
-       public static Package create(File file) {\r
-               if (file == null || (file.exists() && file.isDirectory()))\r
-                       throw new IllegalArgumentException("file");\r
-\r
-               if (file.exists()) {\r
-                       throw new InvalidOperationException(\r
-                                       "This package (or file) already exists : use the open() method or delete the file.");\r
-               }\r
-\r
-               // Creates a new package\r
-               Package pkg = null;\r
-               pkg = new ZipPackage();\r
-               pkg.originalPackagePath = file.getAbsolutePath();\r
-\r
-               configurePackage(pkg);\r
-               return pkg;\r
-       }\r
-\r
-       public static Package create(OutputStream output) {\r
-               Package pkg = null;\r
-               pkg = new ZipPackage();\r
-               pkg.originalPackagePath = null;\r
-               pkg.output = output;\r
-\r
-               configurePackage(pkg);\r
-               return pkg;\r
-       }\r
-\r
-       /**\r
-        * Configure the package.\r
-        * \r
-        * @param pkg\r
-        */\r
-       private static void configurePackage(Package pkg) {\r
-               try {\r
-                       // Content type manager\r
-                       pkg.contentTypeManager = new ZipContentTypeManager(null, pkg);\r
-                       // Add default content types for .xml and .rels\r
-                       pkg.contentTypeManager\r
-                                       .addContentType(\r
-                                                       PackagingURIHelper\r
-                                                                       .createPartName(PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_URI),\r
-                                                       ContentTypes.RELATIONSHIPS_PART);\r
-                       pkg.contentTypeManager\r
-                                       .addContentType(PackagingURIHelper\r
-                                                       .createPartName("/default.xml"),\r
-                                                       ContentTypes.PLAIN_OLD_XML);\r
-\r
-                       // Init some Package properties\r
-                       pkg.packageProperties = new PackagePropertiesPart(pkg,\r
-                                       PackagingURIHelper.CORE_PROPERTIES_PART_NAME);\r
-                       pkg.packageProperties.setCreatorProperty("Generated by OpenXML4J");\r
-                       pkg.packageProperties.setCreatedProperty(new Nullable<Date>(\r
-                                       new Date()));\r
-               } catch (InvalidFormatException e) {\r
-                       // Should never happen\r
-                       throw new IllegalStateException(e);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Flush the package : save all.\r
-        * \r
-        * @see #close()\r
-        */\r
-       public void flush() {\r
-               throwExceptionIfReadOnly();\r
-\r
-               if (this.packageProperties != null)\r
-                       ((PackagePropertiesPart) this.packageProperties).flush();\r
-\r
-               this.flushImpl();\r
-       }\r
-\r
-       /**\r
-        * Close the package and save its content.\r
-        * \r
-        * @throws IOException\r
-        *             If an IO exception occur during the saving process.\r
-        */\r
-       public void close() throws IOException {\r
-               if (this.packageAccess == PackageAccess.READ) {\r
-                       logger\r
-                                       .log(POILogger.WARN, "The close() method is intended to SAVE a package. This package is open in READ ONLY mode, use the revert() method instead !");\r
-                       return;\r
-               }\r
-\r
-               // Save the content\r
-               ReentrantReadWriteLock l = new ReentrantReadWriteLock();\r
-               try {\r
-                       l.writeLock().lock();\r
-                       if (this.originalPackagePath != null\r
-                                       && !"".equals(this.originalPackagePath.trim())) {\r
-                               File targetFile = new File(this.originalPackagePath);\r
-                               if (!targetFile.exists()\r
-                                               || !(this.originalPackagePath\r
-                                                               .equalsIgnoreCase(targetFile.getAbsolutePath()))) {\r
-                                       // Case of a package created from scratch\r
-                                       save(targetFile);\r
-                               } else {\r
-                                       closeImpl();\r
-                               }\r
-                       } else if (this.output != null) {\r
-                               save(this.output);\r
-                       }\r
-               } finally {\r
-                       l.writeLock().unlock();\r
-               }\r
-\r
-               // Clear\r
-               this.contentTypeManager.clearAll();\r
-\r
-               // Call the garbage collector\r
-               Runtime.getRuntime().gc();\r
-       }\r
-\r
-       /**\r
-        * Close the package WITHOUT saving its content. Reinitialize this package\r
-        * and cancel all changes done to it.\r
-        */\r
-       public void revert() {\r
-               revertImpl();\r
-       }\r
-\r
-       /**\r
-        * Add a thumbnail to the package. This method is provided to make easier\r
-        * the addition of a thumbnail in a package. You can do the same work by\r
-        * using the traditionnal relationship and part mechanism.\r
-        * \r
-        * @param path\r
-        *            The full path to the image file.\r
-        */\r
-       public void addThumbnail(String path) throws IOException {\r
-               // Check parameter\r
-               if ("".equals(path))\r
-                       throw new IllegalArgumentException("path");\r
-\r
-               // Get the filename from the path\r
-               String filename = path\r
-                               .substring(path.lastIndexOf(File.separatorChar) + 1);\r
-\r
-               // Create the thumbnail part name\r
-               String contentType = ContentTypes\r
-                               .getContentTypeFromFileExtension(filename);\r
-               PackagePartName thumbnailPartName = null;\r
-               try {\r
-                       thumbnailPartName = PackagingURIHelper.createPartName("/docProps/"\r
-                                       + filename);\r
-               } catch (InvalidFormatException e) {\r
-                       try {\r
-                               thumbnailPartName = PackagingURIHelper\r
-                                               .createPartName("/docProps/thumbnail"\r
-                                                               + path.substring(path.lastIndexOf(".") + 1));\r
-                       } catch (InvalidFormatException e2) {\r
-                               throw new InvalidOperationException(\r
-                                               "Can't add a thumbnail file named '" + filename + "'");\r
-                       }\r
-               }\r
-\r
-               // Check if part already exist\r
-               if (this.getPart(thumbnailPartName) != null)\r
-                       throw new InvalidOperationException(\r
-                                       "You already add a thumbnail named '" + filename + "'");\r
-\r
-               // Add the thumbnail part to this package.\r
-               PackagePart thumbnailPart = this.createPart(thumbnailPartName,\r
-                               contentType, false);\r
-\r
-               // Add the relationship between the package and the thumbnail part\r
-               this.addRelationship(thumbnailPartName, TargetMode.INTERNAL,\r
-                               PackageRelationshipTypes.THUMBNAIL);\r
-\r
-               // Copy file data to the newly created part\r
-               StreamHelper.copyStream(new FileInputStream(path), thumbnailPart\r
-                               .getOutputStream());\r
-       }\r
-\r
-       /**\r
-        * Throws an exception if the package access mode is in read only mode\r
-        * (PackageAccess.Read).\r
-        * \r
-        * @throws InvalidOperationException\r
-        *             Throws if a writing operation is done on a read only package.\r
-        * @see org.apache.poi.openxml4j.opc.PackageAccess\r
-        */\r
-       void throwExceptionIfReadOnly() throws InvalidOperationException {\r
-               if (packageAccess == PackageAccess.READ)\r
-                       throw new InvalidOperationException(\r
-                                       "Operation not allowed, document open in read only mode!");\r
-       }\r
-\r
-       /**\r
-        * Throws an exception if the package access mode is in write only mode\r
-        * (PackageAccess.Write). This method is call when other methods need write\r
-        * right.\r
-        * \r
-        * @throws InvalidOperationException\r
-        *             Throws if a read operation is done on a write only package.\r
-        * @see org.apache.poi.openxml4j.opc.PackageAccess\r
-        */\r
-       void throwExceptionIfWriteOnly() throws InvalidOperationException {\r
-               if (packageAccess == PackageAccess.WRITE)\r
-                       throw new InvalidOperationException(\r
-                                       "Operation not allowed, document open in write only mode!");\r
-       }\r
-\r
-       /**\r
-        * Retrieves or creates if none exists, core package property part.\r
-        * \r
-        * @return The PackageProperties part of this package.\r
-        */\r
-       public PackageProperties getPackageProperties()\r
-                       throws InvalidFormatException {\r
-               this.throwExceptionIfWriteOnly();\r
-               // If no properties part has been found then we create one\r
-               if (this.packageProperties == null) {\r
-                       this.packageProperties = new PackagePropertiesPart(this,\r
-                                       PackagingURIHelper.CORE_PROPERTIES_PART_NAME);\r
-               }\r
-               return this.packageProperties;\r
-       }\r
-\r
-       /**\r
-        * Retrieve a part identified by its name.\r
-        * \r
-        * @param partName\r
-        *            Part name of the part to retrieve.\r
-        * @return The part with the specified name, else <code>null</code>.\r
-        */\r
-       public PackagePart getPart(PackagePartName partName) {\r
-               throwExceptionIfWriteOnly();\r
-\r
-               if (partName == null)\r
-                       throw new IllegalArgumentException("partName");\r
-\r
-               // If the partlist is null, then we parse the package.\r
-               if (partList == null) {\r
-                       try {\r
-                               getParts();\r
-                       } catch (InvalidFormatException e) {\r
-                               return null;\r
-                       }\r
-               }\r
-               return getPartImpl(partName);\r
-       }\r
-\r
-       /**\r
-        * Retrieve parts by content type.\r
-        * \r
-        * @param contentType\r
-        *            The content type criteria.\r
-        * @return All part associated to the specified content type.\r
-        */\r
-       public ArrayList<PackagePart> getPartsByContentType(String contentType) {\r
-               ArrayList<PackagePart> retArr = new ArrayList<PackagePart>();\r
-               for (PackagePart part : partList.values()) {\r
-                       if (part.getContentType().equals(contentType))\r
-                               retArr.add(part);\r
-               }\r
-               return retArr;\r
-       }\r
-\r
-       /**\r
-        * Retrieve parts by relationship type.\r
-        * \r
-        * @param relationshipType\r
-        *            Relationship type.\r
-        * @return All parts which are the target of a relationship with the\r
-        *         specified type, if the method can't retrieve relationships from\r
-        *         the package, then return <code>null</code>.\r
-        */\r
-       public ArrayList<PackagePart> getPartsByRelationshipType(\r
-                       String relationshipType) {\r
-               if (relationshipType == null)\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               ArrayList<PackagePart> retArr = new ArrayList<PackagePart>();\r
-               try {\r
-                       for (PackageRelationship rel : getRelationshipsByType(relationshipType)) {\r
-                               retArr.add(getPart(rel));\r
-                       }\r
-               } catch (OpenXML4JException e) {\r
-                       logger\r
-                                       .log(POILogger.WARN, "Can't retrieve parts by relationship type: an exception has been thrown by getRelationshipsByType method");\r
-                       return null;\r
-               }\r
-               return retArr;\r
-       }\r
-\r
-       /**\r
-        * Get the target part from the specified relationship.\r
-        * \r
-        * @param partRel\r
-        *            The part relationship uses to retrieve the part.\r
-        */\r
-       public PackagePart getPart(PackageRelationship partRel) {\r
-               PackagePart retPart = null;\r
-               ensureRelationships();\r
-               for (PackageRelationship rel : relationships) {\r
-                       if (rel.getRelationshipType().equals(partRel.getRelationshipType())) {\r
-                               try {\r
-                                       retPart = getPart(PackagingURIHelper.createPartName(rel\r
-                                                       .getTargetURI()));\r
-                               } catch (InvalidFormatException e) {\r
-                                       continue;\r
-                               }\r
-                               break;\r
-                       }\r
-               }\r
-               return retPart;\r
-       }\r
-\r
-       /**\r
-        * Load the parts of the archive if it has not been done yet The\r
-        * relationships of each part are not loaded\r
-        * \r
-        * @return All this package's parts.\r
-        */\r
-       public ArrayList<PackagePart> getParts() throws InvalidFormatException {\r
-               throwExceptionIfWriteOnly();\r
-\r
-               // If the part list is null, we parse the package to retrieve all parts.\r
-               if (partList == null) {\r
-                       /* Variables use to validate OPC Compliance */\r
-\r
-                       // Ensure rule M4.1 -> A format consumer shall consider more than\r
-                       // one core properties relationship for a package to be an error\r
-                       boolean hasCorePropertiesPart = false;\r
-\r
-                       PackagePart[] parts = this.getPartsImpl();\r
-                       this.partList = new PackagePartCollection();\r
-                       for (PackagePart part : parts) {\r
-                               if (partList.containsKey(part.partName))\r
-                                       throw new InvalidFormatException(\r
-                                                       "A part with the name '"\r
-                                                                       + part.partName\r
-                                                                       + "' already exist : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");\r
-\r
-                               // Check OPC compliance rule M4.1\r
-                               if (part.getContentType().equals(\r
-                                               ContentTypes.CORE_PROPERTIES_PART)) {\r
-                                       if (!hasCorePropertiesPart)\r
-                                               hasCorePropertiesPart = true;\r
-                                       else\r
-                                               throw new InvalidFormatException(\r
-                                                               "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !");\r
-                               }\r
-\r
-                               PartUnmarshaller partUnmarshaller = partUnmarshallers\r
-                                               .get(part.contentType);\r
-\r
-                               if (partUnmarshaller != null) {\r
-                                       UnmarshallContext context = new UnmarshallContext(this,\r
-                                                       part.partName);\r
-                                       try {\r
-                                               PackagePart unmarshallPart = partUnmarshaller\r
-                                                               .unmarshall(context, part.getInputStream());\r
-                                               partList.put(unmarshallPart.partName, unmarshallPart);\r
-\r
-                                               // Core properties case\r
-                                               if (unmarshallPart instanceof PackagePropertiesPart)\r
-                                                       this.packageProperties = (PackagePropertiesPart) unmarshallPart;\r
-                                       } catch (IOException ioe) {\r
-                                               logger.log(POILogger.WARN, "Unmarshall operation : IOException for "\r
-                                                               + part.partName);\r
-                                               continue;\r
-                                       } catch (InvalidOperationException invoe) {\r
-                                               throw new InvalidFormatException(invoe.getMessage());\r
-                                       }\r
-                               } else {\r
-                                       try {\r
-                                               partList.put(part.partName, part);\r
-                                       } catch (InvalidOperationException e) {\r
-                                               throw new InvalidFormatException(e.getMessage());\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               return new ArrayList<PackagePart>(partList.values());\r
-       }\r
-\r
-       /**\r
-        * Create and add a part, with the specified name and content type, to the\r
-        * package.\r
-        * \r
-        * @param partName\r
-        *            Part name.\r
-        * @param contentType\r
-        *            Part content type.\r
-        * @return The newly created part.\r
-        * @throws InvalidFormatException\r
-        *             If rule M1.12 is not verified : Packages shall not contain\r
-        *             equivalent part names and package implementers shall neither\r
-        *             create nor recognize packages with equivalent part names.\r
-        * @see #createPartImpl(PackagePartName, String, boolean) \r
-        */\r
-       public PackagePart createPart(PackagePartName partName, String contentType) {\r
-               return this.createPart(partName, contentType, true);\r
-       }\r
-\r
-       /**\r
-        * Create and add a part, with the specified name and content type, to the\r
-        * package. For general purpose, prefer the overload version of this method\r
-        * without the 'loadRelationships' parameter.\r
-        * \r
-        * @param partName\r
-        *            Part name.\r
-        * @param contentType\r
-        *            Part content type.\r
-        * @param loadRelationships\r
-        *            Specify if the existing relationship part, if any, logically\r
-        *            associated to the newly created part will be loaded.\r
-        * @return The newly created part.\r
-        * @throws InvalidFormatException\r
-        *             If rule M1.12 is not verified : Packages shall not contain\r
-        *             equivalent part names and package implementers shall neither\r
-        *             create nor recognize packages with equivalent part names.\r
-        * @see {@link#createPartImpl(URI, String)}\r
-        */\r
-       PackagePart createPart(PackagePartName partName, String contentType,\r
-                       boolean loadRelationships) {\r
-               throwExceptionIfReadOnly();\r
-               if (partName == null) {\r
-                       throw new IllegalArgumentException("partName");\r
-               }\r
-\r
-               if (contentType == null || contentType == "") {\r
-                       throw new IllegalArgumentException("contentType");\r
-               }\r
-\r
-               // Check if the specified part name already exists\r
-               if (partList.containsKey(partName)\r
-                               && !partList.get(partName).isDeleted()) {\r
-                       throw new InvalidOperationException(\r
-                                       "A part with the name '"\r
-                                                       + partName.getName()\r
-                                                       + "' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");\r
-               }\r
-\r
-               /* Check OPC compliance */\r
-\r
-               // Rule [M4.1]: The format designer shall specify and the format\r
-               // producer\r
-               // shall create at most one core properties relationship for a package.\r
-               // A format consumer shall consider more than one core properties\r
-               // relationship for a package to be an error. If present, the\r
-               // relationship shall target the Core Properties part.\r
-               if (contentType == ContentTypes.CORE_PROPERTIES_PART) {\r
-                       if (this.packageProperties != null)\r
-                               throw new InvalidOperationException(\r
-                                               "OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !");\r
-               }\r
-\r
-               /* End check OPC compliance */\r
-\r
-               PackagePart part = this.createPartImpl(partName, contentType,\r
-                               loadRelationships);\r
-               this.contentTypeManager.addContentType(partName, contentType);\r
-               this.partList.put(partName, part);\r
-               this.isDirty = true;\r
-               return part;\r
-       }\r
-\r
-       /**\r
-        * Add a part to the package.\r
-        * \r
-        * @param partName\r
-        *            Part name of the part to create.\r
-        * @param contentType\r
-        *            type associated with the file\r
-        * @param content\r
-        *            the contents to add. In order to have faster operation in\r
-        *            document merge, the data are stored in memory not on a hard\r
-        *            disk\r
-        * \r
-        * @return The new part.\r
-        * @see #createPart(PackagePartName, String)\r
-        */\r
-       public PackagePart createPart(PackagePartName partName, String contentType,\r
-                       ByteArrayOutputStream content) {\r
-               PackagePart addedPart = this.createPart(partName, contentType);\r
-               if (addedPart == null) {\r
-                       return null;\r
-               }\r
-               // Extract the zip entry content to put it in the part content\r
-               if (content != null) {\r
-                       try {\r
-                               OutputStream partOutput = addedPart.getOutputStream();\r
-                               if (partOutput == null) {\r
-                                       return null;\r
-                               }\r
-\r
-                               partOutput.write(content.toByteArray(), 0, content.size());\r
-                               partOutput.close();\r
-\r
-                       } catch (IOException ioe) {\r
-                               return null;\r
-                       }\r
-               } else {\r
-                       return null;\r
-               }\r
-               return addedPart;\r
-       }\r
-\r
-       /**\r
-        * Add the specified part to the package. If a part already exists in the\r
-        * package with the same name as the one specified, then we replace the old\r
-        * part by the specified part.\r
-        * \r
-        * @param part\r
-        *            The part to add (or replace).\r
-        * @return The part added to the package, the same as the one specified.\r
-        * @throws InvalidFormatException\r
-        *             If rule M1.12 is not verified : Packages shall not contain\r
-        *             equivalent part names and package implementers shall neither\r
-        *             create nor recognize packages with equivalent part names.\r
-        */\r
-       protected PackagePart addPackagePart(PackagePart part) {\r
-               throwExceptionIfReadOnly();\r
-               if (part == null) {\r
-                       throw new IllegalArgumentException("part");\r
-               }\r
-\r
-               if (partList.containsKey(part.partName)) {\r
-                       if (!partList.get(part.partName).isDeleted()) {\r
-                               throw new InvalidOperationException(\r
-                                               "A part with the name '"\r
-                                                               + part.partName.getName()\r
-                                                               + "' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");\r
-                       } else {\r
-                               // If the specified partis flagged as deleted, we make it\r
-                               // available\r
-                               part.setDeleted(false);\r
-                               // and delete the old part to replace it thereafeter\r
-                               this.partList.remove(part.partName);\r
-                       }\r
-               }\r
-               this.partList.put(part.partName, part);\r
-               this.isDirty = true;\r
-               return part;\r
-       }\r
-\r
-       /**\r
-        * Remove the specified part in this package. If this part is relationship\r
-        * part, then delete all relationships in the source part.\r
-        * \r
-        * @param part\r
-        *            The part to remove. If <code>null</code>, skip the action.\r
-        * @see #removePart(PackagePartName)\r
-        */\r
-       public void removePart(PackagePart part) {\r
-               if (part != null) {\r
-                       removePart(part.getPartName());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Remove a part in this package. If this part is relationship part, then\r
-        * delete all relationships in the source part.\r
-        * \r
-        * @param partName\r
-        *            The part name of the part to remove.\r
-        */\r
-       public void removePart(PackagePartName partName) {\r
-               throwExceptionIfReadOnly();\r
-               if (partName == null || !this.containPart(partName))\r
-                       throw new IllegalArgumentException("partName");\r
-\r
-               // Delete the specified part from the package.\r
-               if (this.partList.containsKey(partName)) {\r
-                       this.partList.get(partName).setDeleted(true);\r
-                       this.removePartImpl(partName);\r
-                       this.partList.remove(partName);\r
-               } else {\r
-                       this.removePartImpl(partName);\r
-               }\r
-\r
-               // Delete content type\r
-               this.contentTypeManager.removeContentType(partName);\r
-\r
-               // If this part is a relationship part, then delete all relationships of\r
-               // the source part.\r
-               if (partName.isRelationshipPartURI()) {\r
-                       URI sourceURI = PackagingURIHelper\r
-                                       .getSourcePartUriFromRelationshipPartUri(partName.getURI());\r
-                       PackagePartName sourcePartName;\r
-                       try {\r
-                               sourcePartName = PackagingURIHelper.createPartName(sourceURI);\r
-                       } catch (InvalidFormatException e) {\r
-                               logger\r
-                                               .log(POILogger.ERROR, "Part name URI '"\r
-                                                               + sourceURI\r
-                                                               + "' is not valid ! This message is not intended to be displayed !");\r
-                               return;\r
-                       }\r
-                       if (sourcePartName.getURI().equals(\r
-                                       PackagingURIHelper.PACKAGE_ROOT_URI)) {\r
-                               clearRelationships();\r
-                       } else if (containPart(sourcePartName)) {\r
-                               PackagePart part = getPart(sourcePartName);\r
-                               if (part != null)\r
-                                       part.clearRelationships();\r
-                       }\r
-               }\r
-\r
-               this.isDirty = true;\r
-       }\r
-\r
-       /**\r
-        * Remove a part from this package as well as its relationship part, if one\r
-        * exists, and all parts listed in the relationship part. Be aware that this\r
-        * do not delete relationships which target the specified part.\r
-        * \r
-        * @param partName\r
-        *            The name of the part to delete.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the associated relationship part of the specified\r
-        *             part is not valid.\r
-        */\r
-       public void removePartRecursive(PackagePartName partName)\r
-                       throws InvalidFormatException {\r
-               // Retrieves relationship part, if one exists\r
-               PackagePart relPart = this.partList.get(PackagingURIHelper\r
-                               .getRelationshipPartName(partName));\r
-               // Retrieves PackagePart object from the package\r
-               PackagePart partToRemove = this.partList.get(partName);\r
-\r
-               if (relPart != null) {\r
-                       PackageRelationshipCollection partRels = new PackageRelationshipCollection(\r
-                                       partToRemove);\r
-                       for (PackageRelationship rel : partRels) {\r
-                               PackagePartName partNameToRemove = PackagingURIHelper\r
-                                               .createPartName(PackagingURIHelper.resolvePartUri(rel\r
-                                                               .getSourceURI(), rel.getTargetURI()));\r
-                               removePart(partNameToRemove);\r
-                       }\r
-\r
-                       // Finally delete its relationship part if one exists\r
-                       this.removePart(relPart.partName);\r
-               }\r
-\r
-               // Delete the specified part\r
-               this.removePart(partToRemove.partName);\r
-       }\r
-\r
-       /**\r
-        * Delete the part with the specified name and its associated relationships\r
-        * part if one exists. Prefer the use of this method to delete a part in the\r
-        * package, compare to the remove() methods that don't remove associated\r
-        * relationships part.\r
-        * \r
-        * @param partName\r
-        *            Name of the part to delete\r
-        */\r
-       public void deletePart(PackagePartName partName) {\r
-               if (partName == null)\r
-                       throw new IllegalArgumentException("partName");\r
-\r
-               // Remove the part\r
-               this.removePart(partName);\r
-               // Remove the relationships part\r
-               this.removePart(PackagingURIHelper.getRelationshipPartName(partName));\r
-       }\r
-\r
-       /**\r
-        * Delete the part with the specified name and all part listed in its\r
-        * associated relationships part if one exists. This process is recursively\r
-        * apply to all parts in the relationships part of the specified part.\r
-        * Prefer the use of this method to delete a part in the package, compare to\r
-        * the remove() methods that don't remove associated relationships part.\r
-        * \r
-        * @param partName\r
-        *            Name of the part to delete\r
-        */\r
-       public void deletePartRecursive(PackagePartName partName) {\r
-               if (partName == null || !this.containPart(partName))\r
-                       throw new IllegalArgumentException("partName");\r
-\r
-               PackagePart partToDelete = this.getPart(partName);\r
-               // Remove the part\r
-               this.removePart(partName);\r
-               // Remove all relationship parts associated\r
-               try {\r
-                       for (PackageRelationship relationship : partToDelete\r
-                                       .getRelationships()) {\r
-                               PackagePartName targetPartName = PackagingURIHelper\r
-                                               .createPartName(PackagingURIHelper.resolvePartUri(\r
-                                                               partName.getURI(), relationship.getTargetURI()));\r
-                               this.deletePartRecursive(targetPartName);\r
-                       }\r
-               } catch (InvalidFormatException e) {\r
-                       logger.log(POILogger.WARN, "An exception occurs while deleting part '"\r
-                                       + partName.getName()\r
-                                       + "'. Some parts may remain in the package. - "\r
-                                       + e.getMessage());\r
-                       return;\r
-               }\r
-               // Remove the relationships part\r
-               PackagePartName relationshipPartName = PackagingURIHelper\r
-                               .getRelationshipPartName(partName);\r
-               if (relationshipPartName != null && containPart(relationshipPartName))\r
-                       this.removePart(relationshipPartName);\r
-       }\r
-\r
-       /**\r
-        * Check if a part already exists in this package from its name.\r
-        * \r
-        * @param partName\r
-        *            Part name to check.\r
-        * @return <i>true</i> if the part is logically added to this package, else\r
-        *         <i>false</i>.\r
-        */\r
-       public boolean containPart(PackagePartName partName) {\r
-               return (this.getPart(partName) != null);\r
-       }\r
-\r
-       /**\r
-        * Add a relationship to the package (except relationships part).\r
-        * \r
-        * Check rule M4.1 : The format designer shall specify and the format\r
-        * producer shall create at most one core properties relationship for a\r
-        * package. A format consumer shall consider more than one core properties\r
-        * relationship for a package to be an error. If present, the relationship\r
-        * shall target the Core Properties part.\r
-        * \r
-        * Check rule M1.25: The Relationships part shall not have relationships to\r
-        * any other part. Package implementers shall enforce this requirement upon\r
-        * the attempt to create such a relationship and shall treat any such\r
-        * relationship as invalid.\r
-        * \r
-        * @param targetPartName\r
-        *            Target part name.\r
-        * @param targetMode\r
-        *            Target mode, either Internal or External.\r
-        * @param relationshipType\r
-        *            Relationship type.\r
-        * @param relID\r
-        *            ID of the relationship.\r
-        * @see PackageRelationshipTypes\r
-        */\r
-       public PackageRelationship addRelationship(PackagePartName targetPartName,\r
-                       TargetMode targetMode, String relationshipType, String relID) {\r
-               /* Check OPC compliance */\r
-\r
-               // Check rule M4.1 : The format designer shall specify and the format\r
-               // producer\r
-               // shall create at most one core properties relationship for a package.\r
-               // A format consumer shall consider more than one core properties\r
-               // relationship for a package to be an error. If present, the\r
-               // relationship shall target the Core Properties part.\r
-               if (relationshipType.equals(PackageRelationshipTypes.CORE_PROPERTIES)\r
-                               && this.packageProperties != null)\r
-                       throw new InvalidOperationException(\r
-                                       "OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead.");\r
-\r
-               /*\r
-                * Check rule M1.25: The Relationships part shall not have relationships\r
-                * to any other part. Package implementers shall enforce this\r
-                * requirement upon the attempt to create such a relationship and shall\r
-                * treat any such relationship as invalid.\r
-                */\r
-               if (targetPartName.isRelationshipPartURI()) {\r
-                       throw new InvalidOperationException(\r
-                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");\r
-               }\r
-\r
-               /* End OPC compliance */\r
-\r
-               ensureRelationships();\r
-               PackageRelationship retRel = relationships.addRelationship(\r
-                               targetPartName.getURI(), targetMode, relationshipType, relID);\r
-               this.isDirty = true;\r
-               return retRel;\r
-       }\r
-\r
-       /**\r
-        * Add a package relationship.\r
-        * \r
-        * @param targetPartName\r
-        *            Target part name.\r
-        * @param targetMode\r
-        *            Target mode, either Internal or External.\r
-        * @param relationshipType\r
-        *            Relationship type.\r
-        * @see PackageRelationshipTypes\r
-        */\r
-       public PackageRelationship addRelationship(PackagePartName targetPartName,\r
-                       TargetMode targetMode, String relationshipType) {\r
-               return this.addRelationship(targetPartName, targetMode,\r
-                               relationshipType, null);\r
-       }\r
-\r
-       /**\r
-        * Adds an external relationship to a part (except relationships part).\r
-        * \r
-        * The targets of external relationships are not subject to the same\r
-        * validity checks that internal ones are, as the contents is potentially\r
-        * any file, URL or similar.\r
-        * \r
-        * @param target\r
-        *            External target of the relationship\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @return The newly created and added relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String,\r
-        *      java.lang.String)\r
-        */\r
-       public PackageRelationship addExternalRelationship(String target,\r
-                       String relationshipType) {\r
-               return addExternalRelationship(target, relationshipType, null);\r
-       }\r
-\r
-       /**\r
-        * Adds an external relationship to a part (except relationships part).\r
-        * \r
-        * The targets of external relationships are not subject to the same\r
-        * validity checks that internal ones are, as the contents is potentially\r
-        * any file, URL or similar.\r
-        * \r
-        * @param target\r
-        *            External target of the relationship\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @param id\r
-        *            Relationship unique id.\r
-        * @return The newly created and added relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String,\r
-        *      java.lang.String)\r
-        */\r
-       public PackageRelationship addExternalRelationship(String target,\r
-                       String relationshipType, String id) {\r
-               if (target == null) {\r
-                       throw new IllegalArgumentException("target");\r
-               }\r
-               if (relationshipType == null) {\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               }\r
-\r
-               URI targetURI;\r
-               try {\r
-                       targetURI = new URI(target);\r
-               } catch (URISyntaxException e) {\r
-                       throw new IllegalArgumentException("Invalid target - " + e);\r
-               }\r
-\r
-               ensureRelationships();\r
-               PackageRelationship retRel = relationships.addRelationship(targetURI,\r
-                               TargetMode.EXTERNAL, relationshipType, id);\r
-               this.isDirty = true;\r
-               return retRel;\r
-       }\r
-\r
-       /**\r
-        * Delete a relationship from this package.\r
-        * \r
-        * @param id\r
-        *            Id of the relationship to delete.\r
-        */\r
-       public void removeRelationship(String id) {\r
-               if (relationships != null) {\r
-                       relationships.removeRelationship(id);\r
-                       this.isDirty = true;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Retrieves all package relationships.\r
-        * \r
-        * @return All package relationships of this package.\r
-        * @throws OpenXML4JException\r
-        * @see #getRelationshipsHelper(String)\r
-        */\r
-       public PackageRelationshipCollection getRelationships()\r
-                       throws OpenXML4JException {\r
-               return getRelationshipsHelper(null);\r
-       }\r
-\r
-       /**\r
-        * Retrives all relationships with the specified type.\r
-        * \r
-        * @param relationshipType\r
-        *            The filter specifying the relationship type.\r
-        * @return All relationships with the specified relationship type.\r
-        * @throws OpenXML4JException\r
-        */\r
-       public PackageRelationshipCollection getRelationshipsByType(\r
-                       String relationshipType) throws IllegalArgumentException,\r
-                       OpenXML4JException {\r
-               throwExceptionIfWriteOnly();\r
-               if (relationshipType == null) {\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               }\r
-               return getRelationshipsHelper(relationshipType);\r
-       }\r
-\r
-       /**\r
-        * Retrieves all relationships with specified id (normally just ine because\r
-        * a relationship id is supposed to be unique).\r
-        * \r
-        * @param id\r
-        *            Id of the wanted relationship.\r
-        * @throws OpenXML4JException\r
-        */\r
-       private PackageRelationshipCollection getRelationshipsHelper(String id)\r
-                       throws OpenXML4JException {\r
-               throwExceptionIfWriteOnly();\r
-               ensureRelationships();\r
-               return this.relationships.getRelationships(id);\r
-       }\r
-\r
-       /**\r
-        * Clear package relationships.\r
-        */\r
-       public void clearRelationships() {\r
-               if (relationships != null) {\r
-                       relationships.clear();\r
-                       this.isDirty = true;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Ensure that the relationships collection is not null.\r
-        */\r
-       public void ensureRelationships() {\r
-               if (this.relationships == null) {\r
-                       try {\r
-                               this.relationships = new PackageRelationshipCollection(this);\r
-                       } catch (InvalidFormatException e) {\r
-                               this.relationships = new PackageRelationshipCollection();\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String)\r
-        */\r
-       public PackageRelationship getRelationship(String id) {\r
-               return this.relationships.getRelationshipByID(id);\r
-       }\r
-\r
-       /**\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships()\r
-        */\r
-       public boolean hasRelationships() {\r
-               return (relationships.size() > 0);\r
-       }\r
-\r
-       /**\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship)\r
-        */\r
-       @SuppressWarnings("finally")\r
-       public boolean isRelationshipExists(PackageRelationship rel) {\r
-               try {\r
-                       for (PackageRelationship r : this.getRelationships()) {\r
-                               if (r == rel)\r
-                                       return true;\r
-                       }\r
-               } finally {\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Add a marshaller.\r
-        * \r
-        * @param contentType\r
-        *            The content type to bind to the specified marshaller.\r
-        * @param marshaller\r
-        *            The marshaller to register with the specified content type.\r
-        */\r
-       public void addMarshaller(String contentType, PartMarshaller marshaller) {\r
-               try {\r
-                       partMarshallers.put(new ContentType(contentType), marshaller);\r
-               } catch (InvalidFormatException e) {\r
-                       logger.log(POILogger.WARN, "The specified content type is not valid: '"\r
-                                       + e.getMessage() + "'. The marshaller will not be added !");\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Add an unmarshaller.\r
-        * \r
-        * @param contentType\r
-        *            The content type to bind to the specified unmarshaller.\r
-        * @param unmarshaller\r
-        *            The unmarshaller to register with the specified content type.\r
-        */\r
-       public void addUnmarshaller(String contentType,\r
-                       PartUnmarshaller unmarshaller) {\r
-               try {\r
-                       partUnmarshallers.put(new ContentType(contentType), unmarshaller);\r
-               } catch (InvalidFormatException e) {\r
-                       logger.log(POILogger.WARN, "The specified content type is not valid: '"\r
-                                       + e.getMessage()\r
-                                       + "'. The unmarshaller will not be added !");\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Remove a marshaller by its content type.\r
-        * \r
-        * @param contentType\r
-        *            The content type associated with the marshaller to remove.\r
-        */\r
-       public void removeMarshaller(String contentType) {\r
-               partMarshallers.remove(contentType);\r
-       }\r
-\r
-       /**\r
-        * Remove an unmarshaller by its content type.\r
-        * \r
-        * @param contentType\r
-        *            The content type associated with the unmarshaller to remove.\r
-        */\r
-       public void removeUnmarshaller(String contentType) {\r
-               partUnmarshallers.remove(contentType);\r
-       }\r
-\r
-       /* Accesseurs */\r
-\r
-       /**\r
-        * Get the package access mode.\r
-        * \r
-        * @return the packageAccess The current package access.\r
-        */\r
-       public PackageAccess getPackageAccess() {\r
-               return packageAccess;\r
-       }\r
-\r
-       /**\r
-        * Validates the package compliance with the OPC specifications.\r
-        * \r
-        * @return <b>true</b> if the package is valid else <b>false</b>\r
-        */\r
-       public boolean validatePackage(Package pkg) throws InvalidFormatException {\r
-               throw new InvalidOperationException("Not implemented yet !!!");\r
-       }\r
-\r
-       /**\r
-        * Save the document in the specified file.\r
-        * \r
-        * @param targetFile\r
-        *            Destination file.\r
-        * @throws IOException\r
-        *             Throws if an IO exception occur.\r
-        * @see #save(OutputStream)\r
-        */\r
-       public void save(File targetFile) throws IOException {\r
-               if (targetFile == null)\r
-                       throw new IllegalArgumentException("targetFile");\r
-\r
-               this.throwExceptionIfReadOnly();\r
-               FileOutputStream fos = null;\r
-               try {\r
-                       fos = new FileOutputStream(targetFile);\r
-               } catch (FileNotFoundException e) {\r
-                       throw new IOException(e.getLocalizedMessage());\r
-               }\r
-               this.save(fos);\r
-       }\r
-\r
-       /**\r
-        * Save the document in the specified output stream.\r
-        * \r
-        * @param outputStream\r
-        *            The stream to save the package.\r
-        * @see #saveImpl(OutputStream)\r
-        */\r
-       public void save(OutputStream outputStream) throws IOException {\r
-               throwExceptionIfReadOnly();\r
-               this.saveImpl(outputStream);\r
-       }\r
-\r
-       /**\r
-        * Core method to create a package part. This method must be implemented by\r
-        * the subclass.\r
-        * \r
-        * @param partName\r
-        *            URI of the part to create.\r
-        * @param contentType\r
-        *            Content type of the part to create.\r
-        * @return The newly created package part.\r
-        */\r
-       protected abstract PackagePart createPartImpl(PackagePartName partName,\r
-                       String contentType, boolean loadRelationships);\r
-\r
-       /**\r
-        * Core method to delete a package part. This method must be implemented by\r
-        * the subclass.\r
-        * \r
-        * @param partName\r
-        *            The URI of the part to delete.\r
-        */\r
-       protected abstract void removePartImpl(PackagePartName partName);\r
-\r
-       /**\r
-        * Flush the package but not save.\r
-        */\r
-       protected abstract void flushImpl();\r
-\r
-       /**\r
-        * Close the package and cause a save of the package.\r
-        * \r
-        */\r
-       protected abstract void closeImpl() throws IOException;\r
-\r
-       /**\r
-        * Close the package without saving the document. Discard all changes made\r
-        * to this package.\r
-        */\r
-       protected abstract void revertImpl();\r
-\r
-       /**\r
-        * Save the package into the specified output stream.\r
-        * \r
-        * @param outputStream\r
-        *            The output stream use to save this package.\r
-        */\r
-       protected abstract void saveImpl(OutputStream outputStream)\r
-                       throws IOException;\r
-\r
-       /**\r
-        * Get the package part mapped to the specified URI.\r
-        * \r
-        * @param partName\r
-        *            The URI of the part to retrieve.\r
-        * @return The package part located by the specified URI, else <b>null</b>.\r
-        */\r
-       protected abstract PackagePart getPartImpl(PackagePartName partName);\r
-\r
-       /**\r
-        * Get all parts link to the package.\r
-        * \r
-        * @return A list of the part owned by the package.\r
-        */\r
-       protected abstract PackagePart[] getPartsImpl()\r
-                       throws InvalidFormatException;\r
-}\r
+/* ====================================================================
+   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.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Date;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
+import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager;
+import org.apache.poi.openxml4j.util.Nullable;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * @deprecated (name clash with {@link java.lang.Package} use {@link OPCPackage} instead.
+ * 
+ * @author Julien Chable, CDubet
+ * 
+ */
+public abstract class Package extends OPCPackage {
+
+       /**
+        * Logger.
+        */
+    private static POILogger logger = POILogFactory.getLogger(Package.class);
+
+
+       /**
+        * @deprecated use {@link OPCPackage} 
+        */
+       protected Package(PackageAccess access) {
+               super(access);
+       }
+
+
+       /**
+        * @deprecated use {@link OPCPackage#open(String)} 
+        */
+       public static Package open(String path) throws InvalidFormatException {
+               return open(path, defaultPackageAccess);
+       }
+
+       /**
+        * @deprecated use {@link OPCPackage#open(String,PackageAccess)} 
+        */
+       public static Package open(String path, PackageAccess access)
+                       throws InvalidFormatException {
+               if (path == null || "".equals(path.trim())
+                               || (new File(path).exists() && new File(path).isDirectory()))
+                       throw new IllegalArgumentException("path");
+
+               Package pack = new ZipPackage(path, access);
+               if (pack.partList == null && access != PackageAccess.WRITE) {
+                       pack.getParts();
+               }
+               pack.originalPackagePath = new File(path).getAbsolutePath();
+               return pack;
+       }
+
+       /**
+        * @deprecated use {@link OPCPackage#open(InputStream)} 
+        */
+       public static Package open(InputStream in) throws InvalidFormatException,
+                       IOException {
+               Package pack = new ZipPackage(in, PackageAccess.READ);
+               if (pack.partList == null) {
+                       pack.getParts();
+               }
+               return pack;
+       }
+
+       /**
+        * @deprecated use {@link OPCPackage#open(File)} 
+        */
+       public static Package openOrCreate(File file) throws InvalidFormatException {
+               Package retPackage = null;
+               if (file.exists()) {
+                       retPackage = open(file.getAbsolutePath());
+               } else {
+                       retPackage = create(file);
+               }
+               return retPackage;
+       }
+
+       /**
+        * @deprecated use {@link OPCPackage#create(String)} 
+        */
+       public static Package create(String path) {
+               return create(new File(path));
+       }
+
+       /**
+        * @deprecated use {@link OPCPackage#create(File)} 
+        */
+       public static Package create(File file) {
+               if (file == null || (file.exists() && file.isDirectory()))
+                       throw new IllegalArgumentException("file");
+
+               if (file.exists()) {
+                       throw new InvalidOperationException(
+                                       "This package (or file) already exists : use the open() method or delete the file.");
+               }
+
+               // Creates a new package
+               Package pkg = null;
+               pkg = new ZipPackage();
+               pkg.originalPackagePath = file.getAbsolutePath();
+
+               configurePackage(pkg);
+               return pkg;
+       }
+
+       /**
+        * @deprecated use {@link OPCPackage#create(OutputStream)} 
+        */
+       public static Package create(OutputStream output) {
+               Package pkg = null;
+               pkg = new ZipPackage();
+               pkg.originalPackagePath = null;
+               pkg.output = output;
+
+               configurePackage(pkg);
+               return pkg;
+       }
+
+       /**
+        * Configure the package.
+        * 
+        * @param pkg
+        */
+       private static void configurePackage(Package pkg) {
+               try {
+                       // Content type manager
+                       pkg.contentTypeManager = new ZipContentTypeManager(null, pkg);
+                       // Add default content types for .xml and .rels
+                       pkg.contentTypeManager
+                                       .addContentType(
+                                                       PackagingURIHelper
+                                                                       .createPartName(PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_URI),
+                                                       ContentTypes.RELATIONSHIPS_PART);
+                       pkg.contentTypeManager
+                                       .addContentType(PackagingURIHelper
+                                                       .createPartName("/default.xml"),
+                                                       ContentTypes.PLAIN_OLD_XML);
+
+                       // Init some Package properties
+                       pkg.packageProperties = new PackagePropertiesPart(pkg,
+                                       PackagingURIHelper.CORE_PROPERTIES_PART_NAME);
+                       pkg.packageProperties.setCreatorProperty("Generated by OpenXML4J");
+                       pkg.packageProperties.setCreatedProperty(new Nullable<Date>(
+                                       new Date()));
+               } catch (InvalidFormatException e) {
+                       // Should never happen
+                       throw new IllegalStateException(e);
+               }
+       }
+
+
+}
index c30e6d98690104dd73154a504b3e534e98e83a27..928e0a783f8bd8bccc6584bc733c9a81786b2a3a 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.opc.internal.ContentType;\r
-\r
-/**\r
- * Provides a base class for parts stored in a Package.\r
- * \r
- * @author Julien Chable\r
- * @version 0.9\r
- */\r
-public abstract class PackagePart implements RelationshipSource {\r
-\r
-       /**\r
-        * This part's container.\r
-        */\r
-       protected Package container;\r
-\r
-       /**\r
-        * The part name. (required by the specification [M1.1])\r
-        */\r
-       protected PackagePartName partName;\r
-\r
-       /**\r
-        * The type of content of this part. (required by the specification [M1.2])\r
-        */\r
-       protected ContentType contentType;\r
-\r
-       /**\r
-        * Flag to know if this part is a relationship.\r
-        */\r
-       private boolean isRelationshipPart;\r
-\r
-       /**\r
-        * Flag to know if this part has been logically deleted.\r
-        */\r
-       private boolean isDeleted;\r
-\r
-       /**\r
-        * This part's relationships.\r
-        */\r
-       private PackageRelationshipCollection relationships;\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pack\r
-        *            Parent package.\r
-        * @param partName\r
-        *            The part name, relative to the parent Package root.\r
-        * @param contentType\r
-        *            The content type.\r
-        * @throws InvalidFormatException\r
-        *             If the specified URI is not valid.\r
-        */\r
-       protected PackagePart(Package pack, PackagePartName partName,\r
-                       ContentType contentType) throws InvalidFormatException {\r
-               this(pack, partName, contentType, true);\r
-       }\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pack\r
-        *            Parent package.\r
-        * @param partName\r
-        *            The part name, relative to the parent Package root.\r
-        * @param contentType\r
-        *            The content type.\r
-        * @param loadRelationships\r
-        *            Specify if the relationships will be loaded\r
-        * @throws InvalidFormatException\r
-        *             If the specified URI is not valid.\r
-        */\r
-       protected PackagePart(Package pack, PackagePartName partName,\r
-                       ContentType contentType, boolean loadRelationships)\r
-                       throws InvalidFormatException {\r
-               this.partName = partName;\r
-               this.contentType = contentType;\r
-               this.container = (ZipPackage) pack;\r
-\r
-               // Check if this part is a relationship part\r
-               isRelationshipPart = this.partName.isRelationshipPartURI();\r
-\r
-               // Load relationships if any\r
-               if (loadRelationships)\r
-                       loadRelationships();\r
-       }\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pack\r
-        *            Parent package.\r
-        * @param partName\r
-        *            The part name, relative to the parent Package root.\r
-        * @param contentType\r
-        *            The Multipurpose Internet Mail Extensions (MIME) content type\r
-        *            of the part's data stream.\r
-        */\r
-       public PackagePart(Package pack, PackagePartName partName,\r
-                       String contentType) throws InvalidFormatException {\r
-               this(pack, partName, new ContentType(contentType));\r
-       }\r
-\r
-       /**\r
-        * Adds an external relationship to a part (except relationships part).\r
-        * \r
-        * The targets of external relationships are not subject to the same\r
-        * validity checks that internal ones are, as the contents is potentially\r
-        * any file, URL or similar.\r
-        * \r
-        * @param target\r
-        *            External target of the relationship\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @return The newly created and added relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String,\r
-        *      java.lang.String)\r
-        */\r
-       public PackageRelationship addExternalRelationship(String target,\r
-                       String relationshipType) {\r
-               return addExternalRelationship(target, relationshipType, null);\r
-       }\r
-\r
-       /**\r
-        * Adds an external relationship to a part (except relationships part).\r
-        * \r
-        * The targets of external relationships are not subject to the same\r
-        * validity checks that internal ones are, as the contents is potentially\r
-        * any file, URL or similar.\r
-        * \r
-        * @param target\r
-        *            External target of the relationship\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @param id\r
-        *            Relationship unique id.\r
-        * @return The newly created and added relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String,\r
-        *      java.lang.String)\r
-        */\r
-       public PackageRelationship addExternalRelationship(String target,\r
-                       String relationshipType, String id) {\r
-               if (target == null) {\r
-                       throw new IllegalArgumentException("target");\r
-               }\r
-               if (relationshipType == null) {\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               }\r
-\r
-               if (relationships == null) {\r
-                       relationships = new PackageRelationshipCollection();\r
-               }\r
-\r
-               URI targetURI;\r
-               try {\r
-                       targetURI = new URI(target);\r
-               } catch (URISyntaxException e) {\r
-                       throw new IllegalArgumentException("Invalid target - " + e);\r
-               }\r
-\r
-               return relationships.addRelationship(targetURI, TargetMode.EXTERNAL,\r
-                               relationshipType, id);\r
-       }\r
-\r
-       /**\r
-        * Add a relationship to a part (except relationships part).\r
-        * \r
-        * @param targetPartName\r
-        *            Name of the target part. This one must be relative to the\r
-        *            source root directory of the part.\r
-        * @param targetMode\r
-        *            Mode [Internal|External].\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @return The newly created and added relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,\r
-        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String)\r
-        */\r
-       public PackageRelationship addRelationship(PackagePartName targetPartName,\r
-                       TargetMode targetMode, String relationshipType) {\r
-               return addRelationship(targetPartName, targetMode, relationshipType,\r
-                               null);\r
-       }\r
-\r
-       /**\r
-        * Add a relationship to a part (except relationships part).\r
-        * <p>\r
-        * Check rule M1.25: The Relationships part shall not have relationships to\r
-        * any other part. Package implementers shall enforce this requirement upon\r
-        * the attempt to create such a relationship and shall treat any such\r
-        * relationship as invalid.\r
-        * </p>\r
-        * @param targetPartName\r
-        *            Name of the target part. This one must be relative to the\r
-        *            source root directory of the part.\r
-        * @param targetMode\r
-        *            Mode [Internal|External].\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @param id\r
-        *            Relationship unique id.\r
-        * @return The newly created and added relationship\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             If the URI point to a relationship part URI.\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,\r
-        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String)\r
-        */\r
-       public PackageRelationship addRelationship(PackagePartName targetPartName,\r
-                       TargetMode targetMode, String relationshipType, String id) {\r
-               container.throwExceptionIfReadOnly();\r
-\r
-               if (targetPartName == null) {\r
-                       throw new IllegalArgumentException("targetPartName");\r
-               }\r
-               if (targetMode == null) {\r
-                       throw new IllegalArgumentException("targetMode");\r
-               }\r
-               if (relationshipType == null) {\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               }\r
-\r
-               if (this.isRelationshipPart || targetPartName.isRelationshipPartURI()) {\r
-                       throw new InvalidOperationException(\r
-                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");\r
-               }\r
-\r
-               if (relationships == null) {\r
-                       relationships = new PackageRelationshipCollection();\r
-               }\r
-\r
-               return relationships.addRelationship(targetPartName.getURI(),\r
-                               targetMode, relationshipType, id);\r
-       }\r
-\r
-       /**\r
-        * Add a relationship to a part (except relationships part).\r
-        * \r
-        * @param targetURI\r
-        *            URI the target part. Must be relative to the source root\r
-        *            directory of the part.\r
-        * @param targetMode\r
-        *            Mode [Internal|External].\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @return The newly created and added relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,\r
-        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String)\r
-        */\r
-       public PackageRelationship addRelationship(URI targetURI,\r
-                       TargetMode targetMode, String relationshipType) {\r
-               return addRelationship(targetURI, targetMode, relationshipType, null);\r
-       }\r
-\r
-       /**\r
-        * Add a relationship to a part (except relationships part).\r
-        * <p>\r
-        * Check rule M1.25: The Relationships part shall not have relationships to\r
-        * any other part. Package implementers shall enforce this requirement upon\r
-        * the attempt to create such a relationship and shall treat any such\r
-        * relationship as invalid.\r
-        * </p>\r
-        * @param targetURI\r
-        *            URI of the target part. Must be relative to the source root\r
-        *            directory of the part.\r
-        * @param targetMode\r
-        *            Mode [Internal|External].\r
-        * @param relationshipType\r
-        *            Type of relationship.\r
-        * @param id\r
-        *            Relationship unique id.\r
-        * @return The newly created and added relationship\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             If the URI point to a relationship part URI.\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,\r
-        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String)\r
-        */\r
-       public PackageRelationship addRelationship(URI targetURI,\r
-                       TargetMode targetMode, String relationshipType, String id) {\r
-               container.throwExceptionIfReadOnly();\r
-\r
-               if (targetURI == null) {\r
-                       throw new IllegalArgumentException("targetPartName");\r
-               }\r
-               if (targetMode == null) {\r
-                       throw new IllegalArgumentException("targetMode");\r
-               }\r
-               if (relationshipType == null) {\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               }\r
-\r
-               // Try to retrieve the target part\r
-\r
-               if (this.isRelationshipPart\r
-                               || PackagingURIHelper.isRelationshipPartURI(targetURI)) {\r
-                       throw new InvalidOperationException(\r
-                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");\r
-               }\r
-\r
-               if (relationships == null) {\r
-                       relationships = new PackageRelationshipCollection();\r
-               }\r
-\r
-               return relationships.addRelationship(targetURI,\r
-                               targetMode, relationshipType, id);\r
-       }\r
-\r
-       /**\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships()\r
-        */\r
-       public void clearRelationships() {\r
-               if (relationships != null) {\r
-                       relationships.clear();\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Delete the relationship specified by its id.\r
-        * \r
-        * @param id\r
-        *            The ID identified the part to delete.\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#removeRelationship(java.lang.String)\r
-        */\r
-       public void removeRelationship(String id) {\r
-               this.container.throwExceptionIfReadOnly();\r
-               if (this.relationships != null)\r
-                       this.relationships.removeRelationship(id);\r
-       }\r
-\r
-       /**\r
-        * Retrieve all the relationships attached to this part.\r
-        * \r
-        * @return This part's relationships.\r
-        * @throws OpenXML4JException\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationships()\r
-        */\r
-       public PackageRelationshipCollection getRelationships()\r
-                       throws InvalidFormatException {\r
-               return getRelationshipsCore(null);\r
-       }\r
-\r
-       /**\r
-        * Retrieves a package relationship from its id.\r
-        * \r
-        * @param id\r
-        *            ID of the package relationship to retrieve.\r
-        * @return The package relationship\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String)\r
-        */\r
-       public PackageRelationship getRelationship(String id) {\r
-               return this.relationships.getRelationshipByID(id);\r
-       }\r
-\r
-       /**\r
-        * Retrieve all relationships attached to this part which have the specified\r
-        * type.\r
-        * \r
-        * @param relationshipType\r
-        *            Relationship type filter.\r
-        * @return All relationships from this part that have the specified type.\r
-        * @throws InvalidFormatException\r
-        *             If an error occurs while parsing the part.\r
-        * @throws InvalidOperationException\r
-        *             If the package is open in write only mode.\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationshipsByType(java.lang.String)\r
-        */\r
-       public PackageRelationshipCollection getRelationshipsByType(\r
-                       String relationshipType) throws InvalidFormatException {\r
-               container.throwExceptionIfWriteOnly();\r
-\r
-               return getRelationshipsCore(relationshipType);\r
-       }\r
-\r
-       /**\r
-        * Implementation of the getRelationships method().\r
-        * \r
-        * @param filter\r
-        *            Relationship type filter. If <i>null</i> then the filter is\r
-        *            disabled and return all the relationships.\r
-        * @return All relationships from this part that have the specified type.\r
-        * @throws InvalidFormatException\r
-        *             Throws if an error occurs during parsing the relationships\r
-        *             part.\r
-        * @throws InvalidOperationException\r
-        *             Throws if the package is open en write only mode.\r
-        * @see #getRelationshipsByType(String)\r
-        */\r
-       private PackageRelationshipCollection getRelationshipsCore(String filter)\r
-                       throws InvalidFormatException {\r
-               this.container.throwExceptionIfWriteOnly();\r
-               if (relationships == null) {\r
-                       this.throwExceptionIfRelationship();\r
-                       relationships = new PackageRelationshipCollection(this);\r
-               }\r
-               return new PackageRelationshipCollection(relationships, filter);\r
-       }\r
-\r
-       /**\r
-        * Knows if the part have any relationships.\r
-        * \r
-        * @return <b>true</b> if the part have at least one relationship else\r
-        *         <b>false</b>.\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships()\r
-        */\r
-       public boolean hasRelationships() {\r
-               return (!this.isRelationshipPart && (relationships != null && relationships\r
-                               .size() > 0));\r
-       }\r
-\r
-       /**\r
-        * Checks if the specified relationship is part of this package part.\r
-        * \r
-        * @param rel\r
-        *            The relationship to check.\r
-        * @return <b>true</b> if the specified relationship exists in this part,\r
-        *         else returns <b>false</b>\r
-        * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship)\r
-        */\r
-       @SuppressWarnings("finally")\r
-       public boolean isRelationshipExists(PackageRelationship rel) {\r
-               try {\r
-                       for (PackageRelationship r : this.getRelationships()) {\r
-                               if (r == rel)\r
-                                       return true;\r
-                       }\r
-               } finally {\r
-                       return false;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Get the input stream of this part to read its content.\r
-        * \r
-        * @return The input stream of the content of this part, else\r
-        *         <code>null</code>.\r
-        */\r
-       public InputStream getInputStream() throws IOException {\r
-               InputStream inStream = this.getInputStreamImpl();\r
-               if (inStream == null) {\r
-                       throw new IOException("Can't obtain the input stream from "\r
-                                       + partName.getName());\r
-               } else\r
-                       return inStream;\r
-       }\r
-\r
-       /**\r
-        * Get the output stream of this part. If the part is originally embedded in\r
-        * Zip package, it'll be transform intot a <i>MemoryPackagePart</i> in\r
-        * order to write inside (the standard Java API doesn't allow to write in\r
-        * the file)\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.internal.MemoryPackagePart\r
-        */\r
-       public OutputStream getOutputStream() {\r
-               OutputStream outStream;\r
-               // If this part is a zip package part (read only by design) we convert\r
-               // this part into a MemoryPackagePart instance for write purpose.\r
-               if (this instanceof ZipPackagePart) {\r
-                       // Delete logically this part\r
-                       this.container.removePart(this.partName);\r
-\r
-                       // Create a memory part\r
-                       PackagePart part = container.createPart(this.partName,\r
-                                       this.contentType.toString(), false);\r
-                       part.relationships = this.relationships;\r
-                       if (part == null) {\r
-                               throw new InvalidOperationException(\r
-                                               "Can't create a temporary part !");\r
-                       }\r
-                       outStream = part.getOutputStreamImpl();\r
-               } else {\r
-                       outStream = this.getOutputStreamImpl();\r
-               }\r
-               return outStream;\r
-       }\r
-\r
-       /**\r
-        * Throws an exception if this package part is a relationship part.\r
-        * \r
-        * @throws InvalidOperationException\r
-        *             If this part is a relationship part.\r
-        */\r
-       private void throwExceptionIfRelationship()\r
-                       throws InvalidOperationException {\r
-               if (this.isRelationshipPart)\r
-                       throw new InvalidOperationException(\r
-                                       "Can do this operation on a relationship part !");\r
-       }\r
-\r
-       /**\r
-        * Ensure the package relationships collection instance is built.\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             Throws if\r
-        */\r
-       private void loadRelationships() throws InvalidFormatException {\r
-               if (this.relationships == null && !this.isRelationshipPart) {\r
-                       this.throwExceptionIfRelationship();\r
-                       relationships = new PackageRelationshipCollection(this);\r
-               }\r
-       }\r
-\r
-       /*\r
-        * Accessors\r
-        */\r
-\r
-       /**\r
-        * @return the uri\r
-        */\r
-       public PackagePartName getPartName() {\r
-               return partName;\r
-       }\r
-\r
-       /**\r
-        * @return the contentType\r
-        */\r
-       public String getContentType() {\r
-               return contentType.toString();\r
-       }\r
-\r
-       /**\r
-        * Set the content type.\r
-        * \r
-        * @param contentType\r
-        *            the contentType to set\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             Throws if the content type is not valid.\r
-        * @throws InvalidOperationException\r
-        *             Throws if you try to change the content type whereas this\r
-        *             part is already attached to a package.\r
-        */\r
-       public void setContentType(String contentType)\r
-                       throws InvalidFormatException {\r
-               if (container == null)\r
-                       this.contentType = new ContentType(contentType);\r
-               else\r
-                       throw new InvalidOperationException(\r
-                                       "You can't change the content type of a part.");\r
-       }\r
-\r
-       public Package getPackage() {\r
-               return container;\r
-       }\r
-\r
-       /**\r
-        * @return true if this part is a relationship\r
-        */\r
-       public boolean isRelationshipPart() {\r
-               return this.isRelationshipPart;\r
-       }\r
-\r
-       /**\r
-        * @return true if this part has been logically deleted\r
-        */\r
-       public boolean isDeleted() {\r
-               return isDeleted;\r
-       }\r
-\r
-       /**\r
-        * @param isDeleted\r
-        *            the isDeleted to set\r
-        */\r
-       public void setDeleted(boolean isDeleted) {\r
-               this.isDeleted = isDeleted;\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               return "Name: " + this.partName + " - Content Type: "\r
-                               + this.contentType.toString();\r
-       }\r
-\r
-       /*-------------- Abstract methods ------------- */\r
-\r
-       /**\r
-        * Abtract method that get the input stream of this part.\r
-        * \r
-        * @exception IOException\r
-        *                Throws if an IO Exception occur in the implementation\r
-        *                method.\r
-        */\r
-       protected abstract InputStream getInputStreamImpl() throws IOException;\r
-\r
-       /**\r
-        * Abstract method that get the output stream of this part.\r
-        */\r
-       protected abstract OutputStream getOutputStreamImpl();\r
-\r
-       /**\r
-        * Save the content of this part and the associated relationships part (if\r
-        * this part own at least one relationship) into the specified output\r
-        * stream.\r
-        * \r
-        * @param zos\r
-        *            Output stream to save this part.\r
-        * @throws OpenXML4JException\r
-        *             If any exception occur.\r
-        */\r
-       public abstract boolean save(OutputStream zos) throws OpenXML4JException;\r
-\r
-       /**\r
-        * Load the content of this part.\r
-        * \r
-        * @param ios\r
-        *            The input stream of the content to load.\r
-        * @return <b>true</b> if the content has been successfully loaded, else\r
-        *         <b>false</b>.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the content format is invalid.\r
-        */\r
-       public abstract boolean load(InputStream ios) throws InvalidFormatException;\r
-\r
-       /**\r
-        * Close this part : flush this part, close the input stream and output\r
-        * stream. After this method call, the part must be available for packaging.\r
-        */\r
-       public abstract void close();\r
-\r
-       /**\r
-        * Flush the content of this part. If the input stream and/or output stream\r
-        * as in a waiting state to read or write, the must to empty their\r
-        * respective buffer.\r
-        */\r
-       public abstract void flush();\r
-}\r
+/* ====================================================================
+   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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.internal.ContentType;
+
+/**
+ * Provides a base class for parts stored in a Package.
+ * 
+ * @author Julien Chable
+ * @version 0.9
+ */
+public abstract class PackagePart implements RelationshipSource {
+
+       /**
+        * This part's container.
+        */
+       protected OPCPackage container;
+
+       /**
+        * The part name. (required by the specification [M1.1])
+        */
+       protected PackagePartName partName;
+
+       /**
+        * The type of content of this part. (required by the specification [M1.2])
+        */
+       protected ContentType contentType;
+
+       /**
+        * Flag to know if this part is a relationship.
+        */
+       private boolean isRelationshipPart;
+
+       /**
+        * Flag to know if this part has been logically deleted.
+        */
+       private boolean isDeleted;
+
+       /**
+        * This part's relationships.
+        */
+       private PackageRelationshipCollection relationships;
+
+       /**
+        * Constructor.
+        * 
+        * @param pack
+        *            Parent package.
+        * @param partName
+        *            The part name, relative to the parent Package root.
+        * @param contentType
+        *            The content type.
+        * @throws InvalidFormatException
+        *             If the specified URI is not valid.
+        */
+       protected PackagePart(OPCPackage pack, PackagePartName partName,
+                       ContentType contentType) throws InvalidFormatException {
+               this(pack, partName, contentType, true);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param pack
+        *            Parent package.
+        * @param partName
+        *            The part name, relative to the parent Package root.
+        * @param contentType
+        *            The content type.
+        * @param loadRelationships
+        *            Specify if the relationships will be loaded
+        * @throws InvalidFormatException
+        *             If the specified URI is not valid.
+        */
+       protected PackagePart(OPCPackage pack, PackagePartName partName,
+                       ContentType contentType, boolean loadRelationships)
+                       throws InvalidFormatException {
+               this.partName = partName;
+               this.contentType = contentType;
+               this.container = (ZipPackage) pack; // TODO - enforcing ZipPackage here - perhaps should change constructor signature
+
+               // Check if this part is a relationship part
+               isRelationshipPart = this.partName.isRelationshipPartURI();
+
+               // Load relationships if any
+               if (loadRelationships)
+                       loadRelationships();
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param pack
+        *            Parent package.
+        * @param partName
+        *            The part name, relative to the parent Package root.
+        * @param contentType
+        *            The Multipurpose Internet Mail Extensions (MIME) content type
+        *            of the part's data stream.
+        */
+       public PackagePart(OPCPackage pack, PackagePartName partName,
+                       String contentType) throws InvalidFormatException {
+               this(pack, partName, new ContentType(contentType));
+       }
+
+       /**
+        * 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) {
+               return addExternalRelationship(target, relationshipType, null);
+       }
+
+       /**
+        * 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) {
+               if (target == null) {
+                       throw new IllegalArgumentException("target");
+               }
+               if (relationshipType == null) {
+                       throw new IllegalArgumentException("relationshipType");
+               }
+
+               if (relationships == null) {
+                       relationships = new PackageRelationshipCollection();
+               }
+
+               URI targetURI;
+               try {
+                       targetURI = new URI(target);
+               } catch (URISyntaxException e) {
+                       throw new IllegalArgumentException("Invalid target - " + e);
+               }
+
+               return relationships.addRelationship(targetURI, TargetMode.EXTERNAL,
+                               relationshipType, id);
+       }
+
+       /**
+        * 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
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,
+        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String)
+        */
+       public PackageRelationship addRelationship(PackagePartName targetPartName,
+                       TargetMode targetMode, String relationshipType) {
+               return addRelationship(targetPartName, targetMode, relationshipType,
+                               null);
+       }
+
+       /**
+        * Add a relationship to a part (except relationships part).
+        * <p>
+        * 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.
+        * </p>
+        * @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.
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,
+        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String)
+        */
+       public PackageRelationship addRelationship(PackagePartName targetPartName,
+                       TargetMode targetMode, String relationshipType, String id) {
+               container.throwExceptionIfReadOnly();
+
+               if (targetPartName == null) {
+                       throw new IllegalArgumentException("targetPartName");
+               }
+               if (targetMode == null) {
+                       throw new IllegalArgumentException("targetMode");
+               }
+               if (relationshipType == null) {
+                       throw new IllegalArgumentException("relationshipType");
+               }
+
+               if (this.isRelationshipPart || targetPartName.isRelationshipPartURI()) {
+                       throw new InvalidOperationException(
+                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");
+               }
+
+               if (relationships == null) {
+                       relationships = new PackageRelationshipCollection();
+               }
+
+               return relationships.addRelationship(targetPartName.getURI(),
+                               targetMode, relationshipType, id);
+       }
+
+       /**
+        * Add a relationship to a part (except relationships part).
+        * 
+        * @param targetURI
+        *            URI the target part. 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
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,
+        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String)
+        */
+       public PackageRelationship addRelationship(URI targetURI,
+                       TargetMode targetMode, String relationshipType) {
+               return addRelationship(targetURI, targetMode, relationshipType, null);
+       }
+
+       /**
+        * Add a relationship to a part (except relationships part).
+        * <p>
+        * 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.
+        * </p>
+        * @param targetURI
+        *            URI of the target part. 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.
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#addRelationship(org.apache.poi.openxml4j.opc.PackagePartName,
+        *      org.apache.poi.openxml4j.opc.TargetMode, java.lang.String, java.lang.String)
+        */
+       public PackageRelationship addRelationship(URI targetURI,
+                       TargetMode targetMode, String relationshipType, String id) {
+               container.throwExceptionIfReadOnly();
+
+               if (targetURI == null) {
+                       throw new IllegalArgumentException("targetPartName");
+               }
+               if (targetMode == null) {
+                       throw new IllegalArgumentException("targetMode");
+               }
+               if (relationshipType == null) {
+                       throw new IllegalArgumentException("relationshipType");
+               }
+
+               // Try to retrieve the target part
+
+               if (this.isRelationshipPart
+                               || PackagingURIHelper.isRelationshipPartURI(targetURI)) {
+                       throw new InvalidOperationException(
+                                       "Rule M1.25: The Relationships part shall not have relationships to any other part.");
+               }
+
+               if (relationships == null) {
+                       relationships = new PackageRelationshipCollection();
+               }
+
+               return relationships.addRelationship(targetURI,
+                               targetMode, relationshipType, id);
+       }
+
+       /**
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#clearRelationships()
+        */
+       public void clearRelationships() {
+               if (relationships != null) {
+                       relationships.clear();
+               }
+       }
+
+       /**
+        * Delete the relationship specified by its id.
+        * 
+        * @param id
+        *            The ID identified the part to delete.
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#removeRelationship(java.lang.String)
+        */
+       public void removeRelationship(String id) {
+               this.container.throwExceptionIfReadOnly();
+               if (this.relationships != null)
+                       this.relationships.removeRelationship(id);
+       }
+
+       /**
+        * Retrieve all the relationships attached to this part.
+        * 
+        * @return This part's relationships.
+        * @throws OpenXML4JException
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationships()
+        */
+       public PackageRelationshipCollection getRelationships()
+                       throws InvalidFormatException {
+               return getRelationshipsCore(null);
+       }
+
+       /**
+        * Retrieves a package relationship from its id.
+        * 
+        * @param id
+        *            ID of the package relationship to retrieve.
+        * @return The package relationship
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationship(java.lang.String)
+        */
+       public PackageRelationship getRelationship(String id) {
+               return this.relationships.getRelationshipByID(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.
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#getRelationshipsByType(java.lang.String)
+        */
+       public PackageRelationshipCollection getRelationshipsByType(
+                       String relationshipType) throws InvalidFormatException {
+               container.throwExceptionIfWriteOnly();
+
+               return getRelationshipsCore(relationshipType);
+       }
+
+       /**
+        * Implementation of the getRelationships method().
+        * 
+        * @param filter
+        *            Relationship type filter. If <i>null</i> then the filter is
+        *            disabled and return all the relationships.
+        * @return All relationships from this part that have the specified type.
+        * @throws InvalidFormatException
+        *             Throws if an error occurs during parsing the relationships
+        *             part.
+        * @throws InvalidOperationException
+        *             Throws if the package is open en write only mode.
+        * @see #getRelationshipsByType(String)
+        */
+       private PackageRelationshipCollection getRelationshipsCore(String filter)
+                       throws InvalidFormatException {
+               this.container.throwExceptionIfWriteOnly();
+               if (relationships == null) {
+                       this.throwExceptionIfRelationship();
+                       relationships = new PackageRelationshipCollection(this);
+               }
+               return new PackageRelationshipCollection(relationships, filter);
+       }
+
+       /**
+        * Knows if the part have any relationships.
+        * 
+        * @return <b>true</b> if the part have at least one relationship else
+        *         <b>false</b>.
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#hasRelationships()
+        */
+       public boolean hasRelationships() {
+               return (!this.isRelationshipPart && (relationships != null && relationships
+                               .size() > 0));
+       }
+
+       /**
+        * 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>
+        * @see org.apache.poi.openxml4j.opc.RelationshipSource#isRelationshipExists(org.apache.poi.openxml4j.opc.PackageRelationship)
+        */
+       @SuppressWarnings("finally")
+       public boolean isRelationshipExists(PackageRelationship rel) {
+               try {
+                       for (PackageRelationship r : this.getRelationships()) {
+                               if (r == rel)
+                                       return true;
+                       }
+               } finally {
+                       return false;
+               }
+       }
+
+       /**
+        * Get the input stream of this part to read its content.
+        * 
+        * @return The input stream of the content of this part, else
+        *         <code>null</code>.
+        */
+       public InputStream getInputStream() throws IOException {
+               InputStream inStream = this.getInputStreamImpl();
+               if (inStream == null) {
+                       throw new IOException("Can't obtain the input stream from "
+                                       + partName.getName());
+               } else
+                       return inStream;
+       }
+
+       /**
+        * Get the output stream of this part. If the part is originally embedded in
+        * Zip package, it'll be transform intot a <i>MemoryPackagePart</i> in
+        * order to write inside (the standard Java API doesn't allow to write in
+        * the file)
+        * 
+        * @see org.apache.poi.openxml4j.opc.internal.MemoryPackagePart
+        */
+       public OutputStream getOutputStream() {
+               OutputStream outStream;
+               // If this part is a zip package part (read only by design) we convert
+               // this part into a MemoryPackagePart instance for write purpose.
+               if (this instanceof ZipPackagePart) {
+                       // Delete logically this part
+                       this.container.removePart(this.partName);
+
+                       // Create a memory part
+                       PackagePart part = container.createPart(this.partName,
+                                       this.contentType.toString(), false);
+                       part.relationships = this.relationships;
+                       if (part == null) {
+                               throw new InvalidOperationException(
+                                               "Can't create a temporary part !");
+                       }
+                       outStream = part.getOutputStreamImpl();
+               } else {
+                       outStream = this.getOutputStreamImpl();
+               }
+               return outStream;
+       }
+
+       /**
+        * Throws an exception if this package part is a relationship part.
+        * 
+        * @throws InvalidOperationException
+        *             If this part is a relationship part.
+        */
+       private void throwExceptionIfRelationship()
+                       throws InvalidOperationException {
+               if (this.isRelationshipPart)
+                       throw new InvalidOperationException(
+                                       "Can do this operation on a relationship part !");
+       }
+
+       /**
+        * Ensure the package relationships collection instance is built.
+        * 
+        * @throws InvalidFormatException
+        *             Throws if
+        */
+       private void loadRelationships() throws InvalidFormatException {
+               if (this.relationships == null && !this.isRelationshipPart) {
+                       this.throwExceptionIfRelationship();
+                       relationships = new PackageRelationshipCollection(this);
+               }
+       }
+
+       /*
+        * Accessors
+        */
+
+       /**
+        * @return the uri
+        */
+       public PackagePartName getPartName() {
+               return partName;
+       }
+
+       /**
+        * @return the contentType
+        */
+       public String getContentType() {
+               return contentType.toString();
+       }
+
+       /**
+        * Set the content type.
+        * 
+        * @param contentType
+        *            the contentType to set
+        * 
+        * @throws InvalidFormatException
+        *             Throws if the content type is not valid.
+        * @throws InvalidOperationException
+        *             Throws if you try to change the content type whereas this
+        *             part is already attached to a package.
+        */
+       public void setContentType(String contentType)
+                       throws InvalidFormatException {
+               if (container == null)
+                       this.contentType = new ContentType(contentType);
+               else
+                       throw new InvalidOperationException(
+                                       "You can't change the content type of a part.");
+       }
+
+       public OPCPackage getPackage() {
+               return container;
+       }
+
+       /**
+        * @return true if this part is a relationship
+        */
+       public boolean isRelationshipPart() {
+               return this.isRelationshipPart;
+       }
+
+       /**
+        * @return true if this part has been logically deleted
+        */
+       public boolean isDeleted() {
+               return isDeleted;
+       }
+
+       /**
+        * @param isDeleted
+        *            the isDeleted to set
+        */
+       public void setDeleted(boolean isDeleted) {
+               this.isDeleted = isDeleted;
+       }
+
+       @Override
+       public String toString() {
+               return "Name: " + this.partName + " - Content Type: "
+                               + this.contentType.toString();
+       }
+
+       /*-------------- Abstract methods ------------- */
+
+       /**
+        * Abtract method that get the input stream of this part.
+        * 
+        * @exception IOException
+        *                Throws if an IO Exception occur in the implementation
+        *                method.
+        */
+       protected abstract InputStream getInputStreamImpl() throws IOException;
+
+       /**
+        * Abstract method that get the output stream of this part.
+        */
+       protected abstract OutputStream getOutputStreamImpl();
+
+       /**
+        * Save the content of this part and the associated relationships part (if
+        * this part own at least one relationship) into the specified output
+        * stream.
+        * 
+        * @param zos
+        *            Output stream to save this part.
+        * @throws OpenXML4JException
+        *             If any exception occur.
+        */
+       public abstract boolean save(OutputStream zos) throws OpenXML4JException;
+
+       /**
+        * Load the content of this part.
+        * 
+        * @param ios
+        *            The input stream of the content to load.
+        * @return <b>true</b> if the content has been successfully loaded, else
+        *         <b>false</b>.
+        * @throws InvalidFormatException
+        *             Throws if the content format is invalid.
+        */
+       public abstract boolean load(InputStream ios) throws InvalidFormatException;
+
+       /**
+        * Close this part : flush this part, close the input stream and output
+        * stream. After this method call, the part must be available for packaging.
+        */
+       public abstract void close();
+
+       /**
+        * Flush the content of this part. If the input stream and/or output stream
+        * as in a waiting state to read or write, the must to empty their
+        * respective buffer.
+        */
+       public abstract void flush();
+}
index 5ab80dd0f81fc489eec90ff2d49ff7c1ae0da837..3013af435424b892b7eda8394e618a26a7bc67d8 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.util.Date;\r
-\r
-import org.apache.poi.openxml4j.util.Nullable;\r
-\r
-/**\r
- * Represents the core properties of an OPC package.\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- * @see org.apache.poi.openxml4j.opc.Package\r
- */\r
-public interface PackageProperties {\r
-       \r
-       /**\r
-        * Dublin Core Terms URI.\r
-        */\r
-       public final static String NAMESPACE_DCTERMS = "http://purl.org/dc/terms/";\r
-       \r
-       /**\r
-        * Dublin Core namespace URI.\r
-        */\r
-       public final static String NAMESPACE_DC = "http://purl.org/dc/elements/1.1/";\r
-\r
-       /* Getters and setters */\r
-\r
-       /**\r
-        * Set the category of the content of this package.\r
-        */\r
-       public abstract Nullable<String> getCategoryProperty();\r
-\r
-       /**\r
-        * Set the category of the content of this package.\r
-        */\r
-       public abstract void setCategoryProperty(String category);\r
-\r
-       /**\r
-        * Set the status of the content.\r
-        */\r
-       public abstract Nullable<String> getContentStatusProperty();\r
-\r
-       /**\r
-        * Get the status of the content.\r
-        */\r
-       public abstract void setContentStatusProperty(String contentStatus);\r
-\r
-       /**\r
-        * Get the type of content represented, generally defined by a specific use\r
-        * and intended audience.\r
-        */\r
-       public abstract Nullable<String> getContentTypeProperty();\r
-\r
-       /**\r
-        * Set the type of content represented, generally defined by a specific use\r
-        * and intended audience.\r
-        */\r
-       public abstract void setContentTypeProperty(String contentType);\r
-\r
-       /**\r
-        * Get the date of creation of the resource.\r
-        */\r
-       public abstract Nullable<Date> getCreatedProperty();\r
-\r
-       /**\r
-        * Set the date of creation of the resource.\r
-        */\r
-       public abstract void setCreatedProperty(String created);\r
-       \r
-       /**\r
-        * Set the date of creation of the resource.\r
-        */\r
-       public abstract void setCreatedProperty(Nullable<Date> created);\r
-\r
-       /**\r
-        * Get the entity primarily responsible for making the content of the\r
-        * resource.\r
-        */\r
-       public abstract Nullable<String> getCreatorProperty();\r
-\r
-       /**\r
-        * Set the entity primarily responsible for making the content of the\r
-        * resource.\r
-        */\r
-       public abstract void setCreatorProperty(String creator);\r
-\r
-       /**\r
-        * Get the explanation of the content of the resource.\r
-        */\r
-       public abstract Nullable<String> getDescriptionProperty();\r
-\r
-       /**\r
-        * Set the explanation of the content of the resource.\r
-        */\r
-       public abstract void setDescriptionProperty(String description);\r
-\r
-       /**\r
-        * Get an unambiguous reference to the resource within a given context.\r
-        */\r
-       public abstract Nullable<String> getIdentifierProperty();\r
-\r
-       /**\r
-        * Set an unambiguous reference to the resource within a given context.\r
-        */\r
-       public abstract void setIdentifierProperty(String identifier);\r
-\r
-       /**\r
-        * Get a delimited set of keywords to support searching and indexing. This\r
-        * is typically a list of terms that are not available elsewhere in the\r
-        * properties\r
-        */\r
-       public abstract Nullable<String> getKeywordsProperty();\r
-\r
-       /**\r
-        * Set a delimited set of keywords to support searching and indexing. This\r
-        * is typically a list of terms that are not available elsewhere in the\r
-        * properties\r
-        */\r
-       public abstract void setKeywordsProperty(String keywords);\r
-\r
-       /**\r
-        * Get the language of the intellectual content of the resource.\r
-        */\r
-       public abstract Nullable<String> getLanguageProperty();\r
-\r
-       /**\r
-        * Set the language of the intellectual content of the resource.\r
-        */\r
-       public abstract void setLanguageProperty(String language);\r
-\r
-       /**\r
-        * Get the user who performed the last modification.\r
-        */\r
-       public abstract Nullable<String> getLastModifiedByProperty();\r
-\r
-       /**\r
-        * Set the user who performed the last modification.\r
-        */\r
-       public abstract void setLastModifiedByProperty(String lastModifiedBy);\r
-\r
-       /**\r
-        * Get the date and time of the last printing.\r
-        */\r
-       public abstract Nullable<Date> getLastPrintedProperty();\r
-\r
-       /**\r
-        * Set the date and time of the last printing.\r
-        */\r
-       public abstract void setLastPrintedProperty(String lastPrinted);\r
-       \r
-       /**\r
-        * Set the date and time of the last printing.\r
-        */\r
-       public abstract void setLastPrintedProperty(Nullable<Date> lastPrinted);\r
-\r
-       /**\r
-        * Get the date on which the resource was changed.\r
-        */\r
-       public abstract Nullable<Date> getModifiedProperty();\r
-\r
-       /**\r
-        * Set the date on which the resource was changed.\r
-        */\r
-       public abstract void setModifiedProperty(String modified);\r
-       \r
-       /**\r
-        * Set the date on which the resource was changed.\r
-        */\r
-       public abstract void setModifiedProperty(Nullable<Date> modified);\r
-\r
-       /**\r
-        * Get the revision number.\r
-        */\r
-       public abstract Nullable<String> getRevisionProperty();\r
-\r
-       /**\r
-        * Set the revision number.\r
-        */\r
-       public abstract void setRevisionProperty(String revision);\r
-\r
-       /**\r
-        * Get the topic of the content of the resource.\r
-        */\r
-       public abstract Nullable<String> getSubjectProperty();\r
-\r
-       /**\r
-        * Set the topic of the content of the resource.\r
-        */\r
-       public abstract void setSubjectProperty(String subject);\r
-\r
-       /**\r
-        * Get the name given to the resource.\r
-        */\r
-       public abstract Nullable<String> getTitleProperty();\r
-\r
-       /**\r
-        * Set the name given to the resource.\r
-        */\r
-       public abstract void setTitleProperty(String title);\r
-\r
-       /**\r
-        * Get the version number.\r
-        */\r
-       public abstract Nullable<String> getVersionProperty();\r
-\r
-       /**\r
-        * Set the version number.\r
-        */\r
-       public abstract void setVersionProperty(String version);\r
-}\r
+/* ====================================================================
+   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.OPCPackage
+ */
+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);
+}
index b8f525a806448ad4426268c599e7d4427bbb9c54..0deb73731436a0a261fecfa65dad1c947ad0fab3 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-\r
-/**\r
- * A part relationship.\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- */\r
-public final class PackageRelationship {\r
-\r
-       private static URI containerRelationshipPart;\r
-\r
-       static {\r
-               try {\r
-                       containerRelationshipPart = new URI("/_rels/.rels");\r
-               } catch (URISyntaxException e) {\r
-                       // Do nothing\r
-               }\r
-       }\r
-\r
-       /* XML markup */\r
-\r
-       public static final String ID_ATTRIBUTE_NAME = "Id";\r
-\r
-       public static final String RELATIONSHIPS_TAG_NAME = "Relationships";\r
-\r
-       public static final String RELATIONSHIP_TAG_NAME = "Relationship";\r
-\r
-       public static final String TARGET_ATTRIBUTE_NAME = "Target";\r
-\r
-       public static final String TARGET_MODE_ATTRIBUTE_NAME = "TargetMode";\r
-\r
-       public static final String TYPE_ATTRIBUTE_NAME = "Type";\r
-\r
-       /* End XML markup */\r
-\r
-       /**\r
-        * L'ID de la relation.\r
-        */\r
-       private String id;\r
-\r
-       /**\r
-        * Reference to the package.\r
-        */\r
-       private Package container;\r
-\r
-       /**\r
-        * Type de relation.\r
-        */\r
-       private String relationshipType;\r
-\r
-       /**\r
-        * Partie source de cette relation.\r
-        */\r
-       private PackagePart source;\r
-\r
-       /**\r
-        * Le mode de ciblage [Internal|External]\r
-        */\r
-       private TargetMode targetMode;\r
-\r
-       /**\r
-        * URI de la partie cible.\r
-        */\r
-       private URI targetUri;\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pkg\r
-        * @param sourcePart\r
-        * @param targetUri\r
-        * @param targetMode\r
-        * @param relationshipType\r
-        * @param id\r
-        */\r
-       public PackageRelationship(Package pkg, PackagePart sourcePart,\r
-                       URI targetUri, TargetMode targetMode, String relationshipType,\r
-                       String id) {\r
-               if (pkg == null)\r
-                       throw new IllegalArgumentException("pkg");\r
-               if (targetUri == null)\r
-                       throw new IllegalArgumentException("targetUri");\r
-               if (relationshipType == null)\r
-                       throw new IllegalArgumentException("relationshipType");\r
-               if (id == null)\r
-                       throw new IllegalArgumentException("id");\r
-\r
-               this.container = pkg;\r
-               this.source = sourcePart;\r
-               this.targetUri = targetUri;\r
-               this.targetMode = targetMode;\r
-               this.relationshipType = relationshipType;\r
-               this.id = id;\r
-       }\r
-\r
-       @Override\r
-       public boolean equals(Object obj) {\r
-               if (!(obj instanceof PackageRelationship)) {\r
-                       return false;\r
-               }\r
-               PackageRelationship rel = (PackageRelationship) obj;\r
-               return (this.id == rel.id\r
-                               && this.relationshipType == rel.relationshipType\r
-                               && (rel.source != null ? rel.source.equals(this.source) : true)\r
-                               && this.targetMode == rel.targetMode && this.targetUri\r
-                               .equals(rel.targetUri));\r
-       }\r
-\r
-       @Override\r
-       public int hashCode() {\r
-               return this.id.hashCode() + this.relationshipType.hashCode()\r
-                               + this.source.hashCode() + this.targetMode.hashCode()\r
-                               + this.targetUri.hashCode();\r
-       }\r
-\r
-       /* Getters */\r
-\r
-       public URI getContainerPartRelationship() {\r
-               return containerRelationshipPart;\r
-       }\r
-\r
-       /**\r
-        * @return the container\r
-        */\r
-       public Package getPackage() {\r
-               return container;\r
-       }\r
-\r
-       /**\r
-        * @return the id\r
-        */\r
-       public String getId() {\r
-               return id;\r
-       }\r
-\r
-       /**\r
-        * @return the relationshipType\r
-        */\r
-       public String getRelationshipType() {\r
-               return relationshipType;\r
-       }\r
-\r
-       /**\r
-        * @return the source\r
-        */\r
-       public PackagePart getSource() {\r
-               return source;\r
-       }\r
-\r
-       /**\r
-        * \r
-        * @return URL of the source part of this relationship\r
-        */\r
-       public URI getSourceURI() {\r
-               if (source == null) {\r
-                       return PackagingURIHelper.PACKAGE_ROOT_URI;\r
-               }\r
-               return source.partName.getURI();\r
-       }\r
-\r
-       /**\r
-        * public URI getSourceUri(){ }\r
-        * \r
-        * @return the targetMode\r
-        */\r
-       public TargetMode getTargetMode() {\r
-               return targetMode;\r
-       }\r
-\r
-       /**\r
-        * @return the targetUri\r
-        */\r
-       public URI getTargetURI() {\r
-               // If it's an external target, we don't\r
-               //  need to apply our normal validation rules\r
-               if(targetMode == TargetMode.EXTERNAL) {\r
-                       return targetUri;\r
-               }\r
-               \r
-               // Internal target\r
-               // If it isn't absolute, resolve it relative\r
-               //  to ourselves\r
-               if (!targetUri.toASCIIString().startsWith("/")) {\r
-                       // So it's a relative part name, try to resolve it\r
-                       return PackagingURIHelper.resolvePartUri(getSourceURI(), targetUri);\r
-               }\r
-               return targetUri;\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               StringBuilder sb = new StringBuilder();\r
-               sb.append(id == null ? "id=null" : "id=" + id);\r
-               sb.append(container == null ? " - container=null" : " - container="\r
-                               + container.toString());\r
-               sb.append(relationshipType == null ? " - relationshipType=null"\r
-                               : " - relationshipType=" + relationshipType.toString());\r
-               sb.append(source == null ? " - source=null" : " - source="\r
-                               + getSourceURI().toASCIIString());\r
-               sb.append(targetUri == null ? " - target=null" : " - target="\r
-                               + getTargetURI().toASCIIString());\r
-               sb.append(targetMode == null ? ",targetMode=null" : ",targetMode="\r
-                               + targetMode.toString());\r
-               return sb.toString();\r
-       }\r
-}\r
+/* ====================================================================
+   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;
+
+       /**
+        * Reference to the package.
+        */
+       private OPCPackage 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 pkg
+        * @param sourcePart
+        * @param targetUri
+        * @param targetMode
+        * @param relationshipType
+        * @param id
+        */
+       public PackageRelationship(OPCPackage 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 OPCPackage 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 URL of the source part of this relationship
+        */
+       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();
+       }
+}
index 09f3280df249bd9b7fb4a6a08755422031346e6a..8a1173871148334ae281fd6bea1b73a383c2be84 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.TreeMap;\r
-\r
-import org.dom4j.Attribute;\r
-import org.dom4j.Document;\r
-import org.dom4j.Element;\r
-import org.dom4j.io.SAXReader;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.POILogFactory;\r
-\r
-/**\r
- * Represents a collection of PackageRelationship elements that are owned by a\r
- * given PackagePart or the Package.\r
- * \r
- * @author Julien Chable, CDubettier\r
- * @version 0.1\r
- */\r
-public final class PackageRelationshipCollection implements\r
-               Iterable<PackageRelationship> {\r
-\r
-    private static POILogger logger = POILogFactory.getLogger(PackageRelationshipCollection.class);\r
-\r
-       /**\r
-        * Package relationships ordered by ID.\r
-        */\r
-       private TreeMap<String, PackageRelationship> relationshipsByID;\r
-\r
-       /**\r
-        * Package relationships ordered by type.\r
-        */\r
-       private TreeMap<String, PackageRelationship> relationshipsByType;\r
-\r
-       /**\r
-        * This relationshipPart.\r
-        */\r
-       private PackagePart relationshipPart;\r
-\r
-       /**\r
-        * Source part.\r
-        */\r
-       private PackagePart sourcePart;\r
-\r
-       /**\r
-        * This part name.\r
-        */\r
-       private PackagePartName partName;\r
-\r
-       /**\r
-        * Reference to the package.\r
-        */\r
-       private Package container;\r
-\r
-       /**\r
-        * Constructor.\r
-        */\r
-       PackageRelationshipCollection() {\r
-               relationshipsByID = new TreeMap<String, PackageRelationship>();\r
-               relationshipsByType = new TreeMap<String, PackageRelationship>();\r
-       }\r
-\r
-       /**\r
-        * Copy constructor.\r
-        * \r
-        * This collection will contain only elements from the specified collection\r
-        * for which the type is compatible with the specified relationship type\r
-        * filter.\r
-        * \r
-        * @param coll\r
-        *            Collection to import.\r
-        * @param filter\r
-        *            Relationship type filter.\r
-        */\r
-       public PackageRelationshipCollection(PackageRelationshipCollection coll,\r
-                       String filter) {\r
-               this();\r
-               for (PackageRelationship rel : coll.relationshipsByID.values()) {\r
-                       if (filter == null || rel.getRelationshipType().equals(filter))\r
-                               addRelationship(rel);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Constructor.\r
-        */\r
-       public PackageRelationshipCollection(Package container)\r
-                       throws InvalidFormatException {\r
-               this(container, null);\r
-       }\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             Throws if the format of the content part is invalid.\r
-        * \r
-        * @throws InvalidOperationException\r
-        *             Throws if the specified part is a relationship part.\r
-        */\r
-       public PackageRelationshipCollection(PackagePart part)\r
-                       throws InvalidFormatException {\r
-               this(part.container, part);\r
-       }\r
-\r
-       /**\r
-        * Constructor. Parse the existing package relationship part if one exists.\r
-        * \r
-        * @param container\r
-        *            The parent package.\r
-        * @param part\r
-        *            The part that own this relationships collection. If <b>null</b>\r
-        *            then this part is considered as the package root.\r
-        * @throws InvalidFormatException\r
-        *             If an error occurs during the parsing of the relatinships\r
-        *             part fo the specified part.\r
-        */\r
-       public PackageRelationshipCollection(Package container, PackagePart part)\r
-                       throws InvalidFormatException {\r
-               this();\r
-\r
-               if (container == null)\r
-                       throw new IllegalArgumentException("container");\r
-\r
-               // Check if the specified part is not a relationship part\r
-               if (part != null && part.isRelationshipPart())\r
-                       throw new IllegalArgumentException("part");\r
-\r
-               this.container = container;\r
-               this.sourcePart = part;\r
-               this.partName = getRelationshipPartName(part);\r
-               if ((container.getPackageAccess() != PackageAccess.WRITE)\r
-                               && container.containPart(this.partName)) {\r
-                       relationshipPart = container.getPart(this.partName);\r
-                       parseRelationshipsPart(relationshipPart);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Get the relationship part name of the specified part.\r
-        * \r
-        * @param part\r
-        *            The part .\r
-        * @return The relationship part name of the specified part. Be careful,\r
-        *         only the correct name is returned, this method does not check if\r
-        *         the part really exist in a package !\r
-        * @throws InvalidOperationException\r
-        *             Throws if the specified part is a relationship part.\r
-        */\r
-       private static PackagePartName getRelationshipPartName(PackagePart part)\r
-                       throws InvalidOperationException {\r
-               PackagePartName partName;\r
-               if (part == null) {\r
-                       partName = PackagingURIHelper.PACKAGE_ROOT_PART_NAME;\r
-               } else {\r
-                       partName = part.getPartName();\r
-               }\r
-               return PackagingURIHelper.getRelationshipPartName(partName);\r
-       }\r
-\r
-       /**\r
-        * Add the specified relationship to the collection.\r
-        * \r
-        * @param relPart\r
-        *            The relationship to add.\r
-        */\r
-       public void addRelationship(PackageRelationship relPart) {\r
-               relationshipsByID.put(relPart.getId(), relPart);\r
-               relationshipsByType.put(relPart.getRelationshipType(), relPart);\r
-       }\r
-\r
-       /**\r
-        * Add a relationship to the collection.\r
-        * \r
-        * @param targetUri\r
-        *            Target URI.\r
-        * @param targetMode\r
-        *            The target mode : INTERNAL or EXTERNAL\r
-        * @param relationshipType\r
-        *            Relationship type.\r
-        * @param id\r
-        *            Relationship ID.\r
-        * @return The newly created relationship.\r
-        * @see PackageAccess\r
-        */\r
-       public PackageRelationship addRelationship(URI targetUri,\r
-                       TargetMode targetMode, String relationshipType, String id) {\r
-\r
-               if (id == null) {\r
-                       // Generate a unique ID is id parameter is null.\r
-                       int i = 0;\r
-                       do {\r
-                               id = "rId" + ++i;\r
-                       } while (relationshipsByID.get(id) != null);\r
-               }\r
-\r
-               PackageRelationship rel = new PackageRelationship(container,\r
-                               sourcePart, targetUri, targetMode, relationshipType, id);\r
-               relationshipsByID.put(rel.getId(), rel);\r
-               relationshipsByType.put(rel.getRelationshipType(), rel);\r
-               return rel;\r
-       }\r
-\r
-       /**\r
-        * Remove a relationship by its ID.\r
-        * \r
-        * @param id\r
-        *            The relationship ID to remove.\r
-        */\r
-       public void removeRelationship(String id) {\r
-               if (relationshipsByID != null && relationshipsByType != null) {\r
-                       PackageRelationship rel = relationshipsByID.get(id);\r
-                       if (rel != null) {\r
-                               relationshipsByID.remove(rel.getId());\r
-                               relationshipsByType.values().remove(rel);\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Remove a relationship by its reference.\r
-        * \r
-        * @param rel\r
-        *            The relationship to delete.\r
-        */\r
-       public void removeRelationship(PackageRelationship rel) {\r
-               if (rel == null)\r
-                       throw new IllegalArgumentException("rel");\r
-\r
-               relationshipsByID.values().remove(rel);\r
-               relationshipsByType.values().remove(rel);\r
-       }\r
-\r
-       /**\r
-        * Retrieves a relationship by its index in the collection.\r
-        * \r
-        * @param index\r
-        *            Must be a value between [0-relationships_count-1]\r
-        */\r
-       public PackageRelationship getRelationship(int index) {\r
-               if (index < 0 || index > relationshipsByID.values().size())\r
-                       throw new IllegalArgumentException("index");\r
-\r
-               PackageRelationship retRel = null;\r
-               int i = 0;\r
-               for (PackageRelationship rel : relationshipsByID.values()) {\r
-                       if (index == i++)\r
-                               return rel;\r
-               }\r
-               return retRel;\r
-       }\r
-\r
-       /**\r
-        * Retrieves a package relationship based on its id.\r
-        * \r
-        * @param id\r
-        *            ID of the package relationship to retrieve.\r
-        * @return The package relationship identified by the specified id.\r
-        */\r
-       public PackageRelationship getRelationshipByID(String id) {\r
-               return relationshipsByID.get(id);\r
-       }\r
-\r
-       /**\r
-        * Get the numbe rof relationships in the collection.\r
-        */\r
-       public int size() {\r
-               return relationshipsByID.values().size();\r
-       }\r
-\r
-       /**\r
-        * Parse the relationship part and add all relationship in this collection.\r
-        * \r
-        * @param relPart\r
-        *            The package part to parse.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the relationship part is invalid.\r
-        */\r
-       private void parseRelationshipsPart(PackagePart relPart)\r
-                       throws InvalidFormatException {\r
-               try {\r
-                       SAXReader reader = new SAXReader();\r
-                       logger.log(POILogger.DEBUG, "Parsing relationship: " + relPart.getPartName());\r
-                       Document xmlRelationshipsDoc = reader\r
-                                       .read(relPart.getInputStream());\r
-\r
-                       // Browse default types\r
-                       Element root = xmlRelationshipsDoc.getRootElement();\r
-\r
-                       // Check OPC compliance M4.1 rule\r
-                       boolean fCorePropertiesRelationship = false;\r
-\r
-                       for (Iterator i = root\r
-                                       .elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i\r
-                                       .hasNext();) {\r
-                               Element element = (Element) i.next();\r
-                               // Relationship ID\r
-                               String id = element.attribute(\r
-                                               PackageRelationship.ID_ATTRIBUTE_NAME).getValue();\r
-                               // Relationship type\r
-                               String type = element.attribute(\r
-                                               PackageRelationship.TYPE_ATTRIBUTE_NAME).getValue();\r
-\r
-                               /* Check OPC Compliance */\r
-                               // Check Rule M4.1\r
-                               if (type.equals(PackageRelationshipTypes.CORE_PROPERTIES))\r
-                                       if (!fCorePropertiesRelationship)\r
-                                               fCorePropertiesRelationship = true;\r
-                                       else\r
-                                               throw new InvalidFormatException(\r
-                                                               "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !");\r
-\r
-                               /* End OPC Compliance */\r
-\r
-                               // TargetMode (default value "Internal")\r
-                               Attribute targetModeAttr = element\r
-                                               .attribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME);\r
-                               TargetMode targetMode = TargetMode.INTERNAL;\r
-                               if (targetModeAttr != null) {\r
-                                       targetMode = targetModeAttr.getValue().toLowerCase()\r
-                                                       .equals("internal") ? TargetMode.INTERNAL\r
-                                                       : TargetMode.EXTERNAL;\r
-                               }\r
-\r
-                               // Target converted in URI\r
-                               URI target;\r
-                               String value = "";\r
-                               try {\r
-                                       value = element.attribute(\r
-                                                       PackageRelationship.TARGET_ATTRIBUTE_NAME)\r
-                                                       .getValue();\r
-\r
-                                       if (value.indexOf("\\") != -1) {\r
-                                               logger\r
-                                                               .log(POILogger.INFO, "target contains \\ therefore not a valid URI"\r
-                                                                               + value + " replaced by /");\r
-                                               value = value.replaceAll("\\\\", "/");\r
-                                               // word can save external relationship with a \ instead\r
-                                               // of /\r
-                                       }\r
-\r
-                                       target = new URI(value);\r
-                               } catch (URISyntaxException e) {\r
-                                       logger.log(POILogger.ERROR, "Cannot convert " + value\r
-                                                       + " in a valid relationship URI-> ignored", e);\r
-                                       continue;\r
-                               }\r
-                               addRelationship(target, targetMode, type, id);\r
-                       }\r
-               } catch (Exception e) {\r
-                       logger.log(POILogger.ERROR, e);\r
-                       throw new InvalidFormatException(e.getMessage());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Retrieves all relations with the specified type.\r
-        * \r
-        * @param typeFilter\r
-        *            Relationship type filter. If <b>null</b> then all\r
-        *            relationships are returned.\r
-        * @return All relationships of the type specified by the filter.\r
-        */\r
-       public PackageRelationshipCollection getRelationships(String typeFilter) {\r
-               PackageRelationshipCollection coll = new PackageRelationshipCollection(\r
-                               this, typeFilter);\r
-               return coll;\r
-       }\r
-\r
-       /**\r
-        * Get this collection's iterator.\r
-        */\r
-       public Iterator<PackageRelationship> iterator() {\r
-               return relationshipsByID.values().iterator();\r
-       }\r
-\r
-       /**\r
-        * Get an iterator of a collection with all relationship with the specified\r
-        * type.\r
-        * \r
-        * @param typeFilter\r
-        *            Type filter.\r
-        * @return An iterator to a collection containing all relationships with the\r
-        *         specified type contain in this collection.\r
-        */\r
-       public Iterator<PackageRelationship> iterator(String typeFilter) {\r
-               ArrayList<PackageRelationship> retArr = new ArrayList<PackageRelationship>();\r
-               for (PackageRelationship rel : relationshipsByID.values()) {\r
-                       if (rel.getRelationshipType().equals(typeFilter))\r
-                               retArr.add(rel);\r
-               }\r
-               return retArr.iterator();\r
-       }\r
-\r
-       /**\r
-        * Clear all relationships.\r
-        */\r
-       public void clear() {\r
-               relationshipsByID.clear();\r
-               relationshipsByType.clear();\r
-       }\r
-\r
-       @Override\r
-       public String toString() {\r
-               String str;\r
-               if (relationshipsByID == null) {\r
-                       str = "relationshipsByID=null";\r
-               } else {\r
-                       str = relationshipsByID.size() + " relationship(s) = [";\r
-               }\r
-               if ((relationshipPart != null) && (relationshipPart.partName != null)) {\r
-                       str = str + "," + relationshipPart.partName;\r
-               } else {\r
-                       str = str + ",relationshipPart=null";\r
-               }\r
-\r
-               // Source of this relationship\r
-               if ((sourcePart != null) && (sourcePart.partName != null)) {\r
-                       str = str + "," + sourcePart.partName;\r
-               } else {\r
-                       str = str + ",sourcePart=null";\r
-               }\r
-               if (partName != null) {\r
-                       str = str + "," + partName;\r
-               } else {\r
-                       str = str + ",uri=null)";\r
-               }\r
-               return str + "]";\r
-       }\r
-}\r
+/* ====================================================================
+   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.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;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
+
+/**
+ * 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 POILogger logger = POILogFactory.getLogger(PackageRelationshipCollection.class);
+
+       /**
+        * 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 OPCPackage 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(OPCPackage 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(OPCPackage 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.log(POILogger.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
+                                                               .log(POILogger.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.log(POILogger.ERROR, "Cannot convert " + value
+                                                       + " in a valid relationship URI-> ignored", e);
+                                       continue;
+                               }
+                               addRelationship(target, targetMode, type, id);
+                       }
+               } catch (Exception e) {
+                       logger.log(POILogger.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 + "]";
+       }
+}
index 2c05898d14b4ec6d323dcaef784b7c8a5f9c6513..a4e50ba0a868df0f01e4af74e3430d5223a0d075 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.util.zip.ZipEntry;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;\r
-\r
-/**\r
- * Zip implementation of a PackagePart.\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- * @see PackagePart\r
- */\r
-public class ZipPackagePart extends PackagePart {\r
-\r
-       /**\r
-        * The zip entry corresponding to this part.\r
-        */\r
-       private ZipEntry zipEntry;\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param container\r
-        *            The container package.\r
-        * @param partName\r
-        *            Part name.\r
-        * @param contentType\r
-        *            Content type.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the content of this part invalid.\r
-        */\r
-       public ZipPackagePart(Package container, PackagePartName partName,\r
-                       String contentType) throws InvalidFormatException {\r
-               super(container, partName, contentType);\r
-       }\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param container\r
-        *            The container package.\r
-        * @param zipEntry\r
-        *            The zip entry corresponding to this part.\r
-        * @param partName\r
-        *            The part name.\r
-        * @param contentType\r
-        *            Content type.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the content of this part is invalid.\r
-        */\r
-       public ZipPackagePart(Package container, ZipEntry zipEntry,\r
-                       PackagePartName partName, String contentType)\r
-                       throws InvalidFormatException {\r
-               super(container, partName, contentType);\r
-               this.zipEntry = zipEntry;\r
-       }\r
-\r
-       /**\r
-        * Get the zip entry of this part.\r
-        * \r
-        * @return The zip entry in the zip structure coresponding to this part.\r
-        */\r
-       public ZipEntry getZipArchive() {\r
-               return zipEntry;\r
-       }\r
-\r
-       /**\r
-        * Implementation of the getInputStream() which return the inputStream of\r
-        * this part zip entry.\r
-        * \r
-        * @return Input stream of this part zip entry.\r
-        */\r
-       @Override\r
-       protected InputStream getInputStreamImpl() throws IOException {\r
-               // We use the getInputStream() method from java.util.zip.ZipFile\r
-               // class which return an InputStream to this part zip entry.\r
-               return ((ZipPackage) container).getZipArchive()\r
-                               .getInputStream(zipEntry);\r
-       }\r
-\r
-       /**\r
-        * Implementation of the getOutputStream(). Return <b>null</b>. Normally\r
-        * will never be called since the MemoryPackage is use instead.\r
-        * \r
-        * @return <b>null</b>\r
-        */\r
-       @Override\r
-       protected OutputStream getOutputStreamImpl() {\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public boolean save(OutputStream os) throws OpenXML4JException {\r
-               return new ZipPartMarshaller().marshall(this, os);\r
-       }\r
-\r
-       @Override\r
-       public boolean load(InputStream ios) throws InvalidFormatException {\r
-               throw new InvalidOperationException("Method not implemented !");\r
-       }\r
-\r
-       @Override\r
-       public void close() {\r
-               throw new InvalidOperationException("Method not implemented !");\r
-       }\r
-\r
-       @Override\r
-       public void flush() {\r
-               throw new InvalidOperationException("Method not implemented !");\r
-       }\r
-}\r
+/* ====================================================================
+   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.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;
+
+/**
+ * Zip implementation of a PackagePart.
+ * 
+ * @author Julien Chable
+ * @version 1.0
+ * @see PackagePart
+ */
+public class ZipPackagePart extends PackagePart {
+
+       /**
+        * The zip entry corresponding to this part.
+        */
+       private ZipEntry zipEntry;
+
+       /**
+        * Constructor.
+        * 
+        * @param container
+        *            The container package.
+        * @param partName
+        *            Part name.
+        * @param contentType
+        *            Content type.
+        * @throws InvalidFormatException
+        *             Throws if the content of this part invalid.
+        */
+       public ZipPackagePart(OPCPackage container, PackagePartName partName,
+                       String contentType) throws InvalidFormatException {
+               super(container, partName, contentType);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param container
+        *            The container package.
+        * @param zipEntry
+        *            The zip entry corresponding to this part.
+        * @param partName
+        *            The part name.
+        * @param contentType
+        *            Content type.
+        * @throws InvalidFormatException
+        *             Throws if the content of this part is invalid.
+        */
+       public ZipPackagePart(OPCPackage container, ZipEntry zipEntry,
+                       PackagePartName partName, String contentType)
+                       throws InvalidFormatException {
+               super(container, partName, contentType);
+               this.zipEntry = zipEntry;
+       }
+
+       /**
+        * Get the zip entry of this part.
+        * 
+        * @return The zip entry in the zip structure coresponding to this part.
+        */
+       public ZipEntry getZipArchive() {
+               return zipEntry;
+       }
+
+       /**
+        * Implementation of the getInputStream() which return the inputStream of
+        * this part zip entry.
+        * 
+        * @return Input stream of this part zip entry.
+        */
+       @Override
+       protected InputStream getInputStreamImpl() throws IOException {
+               // We use the getInputStream() method from java.util.zip.ZipFile
+               // class which return an InputStream to this part zip entry.
+               return ((ZipPackage) container).getZipArchive()
+                               .getInputStream(zipEntry);
+       }
+
+       /**
+        * Implementation of the getOutputStream(). Return <b>null</b>. Normally
+        * will never be called since the MemoryPackage is use instead.
+        * 
+        * @return <b>null</b>
+        */
+       @Override
+       protected OutputStream getOutputStreamImpl() {
+               return null;
+       }
+
+       @Override
+       public boolean save(OutputStream os) throws OpenXML4JException {
+               return new ZipPartMarshaller().marshall(this, os);
+       }
+
+       @Override
+       public boolean load(InputStream ios) throws InvalidFormatException {
+               throw new InvalidOperationException("Method not implemented !");
+       }
+
+       @Override
+       public void close() {
+               throw new InvalidOperationException("Method not implemented !");
+       }
+
+       @Override
+       public void flush() {
+               throw new InvalidOperationException("Method not implemented !");
+       }
+}
index 927102d6dbb8d734955b289f7ef3f87f531cac06..f36bf068ff99d7f5637c0711b4baadb33b7de87b 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.internal;\r
-\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.TreeMap;\r
-import java.util.Map.Entry;\r
-import java.util.zip.ZipOutputStream;\r
-\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentException;\r
-import org.dom4j.DocumentHelper;\r
-import org.dom4j.Element;\r
-import org.dom4j.Namespace;\r
-import org.dom4j.QName;\r
-import org.dom4j.io.SAXReader;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackagePart;\r
-import org.apache.poi.openxml4j.opc.PackagePartName;\r
-import org.apache.poi.openxml4j.opc.PackagingURIHelper;\r
-import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.POILogFactory;\r
-\r
-/**\r
- * Manage package content types ([Content_Types].xml part).\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- */\r
-public abstract class ContentTypeManager {\r
-\r
-    private static POILogger logger = POILogFactory.getLogger(ContentTypeManager.class);\r
-\r
-       /**\r
-        * Reference to the package using this content type manager.\r
-        */\r
-       protected Package container;\r
-\r
-       /**\r
-        * Content type part name.\r
-        */\r
-       public static final String CONTENT_TYPES_PART_NAME = "[Content_Types].xml";\r
-\r
-       /**\r
-        * Content type namespace\r
-        */\r
-       public static final String TYPES_NAMESPACE_URI = "http://schemas.openxmlformats.org/package/2006/content-types";\r
-\r
-       /* Xml elements in content type part */\r
-\r
-       private static final String TYPES_TAG_NAME = "Types";\r
-\r
-       private static final String DEFAULT_TAG_NAME = "Default";\r
-\r
-       private static final String EXTENSION_ATTRIBUTE_NAME = "Extension";\r
-\r
-       private static final String CONTENT_TYPE_ATTRIBUTE_NAME = "ContentType";\r
-\r
-       private static final String OVERRIDE_TAG_NAME = "Override";\r
-\r
-       private static final String PART_NAME_ATTRIBUTE_NAME = "PartName";\r
-\r
-       /**\r
-        * Default content type tree. <Extension, ContentType>\r
-        */\r
-       private TreeMap<String, String> defaultContentType;\r
-\r
-       /**\r
-        * Override content type tree.\r
-        */\r
-       private TreeMap<PackagePartName, String> overrideContentType;\r
-\r
-       /**\r
-        * Constructor. Parses the content of the specified input stream.\r
-        * \r
-        * @param in\r
-        *            If different of <i>null</i> then the content types part is\r
-        *            retrieve and parse.\r
-        * @throws InvalidFormatException\r
-        *             If the content types part content is not valid.\r
-        */\r
-       public ContentTypeManager(InputStream in, Package pkg)\r
-                       throws InvalidFormatException {\r
-               this.container = pkg;\r
-               this.defaultContentType = new TreeMap<String, String>();\r
-               if (in != null) {\r
-                       try {\r
-                               parseContentTypesFile(in);\r
-                       } catch (InvalidFormatException e) {\r
-                               throw new InvalidFormatException(\r
-                                               "Can't read content types part !");\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Build association extention-> content type (will be stored in\r
-        * [Content_Types].xml) for example ContentType="image/png" Extension="png"\r
-        * <p>\r
-        * [M2.8]: When adding a new part to a package, the package implementer\r
-        * shall ensure that a content type for that part is specified in the\r
-        * Content Types stream; the package implementer shall perform the steps\r
-        * described in &#167;9.1.2.3:\r
-        * </p><p>\r
-        * 1. Get the extension from the part name by taking the substring to the\r
-        * right of the rightmost occurrence of the dot character (.) from the\r
-        * rightmost segment.\r
-        * </p><p>\r
-        * 2. If a part name has no extension, a corresponding Override element\r
-        * shall be added to the Content Types stream.\r
-        * </p><p>\r
-        * 3. Compare the resulting extension with the values specified for the\r
-        * Extension attributes of the Default elements in the Content Types stream.\r
-        * The comparison shall be case-insensitive ASCII.\r
-        * </p><p>\r
-        * 4. If there is a Default element with a matching Extension attribute,\r
-        * then the content type of the new part shall be compared with the value of\r
-        * the ContentType attribute. The comparison might be case-sensitive and\r
-        * include every character regardless of the role it plays in the\r
-        * content-type grammar of RFC 2616, or it might follow the grammar of RFC\r
-        * 2616.\r
-        * </p><p>\r
-        * a. If the content types match, no further action is required.\r
-        * </p><p>\r
-        * b. If the content types do not match, a new Override element shall be\r
-        * added to the Content Types stream. .\r
-        * </p><p>\r
-        * 5. If there is no Default element with a matching Extension attribute, a\r
-        * new Default element or Override element shall be added to the Content\r
-        * Types stream.\r
-        * </p>\r
-        */\r
-       public void addContentType(PackagePartName partName, String contentType) {\r
-               boolean defaultCTExists = false;\r
-               String extension = partName.getExtension().toLowerCase();\r
-               if ((extension.length() == 0)\r
-                               || (this.defaultContentType.containsKey(extension) && !(defaultCTExists = this.defaultContentType\r
-                                               .containsValue(contentType))))\r
-                       this.addOverrideContentType(partName, contentType);\r
-               else if (!defaultCTExists)\r
-                       this.addDefaultContentType(extension, contentType);\r
-       }\r
-\r
-       /**\r
-        * Add an override content type for a specific part.\r
-        * \r
-        * @param partName\r
-        *            Name of the part.\r
-        * @param contentType\r
-        *            Content type of the part.\r
-        */\r
-       private void addOverrideContentType(PackagePartName partName,\r
-                       String contentType) {\r
-               if (overrideContentType == null)\r
-                       overrideContentType = new TreeMap<PackagePartName, String>();\r
-               overrideContentType.put(partName, contentType);\r
-       }\r
-\r
-       /**\r
-        * Add a content type associated with the specified extension.\r
-        * \r
-        * @param extension\r
-        *            The part name extension to bind to a content type.\r
-        * @param contentType\r
-        *            The content type associated with the specified extension.\r
-        */\r
-       private void addDefaultContentType(String extension, String contentType) {\r
-               // Remark : Originally the latest parameter was :\r
-               // contentType.toLowerCase(). Change due to a request ID 1996748.\r
-               defaultContentType.put(extension.toLowerCase(), contentType);\r
-       }\r
-\r
-       /**\r
-     * <p>\r
-        * Delete a content type based on the specified part name. If the specified\r
-        * part name is register with an override content type, then this content\r
-        * type is remove, else the content type is remove in the default content\r
-        * type list if it exists and if no part is associated with it yet.\r
-        * </p><p>\r
-        * Check rule M2.4: The package implementer shall require that the Content\r
-        * Types stream contain one of the following for every part in the package:\r
-        * One matching Default element One matching Override element Both a\r
-        * matching Default element and a matching Override element, in which case\r
-        * the Override element takes precedence.\r
-        * </p>\r
-        * @param partName\r
-        *            The part URI associated with the override content type to\r
-        *            delete.\r
-        * @exception InvalidOperationException\r
-        *                Throws if\r
-        */\r
-       public void removeContentType(PackagePartName partName)\r
-                       throws InvalidOperationException {\r
-               if (partName == null)\r
-                       throw new IllegalArgumentException("partName");\r
-\r
-               /* Override content type */\r
-               if (this.overrideContentType != null\r
-                               && (this.overrideContentType.get(partName) != null)) {\r
-                       // Remove the override definition for the specified part.\r
-                       this.overrideContentType.remove(partName);\r
-                       return;\r
-               }\r
-\r
-               /* Default content type */\r
-               String extensionToDelete = partName.getExtension();\r
-               boolean deleteDefaultContentTypeFlag = true;\r
-               if (this.container != null) {\r
-                       try {\r
-                               for (PackagePart part : this.container.getParts()) {\r
-                                       if (!part.getPartName().equals(partName)\r
-                                                       && part.getPartName().getExtension()\r
-                                                                       .equalsIgnoreCase(extensionToDelete)) {\r
-                                               deleteDefaultContentTypeFlag = false;\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       } catch (InvalidFormatException e) {\r
-                               throw new InvalidOperationException(e.getMessage());\r
-                       }\r
-               }\r
-\r
-               // Remove the default content type, no other part use this content type.\r
-               if (deleteDefaultContentTypeFlag) {\r
-                       this.defaultContentType.remove(extensionToDelete);\r
-               }\r
-\r
-               /*\r
-                * Check rule 2.4: The package implementer shall require that the\r
-                * Content Types stream contain one of the following for every part in\r
-                * the package: One matching Default element One matching Override\r
-                * element Both a matching Default element and a matching Override\r
-                * element, in which case the Override element takes precedence.\r
-                */\r
-               if (this.container != null) {\r
-                       try {\r
-                               for (PackagePart part : this.container.getParts()) {\r
-                                       if (!part.getPartName().equals(partName)\r
-                                                       && this.getContentType(part.getPartName()) == null)\r
-                                               throw new InvalidOperationException(\r
-                                                               "Rule M2.4 is not respected: Nor a default element or override element is associated with the part: "\r
-                                                                               + part.getPartName().getName());\r
-                               }\r
-                       } catch (InvalidFormatException e) {\r
-                               throw new InvalidOperationException(e.getMessage());\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Check if the specified content type is already register.\r
-        * \r
-        * @param contentType\r
-        *            The content type to check.\r
-        * @return <code>true</code> if the specified content type is already\r
-        *         register, then <code>false</code>.\r
-        */\r
-       public boolean isContentTypeRegister(String contentType) {\r
-               if (contentType == null)\r
-                       throw new IllegalArgumentException("contentType");\r
-\r
-               return (this.defaultContentType.values().contains(contentType) || (this.overrideContentType != null && this.overrideContentType\r
-                               .values().contains(contentType)));\r
-       }\r
-\r
-       /**\r
-        * Get the content type for the specified part, if any.\r
-        * <p>\r
-        * Rule [M2.9]: To get the content type of a part, the package implementer\r
-        * shall perform the steps described in &#167;9.1.2.4:\r
-        * </p><p>\r
-        * 1. Compare the part name with the values specified for the PartName\r
-        * attribute of the Override elements. The comparison shall be\r
-        * case-insensitive ASCII.\r
-        * </p><p>\r
-        * 2. If there is an Override element with a matching PartName attribute,\r
-        * return the value of its ContentType attribute. No further action is\r
-        * required.\r
-        * </p><p>\r
-        * 3. If there is no Override element with a matching PartName attribute,\r
-        * then a. Get the extension from the part name by taking the substring to\r
-        * the right of the rightmost occurrence of the dot character (.) from the\r
-        * rightmost segment. b. Check the Default elements of the Content Types\r
-        * stream, comparing the extension with the value of the Extension\r
-        * attribute. The comparison shall be case-insensitive ASCII.\r
-        * </p><p>\r
-        * 4. If there is a Default element with a matching Extension attribute,\r
-        * return the value of its ContentType attribute. No further action is\r
-        * required.\r
-        * </p><p>\r
-        * 5. If neither Override nor Default elements with matching attributes are\r
-        * found for the specified part name, the implementation shall not map this\r
-        * part name to a part.\r
-        * </p>\r
-        * @param partName\r
-        *            The URI part to check.\r
-        * @return The content type associated with the URI (in case of an override\r
-        *         content type) or the extension (in case of default content type),\r
-        *         else <code>null</code>.\r
-        * \r
-        * @exception OpenXML4JRuntimeException\r
-        *                Throws if the content type manager is not able to find the\r
-        *                content from an existing part.\r
-        */\r
-       public String getContentType(PackagePartName partName) {\r
-               if (partName == null)\r
-                       throw new IllegalArgumentException("partName");\r
-\r
-               if ((this.overrideContentType != null)\r
-                               && this.overrideContentType.containsKey(partName))\r
-                       return this.overrideContentType.get(partName);\r
-\r
-               String extension = partName.getExtension().toLowerCase();\r
-               if (this.defaultContentType.containsKey(extension))\r
-                       return this.defaultContentType.get(extension);\r
-\r
-               /*\r
-                * [M2.4] : The package implementer shall require that the Content Types\r
-                * stream contain one of the following for every part in the package:\r
-                * One matching Default element, One matching Override element, Both a\r
-                * matching Default element and a matching Override element, in which\r
-                * case the Override element takes precedence.\r
-                */\r
-               if (this.container != null && this.container.getPart(partName) != null) {\r
-                       throw new OpenXML4JRuntimeException(\r
-                                       "Rule M2.4 exception : this error should NEVER happen, if so please send a mail to the developers team, thanks !");\r
-               } else {\r
-                       return null;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Clear all content types.\r
-        */\r
-       public void clearAll() {\r
-               this.defaultContentType.clear();\r
-               if (this.overrideContentType != null)\r
-                       this.overrideContentType.clear();\r
-       }\r
-\r
-       /**\r
-        * Clear all override content types.\r
-        * \r
-        */\r
-       public void clearOverrideContentTypes() {\r
-               if (this.overrideContentType != null)\r
-                       this.overrideContentType.clear();\r
-       }\r
-\r
-       /**\r
-        * Parse the content types part.\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             Throws if the content type doesn't exist or the XML format is\r
-        *             invalid.\r
-        */\r
-       private void parseContentTypesFile(InputStream in)\r
-                       throws InvalidFormatException {\r
-               try {\r
-                       SAXReader xmlReader = new SAXReader();\r
-                       Document xmlContentTypetDoc = xmlReader.read(in);\r
-\r
-                       // Default content types\r
-                       List defaultTypes = xmlContentTypetDoc.getRootElement().elements(\r
-                                       DEFAULT_TAG_NAME);\r
-                       Iterator elementIteratorDefault = defaultTypes.iterator();\r
-                       while (elementIteratorDefault.hasNext()) {\r
-                               Element element = (Element) elementIteratorDefault.next();\r
-                               String extension = element.attribute(EXTENSION_ATTRIBUTE_NAME)\r
-                                               .getValue();\r
-                               String contentType = element.attribute(\r
-                                               CONTENT_TYPE_ATTRIBUTE_NAME).getValue();\r
-                               addDefaultContentType(extension, contentType);\r
-                       }\r
-\r
-                       // Overriden content types\r
-                       List overrideTypes = xmlContentTypetDoc.getRootElement().elements(\r
-                                       OVERRIDE_TAG_NAME);\r
-                       Iterator elementIteratorOverride = overrideTypes.iterator();\r
-                       while (elementIteratorOverride.hasNext()) {\r
-                               Element element = (Element) elementIteratorOverride.next();\r
-                               URI uri = new URI(element.attribute(PART_NAME_ATTRIBUTE_NAME)\r
-                                               .getValue());\r
-                               PackagePartName partName = PackagingURIHelper\r
-                                               .createPartName(uri);\r
-                               String contentType = element.attribute(\r
-                                               CONTENT_TYPE_ATTRIBUTE_NAME).getValue();\r
-                               addOverrideContentType(partName, contentType);\r
-                       }\r
-               } catch (URISyntaxException urie) {\r
-                       throw new InvalidFormatException(urie.getMessage());\r
-               } catch (DocumentException e) {\r
-                       throw new InvalidFormatException(e.getMessage());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Save the contents type part.\r
-        * \r
-        * @param outStream\r
-        *            The output stream use to save the XML content of the content\r
-        *            types part.\r
-        * @return <b>true</b> if the operation success, else <b>false</b>.\r
-        */\r
-       public boolean save(OutputStream outStream) {\r
-               Document xmlOutDoc = DocumentHelper.createDocument();\r
-\r
-               // Building namespace\r
-               Namespace dfNs = Namespace.get("", TYPES_NAMESPACE_URI);\r
-               Element typesElem = xmlOutDoc\r
-                               .addElement(new QName(TYPES_TAG_NAME, dfNs));\r
-\r
-               // Adding default types\r
-               for (Entry<String, String> entry : defaultContentType.entrySet()) {\r
-                       appendDefaultType(typesElem, entry);\r
-               }\r
-\r
-               // Adding specific types if any exist\r
-               if (overrideContentType != null) {\r
-                       for (Entry<PackagePartName, String> entry : overrideContentType\r
-                                       .entrySet()) {\r
-                               appendSpecificTypes(typesElem, entry);\r
-                       }\r
-               }\r
-               xmlOutDoc.normalize();\r
-\r
-               // Save content in the specified output stream\r
-               return this.saveImpl(xmlOutDoc, outStream);\r
-       }\r
-\r
-       /**\r
-        * Use to append specific type XML elements, use by the save() method.\r
-        * \r
-        * @param root\r
-        *            XML parent element use to append this override type element.\r
-        * @param entry\r
-        *            The values to append.\r
-        * @see #save(java.io.OutputStream)\r
-        */\r
-       private void appendSpecificTypes(Element root,\r
-                       Entry<PackagePartName, String> entry) {\r
-               root.addElement(OVERRIDE_TAG_NAME).addAttribute(\r
-                               PART_NAME_ATTRIBUTE_NAME,\r
-                               ((PackagePartName) entry.getKey()).getName()).addAttribute(\r
-                               CONTENT_TYPE_ATTRIBUTE_NAME, (String) entry.getValue());\r
-       }\r
-\r
-       /**\r
-        * Use to append default types XML elements, use by the save() metid.\r
-        * \r
-        * @param root\r
-        *            XML parent element use to append this default type element.\r
-        * @param entry\r
-        *            The values to append.\r
-        * @see #save(java.io.OutputStream)\r
-        */\r
-       private void appendDefaultType(Element root, Entry<String, String> entry) {\r
-               root.addElement(DEFAULT_TAG_NAME).addAttribute(\r
-                               EXTENSION_ATTRIBUTE_NAME, (String) entry.getKey())\r
-                               .addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME,\r
-                                               (String) entry.getValue());\r
-\r
-       }\r
-\r
-       /**\r
-        * Specific implementation of the save method. Call by the save() method,\r
-        * call before exiting.\r
-        * \r
-        * @param out\r
-        *            The output stream use to write the content type XML.\r
-        */\r
-       public abstract boolean saveImpl(Document content, OutputStream out);\r
-}\r
+/* ====================================================================
+   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.internal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+import org.dom4j.QName;
+import org.dom4j.io.SAXReader;
+
+/**
+ * Manage package content types ([Content_Types].xml part).
+ * 
+ * @author Julien Chable
+ * @version 1.0
+ */
+public abstract class ContentTypeManager {
+
+       /**
+        * Content type part name.
+        */
+       public static final String CONTENT_TYPES_PART_NAME = "[Content_Types].xml";
+
+       /**
+        * Content type namespace
+        */
+       public static final String TYPES_NAMESPACE_URI = "http://schemas.openxmlformats.org/package/2006/content-types";
+
+       /* Xml elements in content type part */
+
+       private static final String TYPES_TAG_NAME = "Types";
+
+       private static final String DEFAULT_TAG_NAME = "Default";
+
+       private static final String EXTENSION_ATTRIBUTE_NAME = "Extension";
+
+       private static final String CONTENT_TYPE_ATTRIBUTE_NAME = "ContentType";
+
+       private static final String OVERRIDE_TAG_NAME = "Override";
+
+       private static final String PART_NAME_ATTRIBUTE_NAME = "PartName";
+
+       /**
+        * Reference to the package using this content type manager.
+        */
+       protected OPCPackage container;
+
+       /**
+        * Default content type tree. <Extension, ContentType>
+        */
+       private TreeMap<String, String> defaultContentType;
+
+       /**
+        * Override content type tree.
+        */
+       private TreeMap<PackagePartName, String> overrideContentType;
+
+       /**
+        * Constructor. Parses the content of the specified input stream.
+        * 
+        * @param in
+        *            If different of <i>null</i> then the content types part is
+        *            retrieve and parse.
+        * @throws InvalidFormatException
+        *             If the content types part content is not valid.
+        */
+       public ContentTypeManager(InputStream in, OPCPackage pkg)
+                       throws InvalidFormatException {
+               this.container = pkg;
+               this.defaultContentType = new TreeMap<String, String>();
+               if (in != null) {
+                       try {
+                               parseContentTypesFile(in);
+                       } catch (InvalidFormatException e) {
+                               throw new InvalidFormatException(
+                                               "Can't read content types part !");
+                       }
+               }
+       }
+
+       /**
+        * Build association extention-> content type (will be stored in
+        * [Content_Types].xml) for example ContentType="image/png" Extension="png"
+        * <p>
+        * [M2.8]: When adding a new part to a package, the package implementer
+        * shall ensure that a content type for that part is specified in the
+        * Content Types stream; the package implementer shall perform the steps
+        * described in &#167;9.1.2.3:
+        * </p><p>
+        * 1. Get the extension from the part name by taking the substring to the
+        * right of the rightmost occurrence of the dot character (.) from the
+        * rightmost segment.
+        * </p><p>
+        * 2. If a part name has no extension, a corresponding Override element
+        * shall be added to the Content Types stream.
+        * </p><p>
+        * 3. Compare the resulting extension with the values specified for the
+        * Extension attributes of the Default elements in the Content Types stream.
+        * The comparison shall be case-insensitive ASCII.
+        * </p><p>
+        * 4. If there is a Default element with a matching Extension attribute,
+        * then the content type of the new part shall be compared with the value of
+        * the ContentType attribute. The comparison might be case-sensitive and
+        * include every character regardless of the role it plays in the
+        * content-type grammar of RFC 2616, or it might follow the grammar of RFC
+        * 2616.
+        * </p><p>
+        * a. If the content types match, no further action is required.
+        * </p><p>
+        * b. If the content types do not match, a new Override element shall be
+        * added to the Content Types stream. .
+        * </p><p>
+        * 5. If there is no Default element with a matching Extension attribute, a
+        * new Default element or Override element shall be added to the Content
+        * Types stream.
+        * </p>
+        */
+       public void addContentType(PackagePartName partName, String contentType) {
+               boolean defaultCTExists = false;
+               String extension = partName.getExtension().toLowerCase();
+               if ((extension.length() == 0)
+                               || (this.defaultContentType.containsKey(extension) && !(defaultCTExists = this.defaultContentType
+                                               .containsValue(contentType))))
+                       this.addOverrideContentType(partName, contentType);
+               else if (!defaultCTExists)
+                       this.addDefaultContentType(extension, contentType);
+       }
+
+       /**
+        * Add an override content type for a specific part.
+        * 
+        * @param partName
+        *            Name of the part.
+        * @param contentType
+        *            Content type of the part.
+        */
+       private void addOverrideContentType(PackagePartName partName,
+                       String contentType) {
+               if (overrideContentType == null)
+                       overrideContentType = new TreeMap<PackagePartName, String>();
+               overrideContentType.put(partName, contentType);
+       }
+
+       /**
+        * Add a content type associated with the specified extension.
+        * 
+        * @param extension
+        *            The part name extension to bind to a content type.
+        * @param contentType
+        *            The content type associated with the specified extension.
+        */
+       private void addDefaultContentType(String extension, String contentType) {
+               // Remark : Originally the latest parameter was :
+               // contentType.toLowerCase(). Change due to a request ID 1996748.
+               defaultContentType.put(extension.toLowerCase(), contentType);
+       }
+
+       /**
+     * <p>
+        * Delete a content type based on the specified part name. If the specified
+        * part name is register with an override content type, then this content
+        * type is remove, else the content type is remove in the default content
+        * type list if it exists and if no part is associated with it yet.
+        * </p><p>
+        * Check rule M2.4: The package implementer shall require that the Content
+        * Types stream contain one of the following for every part in the package:
+        * One matching Default element One matching Override element Both a
+        * matching Default element and a matching Override element, in which case
+        * the Override element takes precedence.
+        * </p>
+        * @param partName
+        *            The part URI associated with the override content type to
+        *            delete.
+        * @exception InvalidOperationException
+        *                Throws if
+        */
+       public void removeContentType(PackagePartName partName)
+                       throws InvalidOperationException {
+               if (partName == null)
+                       throw new IllegalArgumentException("partName");
+
+               /* Override content type */
+               if (this.overrideContentType != null
+                               && (this.overrideContentType.get(partName) != null)) {
+                       // Remove the override definition for the specified part.
+                       this.overrideContentType.remove(partName);
+                       return;
+               }
+
+               /* Default content type */
+               String extensionToDelete = partName.getExtension();
+               boolean deleteDefaultContentTypeFlag = true;
+               if (this.container != null) {
+                       try {
+                               for (PackagePart part : this.container.getParts()) {
+                                       if (!part.getPartName().equals(partName)
+                                                       && part.getPartName().getExtension()
+                                                                       .equalsIgnoreCase(extensionToDelete)) {
+                                               deleteDefaultContentTypeFlag = false;
+                                               break;
+                                       }
+                               }
+                       } catch (InvalidFormatException e) {
+                               throw new InvalidOperationException(e.getMessage());
+                       }
+               }
+
+               // Remove the default content type, no other part use this content type.
+               if (deleteDefaultContentTypeFlag) {
+                       this.defaultContentType.remove(extensionToDelete);
+               }
+
+               /*
+                * Check rule 2.4: The package implementer shall require that the
+                * Content Types stream contain one of the following for every part in
+                * the package: One matching Default element One matching Override
+                * element Both a matching Default element and a matching Override
+                * element, in which case the Override element takes precedence.
+                */
+               if (this.container != null) {
+                       try {
+                               for (PackagePart part : this.container.getParts()) {
+                                       if (!part.getPartName().equals(partName)
+                                                       && this.getContentType(part.getPartName()) == null)
+                                               throw new InvalidOperationException(
+                                                               "Rule M2.4 is not respected: Nor a default element or override element is associated with the part: "
+                                                                               + part.getPartName().getName());
+                               }
+                       } catch (InvalidFormatException e) {
+                               throw new InvalidOperationException(e.getMessage());
+                       }
+               }
+       }
+
+       /**
+        * Check if the specified content type is already register.
+        * 
+        * @param contentType
+        *            The content type to check.
+        * @return <code>true</code> if the specified content type is already
+        *         register, then <code>false</code>.
+        */
+       public boolean isContentTypeRegister(String contentType) {
+               if (contentType == null)
+                       throw new IllegalArgumentException("contentType");
+
+               return (this.defaultContentType.values().contains(contentType) || (this.overrideContentType != null && this.overrideContentType
+                               .values().contains(contentType)));
+       }
+
+       /**
+        * Get the content type for the specified part, if any.
+        * <p>
+        * Rule [M2.9]: To get the content type of a part, the package implementer
+        * shall perform the steps described in &#167;9.1.2.4:
+        * </p><p>
+        * 1. Compare the part name with the values specified for the PartName
+        * attribute of the Override elements. The comparison shall be
+        * case-insensitive ASCII.
+        * </p><p>
+        * 2. If there is an Override element with a matching PartName attribute,
+        * return the value of its ContentType attribute. No further action is
+        * required.
+        * </p><p>
+        * 3. If there is no Override element with a matching PartName attribute,
+        * then a. Get the extension from the part name by taking the substring to
+        * the right of the rightmost occurrence of the dot character (.) from the
+        * rightmost segment. b. Check the Default elements of the Content Types
+        * stream, comparing the extension with the value of the Extension
+        * attribute. The comparison shall be case-insensitive ASCII.
+        * </p><p>
+        * 4. If there is a Default element with a matching Extension attribute,
+        * return the value of its ContentType attribute. No further action is
+        * required.
+        * </p><p>
+        * 5. If neither Override nor Default elements with matching attributes are
+        * found for the specified part name, the implementation shall not map this
+        * part name to a part.
+        * </p>
+        * @param partName
+        *            The URI part to check.
+        * @return The content type associated with the URI (in case of an override
+        *         content type) or the extension (in case of default content type),
+        *         else <code>null</code>.
+        * 
+        * @exception OpenXML4JRuntimeException
+        *                Throws if the content type manager is not able to find the
+        *                content from an existing part.
+        */
+       public String getContentType(PackagePartName partName) {
+               if (partName == null)
+                       throw new IllegalArgumentException("partName");
+
+               if ((this.overrideContentType != null)
+                               && this.overrideContentType.containsKey(partName))
+                       return this.overrideContentType.get(partName);
+
+               String extension = partName.getExtension().toLowerCase();
+               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 so please send a mail to the developers team, thanks !");
+               } else {
+                       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 {
+                       SAXReader xmlReader = new SAXReader();
+                       Document xmlContentTypetDoc = xmlReader.read(in);
+
+                       // Default content types
+                       List defaultTypes = xmlContentTypetDoc.getRootElement().elements(
+                                       DEFAULT_TAG_NAME);
+                       Iterator elementIteratorDefault = defaultTypes.iterator();
+                       while (elementIteratorDefault.hasNext()) {
+                               Element element = (Element) elementIteratorDefault.next();
+                               String extension = element.attribute(EXTENSION_ATTRIBUTE_NAME)
+                                               .getValue();
+                               String contentType = element.attribute(
+                                               CONTENT_TYPE_ATTRIBUTE_NAME).getValue();
+                               addDefaultContentType(extension, contentType);
+                       }
+
+                       // Overriden content types
+                       List overrideTypes = xmlContentTypetDoc.getRootElement().elements(
+                                       OVERRIDE_TAG_NAME);
+                       Iterator elementIteratorOverride = overrideTypes.iterator();
+                       while (elementIteratorOverride.hasNext()) {
+                               Element element = (Element) elementIteratorOverride.next();
+                               URI uri = new URI(element.attribute(PART_NAME_ATTRIBUTE_NAME)
+                                               .getValue());
+                               PackagePartName partName = PackagingURIHelper
+                                               .createPartName(uri);
+                               String contentType = element.attribute(
+                                               CONTENT_TYPE_ATTRIBUTE_NAME).getValue();
+                               addOverrideContentType(partName, contentType);
+                       }
+               } catch (URISyntaxException urie) {
+                       throw new InvalidFormatException(urie.getMessage());
+               } catch (DocumentException e) {
+                       throw new InvalidFormatException(e.getMessage());
+               }
+       }
+
+       /**
+        * Save the contents type part.
+        * 
+        * @param outStream
+        *            The output stream use to save the XML content of the content
+        *            types part.
+        * @return <b>true</b> if the operation success, else <b>false</b>.
+        */
+       public boolean save(OutputStream outStream) {
+               Document xmlOutDoc = DocumentHelper.createDocument();
+
+               // Building namespace
+               Namespace dfNs = Namespace.get("", TYPES_NAMESPACE_URI);
+               Element typesElem = xmlOutDoc
+                               .addElement(new QName(TYPES_TAG_NAME, dfNs));
+
+               // Adding default types
+               for (Entry<String, String> entry : defaultContentType.entrySet()) {
+                       appendDefaultType(typesElem, entry);
+               }
+
+               // Adding specific types if any exist
+               if (overrideContentType != null) {
+                       for (Entry<PackagePartName, String> entry : overrideContentType
+                                       .entrySet()) {
+                               appendSpecificTypes(typesElem, entry);
+                       }
+               }
+               xmlOutDoc.normalize();
+
+               // Save content in the specified output stream
+               return this.saveImpl(xmlOutDoc, outStream);
+       }
+
+       /**
+        * Use to append specific type XML elements, use by the save() method.
+        * 
+        * @param root
+        *            XML parent element use to append this override type element.
+        * @param entry
+        *            The values to append.
+        * @see #save(java.io.OutputStream)
+        */
+       private void appendSpecificTypes(Element root,
+                       Entry<PackagePartName, String> entry) {
+               root.addElement(OVERRIDE_TAG_NAME).addAttribute(
+                               PART_NAME_ATTRIBUTE_NAME,
+                               ((PackagePartName) entry.getKey()).getName()).addAttribute(
+                               CONTENT_TYPE_ATTRIBUTE_NAME, (String) entry.getValue());
+       }
+
+       /**
+        * Use to append default types XML elements, use by the save() metid.
+        * 
+        * @param root
+        *            XML parent element use to append this default type element.
+        * @param entry
+        *            The values to append.
+        * @see #save(java.io.OutputStream)
+        */
+       private void appendDefaultType(Element root, Entry<String, String> entry) {
+               root.addElement(DEFAULT_TAG_NAME).addAttribute(
+                               EXTENSION_ATTRIBUTE_NAME, (String) entry.getKey())
+                               .addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME,
+                                               (String) entry.getValue());
+
+       }
+
+       /**
+        * Specific implementation of the save method. Call by the save() method,
+        * call before exiting.
+        * 
+        * @param out
+        *            The output stream use to write the content type XML.
+        */
+       public abstract boolean saveImpl(Document content, OutputStream out);
+}
index 8f29a45875b9c2a199fab1b21e53fa4dc6cea189..0d7f8d39c119161e101ba5ba83f7fd8690f11c3c 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.internal;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackagePart;\r
-import org.apache.poi.openxml4j.opc.PackagePartName;\r
-import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;\r
-\r
-/**\r
- * Memory version of a package part. Use to\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- */\r
-public final class MemoryPackagePart extends PackagePart {\r
-\r
-       /**\r
-        * Storage for the part data.\r
-        */\r
-       protected byte[] data;\r
-\r
-       /**\r
-        * Size of data.\r
-        */\r
-       protected int length;\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pack\r
-        *            The owner package.\r
-        * @param partName\r
-        *            The part name.\r
-        * @param contentType\r
-        *            The content type.\r
-        * @throws InvalidFormatException\r
-        *             If the specified URI is not OPC compliant.\r
-        */\r
-       public MemoryPackagePart(Package pack, PackagePartName partName,\r
-                       String contentType) throws InvalidFormatException {\r
-               super(pack, partName, contentType);\r
-       }\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pack\r
-        *            The owner package.\r
-        * @param partName\r
-        *            The part name.\r
-        * @param contentType\r
-        *            The content type.\r
-        * @param loadRelationships\r
-        *            Specify if the relationships will be loaded.\r
-        * @throws InvalidFormatException\r
-        *             If the specified URI is not OPC compliant.\r
-        */\r
-       public MemoryPackagePart(Package pack, PackagePartName partName,\r
-                       String contentType, boolean loadRelationships)\r
-                       throws InvalidFormatException {\r
-               super(pack, partName, new ContentType(contentType), loadRelationships);\r
-       }\r
-\r
-       @Override\r
-       protected InputStream getInputStreamImpl() {\r
-               // If this part has been created from scratch and/or the data buffer is\r
-               // not\r
-               // initialize, so we do it now.\r
-               if (data == null) {\r
-                       data = new byte[0];\r
-               }\r
-               return new ByteArrayInputStream(data);\r
-       }\r
-\r
-       @Override\r
-       protected OutputStream getOutputStreamImpl() {\r
-               return new MemoryPackagePartOutputStream(this);\r
-       }\r
-\r
-       public void clear() {\r
-               data = null;\r
-               length = 0;\r
-       }\r
-\r
-       @Override\r
-       public boolean save(OutputStream os) throws OpenXML4JException {\r
-               return new ZipPartMarshaller().marshall(this, os);\r
-       }\r
-\r
-       @Override\r
-       public boolean load(InputStream ios) throws InvalidFormatException {\r
-               throw new InvalidFormatException("Method not implemented");\r
-       }\r
-\r
-       @Override\r
-       public void close() {\r
-               // Do nothing\r
-       }\r
-\r
-       @Override\r
-       public void flush() {\r
-               // Do nothing\r
-       }\r
-}\r
+/* ====================================================================
+   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.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;
+
+/**
+ * Memory version of a package part. Use to
+ * 
+ * @author Julien Chable
+ * @version 1.0
+ */
+public final class MemoryPackagePart extends PackagePart {
+
+       /**
+        * Storage for the part data.
+        */
+       protected byte[] data;
+
+       /**
+        * Size of data.
+        */
+       protected int length;
+
+       /**
+        * Constructor.
+        * 
+        * @param pack
+        *            The owner package.
+        * @param partName
+        *            The part name.
+        * @param contentType
+        *            The content type.
+        * @throws InvalidFormatException
+        *             If the specified URI is not OPC compliant.
+        */
+       public MemoryPackagePart(OPCPackage pack, PackagePartName partName,
+                       String contentType) throws InvalidFormatException {
+               super(pack, partName, contentType);
+       }
+
+       /**
+        * Constructor.
+        * 
+        * @param pack
+        *            The owner package.
+        * @param partName
+        *            The part name.
+        * @param contentType
+        *            The content type.
+        * @param loadRelationships
+        *            Specify if the relationships will be loaded.
+        * @throws InvalidFormatException
+        *             If the specified URI is not OPC compliant.
+        */
+       public MemoryPackagePart(OPCPackage pack, PackagePartName partName,
+                       String contentType, boolean loadRelationships)
+                       throws InvalidFormatException {
+               super(pack, partName, new ContentType(contentType), loadRelationships);
+       }
+
+       @Override
+       protected InputStream getInputStreamImpl() {
+               // If this part has been created from scratch and/or the data buffer is
+               // not
+               // initialize, so we do it now.
+               if (data == null) {
+                       data = new byte[0];
+               }
+               return new ByteArrayInputStream(data);
+       }
+
+       @Override
+       protected OutputStream getOutputStreamImpl() {
+               return new MemoryPackagePartOutputStream(this);
+       }
+
+       public void clear() {
+               data = null;
+               length = 0;
+       }
+
+       @Override
+       public boolean save(OutputStream os) throws OpenXML4JException {
+               return new ZipPartMarshaller().marshall(this, os);
+       }
+
+       @Override
+       public boolean load(InputStream ios) throws InvalidFormatException {
+               throw new InvalidFormatException("Method not implemented");
+       }
+
+       @Override
+       public void close() {
+               // Do nothing
+       }
+
+       @Override
+       public void flush() {
+               // Do nothing
+       }
+}
index a9f60b011af9f5d0cb6af857ae762b59d327770f..582fe507a2f54acffd4bf62fdbccadb9fd8e2e4c 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.internal;\r
-\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.text.ParsePosition;\r
-import java.text.SimpleDateFormat;\r
-import java.util.Date;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.opc.ContentTypes;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackagePart;\r
-import org.apache.poi.openxml4j.opc.PackagePartName;\r
-import org.apache.poi.openxml4j.opc.PackageProperties;\r
-import org.apache.poi.openxml4j.util.Nullable;\r
-\r
-/**\r
- * Represents the core properties part of a package.\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- */\r
-public class PackagePropertiesPart extends PackagePart implements\r
-               PackageProperties {\r
-\r
-       public final static String NAMESPACE_DC_URI = "http://purl.org/dc/elements/1.1/";\r
-\r
-       public final static String NAMESPACE_CP_URI = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";\r
-\r
-       public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/";\r
-\r
-       public final static String NAMESPACE_XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param pack\r
-        *            Container package.\r
-        * @param partName\r
-        *            Name of this part.\r
-        * @throws InvalidFormatException\r
-        *             Throws if the content is invalid.\r
-        */\r
-       public PackagePropertiesPart(Package pack, PackagePartName partName)\r
-                       throws InvalidFormatException {\r
-               super(pack, partName, ContentTypes.CORE_PROPERTIES_PART);\r
-       }\r
-\r
-       /**\r
-        * A categorization of the content of this package.\r
-        * \r
-        * [Example: Example values for this property might include: Resume, Letter,\r
-        * Financial Forecast, Proposal, Technical Presentation, and so on. This\r
-        * value might be used by an application's user interface to facilitate\r
-        * navigation of a large set of documents. end example]\r
-        */\r
-       protected Nullable<String> category = new Nullable<String>();\r
-\r
-       /**\r
-        * The status of the content.\r
-        * \r
-        * [Example: Values might include "Draft", "Reviewed", and "Final". end\r
-        * example]\r
-        */\r
-       protected Nullable<String> contentStatus = new Nullable<String>();\r
-\r
-       /**\r
-        * The type of content represented, generally defined by a specific use and\r
-        * intended audience.\r
-        * \r
-        * [Example: Values might include "Whitepaper", "Security Bulletin", and\r
-        * "Exam". end example] [Note: This property is distinct from MIME content\r
-        * types as defined in RFC 2616. end note]\r
-        */\r
-       protected Nullable<String> contentType = new Nullable<String>();\r
-\r
-       /**\r
-        * Date of creation of the resource.\r
-        */\r
-       protected Nullable<Date> created = new Nullable<Date>();\r
-\r
-       /**\r
-        * An entity primarily responsible for making the content of the resource.\r
-        */\r
-       protected Nullable<String> creator = new Nullable<String>();\r
-\r
-       /**\r
-        * An explanation of the content of the resource.\r
-        * \r
-        * [Example: Values might include an abstract, table of contents, reference\r
-        * to a graphical representation of content, and a free-text account of the\r
-        * content. end example]\r
-        */\r
-       protected Nullable<String> description = new Nullable<String>();\r
-\r
-       /**\r
-        * An unambiguous reference to the resource within a given context.\r
-        */\r
-       protected Nullable<String> identifier = new Nullable<String>();\r
-\r
-       /**\r
-        * A delimited set of keywords to support searching and indexing. This is\r
-        * typically a list of terms that are not available elsewhere in the\r
-        * properties.\r
-        */\r
-       protected Nullable<String> keywords = new Nullable<String>();\r
-\r
-       /**\r
-        * The language of the intellectual content of the resource.\r
-        * \r
-        * [Note: IETF RFC 3066 provides guidance on encoding to represent\r
-        * languages. end note]\r
-        */\r
-       protected Nullable<String> language = new Nullable<String>();\r
-\r
-       /**\r
-        * The user who performed the last modification. The identification is\r
-        * environment-specific.\r
-        * \r
-        * [Example: A name, email address, or employee ID. end example] It is\r
-        * recommended that this value be as concise as possible.\r
-        */\r
-       protected Nullable<String> lastModifiedBy = new Nullable<String>();\r
-\r
-       /**\r
-        * The date and time of the last printing.\r
-        */\r
-       protected Nullable<Date> lastPrinted = new Nullable<Date>();\r
-\r
-       /**\r
-        * Date on which the resource was changed.\r
-        */\r
-       protected Nullable<Date> modified = new Nullable<Date>();\r
-\r
-       /**\r
-        * The revision number.\r
-        * \r
-        * [Example: This value might indicate the number of saves or revisions,\r
-        * provided the application updates it after each revision. end example]\r
-        */\r
-       protected Nullable<String> revision = new Nullable<String>();\r
-\r
-       /**\r
-        * The topic of the content of the resource.\r
-        */\r
-       protected Nullable<String> subject = new Nullable<String>();\r
-\r
-       /**\r
-        * The name given to the resource.\r
-        */\r
-       protected Nullable<String> title = new Nullable<String>();\r
-\r
-       /**\r
-        * The version number. This value is set by the user or by the application.\r
-        */\r
-       protected Nullable<String> version = new Nullable<String>();\r
-\r
-       /*\r
-        * Getters and setters\r
-        */\r
-\r
-       /**\r
-        * Get the category property.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty()\r
-        */\r
-       public Nullable<String> getCategoryProperty() {\r
-               return category;\r
-       }\r
-\r
-       /**\r
-        * Get content status.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty()\r
-        */\r
-       public Nullable<String> getContentStatusProperty() {\r
-               return contentStatus;\r
-       }\r
-\r
-       /**\r
-        * Get content type.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty()\r
-        */\r
-       public Nullable<String> getContentTypeProperty() {\r
-               return contentType;\r
-       }\r
-\r
-       /**\r
-        * Get created date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty()\r
-        */\r
-       public Nullable<Date> getCreatedProperty() {\r
-               return created;\r
-       }\r
-\r
-       /**\r
-        * Get created date formated into a String.\r
-        * \r
-        * @return A string representation of the created date.\r
-        */\r
-       public String getCreatedPropertyString() {\r
-               return getDateValue(created);\r
-       }\r
-\r
-       /**\r
-        * Get creator.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty()\r
-        */\r
-       public Nullable<String> getCreatorProperty() {\r
-               return creator;\r
-       }\r
-\r
-       /**\r
-        * Get description.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty()\r
-        */\r
-       public Nullable<String> getDescriptionProperty() {\r
-               return description;\r
-       }\r
-\r
-       /**\r
-        * Get identifier.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty()\r
-        */\r
-       public Nullable<String> getIdentifierProperty() {\r
-               return identifier;\r
-       }\r
-\r
-       /**\r
-        * Get keywords.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty()\r
-        */\r
-       public Nullable<String> getKeywordsProperty() {\r
-               return keywords;\r
-       }\r
-\r
-       /**\r
-        * Get the language.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty()\r
-        */\r
-       public Nullable<String> getLanguageProperty() {\r
-               return language;\r
-       }\r
-\r
-       /**\r
-        * Get the author of last modifications.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastModifiedByProperty()\r
-        */\r
-       public Nullable<String> getLastModifiedByProperty() {\r
-               return lastModifiedBy;\r
-       }\r
-\r
-       /**\r
-        * Get last printed date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastPrintedProperty()\r
-        */\r
-       public Nullable<Date> getLastPrintedProperty() {\r
-               return lastPrinted;\r
-       }\r
-\r
-       /**\r
-        * Get last printed date formated into a String.\r
-        * \r
-        * @return A string representation of the last printed date.\r
-        */\r
-       public String getLastPrintedPropertyString() {\r
-               return getDateValue(created);\r
-       }\r
-\r
-       /**\r
-        * Get modified date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty()\r
-        */\r
-       public Nullable<Date> getModifiedProperty() {\r
-               return modified;\r
-       }\r
-\r
-       /**\r
-        * Get modified date formated into a String.\r
-        * \r
-        * @return A string representation of the modified date.\r
-        */\r
-       public String getModifiedPropertyString() {\r
-               if (!modified.hasValue())\r
-                       return getDateValue(new Nullable<Date>(new Date()));\r
-               else\r
-                       return getDateValue(modified);\r
-       }\r
-\r
-       /**\r
-        * Get revision.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty()\r
-        */\r
-       public Nullable<String> getRevisionProperty() {\r
-               return revision;\r
-       }\r
-\r
-       /**\r
-        * Get subject.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty()\r
-        */\r
-       public Nullable<String> getSubjectProperty() {\r
-               return subject;\r
-       }\r
-\r
-       /**\r
-        * Get title.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty()\r
-        */\r
-       public Nullable<String> getTitleProperty() {\r
-               return title;\r
-       }\r
-\r
-       /**\r
-        * Get version.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty()\r
-        */\r
-       public Nullable<String> getVersionProperty() {\r
-               return version;\r
-       }\r
-\r
-       /**\r
-        * Set the category.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.lang.String)\r
-        */\r
-       public void setCategoryProperty(String category) {\r
-               this.category = setStringValue(category);\r
-       }\r
-\r
-       /**\r
-        * Set the content status.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.lang.String)\r
-        */\r
-       public void setContentStatusProperty(String contentStatus) {\r
-               this.contentStatus = setStringValue(contentStatus);\r
-       }\r
-\r
-       /**\r
-        * Set the content type.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.lang.String)\r
-        */\r
-       public void setContentTypeProperty(String contentType) {\r
-               this.contentType = setStringValue(contentType);\r
-       }\r
-\r
-       /**\r
-        * Set the created date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable)\r
-        */\r
-       public void setCreatedProperty(String created) {\r
-               try {\r
-                       this.created = setDateValue(created);\r
-               } catch (InvalidFormatException e) {\r
-                       new IllegalArgumentException("created  : "\r
-                                       + e.getLocalizedMessage());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Set the created date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable)\r
-        */\r
-       public void setCreatedProperty(Nullable<Date> created) {\r
-               if (created.hasValue())\r
-                       this.created = created;\r
-       }\r
-\r
-       /**\r
-        * Set the creator.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.lang.String)\r
-        */\r
-       public void setCreatorProperty(String creator) {\r
-               this.creator = setStringValue(creator);\r
-       }\r
-\r
-       /**\r
-        * Set the description.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.lang.String)\r
-        */\r
-       public void setDescriptionProperty(String description) {\r
-               this.description = setStringValue(description);\r
-       }\r
-\r
-       /**\r
-        * Set identifier.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.lang.String)\r
-        */\r
-       public void setIdentifierProperty(String identifier) {\r
-               this.identifier = setStringValue(identifier);\r
-       }\r
-\r
-       /**\r
-        * Set keywords.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.lang.String)\r
-        */\r
-       public void setKeywordsProperty(String keywords) {\r
-               this.keywords = setStringValue(keywords);\r
-       }\r
-\r
-       /**\r
-        * Set language.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.lang.String)\r
-        */\r
-       public void setLanguageProperty(String language) {\r
-               this.language = setStringValue(language);\r
-       }\r
-\r
-       /**\r
-        * Set last modifications author.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.lang.String)\r
-        */\r
-       public void setLastModifiedByProperty(String lastModifiedBy) {\r
-               this.lastModifiedBy = setStringValue(lastModifiedBy);\r
-       }\r
-\r
-       /**\r
-        * Set last printed date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable)\r
-        */\r
-       public void setLastPrintedProperty(String lastPrinted) {\r
-               try {\r
-                       this.lastPrinted = setDateValue(lastPrinted);\r
-               } catch (InvalidFormatException e) {\r
-                       new IllegalArgumentException("lastPrinted  : "\r
-                                       + e.getLocalizedMessage());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Set last printed date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable)\r
-        */\r
-       public void setLastPrintedProperty(Nullable<Date> lastPrinted) {\r
-               if (lastPrinted.hasValue())\r
-                       this.lastPrinted = lastPrinted;\r
-       }\r
-\r
-       /**\r
-        * Set last modification date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable)\r
-        */\r
-       public void setModifiedProperty(String modified) {\r
-               try {\r
-                       this.modified = setDateValue(modified);\r
-               } catch (InvalidFormatException e) {\r
-                       new IllegalArgumentException("modified  : "\r
-                                       + e.getLocalizedMessage());\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Set last modification date.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable)\r
-        */\r
-       public void setModifiedProperty(Nullable<Date> modified) {\r
-               if (modified.hasValue())\r
-                       this.modified = modified;\r
-       }\r
-\r
-       /**\r
-        * Set revision.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.lang.String)\r
-        */\r
-       public void setRevisionProperty(String revision) {\r
-               this.revision = setStringValue(revision);\r
-       }\r
-\r
-       /**\r
-        * Set subject.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.lang.String)\r
-        */\r
-       public void setSubjectProperty(String subject) {\r
-               this.subject = setStringValue(subject);\r
-       }\r
-\r
-       /**\r
-        * Set title.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.lang.String)\r
-        */\r
-       public void setTitleProperty(String title) {\r
-               this.title = setStringValue(title);\r
-       }\r
-\r
-       /**\r
-        * Set version.\r
-        * \r
-        * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.lang.String)\r
-        */\r
-       public void setVersionProperty(String version) {\r
-               this.version = setStringValue(version);\r
-       }\r
-\r
-       /**\r
-        * Convert a strig value into a Nullable<String>\r
-        */\r
-       private Nullable<String> setStringValue(String s) {\r
-               if (s == null || s.equals(""))\r
-                       return new Nullable<String>();\r
-               else\r
-                       return new Nullable<String>(s);\r
-       }\r
-\r
-       /**\r
-        * Convert a string value represented a date into a Nullable<Date>.\r
-        * \r
-        * @throws InvalidFormatException\r
-        *             Throws if the date format isnot valid.\r
-        */\r
-       private Nullable<Date> setDateValue(String s) throws InvalidFormatException {\r
-               if (s == null || s.equals(""))\r
-                       return new Nullable<Date>();\r
-               else {\r
-                       SimpleDateFormat df = new SimpleDateFormat(\r
-                                       "yyyy-MM-dd'T'HH:mm:ss'Z'");\r
-                       Date d = df.parse(s, new ParsePosition(0));\r
-                       if (d == null)\r
-                               throw new InvalidFormatException("Date not well formated");\r
-                       return new Nullable<Date>(d);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Convert a Nullable<Date> into a String.\r
-        * \r
-        * @param d\r
-        *            The Date to convert.\r
-        * @return The formated date or null.\r
-        * @see java.util.SimpleDateFormat\r
-        */\r
-       private String getDateValue(Nullable<Date> d) {\r
-               if (d == null || d.equals(""))\r
-                       return "";\r
-               else {\r
-                       SimpleDateFormat df = new SimpleDateFormat(\r
-                                       "yyyy-MM-dd'T'HH:mm:ss'Z'");\r
-                       return df.format(d.getValue());\r
-               }\r
-       }\r
-\r
-       @Override\r
-       protected InputStream getInputStreamImpl() {\r
-               throw new InvalidOperationException("Operation not authorized");\r
-       }\r
-\r
-       @Override\r
-       protected OutputStream getOutputStreamImpl() {\r
-               throw new InvalidOperationException(\r
-                               "Can't use output stream to set properties !");\r
-       }\r
-\r
-       @Override\r
-       public boolean save(OutputStream zos) throws OpenXML4JException {\r
-               throw new InvalidOperationException("Operation not authorized");\r
-       }\r
-\r
-       @Override\r
-       public boolean load(InputStream ios) throws InvalidFormatException {\r
-               throw new InvalidOperationException("Operation not authorized");\r
-       }\r
-\r
-       @Override\r
-       public void close() {\r
-               // Do nothing\r
-       }\r
-\r
-       @Override\r
-       public void flush() {\r
-               // Do nothing\r
-       }\r
-}\r
+/* ====================================================================
+   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.internal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.ContentTypes;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackageProperties;
+import org.apache.poi.openxml4j.util.Nullable;
+
+/**
+ * Represents the core properties part of a package.
+ * 
+ * @author Julien Chable
+ * @version 1.0
+ */
+public class PackagePropertiesPart extends PackagePart implements
+               PackageProperties {
+
+       public final static String NAMESPACE_DC_URI = "http://purl.org/dc/elements/1.1/";
+
+       public final static String NAMESPACE_CP_URI = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
+
+       public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/";
+
+       public final static String NAMESPACE_XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
+
+       /**
+        * Constructor.
+        * 
+        * @param pack
+        *            Container package.
+        * @param partName
+        *            Name of this part.
+        * @throws InvalidFormatException
+        *             Throws if the content is invalid.
+        */
+       public PackagePropertiesPart(OPCPackage pack, PackagePartName partName)
+                       throws InvalidFormatException {
+               super(pack, partName, ContentTypes.CORE_PROPERTIES_PART);
+       }
+
+       /**
+        * A categorization of the content of this package.
+        * 
+        * [Example: Example values for this property might include: Resume, Letter,
+        * Financial Forecast, Proposal, Technical Presentation, and so on. This
+        * value might be used by an application's user interface to facilitate
+        * navigation of a large set of documents. end example]
+        */
+       protected Nullable<String> category = new Nullable<String>();
+
+       /**
+        * The status of the content.
+        * 
+        * [Example: Values might include "Draft", "Reviewed", and "Final". end
+        * example]
+        */
+       protected Nullable<String> contentStatus = new Nullable<String>();
+
+       /**
+        * The type of content represented, generally defined by a specific use and
+        * intended audience.
+        * 
+        * [Example: Values might include "Whitepaper", "Security Bulletin", and
+        * "Exam". end example] [Note: This property is distinct from MIME content
+        * types as defined in RFC 2616. end note]
+        */
+       protected Nullable<String> contentType = new Nullable<String>();
+
+       /**
+        * Date of creation of the resource.
+        */
+       protected Nullable<Date> created = new Nullable<Date>();
+
+       /**
+        * An entity primarily responsible for making the content of the resource.
+        */
+       protected Nullable<String> creator = new Nullable<String>();
+
+       /**
+        * An explanation of the content of the resource.
+        * 
+        * [Example: Values might include an abstract, table of contents, reference
+        * to a graphical representation of content, and a free-text account of the
+        * content. end example]
+        */
+       protected Nullable<String> description = new Nullable<String>();
+
+       /**
+        * An unambiguous reference to the resource within a given context.
+        */
+       protected Nullable<String> identifier = new Nullable<String>();
+
+       /**
+        * 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.
+        */
+       protected Nullable<String> keywords = new Nullable<String>();
+
+       /**
+        * The language of the intellectual content of the resource.
+        * 
+        * [Note: IETF RFC 3066 provides guidance on encoding to represent
+        * languages. end note]
+        */
+       protected Nullable<String> language = new Nullable<String>();
+
+       /**
+        * The user who performed the last modification. The identification is
+        * environment-specific.
+        * 
+        * [Example: A name, email address, or employee ID. end example] It is
+        * recommended that this value be as concise as possible.
+        */
+       protected Nullable<String> lastModifiedBy = new Nullable<String>();
+
+       /**
+        * The date and time of the last printing.
+        */
+       protected Nullable<Date> lastPrinted = new Nullable<Date>();
+
+       /**
+        * Date on which the resource was changed.
+        */
+       protected Nullable<Date> modified = new Nullable<Date>();
+
+       /**
+        * The revision number.
+        * 
+        * [Example: This value might indicate the number of saves or revisions,
+        * provided the application updates it after each revision. end example]
+        */
+       protected Nullable<String> revision = new Nullable<String>();
+
+       /**
+        * The topic of the content of the resource.
+        */
+       protected Nullable<String> subject = new Nullable<String>();
+
+       /**
+        * The name given to the resource.
+        */
+       protected Nullable<String> title = new Nullable<String>();
+
+       /**
+        * The version number. This value is set by the user or by the application.
+        */
+       protected Nullable<String> version = new Nullable<String>();
+
+       /*
+        * Getters and setters
+        */
+
+       /**
+        * Get the category property.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCategoryProperty()
+        */
+       public Nullable<String> getCategoryProperty() {
+               return category;
+       }
+
+       /**
+        * Get content status.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentStatusProperty()
+        */
+       public Nullable<String> getContentStatusProperty() {
+               return contentStatus;
+       }
+
+       /**
+        * Get content type.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getContentTypeProperty()
+        */
+       public Nullable<String> getContentTypeProperty() {
+               return contentType;
+       }
+
+       /**
+        * Get created date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatedProperty()
+        */
+       public Nullable<Date> getCreatedProperty() {
+               return created;
+       }
+
+       /**
+        * Get created date formated into a String.
+        * 
+        * @return A string representation of the created date.
+        */
+       public String getCreatedPropertyString() {
+               return getDateValue(created);
+       }
+
+       /**
+        * Get creator.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getCreatorProperty()
+        */
+       public Nullable<String> getCreatorProperty() {
+               return creator;
+       }
+
+       /**
+        * Get description.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getDescriptionProperty()
+        */
+       public Nullable<String> getDescriptionProperty() {
+               return description;
+       }
+
+       /**
+        * Get identifier.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getIdentifierProperty()
+        */
+       public Nullable<String> getIdentifierProperty() {
+               return identifier;
+       }
+
+       /**
+        * Get keywords.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getKeywordsProperty()
+        */
+       public Nullable<String> getKeywordsProperty() {
+               return keywords;
+       }
+
+       /**
+        * Get the language.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLanguageProperty()
+        */
+       public Nullable<String> getLanguageProperty() {
+               return language;
+       }
+
+       /**
+        * Get the author of last modifications.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastModifiedByProperty()
+        */
+       public Nullable<String> getLastModifiedByProperty() {
+               return lastModifiedBy;
+       }
+
+       /**
+        * Get last printed date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getLastPrintedProperty()
+        */
+       public Nullable<Date> getLastPrintedProperty() {
+               return lastPrinted;
+       }
+
+       /**
+        * Get last printed date formated into a String.
+        * 
+        * @return A string representation of the last printed date.
+        */
+       public String getLastPrintedPropertyString() {
+               return getDateValue(created);
+       }
+
+       /**
+        * Get modified date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getModifiedProperty()
+        */
+       public Nullable<Date> getModifiedProperty() {
+               return modified;
+       }
+
+       /**
+        * Get modified date formated into a String.
+        * 
+        * @return A string representation of the modified date.
+        */
+       public String getModifiedPropertyString() {
+               if (!modified.hasValue())
+                       return getDateValue(new Nullable<Date>(new Date()));
+               else
+                       return getDateValue(modified);
+       }
+
+       /**
+        * Get revision.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getRevisionProperty()
+        */
+       public Nullable<String> getRevisionProperty() {
+               return revision;
+       }
+
+       /**
+        * Get subject.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getSubjectProperty()
+        */
+       public Nullable<String> getSubjectProperty() {
+               return subject;
+       }
+
+       /**
+        * Get title.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getTitleProperty()
+        */
+       public Nullable<String> getTitleProperty() {
+               return title;
+       }
+
+       /**
+        * Get version.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#getVersionProperty()
+        */
+       public Nullable<String> getVersionProperty() {
+               return version;
+       }
+
+       /**
+        * Set the category.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCategoryProperty(java.lang.String)
+        */
+       public void setCategoryProperty(String category) {
+               this.category = setStringValue(category);
+       }
+
+       /**
+        * Set the content status.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentStatusProperty(java.lang.String)
+        */
+       public void setContentStatusProperty(String contentStatus) {
+               this.contentStatus = setStringValue(contentStatus);
+       }
+
+       /**
+        * Set the content type.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setContentTypeProperty(java.lang.String)
+        */
+       public void setContentTypeProperty(String contentType) {
+               this.contentType = setStringValue(contentType);
+       }
+
+       /**
+        * Set the created date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable)
+        */
+       public void setCreatedProperty(String created) {
+               try {
+                       this.created = setDateValue(created);
+               } catch (InvalidFormatException e) {
+                       new IllegalArgumentException("created  : "
+                                       + e.getLocalizedMessage());
+               }
+       }
+
+       /**
+        * Set the created date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatedProperty(org.apache.poi.openxml4j.util.Nullable)
+        */
+       public void setCreatedProperty(Nullable<Date> created) {
+               if (created.hasValue())
+                       this.created = created;
+       }
+
+       /**
+        * Set the creator.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setCreatorProperty(java.lang.String)
+        */
+       public void setCreatorProperty(String creator) {
+               this.creator = setStringValue(creator);
+       }
+
+       /**
+        * Set the description.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setDescriptionProperty(java.lang.String)
+        */
+       public void setDescriptionProperty(String description) {
+               this.description = setStringValue(description);
+       }
+
+       /**
+        * Set identifier.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setIdentifierProperty(java.lang.String)
+        */
+       public void setIdentifierProperty(String identifier) {
+               this.identifier = setStringValue(identifier);
+       }
+
+       /**
+        * Set keywords.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setKeywordsProperty(java.lang.String)
+        */
+       public void setKeywordsProperty(String keywords) {
+               this.keywords = setStringValue(keywords);
+       }
+
+       /**
+        * Set language.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLanguageProperty(java.lang.String)
+        */
+       public void setLanguageProperty(String language) {
+               this.language = setStringValue(language);
+       }
+
+       /**
+        * Set last modifications author.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastModifiedByProperty(java.lang.String)
+        */
+       public void setLastModifiedByProperty(String lastModifiedBy) {
+               this.lastModifiedBy = setStringValue(lastModifiedBy);
+       }
+
+       /**
+        * Set last printed date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable)
+        */
+       public void setLastPrintedProperty(String lastPrinted) {
+               try {
+                       this.lastPrinted = setDateValue(lastPrinted);
+               } catch (InvalidFormatException e) {
+                       new IllegalArgumentException("lastPrinted  : "
+                                       + e.getLocalizedMessage());
+               }
+       }
+
+       /**
+        * Set last printed date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setLastPrintedProperty(org.apache.poi.openxml4j.util.Nullable)
+        */
+       public void setLastPrintedProperty(Nullable<Date> lastPrinted) {
+               if (lastPrinted.hasValue())
+                       this.lastPrinted = lastPrinted;
+       }
+
+       /**
+        * Set last modification date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable)
+        */
+       public void setModifiedProperty(String modified) {
+               try {
+                       this.modified = setDateValue(modified);
+               } catch (InvalidFormatException e) {
+                       new IllegalArgumentException("modified  : "
+                                       + e.getLocalizedMessage());
+               }
+       }
+
+       /**
+        * Set last modification date.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setModifiedProperty(org.apache.poi.openxml4j.util.Nullable)
+        */
+       public void setModifiedProperty(Nullable<Date> modified) {
+               if (modified.hasValue())
+                       this.modified = modified;
+       }
+
+       /**
+        * Set revision.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setRevisionProperty(java.lang.String)
+        */
+       public void setRevisionProperty(String revision) {
+               this.revision = setStringValue(revision);
+       }
+
+       /**
+        * Set subject.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setSubjectProperty(java.lang.String)
+        */
+       public void setSubjectProperty(String subject) {
+               this.subject = setStringValue(subject);
+       }
+
+       /**
+        * Set title.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setTitleProperty(java.lang.String)
+        */
+       public void setTitleProperty(String title) {
+               this.title = setStringValue(title);
+       }
+
+       /**
+        * Set version.
+        * 
+        * @see org.apache.poi.openxml4j.opc.PackageProperties#setVersionProperty(java.lang.String)
+        */
+       public void setVersionProperty(String version) {
+               this.version = setStringValue(version);
+       }
+
+       /**
+        * Convert a strig value into a Nullable<String>
+        */
+       private Nullable<String> setStringValue(String s) {
+               if (s == null || s.equals(""))
+                       return new Nullable<String>();
+               else
+                       return new Nullable<String>(s);
+       }
+
+       /**
+        * Convert a string value represented a date into a Nullable<Date>.
+        * 
+        * @throws InvalidFormatException
+        *             Throws if the date format isnot valid.
+        */
+       private Nullable<Date> setDateValue(String s) throws InvalidFormatException {
+               if (s == null || s.equals(""))
+                       return new Nullable<Date>();
+               else {
+                       SimpleDateFormat df = new SimpleDateFormat(
+                                       "yyyy-MM-dd'T'HH:mm:ss'Z'");
+                       Date d = df.parse(s, new ParsePosition(0));
+                       if (d == null)
+                               throw new InvalidFormatException("Date not well formated");
+                       return new Nullable<Date>(d);
+               }
+       }
+
+       /**
+        * Convert a Nullable<Date> into a String.
+        * 
+        * @param d
+        *            The Date to convert.
+        * @return The formated date or null.
+        * @see java.util.SimpleDateFormat
+        */
+       private String getDateValue(Nullable<Date> d) {
+               if (d == null || d.equals(""))
+                       return "";
+               else {
+                       SimpleDateFormat df = new SimpleDateFormat(
+                                       "yyyy-MM-dd'T'HH:mm:ss'Z'");
+                       return df.format(d.getValue());
+               }
+       }
+
+       @Override
+       protected InputStream getInputStreamImpl() {
+               throw new InvalidOperationException("Operation not authorized");
+       }
+
+       @Override
+       protected OutputStream getOutputStreamImpl() {
+               throw new InvalidOperationException(
+                               "Can't use output stream to set properties !");
+       }
+
+       @Override
+       public boolean save(OutputStream zos) throws OpenXML4JException {
+               throw new InvalidOperationException("Operation not authorized");
+       }
+
+       @Override
+       public boolean load(InputStream ios) throws InvalidFormatException {
+               throw new InvalidOperationException("Operation not authorized");
+       }
+
+       @Override
+       public void close() {
+               // Do nothing
+       }
+
+       @Override
+       public void flush() {
+               // Do nothing
+       }
+}
index d732357b222bcae263043566abaf3255927e00b9..7355c7e099dc866cc17085b461467f171d3ce605 100755 (executable)
@@ -1,93 +1,93 @@
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.internal;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.util.zip.ZipEntry;\r
-import java.util.zip.ZipOutputStream;\r
-\r
-import org.dom4j.Document;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.StreamHelper;\r
-import org.apache.poi.util.POILogger;\r
-import org.apache.poi.util.POILogFactory;\r
-\r
-/**\r
- * Zip implementation of the ContentTypeManager.\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- * @see ContentTypeManager\r
- */\r
-public class ZipContentTypeManager extends ContentTypeManager {\r
-    private static POILogger logger = POILogFactory.getLogger(ZipContentTypeManager.class);\r
-\r
-       /**\r
-        * Delegate constructor to the super constructor.\r
-        * \r
-        * @param in\r
-        *            The input stream to parse to fill internal content type\r
-        *            collections.\r
-        * @throws InvalidFormatException\r
-        *             If the content types part content is not valid.\r
-        */\r
-       public ZipContentTypeManager(InputStream in, Package pkg)\r
-                       throws InvalidFormatException {\r
-               super(in, pkg);\r
-       }\r
-\r
-       @Override\r
-       public boolean saveImpl(Document content, OutputStream out) {\r
-               ZipOutputStream zos = null;\r
-               if (out instanceof ZipOutputStream)\r
-                       zos = (ZipOutputStream) out;\r
-               else\r
-                       zos = new ZipOutputStream(out);\r
-\r
-               ZipEntry partEntry = new ZipEntry(CONTENT_TYPES_PART_NAME);\r
-               try {\r
-                       // Referenced in ZIP\r
-                       zos.putNextEntry(partEntry);\r
-                       // Saving data in the ZIP file\r
-                       ByteArrayOutputStream outTemp = new ByteArrayOutputStream();\r
-                       StreamHelper.saveXmlInStream(content, out);\r
-                       InputStream ins = new ByteArrayInputStream(outTemp.toByteArray());\r
-                       byte[] buff = new byte[ZipHelper.READ_WRITE_FILE_BUFFER_SIZE];\r
-                       while (ins.available() > 0) {\r
-                               int resultRead = ins.read(buff);\r
-                               if (resultRead == -1) {\r
-                                       // end of file reached\r
-                                       break;\r
-                               } else {\r
-                                       zos.write(buff, 0, resultRead);\r
-                               }\r
-                       }\r
-                       zos.closeEntry();\r
-               } catch (IOException ioe) {\r
-                       logger.log(POILogger.ERROR, "Cannot write: " + CONTENT_TYPES_PART_NAME\r
-                                       + " in Zip !", ioe);\r
-                       return false;\r
-               }\r
-               return true;\r
-       }\r
-}\r
+/* ====================================================================
+   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.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.StreamHelper;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.dom4j.Document;
+
+/**
+ * Zip implementation of the ContentTypeManager.
+ * 
+ * @author Julien Chable
+ * @version 1.0
+ * @see ContentTypeManager
+ */
+public class ZipContentTypeManager extends ContentTypeManager {
+    private static POILogger logger = POILogFactory.getLogger(ZipContentTypeManager.class);
+
+       /**
+        * Delegate constructor to the super constructor.
+        * 
+        * @param in
+        *            The input stream to parse to fill internal content type
+        *            collections.
+        * @throws InvalidFormatException
+        *             If the content types part content is not valid.
+        */
+       public ZipContentTypeManager(InputStream in, OPCPackage pkg)
+                       throws InvalidFormatException {
+               super(in, pkg);
+       }
+
+       @Override
+       public boolean saveImpl(Document content, OutputStream out) {
+               ZipOutputStream zos = null;
+               if (out instanceof ZipOutputStream)
+                       zos = (ZipOutputStream) out;
+               else
+                       zos = new ZipOutputStream(out);
+
+               ZipEntry partEntry = new ZipEntry(CONTENT_TYPES_PART_NAME);
+               try {
+                       // Referenced in ZIP
+                       zos.putNextEntry(partEntry);
+                       // Saving data in the ZIP file
+                       ByteArrayOutputStream outTemp = new ByteArrayOutputStream();
+                       StreamHelper.saveXmlInStream(content, out);
+                       InputStream ins = new ByteArrayInputStream(outTemp.toByteArray());
+                       byte[] buff = new byte[ZipHelper.READ_WRITE_FILE_BUFFER_SIZE];
+                       while (ins.available() > 0) {
+                               int resultRead = ins.read(buff);
+                               if (resultRead == -1) {
+                                       // end of file reached
+                                       break;
+                               } else {
+                                       zos.write(buff, 0, resultRead);
+                               }
+                       }
+                       zos.closeEntry();
+               } catch (IOException ioe) {
+                       logger.log(POILogger.ERROR, "Cannot write: " + CONTENT_TYPES_PART_NAME
+                                       + " in Zip !", ioe);
+                       return false;
+               }
+               return true;
+       }
+}
index 689a5c67da0f950fab98e1b6f117ddd7b3b7560c..c4e01ca7a539e26ada6e9806dff592bd607e6462 100755 (executable)
@@ -1,96 +1,96 @@
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.internal.unmarshallers;\r
-\r
-import java.util.zip.ZipEntry;\r
-\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackagePartName;\r
-\r
-/**\r
- * Context needed for the unmarshall process of a part. This class is immutable.\r
- * \r
- * @author Julien Chable\r
- * @version 1.0\r
- */\r
-public final class UnmarshallContext {\r
-\r
-       private Package _package;\r
-\r
-       private PackagePartName partName;\r
-\r
-       private ZipEntry zipEntry;\r
-\r
-       /**\r
-        * Constructor.\r
-        * \r
-        * @param targetPackage\r
-        *            Container.\r
-        * @param partName\r
-        *            Name of the part to unmarshall.\r
-        */\r
-       public UnmarshallContext(Package targetPackage, PackagePartName partName) {\r
-               this._package = targetPackage;\r
-               this.partName = partName;\r
-       }\r
-\r
-       /**\r
-        * @return the container\r
-        */\r
-       Package getPackage() {\r
-               return _package;\r
-       }\r
-\r
-       /**\r
-        * @param container\r
-        *            the container to set\r
-        */\r
-       public void setPackage(Package container) {\r
-               this._package = container;\r
-       }\r
-\r
-       /**\r
-        * @return the partName\r
-        */\r
-       PackagePartName getPartName() {\r
-               return partName;\r
-       }\r
-\r
-       /**\r
-        * @param partName\r
-        *            the partName to set\r
-        */\r
-       public void setPartName(PackagePartName partName) {\r
-               this.partName = partName;\r
-       }\r
-\r
-       /**\r
-        * @return the zipEntry\r
-        */\r
-       ZipEntry getZipEntry() {\r
-               return zipEntry;\r
-       }\r
-\r
-       /**\r
-        * @param zipEntry\r
-        *            the zipEntry to set\r
-        */\r
-       public void setZipEntry(ZipEntry zipEntry) {\r
-               this.zipEntry = zipEntry;\r
-       }\r
-}\r
+/* ====================================================================
+   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.internal.unmarshallers;
+
+import java.util.zip.ZipEntry;
+
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+
+/**
+ * Context needed for the unmarshall process of a part. This class is immutable.
+ * 
+ * @author Julien Chable
+ * @version 1.0
+ */
+public final class UnmarshallContext {
+
+       private OPCPackage _package;
+
+       private PackagePartName partName;
+
+       private ZipEntry zipEntry;
+
+       /**
+        * Constructor.
+        * 
+        * @param targetPackage
+        *            Container.
+        * @param partName
+        *            Name of the part to unmarshall.
+        */
+       public UnmarshallContext(OPCPackage targetPackage, PackagePartName partName) {
+               this._package = targetPackage;
+               this.partName = partName;
+       }
+
+       /**
+        * @return the container
+        */
+       OPCPackage getPackage() {
+               return _package;
+       }
+
+       /**
+        * @param container
+        *            the container to set
+        */
+       public void setPackage(OPCPackage container) {
+               this._package = container;
+       }
+
+       /**
+        * @return the partName
+        */
+       PackagePartName getPartName() {
+               return partName;
+       }
+
+       /**
+        * @param partName
+        *            the partName to set
+        */
+       public void setPartName(PackagePartName partName) {
+               this.partName = partName;
+       }
+
+       /**
+        * @return the zipEntry
+        */
+       ZipEntry getZipEntry() {
+               return zipEntry;
+       }
+
+       /**
+        * @param zipEntry
+        *            the zipEntry to set
+        */
+       public void setZipEntry(ZipEntry zipEntry) {
+               this.zipEntry = zipEntry;
+       }
+}
index 9b42f0ee74f017232c8fd23e6022ec50f67a235f..a3ce259e54383e9d990990187a65ccdd72a50f97 100644 (file)
@@ -22,10 +22,10 @@ import java.io.PushbackInputStream;
 
 import org.apache.poi.POIXMLDocument;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.opc.Package;
 
 /**
  * Factory for creating the appropriate kind of Workbook
@@ -41,7 +41,7 @@ public class WorkbookFactory {
        /**
         * Creates an XSSFWorkbook from the given OOXML Package
         */
-       public static Workbook create(Package pkg) throws IOException {
+       public static Workbook create(OPCPackage pkg) throws IOException {
                return new XSSFWorkbook(pkg);
        }
        /**
@@ -60,7 +60,7 @@ public class WorkbookFactory {
                        return new HSSFWorkbook(inp);
                }
                if(POIXMLDocument.hasOOXMLHeader(inp)) {
-                       return new XSSFWorkbook( Package.open(inp) );
+                       return new XSSFWorkbook(OPCPackage.open(inp));
                }
                throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
        }
index 5b1b7d7476e50f5ddf99df38326a1e74fe740217..78468d5b94597dd57691a362d4f2960d253013df 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-package org.apache.poi.util;\r
-\r
-import org.apache.poi.openxml4j.opc.*;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.util.IOUtils;\r
-\r
-import java.io.*;\r
-\r
-/**\r
- * Provides handy methods to work with OOXML packages\r
- *\r
- * @author Yegor Kozlov\r
- */\r
-public class PackageHelper {\r
-\r
-    /**\r
-     * Clone the specified package.\r
-     *\r
-     * @param   pkg   the package to clone\r
-     * @return  the cloned package\r
-     */\r
-    public static Package clone(Package pkg) throws OpenXML4JException, IOException {\r
-        return clone(pkg, createTempFile());\r
-    }\r
-\r
-    /**\r
-     * Clone the specified package.\r
-     *\r
-     * @param   pkg   the package to clone\r
-     * @param   file  the destination file\r
-     * @return  the cloned package\r
-     */\r
-    public static Package clone(Package pkg, File file) throws OpenXML4JException, IOException {\r
-\r
-        String path = file.getAbsolutePath();\r
-\r
-        Package dest = Package.create(path);\r
-        PackageRelationshipCollection rels = pkg.getRelationships();\r
-        for (PackageRelationship rel : rels) {\r
-            PackagePart part = pkg.getPart(rel);\r
-            PackagePart part_tgt;\r
-            if (rel.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) {\r
-                copyProperties(pkg.getPackageProperties(), dest.getPackageProperties());\r
-                continue;\r
-            } else {\r
-                dest.addRelationship(part.getPartName(), rel.getTargetMode(), rel.getRelationshipType());\r
-                part_tgt = dest.createPart(part.getPartName(), part.getContentType());\r
-            }\r
-\r
-            OutputStream out = part_tgt.getOutputStream();\r
-            IOUtils.copy(part.getInputStream(), out);\r
-            out.close();\r
-\r
-            if(part.hasRelationships()) {\r
-                copy(pkg, part, dest, part_tgt);\r
-            }\r
-        }\r
-        dest.close();\r
-\r
-        //the temp file will be deleted when JVM terminates\r
-        new File(path).deleteOnExit();\r
-        return Package.open(path);\r
-    }\r
-\r
-    /**\r
-     * Creates an empty file in the default temporary-file directory, \r
-     */\r
-    public static File createTempFile() throws IOException {\r
-        File file = File.createTempFile("poi-ooxml-", ".tmp");\r
-        //there is no way to pass an existing file to Package.create(file),\r
-        //delete first, the file will be re-created in Packe.create(file)\r
-        file.delete();\r
-        file.deleteOnExit();\r
-        return file;\r
-\r
-    }\r
-\r
-    /**\r
-     * Recursively copy package parts to the destination package\r
-     */\r
-    private static void copy(Package pkg, PackagePart part, Package tgt, PackagePart part_tgt) throws OpenXML4JException, IOException {\r
-        PackageRelationshipCollection rels = part.getRelationships();\r
-        if(rels != null) for (PackageRelationship rel : rels) {\r
-            PackagePart p;\r
-            if(rel.getTargetMode() == TargetMode.EXTERNAL){\r
-                part_tgt.addExternalRelationship(rel.getTargetURI().toString(), rel.getRelationshipType(), rel.getId());\r
-                //external relations don't have associated package parts\r
-                continue;\r
-            } else {\r
-                PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());\r
-                p = pkg.getPart(relName);\r
-            }\r
-\r
-            part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId());\r
-\r
-            PackagePart dest;\r
-            if(!tgt.containPart(p.getPartName())){\r
-                dest = tgt.createPart(p.getPartName(), p.getContentType());\r
-                OutputStream out = dest.getOutputStream();\r
-                IOUtils.copy(p.getInputStream(), out);\r
-                out.close();\r
-                copy(pkg, p, tgt, dest);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Copy core package properties\r
-     *\r
-     * @param src source properties\r
-     * @param tgt target properties\r
-     */\r
-    private static void copyProperties(PackageProperties src, PackageProperties tgt){\r
-        tgt.setCategoryProperty(src.getCategoryProperty().getValue());\r
-        tgt.setContentStatusProperty(src.getContentStatusProperty().getValue());\r
-        tgt.setContentTypeProperty(src.getContentTypeProperty().getValue());\r
-        tgt.setCreatorProperty(src.getCreatorProperty().getValue());\r
-        tgt.setDescriptionProperty(src.getDescriptionProperty().getValue());\r
-        tgt.setIdentifierProperty(src.getIdentifierProperty().getValue());\r
-        tgt.setKeywordsProperty(src.getKeywordsProperty().getValue());\r
-        tgt.setLanguageProperty(src.getLanguageProperty().getValue());\r
-        tgt.setRevisionProperty(src.getRevisionProperty().getValue());\r
-        tgt.setSubjectProperty(src.getSubjectProperty().getValue());\r
-        tgt.setTitleProperty(src.getTitleProperty().getValue());\r
-        tgt.setVersionProperty(src.getVersionProperty().getValue());\r
-    }\r
-}\r
+/* ====================================================================
+   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.util;
+
+import org.apache.poi.openxml4j.opc.*;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.util.IOUtils;
+
+import java.io.*;
+
+/**
+ * Provides handy methods to work with OOXML packages
+ *
+ * @author Yegor Kozlov
+ */
+public class PackageHelper {
+
+    /**
+     * Clone the specified package.
+     *
+     * @param   pkg   the package to clone
+     * @return  the cloned package
+     */
+    public static OPCPackage clone(OPCPackage pkg) throws OpenXML4JException, IOException {
+        return clone(pkg, createTempFile());
+    }
+
+    /**
+     * Clone the specified package.
+     *
+     * @param   pkg   the package to clone
+     * @param   file  the destination file
+     * @return  the cloned package
+     */
+    public static OPCPackage clone(OPCPackage pkg, File file) throws OpenXML4JException, IOException {
+
+        String path = file.getAbsolutePath();
+
+        OPCPackage dest = OPCPackage.create(path);
+        PackageRelationshipCollection rels = pkg.getRelationships();
+        for (PackageRelationship rel : rels) {
+            PackagePart part = pkg.getPart(rel);
+            PackagePart part_tgt;
+            if (rel.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) {
+                copyProperties(pkg.getPackageProperties(), dest.getPackageProperties());
+                continue;
+            } else {
+                dest.addRelationship(part.getPartName(), rel.getTargetMode(), rel.getRelationshipType());
+                part_tgt = dest.createPart(part.getPartName(), part.getContentType());
+            }
+
+            OutputStream out = part_tgt.getOutputStream();
+            IOUtils.copy(part.getInputStream(), out);
+            out.close();
+
+            if(part.hasRelationships()) {
+                copy(pkg, part, dest, part_tgt);
+            }
+        }
+        dest.close();
+
+        //the temp file will be deleted when JVM terminates
+        new File(path).deleteOnExit();
+        return OPCPackage.open(path);
+    }
+
+    /**
+     * Creates an empty file in the default temporary-file directory, 
+     */
+    public static File createTempFile() throws IOException {
+        File file = File.createTempFile("poi-ooxml-", ".tmp");
+        //there is no way to pass an existing file to Package.create(file),
+        //delete first, the file will be re-created in Packe.create(file)
+        file.delete();
+        file.deleteOnExit();
+        return file;
+
+    }
+
+    /**
+     * Recursively copy package parts to the destination package
+     */
+    private static void copy(OPCPackage pkg, PackagePart part, OPCPackage tgt, PackagePart part_tgt) throws OpenXML4JException, IOException {
+        PackageRelationshipCollection rels = part.getRelationships();
+        if(rels != null) for (PackageRelationship rel : rels) {
+            PackagePart p;
+            if(rel.getTargetMode() == TargetMode.EXTERNAL){
+                part_tgt.addExternalRelationship(rel.getTargetURI().toString(), rel.getRelationshipType(), rel.getId());
+                //external relations don't have associated package parts
+                continue;
+            } else {
+                PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
+                p = pkg.getPart(relName);
+            }
+
+            part_tgt.addRelationship(p.getPartName(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId());
+
+            PackagePart dest;
+            if(!tgt.containPart(p.getPartName())){
+                dest = tgt.createPart(p.getPartName(), p.getContentType());
+                OutputStream out = dest.getOutputStream();
+                IOUtils.copy(p.getInputStream(), out);
+                out.close();
+                copy(pkg, p, tgt, dest);
+            }
+        }
+    }
+
+    /**
+     * Copy core package properties
+     *
+     * @param src source properties
+     * @param tgt target properties
+     */
+    private static void copyProperties(PackageProperties src, PackageProperties tgt){
+        tgt.setCategoryProperty(src.getCategoryProperty().getValue());
+        tgt.setContentStatusProperty(src.getContentStatusProperty().getValue());
+        tgt.setContentTypeProperty(src.getContentTypeProperty().getValue());
+        tgt.setCreatorProperty(src.getCreatorProperty().getValue());
+        tgt.setDescriptionProperty(src.getDescriptionProperty().getValue());
+        tgt.setIdentifierProperty(src.getIdentifierProperty().getValue());
+        tgt.setKeywordsProperty(src.getKeywordsProperty().getValue());
+        tgt.setLanguageProperty(src.getLanguageProperty().getValue());
+        tgt.setRevisionProperty(src.getRevisionProperty().getValue());
+        tgt.setSubjectProperty(src.getSubjectProperty().getValue());
+        tgt.setTitleProperty(src.getTitleProperty().getValue());
+        tgt.setVersionProperty(src.getVersionProperty().getValue());
+    }
+}
index 7b66a3d5a4f007704a4f04ff33118be98abad17d..57b801d9424934759e51463ac059d56feefd18ea 100644 (file)
 package org.apache.poi.xslf;
 
 import java.io.IOException;
-import java.util.List;
 import java.util.LinkedList;
+import java.util.List;
 
 import org.apache.poi.POIXMLDocument;
-import org.apache.xmlbeans.XmlException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
@@ -68,7 +68,7 @@ public class XSLFSlideShow extends POIXMLDocument {
      */
     private List<PackagePart> embedds;
 
-       public XSLFSlideShow(Package container) throws OpenXML4JException, IOException, XmlException {
+       public XSLFSlideShow(OPCPackage container) throws OpenXML4JException, IOException, XmlException {
                super(container);
                
                presentationDoc =
index ad820bd2fbfaf887fe92276206aa9f39b2c227aa..bb3e9143d1cefdd0742178b6f955ddd6a527140e 100644 (file)
@@ -19,12 +19,12 @@ package org.apache.poi.xslf.extractor;
 import java.io.IOException;
 
 import org.apache.poi.POIXMLTextExtractor;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.xslf.XSLFSlideShow;
 import org.apache.poi.xslf.usermodel.XMLSlideShow;
 import org.apache.poi.xslf.usermodel.XSLFSlide;
 import org.apache.xmlbeans.XmlException;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
@@ -48,7 +48,7 @@ public class XSLFPowerPointExtractor extends POIXMLTextExtractor {
        public XSLFPowerPointExtractor(XSLFSlideShow slideshow) throws XmlException, IOException {
                this(new XMLSlideShow(slideshow));
        }
-       public XSLFPowerPointExtractor(Package container) throws XmlException, OpenXML4JException, IOException {
+       public XSLFPowerPointExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException {
                this(new XSLFSlideShow(container));
        }
 
index 29f3bd0832476b1528de0b795310e7acf6eb2263..6814be8c91ddeb73c5092560c5a4a52fefbaf85c 100644 (file)
@@ -18,24 +18,28 @@ package org.apache.poi.xssf.eventusermodel;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 
-import org.apache.poi.xssf.model.SharedStringsTable;
-import org.apache.poi.xssf.model.StylesTable;
-import org.apache.poi.xssf.usermodel.XSSFRelation;
 import org.apache.poi.POIXMLException;
-import org.apache.xmlbeans.XmlException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 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.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.poi.xssf.usermodel.XSSFRelation;
+import org.apache.xmlbeans.XmlException;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
 
 /**
  * This class makes it easy to get at individual parts
@@ -45,13 +49,13 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
  *  for XSSF.
  */
 public class XSSFReader {
-    private Package pkg;
+    private OPCPackage pkg;
     private PackagePart workbookPart;
 
     /**
      * Creates a new XSSFReader, for the given package
      */
-    public XSSFReader(Package pkg) throws IOException, OpenXML4JException {
+    public XSSFReader(OPCPackage pkg) throws IOException, OpenXML4JException {
         this.pkg = pkg;
 
         PackageRelationship coreDocRelationship = this.pkg.getRelationshipsByType(
index 80ba653118cce852cdd367551616e305c252027e..4d38f6f471a2036945f42c2e6c80f4beb77965be 100644 (file)
@@ -21,6 +21,8 @@ import java.util.Iterator;
 
 import org.apache.poi.POIXMLTextExtractor;
 import org.apache.poi.hssf.extractor.ExcelExtractor;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Comment;
 import org.apache.poi.ss.usermodel.HeaderFooter;
@@ -29,8 +31,6 @@ import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.xmlbeans.XmlException;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
 
 /**
  * Helper class to extract text from an OOXML Excel file
@@ -44,7 +44,7 @@ public class XSSFExcelExtractor extends POIXMLTextExtractor implements org.apach
        public XSSFExcelExtractor(String path) throws XmlException, OpenXML4JException, IOException {
                this(new XSSFWorkbook(path));
        }
-       public XSSFExcelExtractor(Package container) throws XmlException, OpenXML4JException, IOException {
+       public XSSFExcelExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException {
                this(new XSSFWorkbook(container));
        }
        public XSSFExcelExtractor(XSSFWorkbook workbook) {
index c2cdcd06d4c19e900bb9c23828afffac74570ca4..4f2cfd43fbe60fa0dd2d3efa7df264ee0f449b27 100644 (file)
@@ -36,6 +36,14 @@ import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLException;
 import org.apache.poi.hssf.record.formula.SheetNameFormatter;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+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.PackageRelationshipTypes;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
@@ -45,20 +53,12 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.PackageHelper;
+import org.apache.poi.xssf.model.CalculationChain;
 import org.apache.poi.xssf.model.SharedStringsTable;
 import org.apache.poi.xssf.model.StylesTable;
-import org.apache.poi.xssf.model.CalculationChain;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
-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.PackageRelationshipTypes;
-import org.apache.poi.openxml4j.opc.PackagingURIHelper;
-import org.apache.poi.openxml4j.opc.TargetMode;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookView;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBookViews;
@@ -152,7 +152,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
      *
      * @param pkg the OpenXML4J <code>Package</code> object.
      */
-    public XSSFWorkbook(Package pkg) throws IOException {
+    public XSSFWorkbook(OPCPackage pkg) throws IOException {
         super(ensureWriteAccess(pkg));
 
         //build a tree of POIXMLDocumentParts, this workbook being the root
@@ -240,9 +240,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
     /**
      * Create a new SpreadsheetML package and setup the default minimal content
      */
-    protected static Package newPackage() {
+    protected static OPCPackage newPackage() {
         try {
-            Package pkg = Package.create(PackageHelper.createTempFile());
+            OPCPackage pkg = OPCPackage.create(PackageHelper.createTempFile());
             // Main part
             PackagePartName corePartName = PackagingURIHelper.createPartName(XSSFRelation.WORKBOOK.getDefaultFileName());
             // Create main part relationship
index 1e97b129ef787970ff2c011483991f2fe59dc2e2..63059653f7e421098246e6b5703172921e86bca4 100644 (file)
@@ -21,16 +21,16 @@ import java.util.Iterator;
 
 import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLTextExtractor;
-import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.xwpf.model.XWPFCommentsDecorator;
 import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
 import org.apache.poi.xwpf.model.XWPFHyperlinkDecorator;
 import org.apache.poi.xwpf.model.XWPFParagraphDecorator;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 import org.apache.poi.xwpf.usermodel.XWPFTable;
 import org.apache.xmlbeans.XmlException;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.Package;
 
 /**
  * Helper class to extract text from an OOXML Word file
@@ -39,7 +39,7 @@ public class XWPFWordExtractor extends POIXMLTextExtractor {
        private XWPFDocument document;
        private boolean fetchHyperlinks = false;
        
-       public XWPFWordExtractor(Package container) throws XmlException, OpenXML4JException, IOException {
+       public XWPFWordExtractor(OPCPackage container) throws XmlException, OpenXML4JException, IOException {
                this(new XWPFDocument(container));
        }
        public XWPFWordExtractor(XWPFDocument document) {
index f1921783d88096047b96d346739435fa42fe3043..63ba925f8d9fbbf88f9ab121c98a04f6668d5fec 100644 (file)
@@ -30,7 +30,6 @@ import org.apache.xmlbeans.XmlOptions;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
 import org.apache.poi.openxml4j.opc.*;
-import org.apache.poi.openxml4j.opc.Package;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
@@ -65,7 +64,7 @@ public class XWPFDocument extends POIXMLDocument {
     /** Handles the joy of different headers/footers for different pages */
     private XWPFHeaderFooterPolicy headerFooterPolicy;
 
-    public XWPFDocument(Package pkg) throws IOException {
+    public XWPFDocument(OPCPackage pkg) throws IOException {
         super(ensureWriteAccess(pkg));
 
         //build a tree of POIXMLDocumentParts, this document being the root
@@ -143,9 +142,9 @@ public class XWPFDocument extends POIXMLDocument {
     /**
      * Create a new SpreadsheetML package and setup the default minimal content
      */
-    protected static Package newPackage() {
+    protected static OPCPackage newPackage() {
         try {
-            Package pkg = Package.create(PackageHelper.createTempFile());
+               OPCPackage pkg = OPCPackage.create(PackageHelper.createTempFile());
             // Main part
             PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName());
             // Create main part relationship
index 6a427bbdc00c50c44d5dd4e68b753e3b406dc1b4..ff97d0329dd64043c33fed4f36e8b976970c0532 100644 (file)
@@ -25,7 +25,7 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.xslf.XSLFSlideShow;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 
 import junit.framework.TestCase;
@@ -47,7 +47,7 @@ public class TestEmbeded extends TestCase
                File f = new File(dirname, "ExcelWithAttachments.xlsx");
                assertTrue(f.exists());
                
-               POIXMLDocument doc = new XSSFWorkbook(Package.open(f.toString()));
+               POIXMLDocument doc = new XSSFWorkbook(OPCPackage.open(f.toString()));
                test(doc, 4);
        }
 
@@ -55,7 +55,7 @@ public class TestEmbeded extends TestCase
                File f = new File(dirname, "WordWithAttachments.docx");
                assertTrue(f.exists());
                
-               POIXMLDocument doc = new XWPFDocument(Package.open(f.toString()));
+               POIXMLDocument doc = new XWPFDocument(OPCPackage.open(f.toString()));
                test(doc, 5);
        }
 
@@ -63,7 +63,7 @@ public class TestEmbeded extends TestCase
                File f = new File(dirname, "PPTWithAttachments.pptx");
                assertTrue(f.exists());
                
-               POIXMLDocument doc = new XSLFSlideShow(Package.open(f.toString()));
+               POIXMLDocument doc = new XSLFSlideShow(OPCPackage.open(f.toString()));
                test(doc, 4);
        }
        
index 33c11436e52831f95f196a45aef9edec79300b00..90a73292715ddbbc18aaaeb9aeed443190e218a2 100644 (file)
@@ -20,7 +20,7 @@ import java.io.File;
 
 import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 
 import junit.framework.TestCase;
 
@@ -33,7 +33,7 @@ public class TestXMLPropertiesTextExtractor extends TestCase {
        }
        
        public void testGetFromMainExtractor() throws Exception {
-               org.apache.poi.openxml4j.opc.Package pkg = Package.open(
+               OPCPackage pkg = OPCPackage.open(
                                (new File(dirname, "ExcelWithAttachments.xlsx")).toString()
                );
                XSSFWorkbook wb = new XSSFWorkbook(pkg);
@@ -54,7 +54,7 @@ public class TestXMLPropertiesTextExtractor extends TestCase {
        }
 
        public void testCore() throws Exception {
-               org.apache.poi.openxml4j.opc.Package pkg = Package.open(
+               OPCPackage pkg = OPCPackage.open(
                                (new File(dirname, "ExcelWithAttachments.xlsx")).toString()
                );
                XSSFWorkbook wb = new XSSFWorkbook(pkg);
@@ -71,7 +71,7 @@ public class TestXMLPropertiesTextExtractor extends TestCase {
        }
        
        public void testExtended() throws Exception {
-               org.apache.poi.openxml4j.opc.Package pkg = Package.open(
+               OPCPackage pkg = OPCPackage.open(
                                (new File(dirname, "ExcelWithAttachments.xlsx")).toString()
                );
                XSSFWorkbook wb = new XSSFWorkbook(pkg);
index e75ba3c9e6d47fe02105e2486085ba58045383df..bbbbaa9733eee06964b61011e56e304b385fb6d4 100644 (file)
@@ -34,7 +34,7 @@ import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
 import junit.framework.TestCase;
 
 import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 
 /**
  * Test that the extractor factory plays nicely
@@ -276,34 +276,34 @@ public class TestExtractorFactory extends TestCase {
        public void testPackage() throws Exception {
                // Excel
                assertTrue(
-                               ExtractorFactory.createExtractor(Package.open(xlsx.toString()))
+                               ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString()))
                                instanceof XSSFExcelExtractor
                );
                assertTrue(
-                               ExtractorFactory.createExtractor(Package.open(xlsx.toString())).getText().length() > 200
+                               ExtractorFactory.createExtractor(OPCPackage.open(xlsx.toString())).getText().length() > 200
                );
                
                // Word
                assertTrue(
-                               ExtractorFactory.createExtractor(Package.open(docx.toString()))
+                               ExtractorFactory.createExtractor(OPCPackage.open(docx.toString()))
                                instanceof XWPFWordExtractor
                );
                assertTrue(
-                               ExtractorFactory.createExtractor(Package.open(docx.toString())).getText().length() > 120
+                               ExtractorFactory.createExtractor(OPCPackage.open(docx.toString())).getText().length() > 120
                );
                
                // PowerPoint
                assertTrue(
-                               ExtractorFactory.createExtractor(Package.open(pptx.toString()))
+                               ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString()))
                                instanceof XSLFPowerPointExtractor
                );
                assertTrue(
-                               ExtractorFactory.createExtractor(Package.open(pptx.toString())).getText().length() > 120
+                               ExtractorFactory.createExtractor(OPCPackage.open(pptx.toString())).getText().length() > 120
                );
                
                // Text
                try {
-                       ExtractorFactory.createExtractor(Package.open(txt.toString()));
+                       ExtractorFactory.createExtractor(OPCPackage.open(txt.toString()));
                        fail();
                } catch(InvalidOperationException e) {
                        // Good
index c35f57833ea21d8312a26bfcdb40155241cc65ec..01e628eba49fbe379988c5c3015027f3c2967f62 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.TreeMap;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-\r
-public final class TestListParts extends TestCase {\r
-       private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");\r
-\r
-       private TreeMap<PackagePartName, String> expectedValues;\r
-\r
-       private TreeMap<PackagePartName, String> values;\r
-\r
-       @Override\r
-       protected void setUp() throws Exception {\r
-               values = new TreeMap<PackagePartName, String>();\r
-\r
-               // Expected values\r
-               expectedValues = new TreeMap<PackagePartName, String>();\r
-               expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"),\r
-                               "application/vnd.openxmlformats-package.relationships+xml");\r
-\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/docProps/app.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.extended-properties+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/docProps/core.xml"),\r
-                               "application/vnd.openxmlformats-package.core-properties+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/word/_rels/document.xml.rels"),\r
-                               "application/vnd.openxmlformats-package.relationships+xml");\r
-               expectedValues\r
-                               .put(\r
-                                               PackagingURIHelper.createPartName("/word/document.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/word/fontTable.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/word/media/image1.gif"), "image/gif");\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/word/settings.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml");\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/word/styles.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/word/theme/theme1.xml"),\r
-                               "application/vnd.openxmlformats-officedocument.theme+xml");\r
-               expectedValues\r
-                               .put(\r
-                                               PackagingURIHelper\r
-                                                               .createPartName("/word/webSettings.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml");\r
-       }\r
-\r
-       /**\r
-        * List all parts of a package.\r
-        */\r
-       public void testListParts() throws InvalidFormatException {\r
-               InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.docx");\r
-\r
-               Package p;\r
-               try {\r
-                       p = Package.open(is);\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               for (PackagePart part : p.getParts()) {\r
-                       values.put(part.getPartName(), part.getContentType());\r
-                       logger.debug(part.getPartName());\r
-               }\r
-\r
-               // Compare expected values with values return by the package\r
-               for (PackagePartName partName : expectedValues.keySet()) {\r
-                       assertNotNull(values.get(partName));\r
-                       assertEquals(expectedValues.get(partName), values.get(partName));\r
-               }\r
-       }\r
-}\r
+/* ====================================================================
+   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.IOException;
+import java.io.InputStream;
+import java.util.TreeMap;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+
+public final class TestListParts extends TestCase {
+       private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");
+
+       private TreeMap<PackagePartName, String> expectedValues;
+
+       private TreeMap<PackagePartName, String> values;
+
+       @Override
+       protected void setUp() throws Exception {
+               values = new TreeMap<PackagePartName, String>();
+
+               // Expected values
+               expectedValues = new TreeMap<PackagePartName, String>();
+               expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"),
+                               "application/vnd.openxmlformats-package.relationships+xml");
+
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/docProps/app.xml"),
+                                               "application/vnd.openxmlformats-officedocument.extended-properties+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/docProps/core.xml"),
+                               "application/vnd.openxmlformats-package.core-properties+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/word/_rels/document.xml.rels"),
+                               "application/vnd.openxmlformats-package.relationships+xml");
+               expectedValues
+                               .put(
+                                               PackagingURIHelper.createPartName("/word/document.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/word/fontTable.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/word/media/image1.gif"), "image/gif");
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/word/settings.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml");
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/word/styles.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/word/theme/theme1.xml"),
+                               "application/vnd.openxmlformats-officedocument.theme+xml");
+               expectedValues
+                               .put(
+                                               PackagingURIHelper
+                                                               .createPartName("/word/webSettings.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml");
+       }
+
+       /**
+        * List all parts of a package.
+        */
+       public void testListParts() throws InvalidFormatException {
+               InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.docx");
+
+               OPCPackage p;
+               try {
+                       p = OPCPackage.open(is);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               for (PackagePart part : p.getParts()) {
+                       values.put(part.getPartName(), part.getContentType());
+                       logger.debug(part.getPartName());
+               }
+
+               // Compare expected values with values return by the package
+               for (PackagePartName partName : expectedValues.keySet()) {
+                       assertNotNull(values.get(partName));
+                       assertEquals(expectedValues.get(partName), values.get(partName));
+               }
+       }
+}
index 0b95bbe1190ca36cbf5627e300c404cda8167b55..5f667deba9c001e6f37248999edf2a4c94e98b9d 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.lang.reflect.Field;\r
-import java.net.URI;\r
-import java.util.TreeMap;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;\r
-import org.apache.poi.openxml4j.opc.internal.FileHelper;\r
-import org.dom4j.Document;\r
-import org.dom4j.DocumentHelper;\r
-import org.dom4j.Element;\r
-import org.dom4j.Namespace;\r
-import org.dom4j.QName;\r
-\r
-public final class TestPackage extends TestCase {\r
-       private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");\r
-\r
-       /**\r
-        * Test that just opening and closing the file doesn't alter the document.\r
-        */\r
-       public void testOpenSave() throws Exception {\r
-               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");\r
-               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx");\r
-\r
-               Package p = Package.open(originalFile, PackageAccess.READ_WRITE);\r
-               p.save(targetFile.getAbsoluteFile());\r
-\r
-               // Compare the original and newly saved document\r
-               assertTrue(targetFile.exists());\r
-               //ZipFileAssert.assertEquals(originalFile, targetFile);\r
-               assertTrue(targetFile.delete());\r
-       }\r
-       \r
-       /**\r
-        * Test that when we create a new Package, we give it\r
-        *  the correct default content types\r
-        */\r
-       public void testCreateGetsContentTypes() throws Exception {\r
-               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx");\r
-               \r
-               // Zap the target file, in case of an earlier run\r
-               if(targetFile.exists()) targetFile.delete();\r
-               \r
-               Package pkg = Package.create(targetFile);\r
-               \r
-               // Check it has content types for rels and xml\r
-               ContentTypeManager ctm = getContentTypeManager(pkg);\r
-               assertEquals(\r
-                               "application/xml",\r
-                               ctm.getContentType(\r
-                                               PackagingURIHelper.createPartName("/foo.xml")\r
-                               )\r
-               );\r
-               assertEquals(\r
-                               ContentTypes.RELATIONSHIPS_PART,\r
-                               ctm.getContentType(\r
-                                               PackagingURIHelper.createPartName("/foo.rels")\r
-                               )\r
-               );\r
-               assertNull(\r
-                               ctm.getContentType(\r
-                                               PackagingURIHelper.createPartName("/foo.txt")\r
-                               )\r
-               );\r
-       }\r
-\r
-       /**\r
-        * Test package creation.\r
-        */\r
-       public void testCreatePackageAddPart() throws Exception {\r
-               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx");\r
-\r
-               File expectedFileFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageOUTPUT.docx");\r
-\r
-               // Zap the target file, in case of an earlier run\r
-               if(targetFile.exists()) targetFile.delete();\r
-               \r
-               // Create a package\r
-               Package pkg = Package.create(targetFile);\r
-               PackagePartName corePartName = PackagingURIHelper\r
-                               .createPartName("/word/document.xml");\r
-\r
-               pkg.addRelationship(corePartName, TargetMode.INTERNAL,\r
-                               PackageRelationshipTypes.CORE_DOCUMENT, "rId1");\r
-\r
-               PackagePart corePart = pkg\r
-                               .createPart(\r
-                                               corePartName,\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");\r
-\r
-               Document doc = DocumentHelper.createDocument();\r
-               Namespace nsWordprocessinML = new Namespace("w",\r
-                               "http://schemas.openxmlformats.org/wordprocessingml/2006/main");\r
-               Element elDocument = doc.addElement(new QName("document",\r
-                               nsWordprocessinML));\r
-               Element elBody = elDocument.addElement(new QName("body",\r
-                               nsWordprocessinML));\r
-               Element elParagraph = elBody.addElement(new QName("p",\r
-                               nsWordprocessinML));\r
-               Element elRun = elParagraph\r
-                               .addElement(new QName("r", nsWordprocessinML));\r
-               Element elText = elRun.addElement(new QName("t", nsWordprocessinML));\r
-               elText.setText("Hello Open XML !");\r
-\r
-               StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());\r
-               pkg.close();\r
-\r
-               //ZipFileAssert.assertEquals(expectedFile, targetFile);\r
-               assertTrue(targetFile.delete());\r
-       }\r
-       \r
-       /**\r
-        * Tests that we can create a new package, add a core\r
-        *  document and another part, save and re-load and\r
-        *  have everything setup as expected\r
-        */\r
-       public void testCreatePackageWithCoreDocument() throws Exception {\r
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
-               Package pkg = Package.create(baos);\r
-               \r
-               // Add a core document\r
-        PackagePartName corePartName = PackagingURIHelper.createPartName("/xl/workbook.xml");\r
-        // Create main part relationship\r
-        pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId1");\r
-        // Create main document part\r
-        PackagePart corePart = pkg.createPart(corePartName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");\r
-        // Put in some dummy content\r
-        OutputStream coreOut = corePart.getOutputStream();\r
-        coreOut.write("<dummy-xml />".getBytes());\r
-        coreOut.close();\r
-               \r
-               // And another bit\r
-        PackagePartName sheetPartName = PackagingURIHelper.createPartName("/xl/worksheets/sheet1.xml");\r
-        PackageRelationship rel =\r
-                corePart.addRelationship(sheetPartName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", "rSheet1");\r
-        PackagePart part = pkg.createPart(sheetPartName, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");\r
-        // Dummy content again\r
-        coreOut = corePart.getOutputStream();\r
-        coreOut.write("<dummy-xml2 />".getBytes());\r
-        coreOut.close();\r
-        \r
-        \r
-        // Check things are as expected\r
-        PackageRelationshipCollection coreRels =\r
-               pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);\r
-        assertEquals(1, coreRels.size());\r
-        PackageRelationship coreRel = coreRels.getRelationship(0);\r
-        assertEquals("/", coreRel.getSourceURI().toString());\r
-        assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString());\r
-        assertNotNull(pkg.getPart(coreRel));\r
-        \r
-        \r
-        // Save and re-load\r
-        pkg.close();\r
-        FileOutputStream fout = new FileOutputStream(File.createTempFile("testCreatePackageWithCoreDocument", ".zip"));\r
-        fout.write(baos.toByteArray());\r
-        fout.close();\r
-        pkg = Package.open(new ByteArrayInputStream(baos.toByteArray()));\r
-        \r
-        \r
-        // Check still right\r
-        coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);\r
-        assertEquals(1, coreRels.size());\r
-        coreRel = coreRels.getRelationship(0);\r
-        assertEquals("/", coreRel.getSourceURI().toString());\r
-        assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString());\r
-        assertNotNull(pkg.getPart(coreRel));\r
-       }\r
-\r
-       /**\r
-        * Test package opening.\r
-        */\r
-       public void testOpenPackage() throws Exception {\r
-               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestOpenPackageTMP.docx");\r
-\r
-               File inputFile = OpenXML4JTestDataSamples.getSampleFile("TestOpenPackageINPUT.docx");\r
-\r
-               File expectedFile = OpenXML4JTestDataSamples.getOutputFile("TestOpenPackageOUTPUT.docx");\r
-\r
-               // Copy the input file in the output directory\r
-               FileHelper.copyFile(inputFile, targetFile);\r
-\r
-               // Create a package\r
-               Package pkg = Package.open(targetFile.getAbsolutePath());\r
-\r
-               // Modify core part\r
-               PackagePartName corePartName = PackagingURIHelper\r
-                               .createPartName("/word/document.xml");\r
-\r
-               PackagePart corePart = pkg.getPart(corePartName);\r
-\r
-               // Delete some part to have a valid document\r
-               for (PackageRelationship rel : corePart.getRelationships()) {\r
-                       corePart.removeRelationship(rel.getId());\r
-                       pkg.removePart(PackagingURIHelper.createPartName(PackagingURIHelper\r
-                                       .resolvePartUri(corePart.getPartName().getURI(), rel\r
-                                                       .getTargetURI())));\r
-               }\r
-\r
-               // Create a content\r
-               Document doc = DocumentHelper.createDocument();\r
-               Namespace nsWordprocessinML = new Namespace("w",\r
-                               "http://schemas.openxmlformats.org/wordprocessingml/2006/main");\r
-               Element elDocument = doc.addElement(new QName("document",\r
-                               nsWordprocessinML));\r
-               Element elBody = elDocument.addElement(new QName("body",\r
-                               nsWordprocessinML));\r
-               Element elParagraph = elBody.addElement(new QName("p",\r
-                               nsWordprocessinML));\r
-               Element elRun = elParagraph\r
-                               .addElement(new QName("r", nsWordprocessinML));\r
-               Element elText = elRun.addElement(new QName("t", nsWordprocessinML));\r
-               elText.setText("Hello Open XML !");\r
-\r
-               StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());\r
-\r
-               // Save and close\r
-               try {\r
-                       pkg.close();\r
-               } catch (IOException e) {\r
-                       fail();\r
-               }\r
-\r
-               //ZipFileAssert.assertEquals(expectedFile, targetFile);\r
-               assertTrue(targetFile.delete());\r
-       }\r
-       \r
-       /**\r
-        * Checks that we can write a package to a simple\r
-        *  OutputStream, in addition to the normal writing\r
-        *  to a file\r
-        */\r
-       public void testSaveToOutputStream() throws Exception {\r
-               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");\r
-               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx");\r
-\r
-               Package p = Package.open(originalFile, PackageAccess.READ_WRITE);\r
-               FileOutputStream fout = new FileOutputStream(targetFile);\r
-               p.save(fout);\r
-               fout.close();\r
-\r
-               // Compare the original and newly saved document\r
-               assertTrue(targetFile.exists());\r
-               //ZipFileAssert.assertEquals(originalFile, targetFile);\r
-               assertTrue(targetFile.delete());\r
-       }\r
-\r
-       /**\r
-        * Checks that we can open+read a package from a\r
-        *  simple InputStream, in addition to the normal\r
-        *  reading from a file\r
-        */\r
-       public void testOpenFromInputStream() throws Exception {\r
-               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");\r
-               \r
-               FileInputStream finp = new FileInputStream(originalFile);\r
-               \r
-               Package p = Package.open(finp);\r
-               \r
-               assertNotNull(p);\r
-               assertNotNull(p.getRelationships());\r
-               assertEquals(12, p.getParts().size());\r
-               \r
-               // Check it has the usual bits\r
-               assertTrue(p.hasRelationships());\r
-               assertTrue(p.containPart(PackagingURIHelper.createPartName("/_rels/.rels")));\r
-       }\r
-\r
-    /**\r
-     * TODO: fix and enable\r
-     */\r
-    public void disabled_testRemovePartRecursive() throws Exception {\r
-               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");\r
-               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveOUTPUT.docx");\r
-               File tempFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveTMP.docx");\r
-\r
-               Package p = Package.open(originalFile, PackageAccess.READ_WRITE);\r
-               p.removePartRecursive(PackagingURIHelper.createPartName(new URI(\r
-                               "/word/document.xml")));\r
-               p.save(tempFile.getAbsoluteFile());\r
-\r
-               // Compare the original and newly saved document\r
-               assertTrue(targetFile.exists());\r
-               //ZipFileAssert.assertEquals(targetFile, tempFile);\r
-               assertTrue(targetFile.delete());\r
-       }\r
-\r
-       public void testDeletePart() throws InvalidFormatException {\r
-               TreeMap<PackagePartName, String> expectedValues;\r
-               TreeMap<PackagePartName, String> values;\r
-\r
-               values = new TreeMap<PackagePartName, String>();\r
-\r
-               // Expected values\r
-               expectedValues = new TreeMap<PackagePartName, String>();\r
-               expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"),\r
-                               "application/vnd.openxmlformats-package.relationships+xml");\r
-\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/docProps/app.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.extended-properties+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/docProps/core.xml"),\r
-                               "application/vnd.openxmlformats-package.core-properties+xml");\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/word/fontTable.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/word/media/image1.gif"), "image/gif");\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/word/settings.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml");\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/word/styles.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/word/theme/theme1.xml"),\r
-                               "application/vnd.openxmlformats-officedocument.theme+xml");\r
-               expectedValues\r
-                               .put(\r
-                                               PackagingURIHelper\r
-                                                               .createPartName("/word/webSettings.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml");\r
-\r
-               String filepath =  OpenXML4JTestDataSamples.getSampleFileName("sample.docx");\r
-\r
-               Package p = Package.open(filepath, PackageAccess.READ_WRITE);\r
-               // Remove the core part\r
-               p.deletePart(PackagingURIHelper.createPartName("/word/document.xml"));\r
-\r
-               for (PackagePart part : p.getParts()) {\r
-                       values.put(part.getPartName(), part.getContentType());\r
-                       logger.debug(part.getPartName());\r
-               }\r
-\r
-               // Compare expected values with values return by the package\r
-               for (PackagePartName partName : expectedValues.keySet()) {\r
-                       assertNotNull(values.get(partName));\r
-                       assertEquals(expectedValues.get(partName), values.get(partName));\r
-               }\r
-               // Don't save modifications\r
-               p.revert();\r
-       }\r
-       \r
-       public void testDeletePartRecursive() throws InvalidFormatException {\r
-               TreeMap<PackagePartName, String> expectedValues;\r
-               TreeMap<PackagePartName, String> values;\r
-\r
-               values = new TreeMap<PackagePartName, String>();\r
-\r
-               // Expected values\r
-               expectedValues = new TreeMap<PackagePartName, String>();\r
-               expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"),\r
-                               "application/vnd.openxmlformats-package.relationships+xml");\r
-\r
-               expectedValues\r
-                               .put(PackagingURIHelper.createPartName("/docProps/app.xml"),\r
-                                               "application/vnd.openxmlformats-officedocument.extended-properties+xml");\r
-               expectedValues.put(PackagingURIHelper\r
-                               .createPartName("/docProps/core.xml"),\r
-                               "application/vnd.openxmlformats-package.core-properties+xml");\r
-\r
-               String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx");\r
-\r
-               Package p = Package.open(filepath, PackageAccess.READ_WRITE);\r
-               // Remove the core part\r
-               p.deletePartRecursive(PackagingURIHelper.createPartName("/word/document.xml"));\r
-\r
-               for (PackagePart part : p.getParts()) {\r
-                       values.put(part.getPartName(), part.getContentType());\r
-                       logger.debug(part.getPartName());\r
-               }\r
-\r
-               // Compare expected values with values return by the package\r
-               for (PackagePartName partName : expectedValues.keySet()) {\r
-                       assertNotNull(values.get(partName));\r
-                       assertEquals(expectedValues.get(partName), values.get(partName));\r
-               }\r
-               // Don't save modifications\r
-               p.revert();\r
-       }\r
-       \r
-       private static ContentTypeManager getContentTypeManager(Package pkg) throws Exception {\r
-               Field f = Package.class.getDeclaredField("contentTypeManager");\r
-               f.setAccessible(true);\r
-               return (ContentTypeManager)f.get(pkg);\r
-       }\r
-}\r
+/* ====================================================================
+   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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.util.TreeMap;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
+import org.apache.poi.openxml4j.opc.internal.FileHelper;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+import org.dom4j.QName;
+
+public final class TestPackage extends TestCase {
+       private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");
+
+       /**
+        * Test that just opening and closing the file doesn't alter the document.
+        */
+       public void testOpenSave() throws Exception {
+               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
+               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx");
+
+               OPCPackage p = OPCPackage.open(originalFile, PackageAccess.READ_WRITE);
+               p.save(targetFile.getAbsoluteFile());
+
+               // Compare the original and newly saved document
+               assertTrue(targetFile.exists());
+               //ZipFileAssert.assertEquals(originalFile, targetFile);
+               assertTrue(targetFile.delete());
+       }
+       
+       /**
+        * Test that when we create a new Package, we give it
+        *  the correct default content types
+        */
+       public void testCreateGetsContentTypes() throws Exception {
+               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx");
+               
+               // Zap the target file, in case of an earlier run
+               if(targetFile.exists()) targetFile.delete();
+               
+               OPCPackage pkg = OPCPackage.create(targetFile);
+               
+               // Check it has content types for rels and xml
+               ContentTypeManager ctm = getContentTypeManager(pkg);
+               assertEquals(
+                               "application/xml",
+                               ctm.getContentType(
+                                               PackagingURIHelper.createPartName("/foo.xml")
+                               )
+               );
+               assertEquals(
+                               ContentTypes.RELATIONSHIPS_PART,
+                               ctm.getContentType(
+                                               PackagingURIHelper.createPartName("/foo.rels")
+                               )
+               );
+               assertNull(
+                               ctm.getContentType(
+                                               PackagingURIHelper.createPartName("/foo.txt")
+                               )
+               );
+       }
+
+       /**
+        * Test package creation.
+        */
+       public void testCreatePackageAddPart() throws Exception {
+               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageTMP.docx");
+
+               File expectedFileFile = OpenXML4JTestDataSamples.getOutputFile("TestCreatePackageOUTPUT.docx");
+
+               // Zap the target file, in case of an earlier run
+               if(targetFile.exists()) targetFile.delete();
+               
+               // Create a package
+               OPCPackage pkg = OPCPackage.create(targetFile);
+               PackagePartName corePartName = PackagingURIHelper
+                               .createPartName("/word/document.xml");
+
+               pkg.addRelationship(corePartName, TargetMode.INTERNAL,
+                               PackageRelationshipTypes.CORE_DOCUMENT, "rId1");
+
+               PackagePart corePart = pkg
+                               .createPart(
+                                               corePartName,
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");
+
+               Document doc = DocumentHelper.createDocument();
+               Namespace nsWordprocessinML = new Namespace("w",
+                               "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
+               Element elDocument = doc.addElement(new QName("document",
+                               nsWordprocessinML));
+               Element elBody = elDocument.addElement(new QName("body",
+                               nsWordprocessinML));
+               Element elParagraph = elBody.addElement(new QName("p",
+                               nsWordprocessinML));
+               Element elRun = elParagraph
+                               .addElement(new QName("r", nsWordprocessinML));
+               Element elText = elRun.addElement(new QName("t", nsWordprocessinML));
+               elText.setText("Hello Open XML !");
+
+               StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());
+               pkg.close();
+
+               //ZipFileAssert.assertEquals(expectedFile, targetFile);
+               assertTrue(targetFile.delete());
+       }
+       
+       /**
+        * Tests that we can create a new package, add a core
+        *  document and another part, save and re-load and
+        *  have everything setup as expected
+        */
+       public void testCreatePackageWithCoreDocument() throws Exception {
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               OPCPackage pkg = OPCPackage.create(baos);
+               
+               // Add a core document
+        PackagePartName corePartName = PackagingURIHelper.createPartName("/xl/workbook.xml");
+        // Create main part relationship
+        pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId1");
+        // Create main document part
+        PackagePart corePart = pkg.createPart(corePartName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
+        // Put in some dummy content
+        OutputStream coreOut = corePart.getOutputStream();
+        coreOut.write("<dummy-xml />".getBytes());
+        coreOut.close();
+               
+               // And another bit
+        PackagePartName sheetPartName = PackagingURIHelper.createPartName("/xl/worksheets/sheet1.xml");
+        PackageRelationship rel =
+                corePart.addRelationship(sheetPartName, TargetMode.INTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", "rSheet1");
+        PackagePart part = pkg.createPart(sheetPartName, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml");
+        // Dummy content again
+        coreOut = corePart.getOutputStream();
+        coreOut.write("<dummy-xml2 />".getBytes());
+        coreOut.close();
+        
+        
+        // Check things are as expected
+        PackageRelationshipCollection coreRels =
+               pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
+        assertEquals(1, coreRels.size());
+        PackageRelationship coreRel = coreRels.getRelationship(0);
+        assertEquals("/", coreRel.getSourceURI().toString());
+        assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString());
+        assertNotNull(pkg.getPart(coreRel));
+        
+        
+        // Save and re-load
+        pkg.close();
+        FileOutputStream fout = new FileOutputStream(File.createTempFile("testCreatePackageWithCoreDocument", ".zip"));
+        fout.write(baos.toByteArray());
+        fout.close();
+        pkg = OPCPackage.open(new ByteArrayInputStream(baos.toByteArray()));
+        
+        
+        // Check still right
+        coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
+        assertEquals(1, coreRels.size());
+        coreRel = coreRels.getRelationship(0);
+        assertEquals("/", coreRel.getSourceURI().toString());
+        assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString());
+        assertNotNull(pkg.getPart(coreRel));
+       }
+
+       /**
+        * Test package opening.
+        */
+       public void testOpenPackage() throws Exception {
+               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestOpenPackageTMP.docx");
+
+               File inputFile = OpenXML4JTestDataSamples.getSampleFile("TestOpenPackageINPUT.docx");
+
+               File expectedFile = OpenXML4JTestDataSamples.getOutputFile("TestOpenPackageOUTPUT.docx");
+
+               // Copy the input file in the output directory
+               FileHelper.copyFile(inputFile, targetFile);
+
+               // Create a package
+               OPCPackage pkg = OPCPackage.open(targetFile.getAbsolutePath());
+
+               // Modify core part
+               PackagePartName corePartName = PackagingURIHelper
+                               .createPartName("/word/document.xml");
+
+               PackagePart corePart = pkg.getPart(corePartName);
+
+               // Delete some part to have a valid document
+               for (PackageRelationship rel : corePart.getRelationships()) {
+                       corePart.removeRelationship(rel.getId());
+                       pkg.removePart(PackagingURIHelper.createPartName(PackagingURIHelper
+                                       .resolvePartUri(corePart.getPartName().getURI(), rel
+                                                       .getTargetURI())));
+               }
+
+               // Create a content
+               Document doc = DocumentHelper.createDocument();
+               Namespace nsWordprocessinML = new Namespace("w",
+                               "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
+               Element elDocument = doc.addElement(new QName("document",
+                               nsWordprocessinML));
+               Element elBody = elDocument.addElement(new QName("body",
+                               nsWordprocessinML));
+               Element elParagraph = elBody.addElement(new QName("p",
+                               nsWordprocessinML));
+               Element elRun = elParagraph
+                               .addElement(new QName("r", nsWordprocessinML));
+               Element elText = elRun.addElement(new QName("t", nsWordprocessinML));
+               elText.setText("Hello Open XML !");
+
+               StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());
+
+               // Save and close
+               try {
+                       pkg.close();
+               } catch (IOException e) {
+                       fail();
+               }
+
+               //ZipFileAssert.assertEquals(expectedFile, targetFile);
+               assertTrue(targetFile.delete());
+       }
+       
+       /**
+        * Checks that we can write a package to a simple
+        *  OutputStream, in addition to the normal writing
+        *  to a file
+        */
+       public void testSaveToOutputStream() throws Exception {
+               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
+               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageOpenSaveTMP.docx");
+
+               OPCPackage p = OPCPackage.open(originalFile, PackageAccess.READ_WRITE);
+               FileOutputStream fout = new FileOutputStream(targetFile);
+               p.save(fout);
+               fout.close();
+
+               // Compare the original and newly saved document
+               assertTrue(targetFile.exists());
+               //ZipFileAssert.assertEquals(originalFile, targetFile);
+               assertTrue(targetFile.delete());
+       }
+
+       /**
+        * Checks that we can open+read a package from a
+        *  simple InputStream, in addition to the normal
+        *  reading from a file
+        */
+       public void testOpenFromInputStream() throws Exception {
+               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
+               
+               FileInputStream finp = new FileInputStream(originalFile);
+               
+               OPCPackage p = OPCPackage.open(finp);
+               
+               assertNotNull(p);
+               assertNotNull(p.getRelationships());
+               assertEquals(12, p.getParts().size());
+               
+               // Check it has the usual bits
+               assertTrue(p.hasRelationships());
+               assertTrue(p.containPart(PackagingURIHelper.createPartName("/_rels/.rels")));
+       }
+
+    /**
+     * TODO: fix and enable
+     */
+    public void disabled_testRemovePartRecursive() throws Exception {
+               String originalFile = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCommon.docx");
+               File targetFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveOUTPUT.docx");
+               File tempFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageRemovePartRecursiveTMP.docx");
+
+               OPCPackage p = OPCPackage.open(originalFile, PackageAccess.READ_WRITE);
+               p.removePartRecursive(PackagingURIHelper.createPartName(new URI(
+                               "/word/document.xml")));
+               p.save(tempFile.getAbsoluteFile());
+
+               // Compare the original and newly saved document
+               assertTrue(targetFile.exists());
+               //ZipFileAssert.assertEquals(targetFile, tempFile);
+               assertTrue(targetFile.delete());
+       }
+
+       public void testDeletePart() throws InvalidFormatException {
+               TreeMap<PackagePartName, String> expectedValues;
+               TreeMap<PackagePartName, String> values;
+
+               values = new TreeMap<PackagePartName, String>();
+
+               // Expected values
+               expectedValues = new TreeMap<PackagePartName, String>();
+               expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"),
+                               "application/vnd.openxmlformats-package.relationships+xml");
+
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/docProps/app.xml"),
+                                               "application/vnd.openxmlformats-officedocument.extended-properties+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/docProps/core.xml"),
+                               "application/vnd.openxmlformats-package.core-properties+xml");
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/word/fontTable.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/word/media/image1.gif"), "image/gif");
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/word/settings.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml");
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/word/styles.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/word/theme/theme1.xml"),
+                               "application/vnd.openxmlformats-officedocument.theme+xml");
+               expectedValues
+                               .put(
+                                               PackagingURIHelper
+                                                               .createPartName("/word/webSettings.xml"),
+                                               "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml");
+
+               String filepath =  OpenXML4JTestDataSamples.getSampleFileName("sample.docx");
+
+               OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ_WRITE);
+               // Remove the core part
+               p.deletePart(PackagingURIHelper.createPartName("/word/document.xml"));
+
+               for (PackagePart part : p.getParts()) {
+                       values.put(part.getPartName(), part.getContentType());
+                       logger.debug(part.getPartName());
+               }
+
+               // Compare expected values with values return by the package
+               for (PackagePartName partName : expectedValues.keySet()) {
+                       assertNotNull(values.get(partName));
+                       assertEquals(expectedValues.get(partName), values.get(partName));
+               }
+               // Don't save modifications
+               p.revert();
+       }
+       
+       public void testDeletePartRecursive() throws InvalidFormatException {
+               TreeMap<PackagePartName, String> expectedValues;
+               TreeMap<PackagePartName, String> values;
+
+               values = new TreeMap<PackagePartName, String>();
+
+               // Expected values
+               expectedValues = new TreeMap<PackagePartName, String>();
+               expectedValues.put(PackagingURIHelper.createPartName("/_rels/.rels"),
+                               "application/vnd.openxmlformats-package.relationships+xml");
+
+               expectedValues
+                               .put(PackagingURIHelper.createPartName("/docProps/app.xml"),
+                                               "application/vnd.openxmlformats-officedocument.extended-properties+xml");
+               expectedValues.put(PackagingURIHelper
+                               .createPartName("/docProps/core.xml"),
+                               "application/vnd.openxmlformats-package.core-properties+xml");
+
+               String filepath = OpenXML4JTestDataSamples.getSampleFileName("sample.docx");
+
+               OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ_WRITE);
+               // Remove the core part
+               p.deletePartRecursive(PackagingURIHelper.createPartName("/word/document.xml"));
+
+               for (PackagePart part : p.getParts()) {
+                       values.put(part.getPartName(), part.getContentType());
+                       logger.debug(part.getPartName());
+               }
+
+               // Compare expected values with values return by the package
+               for (PackagePartName partName : expectedValues.keySet()) {
+                       assertNotNull(values.get(partName));
+                       assertEquals(expectedValues.get(partName), values.get(partName));
+               }
+               // Don't save modifications
+               p.revert();
+       }
+       
+       private static ContentTypeManager getContentTypeManager(OPCPackage pkg) throws Exception {
+               Field f = OPCPackage.class.getDeclaredField("contentTypeManager");
+               f.setAccessible(true);
+               return (ContentTypeManager)f.get(pkg);
+       }
+}
index 54e21b89d3810c203145978ed80fe3543b56f9ea..1014279981f01cb1bf0ad366d9bb9ff0995c0887 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.text.ParsePosition;\r
-import java.text.SimpleDateFormat;\r
-import java.util.Date;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;\r
-import org.apache.poi.openxml4j.util.Nullable;\r
-\r
-public final class TestPackageCoreProperties extends TestCase {\r
-\r
-       /**\r
-        * Test package core properties getters.\r
-        */\r
-       public void testGetProperties() {\r
-               try {\r
-                       // Open the package\r
-                       Package p = Package.open(OpenXML4JTestDataSamples.openSampleStream("TestPackageCoreProperiesGetters.docx"));\r
-                       compareProperties(p);\r
-                       p.revert();\r
-               } catch (OpenXML4JException e) {\r
-                       Logger.getLogger("org.apache.poi.openxml4j.demo").debug(e.getMessage());\r
-                       throw new RuntimeException(e);\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Test package core properties setters.\r
-        */\r
-       public void testSetProperties() throws Exception {\r
-               String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCoreProperiesSetters.docx");\r
-\r
-               File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageCoreProperiesSettersOUTPUT.docx");\r
-\r
-               // Open package\r
-               Package p = Package.open(inputPath, PackageAccess.READ_WRITE);\r
-\r
-               SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");\r
-               Date dateToInsert = df.parse("2007-05-12T08:00:00Z", new ParsePosition(\r
-                               0));\r
-\r
-               PackageProperties props = p.getPackageProperties();\r
-               props.setCategoryProperty("MyCategory");\r
-               props.setContentStatusProperty("MyContentStatus");\r
-               props.setContentTypeProperty("MyContentType");\r
-               props.setCreatedProperty(new Nullable<Date>(dateToInsert));\r
-               props.setCreatorProperty("MyCreator");\r
-               props.setDescriptionProperty("MyDescription");\r
-               props.setIdentifierProperty("MyIdentifier");\r
-               props.setKeywordsProperty("MyKeywords");\r
-               props.setLanguageProperty("MyLanguage");\r
-               props.setLastModifiedByProperty("Julien Chable");\r
-               props.setLastPrintedProperty(new Nullable<Date>(dateToInsert));\r
-               props.setModifiedProperty(new Nullable<Date>(dateToInsert));\r
-               props.setRevisionProperty("2");\r
-               props.setTitleProperty("MyTitle");\r
-               props.setSubjectProperty("MySubject");\r
-               props.setVersionProperty("2");\r
-               // Save the package in the output directory\r
-               p.save(outputFile);\r
-\r
-               // Open the newly created file to check core properties saved values.\r
-               Package p2 = Package.open(outputFile.getAbsolutePath(), PackageAccess.READ);\r
-               compareProperties(p2);\r
-               p2.revert();\r
-               outputFile.delete();\r
-       }\r
-\r
-       private void compareProperties(Package p) throws InvalidFormatException {\r
-               SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");\r
-               Date expectedDate = df.parse("2007-05-12T08:00:00Z", new ParsePosition(\r
-                               0));\r
-\r
-               // Gets the core properties\r
-               PackageProperties props = p.getPackageProperties();\r
-               assertEquals("MyCategory", props.getCategoryProperty().getValue());\r
-               assertEquals("MyContentStatus", props.getContentStatusProperty()\r
-                               .getValue());\r
-               assertEquals("MyContentType", props.getContentTypeProperty().getValue());\r
-               assertEquals(expectedDate, props.getCreatedProperty().getValue());\r
-               assertEquals("MyCreator", props.getCreatorProperty().getValue());\r
-               assertEquals("MyDescription", props.getDescriptionProperty().getValue());\r
-               assertEquals("MyIdentifier", props.getIdentifierProperty().getValue());\r
-               assertEquals("MyKeywords", props.getKeywordsProperty().getValue());\r
-               assertEquals("MyLanguage", props.getLanguageProperty().getValue());\r
-               assertEquals("Julien Chable", props.getLastModifiedByProperty()\r
-                               .getValue());\r
-               assertEquals(expectedDate, props.getLastPrintedProperty().getValue());\r
-               assertEquals(expectedDate, props.getModifiedProperty().getValue());\r
-               assertEquals("2", props.getRevisionProperty().getValue());\r
-               assertEquals("MySubject", props.getSubjectProperty().getValue());\r
-               assertEquals("MyTitle", props.getTitleProperty().getValue());\r
-               assertEquals("2", props.getVersionProperty().getValue());\r
-       }\r
-}\r
+/* ====================================================================
+   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.File;
+import java.io.IOException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.util.Nullable;
+
+public final class TestPackageCoreProperties extends TestCase {
+
+       /**
+        * Test package core properties getters.
+        */
+       public void testGetProperties() {
+               try {
+                       // Open the package
+                       OPCPackage p = OPCPackage.open(OpenXML4JTestDataSamples.openSampleStream("TestPackageCoreProperiesGetters.docx"));
+                       compareProperties(p);
+                       p.revert();
+               } catch (OpenXML4JException e) {
+                       Logger.getLogger("org.apache.poi.openxml4j.demo").debug(e.getMessage());
+                       throw new RuntimeException(e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Test package core properties setters.
+        */
+       public void testSetProperties() throws Exception {
+               String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageCoreProperiesSetters.docx");
+
+               File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageCoreProperiesSettersOUTPUT.docx");
+
+               // Open package
+               OPCPackage p = OPCPackage.open(inputPath, PackageAccess.READ_WRITE);
+
+               SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+               Date dateToInsert = df.parse("2007-05-12T08:00:00Z", new ParsePosition(
+                               0));
+
+               PackageProperties props = p.getPackageProperties();
+               props.setCategoryProperty("MyCategory");
+               props.setContentStatusProperty("MyContentStatus");
+               props.setContentTypeProperty("MyContentType");
+               props.setCreatedProperty(new Nullable<Date>(dateToInsert));
+               props.setCreatorProperty("MyCreator");
+               props.setDescriptionProperty("MyDescription");
+               props.setIdentifierProperty("MyIdentifier");
+               props.setKeywordsProperty("MyKeywords");
+               props.setLanguageProperty("MyLanguage");
+               props.setLastModifiedByProperty("Julien Chable");
+               props.setLastPrintedProperty(new Nullable<Date>(dateToInsert));
+               props.setModifiedProperty(new Nullable<Date>(dateToInsert));
+               props.setRevisionProperty("2");
+               props.setTitleProperty("MyTitle");
+               props.setSubjectProperty("MySubject");
+               props.setVersionProperty("2");
+               // Save the package in the output directory
+               p.save(outputFile);
+
+               // Open the newly created file to check core properties saved values.
+               OPCPackage p2 = OPCPackage.open(outputFile.getAbsolutePath(), PackageAccess.READ);
+               compareProperties(p2);
+               p2.revert();
+               outputFile.delete();
+       }
+
+       private void compareProperties(OPCPackage p) throws InvalidFormatException {
+               SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+               Date expectedDate = df.parse("2007-05-12T08:00:00Z", new ParsePosition(
+                               0));
+
+               // Gets the core properties
+               PackageProperties props = p.getPackageProperties();
+               assertEquals("MyCategory", props.getCategoryProperty().getValue());
+               assertEquals("MyContentStatus", props.getContentStatusProperty()
+                               .getValue());
+               assertEquals("MyContentType", props.getContentTypeProperty().getValue());
+               assertEquals(expectedDate, props.getCreatedProperty().getValue());
+               assertEquals("MyCreator", props.getCreatorProperty().getValue());
+               assertEquals("MyDescription", props.getDescriptionProperty().getValue());
+               assertEquals("MyIdentifier", props.getIdentifierProperty().getValue());
+               assertEquals("MyKeywords", props.getKeywordsProperty().getValue());
+               assertEquals("MyLanguage", props.getLanguageProperty().getValue());
+               assertEquals("Julien Chable", props.getLastModifiedByProperty()
+                               .getValue());
+               assertEquals(expectedDate, props.getLastPrintedProperty().getValue());
+               assertEquals(expectedDate, props.getModifiedProperty().getValue());
+               assertEquals("2", props.getRevisionProperty().getValue());
+               assertEquals("MySubject", props.getSubjectProperty().getValue());
+               assertEquals("MyTitle", props.getTitleProperty().getValue());
+               assertEquals("2", props.getVersionProperty().getValue());
+       }
+}
index a7b9e7b6f660025dbdfd16be0d938a25e86e0ee2..01a44327c7b72335769cdea5bb2a394c91fc4b76 100755 (executable)
@@ -1,57 +1,57 @@
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.io.File;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;\r
-\r
-/**\r
- * Test the addition of thumbnail in a package.\r
- * \r
- * @author Julien Chable\r
- */\r
-public final class TestPackageThumbnail extends TestCase {\r
-\r
-       /**\r
-        * Test package addThumbnail() method.\r
-        */\r
-       public void testSetProperties() throws Exception {\r
-               String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageThumbnail.docx");\r
-\r
-               String imagePath = OpenXML4JTestDataSamples.getSampleFileName("thumbnail.jpg");\r
-\r
-               File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageThumbnailOUTPUT.docx");\r
-\r
-               // Open package\r
-               Package p = Package.open(inputPath, PackageAccess.READ_WRITE);\r
-               p.addThumbnail(imagePath);\r
-               // Save the package in the output directory\r
-               p.save(outputFile);\r
-\r
-               // Open the newly created file to check core properties saved values.\r
-               Package p2 = Package.open(outputFile.getAbsolutePath(), PackageAccess.READ);\r
-               if (p2.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL)\r
-                               .size() == 0)\r
-                       fail("Thumbnail not added to the package !");\r
-               p2.revert();\r
-               outputFile.delete();\r
-       }\r
-}\r
+/* ====================================================================
+   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.File;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
+
+/**
+ * Test the addition of thumbnail in a package.
+ * 
+ * @author Julien Chable
+ */
+public final class TestPackageThumbnail extends TestCase {
+
+       /**
+        * Test package addThumbnail() method.
+        */
+       public void testSetProperties() throws Exception {
+               String inputPath = OpenXML4JTestDataSamples.getSampleFileName("TestPackageThumbnail.docx");
+
+               String imagePath = OpenXML4JTestDataSamples.getSampleFileName("thumbnail.jpg");
+
+               File outputFile = OpenXML4JTestDataSamples.getOutputFile("TestPackageThumbnailOUTPUT.docx");
+
+               // Open package
+               OPCPackage p = OPCPackage.open(inputPath, PackageAccess.READ_WRITE);
+               p.addThumbnail(imagePath);
+               // Save the package in the output directory
+               p.save(outputFile);
+
+               // Open the newly created file to check core properties saved values.
+               OPCPackage p2 = OPCPackage.open(outputFile.getAbsolutePath(), PackageAccess.READ);
+               if (p2.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL)
+                               .size() == 0)
+                       fail("Thumbnail not added to the package !");
+               p2.revert();
+               outputFile.delete();
+       }
+}
index 478552f70f7eca3ac2b4011e5122595e01456590..48a4b4ecc16ee02b3422827cec74810e81bf5109 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-package org.apache.poi.openxml4j.opc;\r
-\r
-import java.net.URI;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.opc.ContentTypes;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackagePart;\r
-import org.apache.poi.openxml4j.opc.PackagePartName;\r
-import org.apache.poi.openxml4j.opc.PackagingURIHelper;\r
-\r
-public class TestPackagingURIHelper extends TestCase {\r
-\r
-       /**\r
-        * Test relativizePartName() method.\r
-     *\r
-     * TODO: fix and unable\r
-        */\r
-       public void testRelativizeURI() throws Exception {\r
-               URI uri1 = new URI("/word/document.xml");\r
-               URI uri2 = new URI("/word/media/image1.gif");\r
-               \r
-               // Document to image is down a directory\r
-               URI retURI1to2 = PackagingURIHelper.relativizeURI(uri1, uri2);\r
-               assertEquals("media/image1.gif", retURI1to2.getPath());\r
-               // Image to document is up a directory\r
-               URI retURI2to1 = PackagingURIHelper.relativizeURI(uri2, uri1);\r
-               assertEquals("../document.xml", retURI2to1.getPath());\r
-               \r
-               // Document and CustomXML parts totally different [Julien C.]\r
-               URI uriCustomXml = new URI("/customXml/item1.xml");\r
-               URI uriRes = PackagingURIHelper.relativizeURI(uri1, uriCustomXml);\r
-               assertEquals("../customXml/item1.xml", uriRes.toString());\r
-\r
-               // Document to itself is the same place (empty URI)\r
-               URI retURI2 = PackagingURIHelper.relativizeURI(uri1, uri1);\r
-               assertEquals("", retURI2.getPath());\r
-\r
-               // Document and root totally different\r
-               URI uri4 = new URI("/");\r
-               try {\r
-                       PackagingURIHelper.relativizeURI(uri1, uri4);\r
-                       //TODO: figure oout why the assertion fails\r
-            //fail("Must throw an exception ! Can't relativize with an empty URI");\r
-               } catch (Exception e) {\r
-                       // Do nothing\r
-               }\r
-               try {\r
-                       PackagingURIHelper.relativizeURI(uri4, uri1);\r
-            //TODO: figure oout why the assertion fails\r
-                       //fail("Must throw an exception ! Can't relativize with an empty URI");\r
-               } catch (Exception e) {\r
-                       // Do nothing\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Test createPartName(String, y)\r
-        */\r
-       public void testCreatePartNameRelativeString()\r
-                       throws InvalidFormatException {\r
-               PackagePartName partNameToValid = PackagingURIHelper\r
-                               .createPartName("/word/media/image1.gif");\r
-\r
-               Package pkg = Package.create("DELETEIFEXISTS.docx");\r
-               // Base part\r
-               PackagePartName nameBase = PackagingURIHelper\r
-                               .createPartName("/word/document.xml");\r
-               PackagePart partBase = pkg.createPart(nameBase, ContentTypes.XML);\r
-               // Relative part name\r
-               PackagePartName relativeName = PackagingURIHelper.createPartName(\r
-                               "media/image1.gif", partBase);\r
-               assertTrue("The part name must be equal to "\r
-                               + partNameToValid.getName(), partNameToValid\r
-                               .equals(relativeName));\r
-               pkg.revert();\r
-       }\r
-\r
-       /**\r
-        * Test createPartName(URI, y)\r
-        */\r
-       public void testCreatePartNameRelativeURI() throws Exception {\r
-               PackagePartName partNameToValid = PackagingURIHelper\r
-                               .createPartName("/word/media/image1.gif");\r
-\r
-               Package pkg = Package.create("DELETEIFEXISTS.docx");\r
-               // Base part\r
-               PackagePartName nameBase = PackagingURIHelper\r
-                               .createPartName("/word/document.xml");\r
-               PackagePart partBase = pkg.createPart(nameBase, ContentTypes.XML);\r
-               // Relative part name\r
-               PackagePartName relativeName = PackagingURIHelper.createPartName(\r
-                               new URI("media/image1.gif"), partBase);\r
-               assertTrue("The part name must be equal to "\r
-                               + partNameToValid.getName(), partNameToValid\r
-                               .equals(relativeName));\r
-               pkg.revert();\r
-       }\r
-}\r
+/* ====================================================================
+   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 junit.framework.TestCase;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.ContentTypes;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+
+public class TestPackagingURIHelper extends TestCase {
+
+       /**
+        * Test relativizePartName() method.
+     *
+     * TODO: fix and unable
+        */
+       public void testRelativizeURI() throws Exception {
+               URI uri1 = new URI("/word/document.xml");
+               URI uri2 = new URI("/word/media/image1.gif");
+               
+               // Document to image is down a directory
+               URI retURI1to2 = PackagingURIHelper.relativizeURI(uri1, uri2);
+               assertEquals("media/image1.gif", retURI1to2.getPath());
+               // Image to document is up a directory
+               URI retURI2to1 = PackagingURIHelper.relativizeURI(uri2, uri1);
+               assertEquals("../document.xml", retURI2to1.getPath());
+               
+               // Document and CustomXML parts totally different [Julien C.]
+               URI uriCustomXml = new URI("/customXml/item1.xml");
+               URI uriRes = PackagingURIHelper.relativizeURI(uri1, uriCustomXml);
+               assertEquals("../customXml/item1.xml", uriRes.toString());
+
+               // Document to itself is the same place (empty URI)
+               URI retURI2 = PackagingURIHelper.relativizeURI(uri1, uri1);
+               assertEquals("", retURI2.getPath());
+
+               // Document and root totally different
+               URI uri4 = new URI("/");
+               try {
+                       PackagingURIHelper.relativizeURI(uri1, uri4);
+                       //TODO: figure oout why the assertion fails
+            //fail("Must throw an exception ! Can't relativize with an empty URI");
+               } catch (Exception e) {
+                       // Do nothing
+               }
+               try {
+                       PackagingURIHelper.relativizeURI(uri4, uri1);
+            //TODO: figure oout why the assertion fails
+                       //fail("Must throw an exception ! Can't relativize with an empty URI");
+               } catch (Exception e) {
+                       // Do nothing
+               }
+       }
+
+       /**
+        * Test createPartName(String, y)
+        */
+       public void testCreatePartNameRelativeString()
+                       throws InvalidFormatException {
+               PackagePartName partNameToValid = PackagingURIHelper
+                               .createPartName("/word/media/image1.gif");
+
+               OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx");
+               // Base part
+               PackagePartName nameBase = PackagingURIHelper
+                               .createPartName("/word/document.xml");
+               PackagePart partBase = pkg.createPart(nameBase, ContentTypes.XML);
+               // Relative part name
+               PackagePartName relativeName = PackagingURIHelper.createPartName(
+                               "media/image1.gif", partBase);
+               assertTrue("The part name must be equal to "
+                               + partNameToValid.getName(), partNameToValid
+                               .equals(relativeName));
+               pkg.revert();
+       }
+
+       /**
+        * Test createPartName(URI, y)
+        */
+       public void testCreatePartNameRelativeURI() throws Exception {
+               PackagePartName partNameToValid = PackagingURIHelper
+                               .createPartName("/word/media/image1.gif");
+
+               OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx");
+               // Base part
+               PackagePartName nameBase = PackagingURIHelper
+                               .createPartName("/word/document.xml");
+               PackagePart partBase = pkg.createPart(nameBase, ContentTypes.XML);
+               // Relative part name
+               PackagePartName relativeName = PackagingURIHelper.createPartName(
+                               new URI("media/image1.gif"), partBase);
+               assertTrue("The part name must be equal to "
+                               + partNameToValid.getName(), partNameToValid
+                               .equals(relativeName));
+               pkg.revert();
+       }
+}
index 972bd268a3f988eedeeb964903fd5e9e4baf12de..a4ef876b478586dc2360d392ab4aba427193e62b 100755 (executable)
@@ -45,7 +45,7 @@ public class TestRelationships extends TestCase {
      */
     public void testLoadRelationships() throws Exception {
         InputStream is = OpenXML4JTestDataSamples.openSampleStream("sample.xlsx");
-        Package pkg = Package.open(is);
+        OPCPackage pkg = OPCPackage.open(is);
         logger.debug("1: " + pkg);
         PackageRelationshipCollection rels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
         PackageRelationship coreDocRelationship = rels.getRelationship(0);
@@ -66,7 +66,7 @@ public class TestRelationships extends TestCase {
      */
     public void testFetchFromCollection() throws Exception {
         InputStream is = OpenXML4JTestDataSamples.openSampleStream("ExcelWithHyperlinks.xlsx");
-        Package pkg = Package.open(is);
+        OPCPackage pkg = OPCPackage.open(is);
         PackagePart sheet = pkg.getPart(
                        PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS));
         assertNotNull(sheet);
@@ -107,7 +107,7 @@ public class TestRelationships extends TestCase {
      */
     public void testLoadExcelHyperlinkRelations() throws Exception {
         InputStream is = OpenXML4JTestDataSamples.openSampleStream("ExcelWithHyperlinks.xlsx");
-        Package pkg = Package.open(is);
+        OPCPackage pkg = OPCPackage.open(is);
            PackagePart sheet = pkg.getPart(
                        PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS));
            assertNotNull(sheet);
@@ -141,7 +141,7 @@ public class TestRelationships extends TestCase {
      */
     public void testCreateExcelHyperlinkRelations() throws Exception {
        String filepath = OpenXML4JTestDataSamples.getSampleFileName("ExcelWithHyperlinks.xlsx");
-           Package pkg = Package.open(filepath, PackageAccess.READ_WRITE);
+           OPCPackage pkg = OPCPackage.open(filepath, PackageAccess.READ_WRITE);
            PackagePart sheet = pkg.getPart(
                        PackagingURIHelper.createPartName(SHEET_WITH_COMMENTS));
            assertNotNull(sheet);
@@ -185,7 +185,7 @@ public class TestRelationships extends TestCase {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            pkg.save(baos);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-           pkg = Package.open(bais);
+           pkg = OPCPackage.open(bais);
            
            // Check again
            sheet = pkg.getPart(
@@ -208,7 +208,7 @@ public class TestRelationships extends TestCase {
 
     public void testCreateRelationsFromScratch() throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-       Package pkg = Package.create(baos);
+       OPCPackage pkg = OPCPackage.create(baos);
        
        PackagePart partA =
                pkg.createPart(PackagingURIHelper.createPartName("/partA"), "text/plain");
@@ -235,7 +235,7 @@ public class TestRelationships extends TestCase {
        // Save, and re-load
        pkg.close();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-       pkg = Package.open(bais);
+       pkg = OPCPackage.open(bais);
        
        partA = pkg.getPart(PackagingURIHelper.createPartName("/partA"));
        partB = pkg.getPart(PackagingURIHelper.createPartName("/partB"));
index d2cb8f616e314e7e195d902a15274ade9feda300..7d26fddd7af809afd3998a68618ce0df95c15e95 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.compliance;\r
-\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.net.URI;\r
-import java.net.URISyntaxException;\r
-\r
-import junit.framework.AssertionFailedError;\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.opc.ContentTypes;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;\r
-import org.apache.poi.openxml4j.opc.PackagingURIHelper;\r
-import org.apache.poi.openxml4j.opc.TargetMode;\r
-\r
-/**\r
- * Test core properties Open Packaging Convention compliance.\r
- * \r
- * M4.1: The format designer shall specify and the format producer shall create\r
- * at most one core properties relationship for a package. A format consumer\r
- * shall consider more than one core properties relationship for a package to be\r
- * an error. If present, the relationship shall target the Core Properties part.\r
- * \r
- * M4.2: The format designer shall not specify and the format producer shall not\r
- * create Core Properties that use the Markup Compatibility namespace as defined\r
- * in Annex F, "Standard Namespaces and Content Types". A format consumer shall\r
- * consider the use of the Markup Compatibility namespace to be an error.\r
- * \r
- * M4.3: Producers shall not create a document element that contains refinements\r
- * to the Dublin Core elements, except for the two specified in the schema:\r
- * <dcterms:created> and <dcterms:modified> Consumers shall consider a document\r
- * element that violates this constraint to be an error.\r
- * \r
- * M4.4: Producers shall not create a document element that contains the\r
- * xml:lang attribute. Consumers shall consider a document element that violates\r
- * this constraint to be an error.\r
- * \r
- * M4.5: Producers shall not create a document element that contains the\r
- * xsi:type attribute, except for a <dcterms:created> or <dcterms:modified>\r
- * element where the xsi:type attribute shall be present and shall hold the\r
- * value dcterms:W3CDTF, where dcterms is the namespace prefix of the Dublin\r
- * Core namespace. Consumers shall consider a document element that violates\r
- * this constraint to be an error.\r
- * \r
- * @author Julien Chable\r
- */\r
-public final class TestOPCComplianceCoreProperties extends TestCase {\r
-\r
-       public void testCorePropertiesPart() {\r
-               Package pkg;\r
-               try {\r
-                       InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");\r
-                       pkg = Package.open(is);\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               pkg.revert();\r
-       }\r
-\r
-       private static String extractInvalidFormatMessage(String sampleNameSuffix) {\r
-\r
-               InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_" + sampleNameSuffix);\r
-               Package pkg;\r
-               try {\r
-                       pkg = Package.open(is);\r
-               } catch (InvalidFormatException e) {\r
-                       // expected during successful test\r
-                       return e.getMessage();\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               pkg.revert();\r
-               // Normally must thrown an InvalidFormatException exception.\r
-               throw new AssertionFailedError("expected OPC compliance exception was not thrown");\r
-       }\r
-       \r
-       /**\r
-        * Test M4.1 rule.\r
-        */\r
-       public void testOnlyOneCorePropertiesPart() {\r
-               String msg = extractInvalidFormatMessage("OnlyOneCorePropertiesPartFAIL.docx");\r
-               assertEquals("OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !", msg);\r
-       }\r
-       \r
-       private static URI createURI(String text) {\r
-               try {\r
-                       return new URI(text);\r
-               } catch (URISyntaxException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Test M4.1 rule.\r
-        */\r
-       public void testOnlyOneCorePropertiesPart_AddRelationship() {\r
-               InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");\r
-               Package pkg;\r
-               try {\r
-                       pkg = Package.open(is);\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               URI partUri = createURI("/docProps/core2.xml");\r
-               try {\r
-                       pkg.addRelationship(PackagingURIHelper.createPartName(partUri), TargetMode.INTERNAL,\r
-                                       PackageRelationshipTypes.CORE_PROPERTIES);\r
-                       fail("expected OPC compliance exception was not thrown");\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               } catch (InvalidOperationException e) {\r
-                       // expected during successful test\r
-                       assertEquals("OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead.", e.getMessage());\r
-               }\r
-               pkg.revert();\r
-       }\r
-\r
-       /**\r
-        * Test M4.1 rule.\r
-        */\r
-       public void testOnlyOneCorePropertiesPart_AddPart() {\r
-               String sampleFileName = OpenXML4JTestDataSamples.getComplianceSampleFileName("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");\r
-               Package pkg = null;\r
-               try {\r
-                       pkg = Package.open(sampleFileName);\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               \r
-               URI partUri = createURI("/docProps/core2.xml");\r
-               try {\r
-                       pkg.createPart(PackagingURIHelper.createPartName(partUri),\r
-                                       ContentTypes.CORE_PROPERTIES_PART);\r
-                       fail("expected OPC compliance exception was not thrown");\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               } catch (InvalidOperationException e) {\r
-                       // expected during successful test\r
-                       assertEquals("OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !", e.getMessage());\r
-               }\r
-               pkg.revert();\r
-       }\r
-\r
-       /**\r
-        * Test M4.2 rule.\r
-        */\r
-       public void testDoNotUseCompatibilityMarkup() {\r
-               String msg = extractInvalidFormatMessage("DoNotUseCompatibilityMarkupFAIL.docx");\r
-               assertEquals("OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.", msg);\r
-       }\r
-\r
-       /**\r
-        * Test M4.3 rule.\r
-        */\r
-       public void testDCTermsNamespaceLimitedUse() {\r
-               String msg = extractInvalidFormatMessage("DCTermsNamespaceLimitedUseFAIL.docx");\r
-               assertEquals("OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error.", msg);\r
-       }\r
-\r
-       /**\r
-        * Test M4.4 rule.\r
-        */\r
-       public void testUnauthorizedXMLLangAttribute() {\r
-               String msg = extractInvalidFormatMessage("UnauthorizedXMLLangAttributeFAIL.docx");\r
-               assertEquals("OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error.", msg);\r
-       }\r
-\r
-       /**\r
-        * Test M4.5 rule.\r
-        */\r
-       public void testLimitedXSITypeAttribute_NotPresent() {\r
-               String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_NotPresentFAIL.docx");\r
-               assertEquals("The element 'created' must have the 'xsi:type' attribute present !", msg);\r
-       }\r
-\r
-       /**\r
-        * Test M4.5 rule.\r
-        */\r
-       public void testLimitedXSITypeAttribute_PresentWithUnauthorizedValue() {\r
-               String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx");\r
-               assertEquals("The element 'modified' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF' !", msg);\r
-       }\r
-}\r
+/* ====================================================================
+   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.compliance;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.opc.ContentTypes;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.TargetMode;
+
+/**
+ * Test core properties Open Packaging Convention compliance.
+ * 
+ * M4.1: The format designer shall specify and the format producer shall create
+ * at most one core properties relationship for a package. A format consumer
+ * shall consider more than one core properties relationship for a package to be
+ * an error. If present, the relationship shall target the Core Properties part.
+ * 
+ * M4.2: The format designer shall not specify and the format producer shall not
+ * create Core Properties that use the Markup Compatibility namespace as defined
+ * in Annex F, "Standard Namespaces and Content Types". A format consumer shall
+ * consider the use of the Markup Compatibility namespace to be an error.
+ * 
+ * M4.3: Producers shall not create a document element that contains refinements
+ * to the Dublin Core elements, except for the two specified in the schema:
+ * <dcterms:created> and <dcterms:modified> Consumers shall consider a document
+ * element that violates this constraint to be an error.
+ * 
+ * M4.4: Producers shall not create a document element that contains the
+ * xml:lang attribute. Consumers shall consider a document element that violates
+ * this constraint to be an error.
+ * 
+ * M4.5: Producers shall not create a document element that contains the
+ * xsi:type attribute, except for a <dcterms:created> or <dcterms:modified>
+ * element where the xsi:type attribute shall be present and shall hold the
+ * value dcterms:W3CDTF, where dcterms is the namespace prefix of the Dublin
+ * Core namespace. Consumers shall consider a document element that violates
+ * this constraint to be an error.
+ * 
+ * @author Julien Chable
+ */
+public final class TestOPCComplianceCoreProperties extends TestCase {
+
+       public void testCorePropertiesPart() {
+               OPCPackage pkg;
+               try {
+                       InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");
+                       pkg = OPCPackage.open(is);
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               pkg.revert();
+       }
+
+       private static String extractInvalidFormatMessage(String sampleNameSuffix) {
+
+               InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_" + sampleNameSuffix);
+               OPCPackage pkg;
+               try {
+                       pkg = OPCPackage.open(is);
+               } catch (InvalidFormatException e) {
+                       // expected during successful test
+                       return e.getMessage();
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               pkg.revert();
+               // Normally must thrown an InvalidFormatException exception.
+               throw new AssertionFailedError("expected OPC compliance exception was not thrown");
+       }
+       
+       /**
+        * Test M4.1 rule.
+        */
+       public void testOnlyOneCorePropertiesPart() {
+               String msg = extractInvalidFormatMessage("OnlyOneCorePropertiesPartFAIL.docx");
+               assertEquals("OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !", msg);
+       }
+       
+       private static URI createURI(String text) {
+               try {
+                       return new URI(text);
+               } catch (URISyntaxException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Test M4.1 rule.
+        */
+       public void testOnlyOneCorePropertiesPart_AddRelationship() {
+               InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");
+               OPCPackage pkg;
+               try {
+                       pkg = OPCPackage.open(is);
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               URI partUri = createURI("/docProps/core2.xml");
+               try {
+                       pkg.addRelationship(PackagingURIHelper.createPartName(partUri), TargetMode.INTERNAL,
+                                       PackageRelationshipTypes.CORE_PROPERTIES);
+                       fail("expected OPC compliance exception was not thrown");
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               } catch (InvalidOperationException e) {
+                       // expected during successful test
+                       assertEquals("OPC Compliance error [M4.1]: can't add another core properties part ! Use the built-in package method instead.", e.getMessage());
+               }
+               pkg.revert();
+       }
+
+       /**
+        * Test M4.1 rule.
+        */
+       public void testOnlyOneCorePropertiesPart_AddPart() {
+               String sampleFileName = OpenXML4JTestDataSamples.getComplianceSampleFileName("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");
+               OPCPackage pkg = null;
+               try {
+                       pkg = OPCPackage.open(sampleFileName);
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               }
+               
+               URI partUri = createURI("/docProps/core2.xml");
+               try {
+                       pkg.createPart(PackagingURIHelper.createPartName(partUri),
+                                       ContentTypes.CORE_PROPERTIES_PART);
+                       fail("expected OPC compliance exception was not thrown");
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               } catch (InvalidOperationException e) {
+                       // expected during successful test
+                       assertEquals("OPC Compliance error [M4.1]: you try to add more than one core properties relationship in the package !", e.getMessage());
+               }
+               pkg.revert();
+       }
+
+       /**
+        * Test M4.2 rule.
+        */
+       public void testDoNotUseCompatibilityMarkup() {
+               String msg = extractInvalidFormatMessage("DoNotUseCompatibilityMarkupFAIL.docx");
+               assertEquals("OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.", msg);
+       }
+
+       /**
+        * Test M4.3 rule.
+        */
+       public void testDCTermsNamespaceLimitedUse() {
+               String msg = extractInvalidFormatMessage("DCTermsNamespaceLimitedUseFAIL.docx");
+               assertEquals("OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error.", msg);
+       }
+
+       /**
+        * Test M4.4 rule.
+        */
+       public void testUnauthorizedXMLLangAttribute() {
+               String msg = extractInvalidFormatMessage("UnauthorizedXMLLangAttributeFAIL.docx");
+               assertEquals("OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error.", msg);
+       }
+
+       /**
+        * Test M4.5 rule.
+        */
+       public void testLimitedXSITypeAttribute_NotPresent() {
+               String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_NotPresentFAIL.docx");
+               assertEquals("The element 'created' must have the 'xsi:type' attribute present !", msg);
+       }
+
+       /**
+        * Test M4.5 rule.
+        */
+       public void testLimitedXSITypeAttribute_PresentWithUnauthorizedValue() {
+               String msg = extractInvalidFormatMessage("LimitedXSITypeAttribute_PresentWithUnauthorizedValueFAIL.docx");
+               assertEquals("The element 'modified' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF' !", msg);
+       }
+}
index f135b413889f13ab9fa2211afaec6f676402ac8a..332642f69af646e50e8d3875a39e2b8f8a7cc85f 100755 (executable)
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.openxml4j.opc.compliance;\r
-\r
-import java.io.File;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.exceptions.InvalidOperationException;\r
-import org.apache.poi.openxml4j.opc.ContentTypes;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-import org.apache.poi.openxml4j.opc.PackagePartName;\r
-import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;\r
-import org.apache.poi.openxml4j.opc.PackagingURIHelper;\r
-import org.apache.poi.openxml4j.opc.TargetMode;\r
-\r
-/**\r
- * Test Open Packaging Convention package model compliance.\r
- * \r
- * M1.11 : A package implementer shall neither create nor recognize a part with\r
- * a part name derived from another part name by appending segments to it.\r
- * \r
- * @author Julien Chable\r
- */\r
-public class TestOPCCompliancePackageModel extends TestCase {\r
-\r
-       public TestOPCCompliancePackageModel(String name) {\r
-               super(name);\r
-       }\r
-\r
-       /**\r
-        * A package implementer shall neither create nor recognize a part with a\r
-        * part name derived from another part name by appending segments to it.\r
-        * [M1.11]\r
-        */\r
-       public void testPartNameDerivationAdditionFailure() {\r
-               Package pkg = Package.create("TODELETEIFEXIST.docx");\r
-               try {\r
-                       PackagePartName name = PackagingURIHelper\r
-                                       .createPartName("/word/document.xml");\r
-                       PackagePartName nameDerived = PackagingURIHelper\r
-                                       .createPartName("/word/document.xml/image1.gif");\r
-                       pkg.createPart(name, ContentTypes.XML);\r
-                       pkg.createPart(nameDerived, ContentTypes.EXTENSION_GIF);\r
-               } catch (InvalidOperationException e) {\r
-                       pkg.revert();\r
-                       return;\r
-               } catch (InvalidFormatException e) {\r
-                       fail(e.getMessage());\r
-               }\r
-               fail("A package implementer shall neither create nor recognize a part with a"\r
-                               + " part name derived from another part name by appending segments to it."\r
-                               + " [M1.11]");\r
-       }\r
-\r
-       /**\r
-        * A package implementer shall neither create nor recognize a part with a\r
-        * part name derived from another part name by appending segments to it.\r
-        * [M1.11]\r
-        */\r
-       public void testPartNameDerivationReadingFailure() {\r
-               String filepath = System.getProperty("openxml4j.compliance.input")\r
-                               + File.separator + "OPCCompliance_DerivedPartNameFAIL.docx";\r
-               try {\r
-                       Package.open(filepath);\r
-               } catch (InvalidFormatException e) {\r
-                       return;\r
-               }\r
-               fail("A package implementer shall neither create nor recognize a part with a"\r
-                               + " part name derived from another part name by appending segments to it."\r
-                               + " [M1.11]");\r
-       }\r
-\r
-       /**\r
-        * Rule M1.12 : Packages shall not contain equivalent part names and package\r
-        * implementers shall neither create nor recognize packages with equivalent\r
-        * part names.\r
-        */\r
-       public void testAddPackageAlreadyAddFailure() throws Exception {\r
-               Package pkg = Package.create("DELETEIFEXISTS.docx");\r
-               PackagePartName name1 = null;\r
-               PackagePartName name2 = null;\r
-               try {\r
-                       name1 = PackagingURIHelper.createPartName("/word/document.xml");\r
-                       name2 = PackagingURIHelper.createPartName("/word/document.xml");\r
-               } catch (InvalidFormatException e) {\r
-                       throw new Exception(e.getMessage());\r
-               }\r
-               pkg.createPart(name1, ContentTypes.XML);\r
-               try {\r
-                       pkg.createPart(name2, ContentTypes.XML);\r
-               } catch (InvalidOperationException e) {\r
-                       return;\r
-               }\r
-               fail("Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");\r
-       }\r
-\r
-       /**\r
-        * Rule M1.12 : Packages shall not contain equivalent part names and package\r
-        * implementers shall neither create nor recognize packages with equivalent\r
-        * part names.\r
-        */\r
-       public void testAddPackageAlreadyAddFailure2() throws Exception {\r
-               Package pkg = Package.create("DELETEIFEXISTS.docx");\r
-               PackagePartName partName = null;\r
-               try {\r
-                       partName = PackagingURIHelper.createPartName("/word/document.xml");\r
-               } catch (InvalidFormatException e) {\r
-                       throw new Exception(e.getMessage());\r
-               }\r
-               pkg.createPart(partName, ContentTypes.XML);\r
-               try {\r
-                       pkg.createPart(partName, ContentTypes.XML);\r
-               } catch (InvalidOperationException e) {\r
-                       return;\r
-               }\r
-               fail("Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");\r
-       }\r
-\r
-       /**\r
-        * Try to add a relationship to a relationship part.\r
-        * \r
-        * Check rule M1.25: The Relationships part shall not have relationships to\r
-        * any other part. Package implementers shall enforce this requirement upon\r
-        * the attempt to create such a relationship and shall treat any such\r
-        * relationship as invalid.\r
-        */\r
-       public void testAddRelationshipRelationshipsPartFailure() {\r
-               Package pkg = Package.create("DELETEIFEXISTS.docx");\r
-               PackagePartName name1 = null;\r
-               try {\r
-                       name1 = PackagingURIHelper\r
-                                       .createPartName("/test/_rels/document.xml.rels");\r
-               } catch (InvalidFormatException e) {\r
-                       fail("This exception should never happen !");\r
-               }\r
-\r
-               try {\r
-                       pkg.addRelationship(name1, TargetMode.INTERNAL,\r
-                                       PackageRelationshipTypes.CORE_DOCUMENT);\r
-               } catch (InvalidOperationException e) {\r
-                       return;\r
-               }\r
-               fail("Fail test -> M1.25: The Relationships part shall not have relationships to any other part");\r
-       }\r
-}\r
+/* ====================================================================
+   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.compliance;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
+import org.apache.poi.openxml4j.opc.ContentTypes;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePartName;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.TargetMode;
+
+/**
+ * Test Open Packaging Convention package model compliance.
+ * 
+ * M1.11 : A package implementer shall neither create nor recognize a part with
+ * a part name derived from another part name by appending segments to it.
+ * 
+ * @author Julien Chable
+ */
+public class TestOPCCompliancePackageModel extends TestCase {
+
+       public TestOPCCompliancePackageModel(String name) {
+               super(name);
+       }
+
+       /**
+        * A package implementer shall neither create nor recognize a part with a
+        * part name derived from another part name by appending segments to it.
+        * [M1.11]
+        */
+       public void testPartNameDerivationAdditionFailure() {
+               OPCPackage pkg = OPCPackage.create("TODELETEIFEXIST.docx");
+               try {
+                       PackagePartName name = PackagingURIHelper
+                                       .createPartName("/word/document.xml");
+                       PackagePartName nameDerived = PackagingURIHelper
+                                       .createPartName("/word/document.xml/image1.gif");
+                       pkg.createPart(name, ContentTypes.XML);
+                       pkg.createPart(nameDerived, ContentTypes.EXTENSION_GIF);
+               } catch (InvalidOperationException e) {
+                       pkg.revert();
+                       return;
+               } catch (InvalidFormatException e) {
+                       fail(e.getMessage());
+               }
+               fail("A package implementer shall neither create nor recognize a part with a"
+                               + " part name derived from another part name by appending segments to it."
+                               + " [M1.11]");
+       }
+
+       /**
+        * A package implementer shall neither create nor recognize a part with a
+        * part name derived from another part name by appending segments to it.
+        * [M1.11]
+        */
+       public void testPartNameDerivationReadingFailure() {
+               String filepath = System.getProperty("openxml4j.compliance.input")
+                               + File.separator + "OPCCompliance_DerivedPartNameFAIL.docx";
+               try {
+                       OPCPackage.open(filepath);
+               } catch (InvalidFormatException e) {
+                       return;
+               }
+               fail("A package implementer shall neither create nor recognize a part with a"
+                               + " part name derived from another part name by appending segments to it."
+                               + " [M1.11]");
+       }
+
+       /**
+        * Rule M1.12 : Packages shall not contain equivalent part names and package
+        * implementers shall neither create nor recognize packages with equivalent
+        * part names.
+        */
+       public void testAddPackageAlreadyAddFailure() throws Exception {
+               OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx");
+               PackagePartName name1 = null;
+               PackagePartName name2 = null;
+               try {
+                       name1 = PackagingURIHelper.createPartName("/word/document.xml");
+                       name2 = PackagingURIHelper.createPartName("/word/document.xml");
+               } catch (InvalidFormatException e) {
+                       throw new Exception(e.getMessage());
+               }
+               pkg.createPart(name1, ContentTypes.XML);
+               try {
+                       pkg.createPart(name2, ContentTypes.XML);
+               } catch (InvalidOperationException e) {
+                       return;
+               }
+               fail("Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");
+       }
+
+       /**
+        * Rule M1.12 : Packages shall not contain equivalent part names and package
+        * implementers shall neither create nor recognize packages with equivalent
+        * part names.
+        */
+       public void testAddPackageAlreadyAddFailure2() throws Exception {
+               OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx");
+               PackagePartName partName = null;
+               try {
+                       partName = PackagingURIHelper.createPartName("/word/document.xml");
+               } catch (InvalidFormatException e) {
+                       throw new Exception(e.getMessage());
+               }
+               pkg.createPart(partName, ContentTypes.XML);
+               try {
+                       pkg.createPart(partName, ContentTypes.XML);
+               } catch (InvalidOperationException e) {
+                       return;
+               }
+               fail("Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12]");
+       }
+
+       /**
+        * Try to add a relationship to a relationship 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.
+        */
+       public void testAddRelationshipRelationshipsPartFailure() {
+               OPCPackage pkg = OPCPackage.create("DELETEIFEXISTS.docx");
+               PackagePartName name1 = null;
+               try {
+                       name1 = PackagingURIHelper
+                                       .createPartName("/test/_rels/document.xml.rels");
+               } catch (InvalidFormatException e) {
+                       fail("This exception should never happen !");
+               }
+
+               try {
+                       pkg.addRelationship(name1, TargetMode.INTERNAL,
+                                       PackageRelationshipTypes.CORE_DOCUMENT);
+               } catch (InvalidOperationException e) {
+                       return;
+               }
+               fail("Fail test -> M1.25: The Relationships part shall not have relationships to any other part");
+       }
+}
index f1553e0e16aa725394bdb36faccbb3ab69b75a53..af93ba9aa544ceb164ef0a61af32416188ab0298 100644 (file)
@@ -24,7 +24,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 
 import junit.framework.TestCase;
 
@@ -63,7 +63,7 @@ public class TestWorkbookFactory extends TestCase {
                
                // Package -> xssf
                wb = WorkbookFactory.create(
-                               Package.open(xlsx.toString())
+                               OPCPackage.open(xlsx.toString())
                );
                assertNotNull(wb);
                assertTrue(wb instanceof XSSFWorkbook);
index 13971f7efe094771281d1efbf0431a5c07c61dcd..e1e821323caaccc41b7e797285dda0349e02c7a6 100644 (file)
@@ -18,14 +18,14 @@ package org.apache.poi.xslf;
 
 import java.io.File;
 
+import junit.framework.TestCase;
+
 import org.apache.poi.POIXMLDocument;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
 
-import junit.framework.TestCase;
-
 public class TestXSLFSlideShow extends TestCase {
        private String sampleFile;
 
@@ -39,7 +39,7 @@ public class TestXSLFSlideShow extends TestCase {
        }
 
        public void testContainsMainContentType() throws Exception {
-               Package pack = POIXMLDocument.openPackage(sampleFile);
+               OPCPackage pack = POIXMLDocument.openPackage(sampleFile);
                
                boolean found = false;
                for(PackagePart part : pack.getParts()) {
index 5214a22a2e76e32eee7a1f27a1880e28d0553c61..6c37c7086f017798094b89102aaeb2f129820df2 100644 (file)
@@ -1,75 +1,80 @@
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.xssf;\r
-\r
-import java.io.*;\r
-\r
-import org.apache.poi.hssf.HSSFTestDataSamples;\r
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;\r
-import org.apache.poi.ss.usermodel.Workbook;\r
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;\r
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
-import org.apache.poi.openxml4j.opc.Package;\r
-\r
-/**\r
- * Centralises logic for finding/opening sample files in the src/testcases/org/apache/poi/hssf/hssf/data folder. \r
- * \r
- * @author Josh Micich\r
- */\r
-public class XSSFTestDataSamples {\r
-       public static final XSSFWorkbook openSampleWorkbook(String sampleName) {\r
-               InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleName);\r
-               try {\r
-                       Package pkg = Package.open(is);\r
-                       return new XSSFWorkbook(pkg);\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-       }\r
-    public static <R extends Workbook> R writeOutAndReadBack(R wb) {\r
-       Workbook result;\r
-               try {\r
-               if (wb instanceof HSSFWorkbook) {\r
-                ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);\r
-                wb.write(baos);\r
-                InputStream is = new ByteArrayInputStream(baos.toByteArray());\r
-                       result = new HSSFWorkbook(is);\r
-               } else if (wb instanceof XSSFWorkbook) {\r
-                File tmp = File.createTempFile("poi-ooxml-", ".xlsx");\r
-                tmp.deleteOnExit();\r
-                FileOutputStream out = new FileOutputStream(tmp);\r
-                wb.write(out);\r
-                out.close();\r
-                       Package pkg = Package.open(tmp.getAbsolutePath());\r
-                       result = new XSSFWorkbook(pkg);\r
-               } else {\r
-                       throw new RuntimeException("Unexpected workbook type (" \r
-                                       + wb.getClass().getName() + ")");\r
-               }\r
-               } catch (InvalidFormatException e) {\r
-                       throw new RuntimeException(e);\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               @SuppressWarnings("unchecked")\r
-               R r = (R) result;\r
-               return r;\r
-    }\r
-}\r
+/* ====================================================================
+   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.xssf;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+/**
+ * Centralises logic for finding/opening sample files in the src/testcases/org/apache/poi/hssf/hssf/data folder. 
+ * 
+ * @author Josh Micich
+ */
+public class XSSFTestDataSamples {
+       public static final XSSFWorkbook openSampleWorkbook(String sampleName) {
+               InputStream is = HSSFTestDataSamples.openSampleFileStream(sampleName);
+               try {
+                       OPCPackage pkg = OPCPackage.open(is);
+                       return new XSSFWorkbook(pkg);
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+    public static <R extends Workbook> R writeOutAndReadBack(R wb) {
+       Workbook result;
+               try {
+               if (wb instanceof HSSFWorkbook) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
+                wb.write(baos);
+                InputStream is = new ByteArrayInputStream(baos.toByteArray());
+                       result = new HSSFWorkbook(is);
+               } else if (wb instanceof XSSFWorkbook) {
+                File tmp = File.createTempFile("poi-ooxml-", ".xlsx");
+                tmp.deleteOnExit();
+                FileOutputStream out = new FileOutputStream(tmp);
+                wb.write(out);
+                out.close();
+                OPCPackage pkg = OPCPackage.open(tmp.getAbsolutePath());
+                       result = new XSSFWorkbook(pkg);
+               } else {
+                       throw new RuntimeException("Unexpected workbook type (" 
+                                       + wb.getClass().getName() + ")");
+               }
+               } catch (InvalidFormatException e) {
+                       throw new RuntimeException(e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               @SuppressWarnings("unchecked")
+               R r = (R) result;
+               return r;
+    }
+}
index 9ad4af7baaed9c1d66e5d351a6ccf303d5a66bdc..567cd014ea7548195b954b1ee74a729fb5268452 100644 (file)
@@ -25,7 +25,7 @@ import junit.framework.TestCase;
 
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.usermodel.XSSFRichTextString;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 
 /**
  * Tests for XSSFReader
@@ -49,7 +49,7 @@ public class TestXSSFReader extends TestCase {
     
     public void testGetBits() throws Exception {
        File f = new File(dirName, "SampleSS.xlsx");
-       Package pkg = Package.open(f.toString());
+       OPCPackage pkg = OPCPackage.open(f.toString());
        
        XSSFReader r = new XSSFReader(pkg);
        
@@ -63,7 +63,7 @@ public class TestXSSFReader extends TestCase {
     
     public void testStyles() throws Exception {
        File f = new File(dirName, "SampleSS.xlsx");
-       Package pkg = Package.open(f.toString());
+       OPCPackage pkg = OPCPackage.open(f.toString());
        
        XSSFReader r = new XSSFReader(pkg);
        
@@ -73,7 +73,7 @@ public class TestXSSFReader extends TestCase {
     
     public void testStrings() throws Exception {
        File f = new File(dirName, "SampleSS.xlsx");
-       Package pkg = Package.open(f.toString());
+       OPCPackage pkg = OPCPackage.open(f.toString());
        
        XSSFReader r = new XSSFReader(pkg);
        
@@ -83,7 +83,7 @@ public class TestXSSFReader extends TestCase {
     
     public void testSheets() throws Exception {
        File f = new File(dirName, "SampleSS.xlsx");
-       Package pkg = Package.open(f.toString());
+       OPCPackage pkg = OPCPackage.open(f.toString());
        
        XSSFReader r = new XSSFReader(pkg);
        byte[] data = new byte[4096]; 
@@ -116,7 +116,7 @@ public class TestXSSFReader extends TestCase {
      */
     public void testOrderOfSheets() throws Exception {
         File f = new File(dirName, "reordered_sheets.xlsx");
-        Package pkg = Package.open(f.toString());
+        OPCPackage pkg = OPCPackage.open(f.toString());
 
         XSSFReader r = new XSSFReader(pkg);
 
index 062a93e7c07da6facab3398238ddc3d710d56893..05a85fc5487ad98920f3e7f99d306e88f49bda49 100644 (file)
@@ -32,7 +32,7 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
 
 import junit.framework.TestCase;
@@ -125,7 +125,7 @@ public class TestCommentsTable extends TestCase {
                );
                assertTrue(xml.exists());
        
-               Package pkg = Package.open(xml.toString());
+               OPCPackage pkg = OPCPackage.open(xml.toString());
                XSSFWorkbook wb = new XSSFWorkbook(pkg);
         List<POIXMLDocumentPart> rels = wb.getSheetAt(0).getRelations();
         CommentsTable ct = null;
index 01160f23f5f3c0b351d9194cafe53ee5f4315160..b6182cb418190fe01cc2b6ba7ecf598cf572ad64 100644 (file)
@@ -32,7 +32,7 @@ import org.apache.poi.ss.usermodel.CellValue;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 
 /**
  * Performs much the same role as {@link TestFormulasFromSpreadsheet},
@@ -149,7 +149,7 @@ public final class TestFormulaEvaluatorOnXSSF extends TestCase {
        protected void setUp() throws Exception {
                if (workbook == null) {
                        InputStream is = HSSFTestDataSamples.openSampleFileStream(SS.FILENAME);
-                       Package pkg = Package.open(is);
+                       OPCPackage pkg = OPCPackage.open(is);
                        workbook = new XSSFWorkbook( pkg );
                        sheet = workbook.getSheetAt( 0 );
                  }
index b35d59c5b480745db8e57885adf6521ee9d6316c..3715410ef9541988effc2d6951a66eb2c47966c0 100644 (file)
@@ -21,7 +21,8 @@ import java.io.File;
 
 import junit.framework.TestCase;
 
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -71,7 +72,7 @@ public class TestXSSFBugs extends TestCase {
      * We should carry vba macros over after save
      */
     public void test45431() throws Exception {
-        Package pkg = Package.open(getFilePath("45431.xlsm"));
+        OPCPackage pkg = OPCPackage.open(getFilePath("45431.xlsm"));
         XSSFWorkbook wb = new XSSFWorkbook(pkg);
         assertTrue(wb.isMacroEnabled());
 
@@ -89,7 +90,7 @@ public class TestXSSFBugs extends TestCase {
 
         // Save and re-open, both still there
         XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
-        Package nPkg = nwb.getPackage();
+        OPCPackage nPkg = nwb.getPackage();
         assertTrue(nwb.isMacroEnabled());
 
         vba = nPkg.getPart(
index e4d6bc091fbd6c4146329c20eae7d3bb447fd508..8b721b6199232d9f268b1716f48b952dc294c3bc 100755 (executable)
@@ -1,77 +1,79 @@
-/* ====================================================================\r
-   Licensed to the Apache Software Foundation (ASF) under one or more\r
-   contributor license agreements.  See the NOTICE file distributed with\r
-   this work for additional information regarding copyright ownership.\r
-   The ASF licenses this file to You under the Apache License, Version 2.0\r
-   (the "License"); you may not use this file except in compliance with\r
-   the License.  You may obtain a copy of the License at\r
-\r
-       http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-==================================================================== */\r
-package org.apache.poi.xssf.usermodel;\r
-\r
-import junit.framework.TestCase;\r
-import org.apache.poi.xssf.XSSFTestDataSamples;\r
-import org.apache.poi.POIXMLDocumentPart;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * @author Yegor Kozlov\r
- */\r
-public class TestXSSFDrawing extends TestCase {\r
-    public void testRead(){\r
-        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");\r
-        XSSFSheet sheet = wb.getSheetAt(0);\r
-        //the sheet has one relationship and it is XSSFDrawing\r
-        List<POIXMLDocumentPart> rels = sheet.getRelations();\r
-        assertEquals(1, rels.size());\r
-        assertTrue(rels.get(0) instanceof XSSFDrawing);\r
-\r
-        XSSFDrawing drawing = (XSSFDrawing)rels.get(0);\r
-        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing\r
-        assertSame(drawing, sheet.createDrawingPatriarch());\r
-        String drawingId = drawing.getPackageRelationship().getId();\r
-\r
-        //there should be a relation to this drawing in the worksheet\r
-        assertTrue(sheet.getCTWorksheet().isSetDrawing());\r
-        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());\r
-\r
-    }\r
-\r
-    public void testNew(){\r
-        XSSFWorkbook wb = new XSSFWorkbook();\r
-        XSSFSheet sheet = wb.createSheet();\r
-        //multiple calls of createDrawingPatriarch should return the same instance of XSSFDrawing\r
-        XSSFDrawing dr1 = sheet.createDrawingPatriarch();\r
-        XSSFDrawing dr2 = sheet.createDrawingPatriarch();\r
-        assertSame(dr1, dr2);\r
-\r
-        List<POIXMLDocumentPart> rels = sheet.getRelations();\r
-        assertEquals(1, rels.size());\r
-        assertTrue(rels.get(0) instanceof XSSFDrawing);\r
-\r
-        XSSFDrawing drawing = (XSSFDrawing)rels.get(0);\r
-        String drawingId = drawing.getPackageRelationship().getId();\r
-\r
-        //there should be a relation to this drawing in the worksheet\r
-        assertTrue(sheet.getCTWorksheet().isSetDrawing());\r
-        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());\r
-\r
-    }\r
-    public void testMultipleDrawings(){\r
-        XSSFWorkbook wb = new XSSFWorkbook();\r
-        for (int i = 0; i < 3; i++) {\r
-            XSSFSheet sheet = wb.createSheet();\r
-            XSSFDrawing drawing = sheet.createDrawingPatriarch();\r
-        }\r
-        org.apache.poi.openxml4j.opc.Package pkg = wb.getPackage();\r
-        assertEquals(3, pkg.getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size());\r
-    }\r
-}\r
+/* ====================================================================
+   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.xssf.usermodel;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+
+/**
+ * @author Yegor Kozlov
+ */
+public class TestXSSFDrawing extends TestCase {
+    public void testRead(){
+        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
+        XSSFSheet sheet = wb.getSheetAt(0);
+        //the sheet has one relationship and it is XSSFDrawing
+        List<POIXMLDocumentPart> rels = sheet.getRelations();
+        assertEquals(1, rels.size());
+        assertTrue(rels.get(0) instanceof XSSFDrawing);
+
+        XSSFDrawing drawing = (XSSFDrawing)rels.get(0);
+        //sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
+        assertSame(drawing, sheet.createDrawingPatriarch());
+        String drawingId = drawing.getPackageRelationship().getId();
+
+        //there should be a relation to this drawing in the worksheet
+        assertTrue(sheet.getCTWorksheet().isSetDrawing());
+        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());
+
+    }
+
+    public void testNew(){
+        XSSFWorkbook wb = new XSSFWorkbook();
+        XSSFSheet sheet = wb.createSheet();
+        //multiple calls of createDrawingPatriarch should return the same instance of XSSFDrawing
+        XSSFDrawing dr1 = sheet.createDrawingPatriarch();
+        XSSFDrawing dr2 = sheet.createDrawingPatriarch();
+        assertSame(dr1, dr2);
+
+        List<POIXMLDocumentPart> rels = sheet.getRelations();
+        assertEquals(1, rels.size());
+        assertTrue(rels.get(0) instanceof XSSFDrawing);
+
+        XSSFDrawing drawing = (XSSFDrawing)rels.get(0);
+        String drawingId = drawing.getPackageRelationship().getId();
+
+        //there should be a relation to this drawing in the worksheet
+        assertTrue(sheet.getCTWorksheet().isSetDrawing());
+        assertEquals(drawingId, sheet.getCTWorksheet().getDrawing().getId());
+
+    }
+    public void testMultipleDrawings(){
+        XSSFWorkbook wb = new XSSFWorkbook();
+        for (int i = 0; i < 3; i++) {
+            XSSFSheet sheet = wb.createSheet();
+            XSSFDrawing drawing = sheet.createDrawingPatriarch();
+        }
+        OPCPackage pkg = wb.getPackage();
+        assertEquals(3, pkg.getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size());
+    }
+}
index 09acaac09e46e7ef220d18eb3fe2490b2cf7ac22..73c181bd2bbb9f4c9ba525c62512c40dbdcc2354 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.model.StylesTable;
 import org.apache.poi.openxml4j.opc.ContentTypes;
-import org.apache.poi.openxml4j.opc.Package;
+import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
@@ -251,7 +251,7 @@ public final class TestXSSFWorkbook extends TestCase {
                out.close();
                
                // Check the package contains what we'd expect it to
-               Package pkg = Package.open(file.toString());
+               OPCPackage pkg = OPCPackage.open(file.toString());
                PackagePart wbRelPart = 
                        pkg.getPart(PackagingURIHelper.createPartName("/xl/_rels/workbook.xml.rels"));
                assertNotNull(wbRelPart);
@@ -293,7 +293,7 @@ public final class TestXSSFWorkbook extends TestCase {
                assertNotNull(workbook.getStylesSource());
                
                // And check a few low level bits too
-               Package pkg = Package.open(HSSFTestDataSamples.openSampleFileStream("Formatting.xlsx"));
+               OPCPackage pkg = OPCPackage.open(HSSFTestDataSamples.openSampleFileStream("Formatting.xlsx"));
                PackagePart wbPart = 
                        pkg.getPart(PackagingURIHelper.createPartName("/xl/workbook.xml"));
                
index 24fbfcc8952bc62c32e60e07db0772d4e1187404..68df95786cdb05d1f8bf60b07f4d1ecb1bff0175 100644 (file)
@@ -18,13 +18,13 @@ package org.apache.poi.xwpf;
 
 import java.io.File;
 
+import junit.framework.TestCase;
+
 import org.apache.poi.POIXMLDocument;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.apache.poi.xwpf.usermodel.XWPFRelation;
-import org.apache.poi.openxml4j.opc.Package;
-import org.apache.poi.openxml4j.opc.PackagePart;
-
-import junit.framework.TestCase;
 
 public class TestXWPFDocument extends TestCase {
        private File sampleFile;
@@ -47,7 +47,7 @@ public class TestXWPFDocument extends TestCase {
        }
 
        public void testContainsMainContentType() throws Exception {
-               Package pack = POIXMLDocument.openPackage(sampleFile.toString());
+               OPCPackage pack = POIXMLDocument.openPackage(sampleFile.toString());
                
                boolean found = false;
                for(PackagePart part : pack.getParts()) {