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;
*/
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();
}
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();
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;
}
* 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;
}
* @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) {
* 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);
-/* ====================================================================\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{
+
+ }
+
+}
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
* Writes out the ooxml properties into the supplied,
* new Package
*/
- public void write(Package pkg) {
+ public void write(OPCPackage pkg) {
// TODO
}
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;
* 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;
}
}
OOXMLLister lister = new OOXMLLister(
- Package.open(f.toString(), PackageAccess.READ)
+ OPCPackage.open(f.toString(), PackageAccess.READ)
);
lister.disp.println(f.toString() + "\n");
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;
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
}
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");
}
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) {
--- /dev/null
+/* ====================================================================
+ 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;
+}
-/* ====================================================================\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);
+ }
+ }
+
+
+}
-/* ====================================================================\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();
+}
-/* ====================================================================\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);
+}
-/* ====================================================================\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();
+ }
+}
-/* ====================================================================\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 + "]";
+ }
+}
-/* ====================================================================\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 !");
+ }
+}
-/* ====================================================================\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 §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 §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 §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 §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);
+}
-/* ====================================================================\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
+ }
+}
-/* ====================================================================\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
+ }
+}
-/* ====================================================================\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;
+ }
+}
-/* ====================================================================\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;
+ }
+}
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
/**
* 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);
}
/**
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");
}
-/* ====================================================================\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());
+ }
+}
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;
*/
private List<PackagePart> embedds;
- public XSLFSlideShow(Package container) throws OpenXML4JException, IOException, XmlException {
+ public XSLFSlideShow(OPCPackage container) throws OpenXML4JException, IOException, XmlException {
super(container);
presentationDoc =
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;
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));
}
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
* 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(
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;
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
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) {
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;
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;
*
* @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
/**
* 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
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
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) {
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;
/** 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
/**
* 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
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;
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);
}
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);
}
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);
}
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;
}
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);
}
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);
}
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);
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
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
-/* ====================================================================\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));
+ }
+ }
+}
-/* ====================================================================\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);
+ }
+}
-/* ====================================================================\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());
+ }
+}
-/* ====================================================================\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();
+ }
+}
-/* ====================================================================\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();
+ }
+}
*/
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);
*/
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);
*/
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);
*/
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);
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(
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");
// 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"));
-/* ====================================================================\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);
+ }
+}
-/* ====================================================================\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");
+ }
+}
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;
// Package -> xssf
wb = WorkbookFactory.create(
- Package.open(xlsx.toString())
+ OPCPackage.open(xlsx.toString())
);
assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook);
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;
}
public void testContainsMainContentType() throws Exception {
- Package pack = POIXMLDocument.openPackage(sampleFile);
+ OPCPackage pack = POIXMLDocument.openPackage(sampleFile);
boolean found = false;
for(PackagePart part : pack.getParts()) {
-/* ====================================================================\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;
+ }
+}
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
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);
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);
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);
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];
*/
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);
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;
);
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;
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},
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 );
}
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;
* 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());
// 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(
-/* ====================================================================\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());
+ }
+}
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;
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);
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"));
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;
}
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()) {