import OpenXML4j codebase
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@738842 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
980ff2cf30
commit
ef4b2ebc2e
25
build.xml
25
build.xml
@ -124,8 +124,6 @@ under the License.
|
||||
<property name="ooxml.testokfile" location="build/ooxml-testokfile.txt"/>
|
||||
|
||||
<!-- The following jars are downloaded by the fetch-ooxml-jars task -->
|
||||
<property name="ooxml.openxml4j.jar" location="${ooxml.lib}/openxml4j-1.0-beta.jar"/>
|
||||
<property name="ooxml.openxml4j.url" value="http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/poi/openxml4j/1.0-beta/openxml4j-1.0-beta.jar"/>
|
||||
<property name="ooxml.dom4j.jar" location="${ooxml.lib}/dom4j-1.6.1.jar"/>
|
||||
<property name="ooxml.dom4j.url" value="${repository}/dom4j/jars/dom4j-1.6.1.jar"/>
|
||||
<property name="ooxml.xmlbeans.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
|
||||
@ -144,8 +142,6 @@ under the License.
|
||||
|
||||
<property name="maven.ooxml.xsds.version.id" value="1.0"/>
|
||||
<property name="maven.ooxml.xsds.jar" value="ooxml-schemas-${maven.ooxml.xsds.version.id}.jar"/>
|
||||
<property name="maven.openxml4j.version.id" value="1.0-beta"/>
|
||||
<property name="maven.openxml4j.jar" value="openxml4j-${maven.openxml4j.version.id}.jar"/>
|
||||
|
||||
<property name="build.site" location="build/tmp/site/build/site"/>
|
||||
<property name="build.site.src" location="build/tmp/site"/>
|
||||
@ -354,7 +350,6 @@ under the License.
|
||||
<available file="${ooxml.xmlbeans.jar}"/>
|
||||
<available file="${ooxml.jsr173.jar}"/>
|
||||
<available file="${ooxml.schemas.jar}"/>
|
||||
<available file="${ooxml.openxml4j.jar}"/>
|
||||
</and>
|
||||
<isset property="disconnected"/>
|
||||
</or>
|
||||
@ -377,10 +372,6 @@ under the License.
|
||||
<param name="sourcefile" value="${ooxml.schemas.url}"/>
|
||||
<param name="destfile" value="${ooxml.schemas.jar}"/>
|
||||
</antcall>
|
||||
<antcall target="downloadfile">
|
||||
<param name="sourcefile" value="${ooxml.openxml4j.url}"/>
|
||||
<param name="destfile" value="${ooxml.openxml4j.jar}"/>
|
||||
</antcall>
|
||||
</target>
|
||||
|
||||
<target name="check-ooxml-xsds">
|
||||
@ -524,7 +515,6 @@ under the License.
|
||||
</target>
|
||||
|
||||
<target name="compile-ooxml" depends="init, compile-main, compile-scratchpad">
|
||||
<!-- openxml4j requires java 1.5, so so must we, for now -->
|
||||
<javac target="1.5" source="1.5"
|
||||
destdir="${ooxml.output.dir}" debug="on" srcdir="${ooxml.src}">
|
||||
<classpath refid="ooxml.classpath"/>
|
||||
@ -805,6 +795,9 @@ under the License.
|
||||
<sysproperty key="HSLF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hslf/data"/>
|
||||
<sysproperty key="HDGF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hdgf/data"/>
|
||||
<sysproperty key="OOXML.testdata.path" file="${ooxml.src.test}/org/apache/poi/ooxml/data"/>
|
||||
<sysproperty key="openxml4j.compliance.input" file="${ooxml.src.test}/org/apache/poi/openxml4j/opc/compliance/input"/>
|
||||
<sysproperty key="openxml4j.testdata.input" file="${ooxml.src.test}/org/apache/poi/openxml4j/opc/INPUT"/>
|
||||
<sysproperty key="openxml4j.testdata.output" file="${ooxml.src.test}/org/apache/poi/openxml4j/opc/OUTPUT"/>
|
||||
<sysproperty key="java.awt.headless" value="true"/>
|
||||
<formatter type="plain"/>
|
||||
<formatter type="xml"/>
|
||||
@ -812,6 +805,7 @@ under the License.
|
||||
<fileset dir="${ooxml.src.test}">
|
||||
<include name="**/Test*.java"/>
|
||||
<exclude name="**/All*Tests.java"/>
|
||||
<exclude name="**/TestCore.java"/> <!--non-junit class from OpenXML4j-->
|
||||
</fileset>
|
||||
</batchtest>
|
||||
</junit>
|
||||
@ -1129,16 +1123,7 @@ FORREST_HOME environment variable!</echo>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="maven-ooxml-dependencies" description="Builds the POM files for OpenXml4J and compiled XmlBeans generated from the Ecma supplied xsds">
|
||||
<!-- OpenXml4J -->
|
||||
<copy file="${ooxml.jar6.dir}" tofile="${mavendist.ooxml.dir}/org.openxml4j/jars/${maven.openxml4j.jar}" />
|
||||
<copy file="maven/openxml4j.pom" tofile="${mavendist.ooxml.dir}/org.openxml4j/poms/openxml4j-${maven.openxml4j.version.id}.pom">
|
||||
<filterchain>
|
||||
<replacetokens>
|
||||
<token key="VERSION" value="${maven.openxml4j.version.id}" />
|
||||
</replacetokens>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<target name="maven-ooxml-dependencies" description="Builds the POM files for the compiled XmlBeans generated from the Ecma supplied xsds">
|
||||
|
||||
<!-- ooxml-schemas -->
|
||||
<copy file="${ooxml.xsds.jar}" tofile="${mavendist.ooxml.dir}/org.apache.poi/jars/${maven.ooxml.xsds.jar}" />
|
||||
|
@ -17,6 +17,3 @@ own licensing:
|
||||
Apache Licence Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0
|
||||
* DOM4J - http://www.dom4j.org/
|
||||
BSD Licence - http://www.dom4j.org/license.html
|
||||
* OpenXml4J - http://www.openxml4j.org/
|
||||
BSD Licence or Apache Licence Version 2.0 -
|
||||
http://www.openxml4j.org/Licensing/Default.html
|
||||
|
@ -1,70 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.openxml4j</groupId>
|
||||
<artifactId>openxml4j</artifactId>
|
||||
<version>@VERSION@</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>OpenXML4J</name>
|
||||
<url>http://openxml4j.org/</url>
|
||||
<description>Office Open XML File Format library for Java</description>
|
||||
|
||||
<mailingLists>
|
||||
<mailingList>
|
||||
<name>OpenXML4J Users List</name>
|
||||
<archive>http://sourceforge.net/mailarchive/forum.php?forum_name=openxml4j-users</archive>
|
||||
</mailingList>
|
||||
<mailingList>
|
||||
<name>OpenXML4J Developer List</name>
|
||||
<archive>http://sourceforge.net/mailarchive/forum.php?forum_name=openxml4j-devs</archive>
|
||||
</mailingList>
|
||||
</mailingLists>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<organization>
|
||||
<name>OpenXML4J</name>
|
||||
<url>http://www.openxml4j.org/</url>
|
||||
</organization>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -60,26 +60,19 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.13</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>openxml4j</artifactId>
|
||||
<version>1.0-beta</version>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>@VERSION@</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>ooxml-schemas</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -42,7 +42,8 @@
|
||||
<menu-item label="HSMF" href="hsmf/index.html"/>
|
||||
<menu-item label="HDGF" href="hdgf/index.html"/>
|
||||
<menu-item label="HPBF" href="hpbf/index.html"/>
|
||||
<menu-item label="POI-Ruby" href="poi-ruby.html"/>
|
||||
<menu-item label="OpenXML4J" href="oxml4j/index.html"/>
|
||||
<menu-item label="POI-Ruby" href="poi-ruby.html"/>
|
||||
<menu-item label="POI-Utils" href="utils/index.html"/>
|
||||
<menu-item label="Text Extraction" href="text-extraction.html"/>
|
||||
<menu-item label="Download" href="ext:download"/>
|
||||
|
34
src/documentation/content/xdocs/oxml4j/book.xml
Executable file
34
src/documentation/content/xdocs/oxml4j/book.xml
Executable file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN" "../dtd/book-cocoon-v10.dtd">
|
||||
|
||||
<book software="POI Project"
|
||||
title="OpenXML4J"
|
||||
copyright="@year@ POI Project">
|
||||
|
||||
<menu label="Apache POI">
|
||||
<menu-item label="Top" href="../index.html"/>
|
||||
</menu>
|
||||
|
||||
<menu label="OpenXML4J">
|
||||
<menu-item label="Overview" href="index.html"/>
|
||||
</menu>
|
||||
|
||||
</book>
|
42
src/documentation/content/xdocs/oxml4j/index.xml
Executable file
42
src/documentation/content/xdocs/oxml4j/index.xml
Executable file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
|
||||
|
||||
<document>
|
||||
<header>
|
||||
<title>POI-OpenXML4J - Java API To Access Office Open XML documents</title>
|
||||
<subtitle>Overview</subtitle>
|
||||
</header>
|
||||
|
||||
<body>
|
||||
<section>
|
||||
<title>Overview</title>
|
||||
<p>OpenXML4J is the POI Project's pure Java implementation of the Open Packaging Conventions (OPC) defined in
|
||||
<link href="http://www.ecma-international.org/publications/standards/Ecma-376.htm">ECMA-376</link>.</p>
|
||||
<p>Every OpenXML file comprises a collection of byte streams called parts, combined into a container called a package.
|
||||
POI OpenXML4J provides a physical implementation of the OPC that uses the Zip file format.</p>
|
||||
</section>
|
||||
<section>
|
||||
<title>History</title>
|
||||
<p>OpenXML4J was originally developed by <link href="http://openxml4j.org/">http://openxml4j.org/</link> and contributed to POI in 2008.
|
||||
Thanks to the support and guidance of Julien Chable</p>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
@ -509,7 +509,7 @@ import java.util.Iterator;
|
||||
|
||||
import org.apache.poi.xssf.eventusermodel.XSSFReader;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
|
@ -22,7 +22,7 @@ import java.util.Iterator;
|
||||
import org.apache.poi.xssf.eventusermodel.XSSFReader;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
|
@ -23,10 +23,10 @@ import org.apache.poi.poifs.common.POIFSConstants;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.PackageHelper;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.*;
|
||||
import org.openxml4j.opc.Package;
|
||||
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;
|
||||
|
||||
public abstract class POIXMLDocument extends POIXMLDocumentPart{
|
||||
|
||||
|
@ -23,15 +23,15 @@ import java.util.List;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.*;
|
||||
import org.openxml4j.opc.Package;
|
||||
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.openxml4j.opc.PackagePart}.
|
||||
* Each POIXMLDocumentPart keeps a reference to the underlying a {@link org.apache.poi.openxml4j.opc.PackagePart}.
|
||||
* </p>
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
|
@ -16,8 +16,8 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi;
|
||||
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -19,10 +19,10 @@ package org.apache.poi;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
|
||||
/**
|
||||
* Wrapper around the two different kinds of OOXML properties
|
||||
|
@ -19,8 +19,8 @@ package org.apache.poi;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ import java.io.IOException;
|
||||
|
||||
import org.apache.poi.POIXMLProperties.*;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
|
||||
public abstract class POIXMLTextExtractor extends POITextExtractor {
|
||||
/** The POIXMLDocument that's open */
|
||||
|
@ -22,11 +22,11 @@ import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackageAccess;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.PackageAccess;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
|
||||
/**
|
||||
* Prints out the contents of a OOXML container.
|
||||
|
@ -41,15 +41,14 @@ import org.apache.poi.xslf.XSLFSlideShow;
|
||||
import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
|
||||
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRelation;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRelation;
|
||||
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
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
|
||||
|
@ -0,0 +1,27 @@
|
||||
/* ====================================================================
|
||||
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.exceptions;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class InvalidFormatException extends OpenXML4JException{
|
||||
|
||||
public InvalidFormatException(String message){
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.exceptions;
|
||||
|
||||
/**
|
||||
* Throw when an invalid operation is done.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class InvalidOperationException extends OpenXML4JRuntimeException{
|
||||
|
||||
public InvalidOperationException(String message){
|
||||
super(message);
|
||||
}
|
||||
}
|
34
src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java
Executable file
34
src/ooxml/java/org/apache/poi/openxml4j/exceptions/OpenXML4JException.java
Executable file
@ -0,0 +1,34 @@
|
||||
/* ====================================================================
|
||||
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.exceptions;
|
||||
|
||||
/**
|
||||
* Global exception throws when a critical error occurs. (this exception is not
|
||||
* set as Runtime in order to force user to manage the exception in a
|
||||
* try/catch).
|
||||
*
|
||||
* @author CDubettier, Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class OpenXML4JException extends Exception {
|
||||
|
||||
public OpenXML4JException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/* ====================================================================
|
||||
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.exceptions;
|
||||
|
||||
/**
|
||||
* Global exception throws when a critical error occurs (this exception is
|
||||
* set as Runtime in order not to force the user to manage the exception in a
|
||||
* try/catch).
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class OpenXML4JRuntimeException extends RuntimeException {
|
||||
|
||||
public OpenXML4JRuntimeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
33
src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java
Executable file
33
src/ooxml/java/org/apache/poi/openxml4j/opc/CertificateEmbeddingOption.java
Executable file
@ -0,0 +1,33 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
/**
|
||||
* Specifies the location where the X.509 certificate that is used in signing is stored.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public enum CertificateEmbeddingOption {
|
||||
/** The certificate is embedded in its own PackagePart. */
|
||||
IN_CERTIFICATE_PART,
|
||||
/** The certificate is embedded in the SignaturePart that is created for the signature being added. */
|
||||
IN_SIGNATURE_PART,
|
||||
/** The certificate in not embedded in the package. */
|
||||
NOT_EMBEDDED
|
||||
}
|
47
src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java
Executable file
47
src/ooxml/java/org/apache/poi/openxml4j/opc/CompressionOption.java
Executable file
@ -0,0 +1,47 @@
|
||||
/* ====================================================================
|
||||
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.zip.Deflater;
|
||||
|
||||
/**
|
||||
* Specifies the compression level for content that is stored in a PackagePart.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public enum CompressionOption {
|
||||
/** Compression is optimized for performance. */
|
||||
FAST(Deflater.BEST_SPEED),
|
||||
/** Compression is optimized for size. */
|
||||
MAXIMUM(Deflater.BEST_COMPRESSION),
|
||||
/** Compression is optimized for a balance between size and performance. */
|
||||
NORMAL(Deflater.DEFAULT_COMPRESSION),
|
||||
/** Compression is turned off. */
|
||||
NOT_COMPRESSED(Deflater.NO_COMPRESSION);
|
||||
|
||||
private final int value;
|
||||
|
||||
CompressionOption(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
43
src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java
Executable file
43
src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java
Executable file
@ -0,0 +1,43 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
/**
|
||||
* Storage class for configuration storage parameters.
|
||||
* TODO xml syntax checking is no longer done with DOM4j parser -> remove the schema or do it ?
|
||||
*
|
||||
* @author CDubettier, Julen Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Configuration {
|
||||
// TODO configuration by default. should be clearly stated that it should be
|
||||
// changed to match installation path
|
||||
// as schemas dir is needed in runtime
|
||||
static private String pathForXmlSchema = System.getProperty("user.dir")
|
||||
+ File.separator + "src" + File.separator + "schemas";
|
||||
|
||||
public static String getPathForXmlSchema() {
|
||||
return pathForXmlSchema;
|
||||
}
|
||||
|
||||
public static void setPathForXmlSchema(String pathForXmlSchema) {
|
||||
Configuration.pathForXmlSchema = pathForXmlSchema;
|
||||
}
|
||||
}
|
129
src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java
Executable file
129
src/ooxml/java/org/apache/poi/openxml4j/opc/ContentTypes.java
Executable file
@ -0,0 +1,129 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
/**
|
||||
* Open Packaging Convention content types (see Annex F : Standard Namespaces
|
||||
* and Content Types).
|
||||
*
|
||||
* @author CDubettier define some constants, Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public class ContentTypes {
|
||||
|
||||
/*
|
||||
* Open Packaging Convention (Annex F : Standard Namespaces and Content
|
||||
* Types)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core Properties part.
|
||||
*/
|
||||
public static final String CORE_PROPERTIES_PART = "application/vnd.openxmlformats-package.core-properties+xml";
|
||||
|
||||
/**
|
||||
* Digital Signature Certificate part.
|
||||
*/
|
||||
public static final String DIGITAL_SIGNATURE_CERTIFICATE_PART = "application/vnd.openxmlformats-package.digital-signature-certificate";
|
||||
|
||||
/**
|
||||
* Digital Signature Origin part.
|
||||
*/
|
||||
public static final String DIGITAL_SIGNATURE_ORIGIN_PART = "application/vnd.openxmlformats-package.digital-signature-origin";
|
||||
|
||||
/**
|
||||
* Digital Signature XML Signature part.
|
||||
*/
|
||||
public static final String DIGITAL_SIGNATURE_XML_SIGNATURE_PART = "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml";
|
||||
|
||||
/**
|
||||
* Relationships part.
|
||||
*/
|
||||
public static final String RELATIONSHIPS_PART = "application/vnd.openxmlformats-package.relationships+xml";
|
||||
|
||||
/**
|
||||
* Custom XML part.
|
||||
*/
|
||||
public static final String CUSTOM_XML_PART = "application/vnd.openxmlformats-officedocument.customXmlProperties+xml";
|
||||
|
||||
/**
|
||||
* Plain old xml. Note - OOXML uses application/xml, and not text/xml!
|
||||
*/
|
||||
public static final String PLAIN_OLD_XML = "application/xml";
|
||||
|
||||
public static final String IMAGE_JPEG = "image/jpeg";
|
||||
|
||||
public static final String EXTENSION_JPG_1 = "jpg";
|
||||
|
||||
public static final String EXTENSION_JPG_2 = "jpeg";
|
||||
|
||||
// image/png ISO/IEC 15948:2003 http://www.libpng.org/pub/png/spec/
|
||||
public static final String IMAGE_PNG = "image/png";
|
||||
|
||||
public static final String EXTENSION_PNG = "png";
|
||||
|
||||
// image/gif http://www.w3.org/Graphics/GIF/spec-gif89a.txt
|
||||
public static final String IMAGE_GIF = "image/gif";
|
||||
|
||||
public static final String EXTENSION_GIF = "gif";
|
||||
|
||||
/**
|
||||
* TIFF image format.
|
||||
*
|
||||
* @see http://partners.adobe.com/public/developer/tiff/index.html#spec
|
||||
*/
|
||||
public static final String IMAGE_TIFF = "image/tiff";
|
||||
|
||||
public static final String EXTENSION_TIFF = "tiff";
|
||||
|
||||
/**
|
||||
* Pict image format.
|
||||
*
|
||||
* @see http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html
|
||||
*/
|
||||
public static final String IMAGE_PICT = "image/pict";
|
||||
|
||||
public static final String EXTENSION_PICT = "tiff";
|
||||
|
||||
/**
|
||||
* XML file.
|
||||
*/
|
||||
public static final String XML = "text/xml";
|
||||
|
||||
public static final String EXTENSION_XML = "xml";
|
||||
|
||||
public static String getContentTypeFromFileExtension(String filename) {
|
||||
String extension = filename.substring(filename.lastIndexOf(".") + 1)
|
||||
.toLowerCase();
|
||||
if (extension.equals(EXTENSION_JPG_1)
|
||||
|| extension.equals(EXTENSION_JPG_2))
|
||||
return IMAGE_JPEG;
|
||||
else if (extension.equals(EXTENSION_GIF))
|
||||
return IMAGE_GIF;
|
||||
else if (extension.equals(EXTENSION_PICT))
|
||||
return IMAGE_PICT;
|
||||
else if (extension.equals(EXTENSION_PNG))
|
||||
return IMAGE_PNG;
|
||||
else if (extension.equals(EXTENSION_TIFF))
|
||||
return IMAGE_TIFF;
|
||||
else if (extension.equals(EXTENSION_XML))
|
||||
return XML;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
29
src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java
Executable file
29
src/ooxml/java/org/apache/poi/openxml4j/opc/EncryptionOption.java
Executable file
@ -0,0 +1,29 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
/**
|
||||
* Specifies the encryption option for parts in a Package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public enum EncryptionOption {
|
||||
/** No encryption. */
|
||||
NONE
|
||||
}
|
1396
src/ooxml/java/org/apache/poi/openxml4j/opc/Package.java
Executable file
1396
src/ooxml/java/org/apache/poi/openxml4j/opc/Package.java
Executable file
File diff suppressed because it is too large
Load Diff
33
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java
Executable file
33
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageAccess.java
Executable file
@ -0,0 +1,33 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
/**
|
||||
* Specifies package access.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public enum PackageAccess {
|
||||
/** Read only. Write not authorized. */
|
||||
READ,
|
||||
/** Write only. Read not authorized. */
|
||||
WRITE,
|
||||
/** Read and Write mode. */
|
||||
READ_WRITE
|
||||
}
|
52
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java
Executable file
52
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageNamespaces.java
Executable file
@ -0,0 +1,52 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
/**
|
||||
* Open Packaging Convention namespaces URI.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface PackageNamespaces {
|
||||
|
||||
/**
|
||||
* Content Types.
|
||||
*/
|
||||
public static final String CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
||||
|
||||
/**
|
||||
* Core Properties.
|
||||
*/
|
||||
public static final String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
|
||||
|
||||
/**
|
||||
* Digital Signatures.
|
||||
*/
|
||||
public static final String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/digital-signature";
|
||||
|
||||
/**
|
||||
* Relationships.
|
||||
*/
|
||||
public static final String RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
||||
|
||||
/**
|
||||
* Markup Compatibility.
|
||||
*/
|
||||
public static final String MARKUP_COMPATIBILITY = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
||||
}
|
654
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
Executable file
654
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
Executable file
@ -0,0 +1,654 @@
|
||||
/* ====================================================================
|
||||
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 Package 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(Package 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(Package pack, PackagePartName partName,
|
||||
ContentType contentType, boolean loadRelationships)
|
||||
throws InvalidFormatException {
|
||||
this.partName = partName;
|
||||
this.contentType = contentType;
|
||||
this.container = (ZipPackage) pack;
|
||||
|
||||
// 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(Package 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).
|
||||
*
|
||||
* Check rule M1.25: The Relationships part shall not have relationships to
|
||||
* any other part. Package implementers shall enforce this requirement upon
|
||||
* the attempt to create such a relationship and shall treat any such
|
||||
* relationship as invalid.
|
||||
*
|
||||
* @param targetPartName
|
||||
* Name of the target part. This one must be relative to the
|
||||
* source root directory of the part.
|
||||
* @param targetMode
|
||||
* Mode [Internal|External].
|
||||
* @param relationshipType
|
||||
* Type of relationship.
|
||||
* @param id
|
||||
* Relationship unique id.
|
||||
* @return The newly created and added relationship
|
||||
*
|
||||
* @throws InvalidFormatException
|
||||
* If the URI point to a relationship part URI.
|
||||
* @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).
|
||||
*
|
||||
* 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 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 Package getPackage() {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean isRelationshipPart() {
|
||||
return this.isRelationshipPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
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();
|
||||
}
|
81
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java
Executable file
81
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartCollection.java
Executable file
@ -0,0 +1,81 @@
|
||||
/* ====================================================================
|
||||
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.ArrayList;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
|
||||
/**
|
||||
* A package part collection.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class PackagePartCollection extends
|
||||
TreeMap<PackagePartName, PackagePart> {
|
||||
|
||||
private static final long serialVersionUID = 2515031135957635515L;
|
||||
|
||||
/**
|
||||
* Arraylist use to store this collection part names as string for rule
|
||||
* M1.11 optimized checking.
|
||||
*/
|
||||
private ArrayList<String> registerPartNameStr = new ArrayList<String>();
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check rule [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.
|
||||
*
|
||||
* @exception InvalidOperationException
|
||||
* Throws if you try to add a part with a name derived from
|
||||
* another part name.
|
||||
*/
|
||||
@Override
|
||||
public PackagePart put(PackagePartName partName, PackagePart part) {
|
||||
String[] segments = partName.getURI().toASCIIString().split(
|
||||
PackagingURIHelper.FORWARD_SLASH_STRING);
|
||||
StringBuffer concatSeg = new StringBuffer();
|
||||
for (String seg : segments) {
|
||||
if (!seg.equals(""))
|
||||
concatSeg.append(PackagingURIHelper.FORWARD_SLASH_CHAR);
|
||||
concatSeg.append(seg);
|
||||
if (this.registerPartNameStr.contains(concatSeg.toString())) {
|
||||
throw new InvalidOperationException(
|
||||
"You can't add a part with a part name derived from another part ! [M1.11]");
|
||||
}
|
||||
}
|
||||
this.registerPartNameStr.add(partName.getName());
|
||||
return super.put(partName, part);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackagePart remove(Object key) {
|
||||
if (key instanceof PackagePartName) {
|
||||
this.registerPartNameStr.remove(((PackagePartName) key).getName());
|
||||
}
|
||||
return super.remove(key);
|
||||
}
|
||||
}
|
509
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
Executable file
509
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePartName.java
Executable file
@ -0,0 +1,509 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
|
||||
|
||||
/**
|
||||
* An immutable Open Packaging Convention compliant part name.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*
|
||||
* @see http://www.ietf.org/rfc/rfc3986.txt
|
||||
*/
|
||||
public final class PackagePartName implements Comparable<PackagePartName> {
|
||||
|
||||
/**
|
||||
* Part name stored as an URI.
|
||||
*/
|
||||
private URI partNameURI;
|
||||
|
||||
/*
|
||||
* URI Characters definition (RFC 3986)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reserved characters for sub delimitations.
|
||||
*/
|
||||
private static String[] RFC3986_PCHAR_SUB_DELIMS = { "!", "$", "&", "'",
|
||||
"(", ")", "*", "+", ",", ";", "=" };
|
||||
|
||||
/**
|
||||
* Unreserved character (+ ALPHA & DIGIT).
|
||||
*/
|
||||
private static String[] RFC3986_PCHAR_UNRESERVED_SUP = { "-", ".", "_", "~" };
|
||||
|
||||
/**
|
||||
* Authorized reserved characters for pChar.
|
||||
*/
|
||||
private static String[] RFC3986_PCHAR_AUTHORIZED_SUP = { ":", "@" };
|
||||
|
||||
/**
|
||||
* Flag to know if this part name is from a relationship part name.
|
||||
*/
|
||||
private boolean isRelationship;
|
||||
|
||||
/**
|
||||
* Constructor. Makes a ValidPartName object from a java.net.URI
|
||||
*
|
||||
* @param uri
|
||||
* The URI to validate and to transform into ValidPartName.
|
||||
* @param checkConformance
|
||||
* Flag to specify if the contructor have to validate the OPC
|
||||
* conformance. Must be always <code>true</code> except for
|
||||
* special URI like '/' which is needed for internal use by
|
||||
* OpenXML4J but is not valid.
|
||||
* @throws InvalidFormatException
|
||||
* Throw if the specified part name is not conform to Open
|
||||
* Packaging Convention specifications.
|
||||
* @see java.net.URI
|
||||
*/
|
||||
PackagePartName(URI uri, boolean checkConformance)
|
||||
throws InvalidFormatException {
|
||||
if (checkConformance) {
|
||||
throwExceptionIfInvalidPartUri(uri);
|
||||
} else {
|
||||
if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(uri)) {
|
||||
throw new OpenXML4JRuntimeException(
|
||||
"OCP conformance must be check for ALL part name except special cases : ['/']");
|
||||
}
|
||||
}
|
||||
this.partNameURI = uri;
|
||||
this.isRelationship = isRelationshipPartURI(this.partNameURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Makes a ValidPartName object from a String part name.
|
||||
*
|
||||
* @param partName
|
||||
* Part name to valid and to create.
|
||||
* @param checkConformance
|
||||
* Flag to specify if the contructor have to validate the OPC
|
||||
* conformance. Must be always <code>true</code> except for
|
||||
* special URI like '/' which is needed for internal use by
|
||||
* OpenXML4J but is not valid.
|
||||
* @throws InvalidFormatException
|
||||
* Throw if the specified part name is not conform to Open
|
||||
* Packaging Convention specifications.
|
||||
*/
|
||||
PackagePartName(String partName, boolean checkConformance)
|
||||
throws InvalidFormatException {
|
||||
URI partURI;
|
||||
try {
|
||||
partURI = new URI(partName);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"partName argmument is not a valid OPC part name !");
|
||||
}
|
||||
|
||||
if (checkConformance) {
|
||||
throwExceptionIfInvalidPartUri(partURI);
|
||||
} else {
|
||||
if (!PackagingURIHelper.PACKAGE_ROOT_URI.equals(partURI)) {
|
||||
throw new OpenXML4JRuntimeException(
|
||||
"OCP conformance must be check for ALL part name except special cases : ['/']");
|
||||
}
|
||||
}
|
||||
this.partNameURI = partURI;
|
||||
this.isRelationship = isRelationshipPartURI(this.partNameURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified part name is a relationship part name.
|
||||
*
|
||||
* @param partUri
|
||||
* The URI to check.
|
||||
* @return <code>true</code> if this part name respect the relationship
|
||||
* part naming convention else <code>false</code>.
|
||||
*/
|
||||
private boolean isRelationshipPartURI(URI partUri) {
|
||||
if (partUri == null)
|
||||
throw new IllegalArgumentException("partUri");
|
||||
|
||||
return partUri.getPath().matches(
|
||||
"^.*/" + PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME + "/.*\\"
|
||||
+ PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME
|
||||
+ "$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Know if this part name is a relationship part name.
|
||||
*
|
||||
* @return <code>true</code> if this part name respect the relationship
|
||||
* part naming convention else <code>false</code>.
|
||||
*/
|
||||
public boolean isRelationshipPartURI() {
|
||||
return this.isRelationship;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception (of any kind) if the specified part name does not
|
||||
* follow the Open Packaging Convention specifications naming rules.
|
||||
*
|
||||
* @param partUri
|
||||
* The part name to check.
|
||||
* @throws Exception
|
||||
* Throws if the part name is invalid.
|
||||
*/
|
||||
private static void throwExceptionIfInvalidPartUri(URI partUri)
|
||||
throws InvalidFormatException {
|
||||
if (partUri == null)
|
||||
throw new IllegalArgumentException("partUri");
|
||||
// Check if the part name URI is empty [M1.1]
|
||||
throwExceptionIfEmptyURI(partUri);
|
||||
|
||||
// Check if the part name URI is absolute
|
||||
throwExceptionIfAbsoluteUri(partUri);
|
||||
|
||||
// Check if the part name URI starts with a forward slash [M1.4]
|
||||
throwExceptionIfPartNameNotStartsWithForwardSlashChar(partUri);
|
||||
|
||||
// Check if the part name URI ends with a forward slash [M1.5]
|
||||
throwExceptionIfPartNameEndsWithForwardSlashChar(partUri);
|
||||
|
||||
// Check if the part name does not have empty segments. [M1.3]
|
||||
// Check if a segment ends with a dot ('.') character. [M1.9]
|
||||
throwExceptionIfPartNameHaveInvalidSegments(partUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the specified URI is empty. [M1.1]
|
||||
*
|
||||
* @param partURI
|
||||
* Part URI to check.
|
||||
* @throws InvalidFormatException
|
||||
* If the specified URI is empty.
|
||||
*/
|
||||
private static void throwExceptionIfEmptyURI(URI partURI)
|
||||
throws InvalidFormatException {
|
||||
if (partURI == null)
|
||||
throw new IllegalArgumentException("partURI");
|
||||
|
||||
String uriPath = partURI.getPath();
|
||||
if (uriPath.length() == 0
|
||||
|| ((uriPath.length() == 1) && (uriPath.charAt(0) == PackagingURIHelper.FORWARD_SLASH_CHAR)))
|
||||
throw new InvalidFormatException(
|
||||
"A part name shall not be empty [M1.1]: "
|
||||
+ partURI.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the part name has empty segments. [M1.3]
|
||||
*
|
||||
* Throws an exception if a segment any characters other than pchar
|
||||
* characters. [M1.6]
|
||||
*
|
||||
* Throws an exception if a segment contain percent-encoded forward slash
|
||||
* ('/'), or backward slash ('\') characters. [M1.7]
|
||||
*
|
||||
* Throws an exception if a segment contain percent-encoded unreserved
|
||||
* characters. [M1.8]
|
||||
*
|
||||
* Throws an exception if the specified part name's segments end with a dot
|
||||
* ('.') character. [M1.9]
|
||||
*
|
||||
* Throws an exception if a segment doesn't include at least one non-dot
|
||||
* character. [M1.10]
|
||||
*
|
||||
* @param partUri
|
||||
* The part name to check.
|
||||
* @throws InvalidFormatException
|
||||
* if the specified URI contain an empty segments or if one the
|
||||
* segments contained in the part name, ends with a dot ('.')
|
||||
* character.
|
||||
*/
|
||||
private static void throwExceptionIfPartNameHaveInvalidSegments(URI partUri)
|
||||
throws InvalidFormatException {
|
||||
if (partUri == null || "".equals(partUri)) {
|
||||
throw new IllegalArgumentException("partUri");
|
||||
}
|
||||
|
||||
// Split the URI into several part and analyze each
|
||||
String[] segments = partUri.toASCIIString().split("/");
|
||||
if (segments.length <= 1 || !segments[0].equals(""))
|
||||
throw new InvalidFormatException(
|
||||
"A part name shall not have empty segments [M1.3]: "
|
||||
+ partUri.getPath());
|
||||
|
||||
for (int i = 1; i < segments.length; ++i) {
|
||||
String seg = segments[i];
|
||||
if (seg == null || "".equals(seg)) {
|
||||
throw new InvalidFormatException(
|
||||
"A part name shall not have empty segments [M1.3]: "
|
||||
+ partUri.getPath());
|
||||
}
|
||||
|
||||
if (seg.endsWith(".")) {
|
||||
throw new InvalidFormatException(
|
||||
"A segment shall not end with a dot ('.') character [M1.9]: "
|
||||
+ partUri.getPath());
|
||||
}
|
||||
|
||||
if ("".equals(seg.replaceAll("\\\\.", ""))) {
|
||||
// Normally will never been invoked with the previous
|
||||
// implementation rule [M1.9]
|
||||
throw new InvalidFormatException(
|
||||
"A segment shall include at least one non-dot character. [M1.10]: "
|
||||
+ partUri.getPath());
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for rule M1.6, M1.7, M1.8
|
||||
*/
|
||||
checkPCharCompliance(seg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if a segment any characters other than pchar
|
||||
* characters. [M1.6]
|
||||
*
|
||||
* Throws an exception if a segment contain percent-encoded forward slash
|
||||
* ('/'), or backward slash ('\') characters. [M1.7]
|
||||
*
|
||||
* Throws an exception if a segment contain percent-encoded unreserved
|
||||
* characters. [M1.8]
|
||||
*
|
||||
* @param segment
|
||||
* The segment to check
|
||||
*/
|
||||
private static void checkPCharCompliance(String segment)
|
||||
throws InvalidFormatException {
|
||||
boolean errorFlag;
|
||||
for (int i = 0; i < segment.length(); ++i) {
|
||||
char c = segment.charAt(i);
|
||||
errorFlag = true;
|
||||
|
||||
/* Check rule M1.6 */
|
||||
|
||||
// Check for digit or letter
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
|
||||
|| (c >= '0' && c <= '9')) {
|
||||
errorFlag = false;
|
||||
} else {
|
||||
// Check "-", ".", "_", "~"
|
||||
for (int j = 0; j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) {
|
||||
if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) {
|
||||
errorFlag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check ":", "@"
|
||||
for (int j = 0; errorFlag
|
||||
&& j < RFC3986_PCHAR_AUTHORIZED_SUP.length; ++j) {
|
||||
if (c == RFC3986_PCHAR_AUTHORIZED_SUP[j].charAt(0)) {
|
||||
errorFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
|
||||
for (int j = 0; errorFlag
|
||||
&& j < RFC3986_PCHAR_SUB_DELIMS.length; ++j) {
|
||||
if (c == RFC3986_PCHAR_SUB_DELIMS[j].charAt(0)) {
|
||||
errorFlag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorFlag && c == '%') {
|
||||
// We certainly found an encoded character, check for length
|
||||
// now ( '%' HEXDIGIT HEXDIGIT)
|
||||
if (((segment.length() - i) < 2)) {
|
||||
throw new InvalidFormatException("The segment " + segment
|
||||
+ " contain invalid encoded character !");
|
||||
}
|
||||
|
||||
// If not percent encoded character error occur then reset the
|
||||
// flag -> the character is valid
|
||||
errorFlag = false;
|
||||
|
||||
// Decode the encoded character
|
||||
char decodedChar = (char) Integer.parseInt(segment.substring(
|
||||
i + 1, i + 3), 16);
|
||||
i += 2;
|
||||
|
||||
/* Check rule M1.7 */
|
||||
if (decodedChar == '/' || decodedChar == '\\')
|
||||
throw new InvalidFormatException(
|
||||
"A segment shall not contain percent-encoded forward slash ('/'), or backward slash ('\') characters. [M1.7]");
|
||||
|
||||
/* Check rule M1.8 */
|
||||
|
||||
// Check for unreserved character like define in RFC3986
|
||||
if ((decodedChar >= 'A' && decodedChar <= 'Z')
|
||||
|| (decodedChar >= 'a' && decodedChar <= 'z')
|
||||
|| (decodedChar >= '0' && decodedChar <= '9'))
|
||||
errorFlag = true;
|
||||
|
||||
// Check for unreserved character "-", ".", "_", "~"
|
||||
for (int j = 0; !errorFlag
|
||||
&& j < RFC3986_PCHAR_UNRESERVED_SUP.length; ++j) {
|
||||
if (c == RFC3986_PCHAR_UNRESERVED_SUP[j].charAt(0)) {
|
||||
errorFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errorFlag)
|
||||
throw new InvalidFormatException(
|
||||
"A segment shall not contain percent-encoded unreserved characters. [M1.8]");
|
||||
}
|
||||
|
||||
if (errorFlag)
|
||||
throw new InvalidFormatException(
|
||||
"A segment shall not hold any characters other than pchar characters. [M1.6]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the specified part name doesn't start with a
|
||||
* forward slash character '/'. [M1.4]
|
||||
*
|
||||
* @param partUri
|
||||
* The part name to check.
|
||||
* @throws InvalidFormatException
|
||||
* If the specified part name doesn't start with a forward slash
|
||||
* character '/'.
|
||||
*/
|
||||
private static void throwExceptionIfPartNameNotStartsWithForwardSlashChar(
|
||||
URI partUri) throws InvalidFormatException {
|
||||
String uriPath = partUri.getPath();
|
||||
if (uriPath.length() > 0
|
||||
&& uriPath.charAt(0) != PackagingURIHelper.FORWARD_SLASH_CHAR)
|
||||
throw new InvalidFormatException(
|
||||
"A part name shall start with a forward slash ('/') character [M1.4]: "
|
||||
+ partUri.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the specified part name ends with a forwar slash
|
||||
* character '/'. [M1.5]
|
||||
*
|
||||
* @param partUri
|
||||
* The part name to check.
|
||||
* @throws InvalidFormatException
|
||||
* If the specified part name ends with a forwar slash character
|
||||
* '/'.
|
||||
*/
|
||||
private static void throwExceptionIfPartNameEndsWithForwardSlashChar(
|
||||
URI partUri) throws InvalidFormatException {
|
||||
String uriPath = partUri.getPath();
|
||||
if (uriPath.length() > 0
|
||||
&& uriPath.charAt(uriPath.length() - 1) == PackagingURIHelper.FORWARD_SLASH_CHAR)
|
||||
throw new InvalidFormatException(
|
||||
"A part name shall not have a forward slash as the last character [M1.5]: "
|
||||
+ partUri.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the specified URI is absolute.
|
||||
*
|
||||
* @param partUri
|
||||
* The URI to check.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the specified URI is absolute.
|
||||
*/
|
||||
private static void throwExceptionIfAbsoluteUri(URI partUri)
|
||||
throws InvalidFormatException {
|
||||
if (partUri.isAbsolute())
|
||||
throw new InvalidFormatException("Absolute URI forbidden: "
|
||||
+ partUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two part name following the rule M1.12 :
|
||||
*
|
||||
* Part name equivalence is determined by comparing part names as
|
||||
* case-insensitive ASCII strings. Packages shall not contain equivalent
|
||||
* part names and package implementers shall neither create nor recognize
|
||||
* packages with equivalent part names. [M1.12]
|
||||
*/
|
||||
public int compareTo(PackagePartName otherPartName) {
|
||||
if (otherPartName == null)
|
||||
return -1;
|
||||
return this.partNameURI.toASCIIString().toLowerCase().compareTo(
|
||||
otherPartName.partNameURI.toASCIIString().toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the extension of the part name if any. If there is no extension
|
||||
* returns an empty String. Example : '/document/content.xml' => 'xml'
|
||||
*
|
||||
* @return The extension of the part name.
|
||||
*/
|
||||
public String getExtension() {
|
||||
String fragment = this.partNameURI.getPath();
|
||||
if (fragment.length() > 0) {
|
||||
int i = fragment.lastIndexOf(".");
|
||||
if (i > -1)
|
||||
return fragment.substring(i + 1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this part name.
|
||||
*
|
||||
* @return The name of this part name.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.partNameURI.toASCIIString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Part name equivalence is determined by comparing part names as
|
||||
* case-insensitive ASCII strings. Packages shall not contain equivalent
|
||||
* part names and package implementers shall neither create nor recognize
|
||||
* packages with equivalent part names. [M1.12]
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object otherPartName) {
|
||||
if (otherPartName == null
|
||||
|| !(otherPartName instanceof PackagePartName))
|
||||
return false;
|
||||
return this.partNameURI.toASCIIString().toLowerCase().equals(
|
||||
((PackagePartName) otherPartName).partNameURI.toASCIIString()
|
||||
.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.partNameURI.toASCIIString().toLowerCase().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
/* Getters and setters */
|
||||
|
||||
/**
|
||||
* Part name property getter.
|
||||
*
|
||||
* @return This part name URI.
|
||||
*/
|
||||
public URI getURI() {
|
||||
return this.partNameURI;
|
||||
}
|
||||
}
|
227
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java
Executable file
227
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageProperties.java
Executable file
@ -0,0 +1,227 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.poi.openxml4j.util.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the core properties of an OPC package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
* @see org.apache.poi.openxml4j.opc.Package
|
||||
*/
|
||||
public interface PackageProperties {
|
||||
|
||||
/**
|
||||
* Dublin Core Terms URI.
|
||||
*/
|
||||
public final static String NAMESPACE_DCTERMS = "http://purl.org/dc/terms/";
|
||||
|
||||
/**
|
||||
* Dublin Core namespace URI.
|
||||
*/
|
||||
public final static String NAMESPACE_DC = "http://purl.org/dc/elements/1.1/";
|
||||
|
||||
/* Getters and setters */
|
||||
|
||||
/**
|
||||
* Set the category of the content of this package.
|
||||
*/
|
||||
public abstract Nullable<String> getCategoryProperty();
|
||||
|
||||
/**
|
||||
* Set the category of the content of this package.
|
||||
*/
|
||||
public abstract void setCategoryProperty(String category);
|
||||
|
||||
/**
|
||||
* Set the status of the content.
|
||||
*/
|
||||
public abstract Nullable<String> getContentStatusProperty();
|
||||
|
||||
/**
|
||||
* Get the status of the content.
|
||||
*/
|
||||
public abstract void setContentStatusProperty(String contentStatus);
|
||||
|
||||
/**
|
||||
* Get the type of content represented, generally defined by a specific use
|
||||
* and intended audience.
|
||||
*/
|
||||
public abstract Nullable<String> getContentTypeProperty();
|
||||
|
||||
/**
|
||||
* Set the type of content represented, generally defined by a specific use
|
||||
* and intended audience.
|
||||
*/
|
||||
public abstract void setContentTypeProperty(String contentType);
|
||||
|
||||
/**
|
||||
* Get the date of creation of the resource.
|
||||
*/
|
||||
public abstract Nullable<Date> getCreatedProperty();
|
||||
|
||||
/**
|
||||
* Set the date of creation of the resource.
|
||||
*/
|
||||
public abstract void setCreatedProperty(String created);
|
||||
|
||||
/**
|
||||
* Set the date of creation of the resource.
|
||||
*/
|
||||
public abstract void setCreatedProperty(Nullable<Date> created);
|
||||
|
||||
/**
|
||||
* Get the entity primarily responsible for making the content of the
|
||||
* resource.
|
||||
*/
|
||||
public abstract Nullable<String> getCreatorProperty();
|
||||
|
||||
/**
|
||||
* Set the entity primarily responsible for making the content of the
|
||||
* resource.
|
||||
*/
|
||||
public abstract void setCreatorProperty(String creator);
|
||||
|
||||
/**
|
||||
* Get the explanation of the content of the resource.
|
||||
*/
|
||||
public abstract Nullable<String> getDescriptionProperty();
|
||||
|
||||
/**
|
||||
* Set the explanation of the content of the resource.
|
||||
*/
|
||||
public abstract void setDescriptionProperty(String description);
|
||||
|
||||
/**
|
||||
* Get an unambiguous reference to the resource within a given context.
|
||||
*/
|
||||
public abstract Nullable<String> getIdentifierProperty();
|
||||
|
||||
/**
|
||||
* Set an unambiguous reference to the resource within a given context.
|
||||
*/
|
||||
public abstract void setIdentifierProperty(String identifier);
|
||||
|
||||
/**
|
||||
* Get a delimited set of keywords to support searching and indexing. This
|
||||
* is typically a list of terms that are not available elsewhere in the
|
||||
* properties
|
||||
*/
|
||||
public abstract Nullable<String> getKeywordsProperty();
|
||||
|
||||
/**
|
||||
* Set a delimited set of keywords to support searching and indexing. This
|
||||
* is typically a list of terms that are not available elsewhere in the
|
||||
* properties
|
||||
*/
|
||||
public abstract void setKeywordsProperty(String keywords);
|
||||
|
||||
/**
|
||||
* Get the language of the intellectual content of the resource.
|
||||
*/
|
||||
public abstract Nullable<String> getLanguageProperty();
|
||||
|
||||
/**
|
||||
* Set the language of the intellectual content of the resource.
|
||||
*/
|
||||
public abstract void setLanguageProperty(String language);
|
||||
|
||||
/**
|
||||
* Get the user who performed the last modification.
|
||||
*/
|
||||
public abstract Nullable<String> getLastModifiedByProperty();
|
||||
|
||||
/**
|
||||
* Set the user who performed the last modification.
|
||||
*/
|
||||
public abstract void setLastModifiedByProperty(String lastModifiedBy);
|
||||
|
||||
/**
|
||||
* Get the date and time of the last printing.
|
||||
*/
|
||||
public abstract Nullable<Date> getLastPrintedProperty();
|
||||
|
||||
/**
|
||||
* Set the date and time of the last printing.
|
||||
*/
|
||||
public abstract void setLastPrintedProperty(String lastPrinted);
|
||||
|
||||
/**
|
||||
* Set the date and time of the last printing.
|
||||
*/
|
||||
public abstract void setLastPrintedProperty(Nullable<Date> lastPrinted);
|
||||
|
||||
/**
|
||||
* Get the date on which the resource was changed.
|
||||
*/
|
||||
public abstract Nullable<Date> getModifiedProperty();
|
||||
|
||||
/**
|
||||
* Set the date on which the resource was changed.
|
||||
*/
|
||||
public abstract void setModifiedProperty(String modified);
|
||||
|
||||
/**
|
||||
* Set the date on which the resource was changed.
|
||||
*/
|
||||
public abstract void setModifiedProperty(Nullable<Date> modified);
|
||||
|
||||
/**
|
||||
* Get the revision number.
|
||||
*/
|
||||
public abstract Nullable<String> getRevisionProperty();
|
||||
|
||||
/**
|
||||
* Set the revision number.
|
||||
*/
|
||||
public abstract void setRevisionProperty(String revision);
|
||||
|
||||
/**
|
||||
* Get the topic of the content of the resource.
|
||||
*/
|
||||
public abstract Nullable<String> getSubjectProperty();
|
||||
|
||||
/**
|
||||
* Set the topic of the content of the resource.
|
||||
*/
|
||||
public abstract void setSubjectProperty(String subject);
|
||||
|
||||
/**
|
||||
* Get the name given to the resource.
|
||||
*/
|
||||
public abstract Nullable<String> getTitleProperty();
|
||||
|
||||
/**
|
||||
* Set the name given to the resource.
|
||||
*/
|
||||
public abstract void setTitleProperty(String title);
|
||||
|
||||
/**
|
||||
* Get the version number.
|
||||
*/
|
||||
public abstract Nullable<String> getVersionProperty();
|
||||
|
||||
/**
|
||||
* Set the version number.
|
||||
*/
|
||||
public abstract void setVersionProperty(String version);
|
||||
}
|
227
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java
Executable file
227
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationship.java
Executable file
@ -0,0 +1,227 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* A part relationship.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class PackageRelationship {
|
||||
|
||||
private static URI containerRelationshipPart;
|
||||
|
||||
static {
|
||||
try {
|
||||
containerRelationshipPart = new URI("/_rels/.rels");
|
||||
} catch (URISyntaxException e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/* XML markup */
|
||||
|
||||
public static final String ID_ATTRIBUTE_NAME = "Id";
|
||||
|
||||
public static final String RELATIONSHIPS_TAG_NAME = "Relationships";
|
||||
|
||||
public static final String RELATIONSHIP_TAG_NAME = "Relationship";
|
||||
|
||||
public static final String TARGET_ATTRIBUTE_NAME = "Target";
|
||||
|
||||
public static final String TARGET_MODE_ATTRIBUTE_NAME = "TargetMode";
|
||||
|
||||
public static final String TYPE_ATTRIBUTE_NAME = "Type";
|
||||
|
||||
/* End XML markup */
|
||||
|
||||
/**
|
||||
* L'ID de la relation.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* R<EFBFBD>f<EFBFBD>rence vers le package.
|
||||
*/
|
||||
private Package container;
|
||||
|
||||
/**
|
||||
* Type de relation.
|
||||
*/
|
||||
private String relationshipType;
|
||||
|
||||
/**
|
||||
* Partie source de cette relation.
|
||||
*/
|
||||
private PackagePart source;
|
||||
|
||||
/**
|
||||
* Le mode de ciblage [Internal|External]
|
||||
*/
|
||||
private TargetMode targetMode;
|
||||
|
||||
/**
|
||||
* URI de la partie cible.
|
||||
*/
|
||||
private URI targetUri;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param packageParent
|
||||
* @param sourcePart
|
||||
* @param targetUri
|
||||
* @param targetMode
|
||||
* @param relationshipType
|
||||
* @param id
|
||||
*/
|
||||
public PackageRelationship(Package pkg, PackagePart sourcePart,
|
||||
URI targetUri, TargetMode targetMode, String relationshipType,
|
||||
String id) {
|
||||
if (pkg == null)
|
||||
throw new IllegalArgumentException("pkg");
|
||||
if (targetUri == null)
|
||||
throw new IllegalArgumentException("targetUri");
|
||||
if (relationshipType == null)
|
||||
throw new IllegalArgumentException("relationshipType");
|
||||
if (id == null)
|
||||
throw new IllegalArgumentException("id");
|
||||
|
||||
this.container = pkg;
|
||||
this.source = sourcePart;
|
||||
this.targetUri = targetUri;
|
||||
this.targetMode = targetMode;
|
||||
this.relationshipType = relationshipType;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof PackageRelationship)) {
|
||||
return false;
|
||||
}
|
||||
PackageRelationship rel = (PackageRelationship) obj;
|
||||
return (this.id == rel.id
|
||||
&& this.relationshipType == rel.relationshipType
|
||||
&& (rel.source != null ? rel.source.equals(this.source) : true)
|
||||
&& this.targetMode == rel.targetMode && this.targetUri
|
||||
.equals(rel.targetUri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode() + this.relationshipType.hashCode()
|
||||
+ this.source.hashCode() + this.targetMode.hashCode()
|
||||
+ this.targetUri.hashCode();
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
public URI getContainerPartRelationship() {
|
||||
return containerRelationshipPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the container
|
||||
*/
|
||||
public Package getPackage() {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the relationshipType
|
||||
*/
|
||||
public String getRelationshipType() {
|
||||
return relationshipType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the source
|
||||
*/
|
||||
public PackagePart getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public URI getSourceURI() {
|
||||
if (source == null) {
|
||||
return PackagingURIHelper.PACKAGE_ROOT_URI;
|
||||
}
|
||||
return source.partName.getURI();
|
||||
}
|
||||
|
||||
/**
|
||||
* public URI getSourceUri(){ }
|
||||
*
|
||||
* @return the targetMode
|
||||
*/
|
||||
public TargetMode getTargetMode() {
|
||||
return targetMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the targetUri
|
||||
*/
|
||||
public URI getTargetURI() {
|
||||
// If it's an external target, we don't
|
||||
// need to apply our normal validation rules
|
||||
if(targetMode == TargetMode.EXTERNAL) {
|
||||
return targetUri;
|
||||
}
|
||||
|
||||
// Internal target
|
||||
// If it isn't absolute, resolve it relative
|
||||
// to ourselves
|
||||
if (!targetUri.toASCIIString().startsWith("/")) {
|
||||
// So it's a relative part name, try to resolve it
|
||||
return PackagingURIHelper.resolvePartUri(getSourceURI(), targetUri);
|
||||
}
|
||||
return targetUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(id == null ? "id=null" : "id=" + id);
|
||||
sb.append(container == null ? " - container=null" : " - container="
|
||||
+ container.toString());
|
||||
sb.append(relationshipType == null ? " - relationshipType=null"
|
||||
: " - relationshipType=" + relationshipType.toString());
|
||||
sb.append(source == null ? " - source=null" : " - source="
|
||||
+ getSourceURI().toASCIIString());
|
||||
sb.append(targetUri == null ? " - target=null" : " - target="
|
||||
+ getTargetURI().toASCIIString());
|
||||
sb.append(targetMode == null ? ",targetMode=null" : ",targetMode="
|
||||
+ targetMode.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
450
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
Executable file
450
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java
Executable file
@ -0,0 +1,450 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dom4j.Attribute;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
|
||||
/**
|
||||
* Represents a collection of PackageRelationship elements that are owned by a
|
||||
* given PackagePart or the Package.
|
||||
*
|
||||
* @author Julien Chable, CDubettier
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class PackageRelationshipCollection implements
|
||||
Iterable<PackageRelationship> {
|
||||
|
||||
private static Logger logger = Logger.getLogger("org.openxml4j.opc");
|
||||
|
||||
/**
|
||||
* Package relationships ordered by ID.
|
||||
*/
|
||||
private TreeMap<String, PackageRelationship> relationshipsByID;
|
||||
|
||||
/**
|
||||
* Package relationships ordered by type.
|
||||
*/
|
||||
private TreeMap<String, PackageRelationship> relationshipsByType;
|
||||
|
||||
/**
|
||||
* This relationshipPart.
|
||||
*/
|
||||
private PackagePart relationshipPart;
|
||||
|
||||
/**
|
||||
* Source part.
|
||||
*/
|
||||
private PackagePart sourcePart;
|
||||
|
||||
/**
|
||||
* This part name.
|
||||
*/
|
||||
private PackagePartName partName;
|
||||
|
||||
/**
|
||||
* Reference to the package.
|
||||
*/
|
||||
private Package container;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
PackageRelationshipCollection() {
|
||||
relationshipsByID = new TreeMap<String, PackageRelationship>();
|
||||
relationshipsByType = new TreeMap<String, PackageRelationship>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* This collection will contain only elements from the specified collection
|
||||
* for which the type is compatible with the specified relationship type
|
||||
* filter.
|
||||
*
|
||||
* @param coll
|
||||
* Collection to import.
|
||||
* @param filter
|
||||
* Relationship type filter.
|
||||
*/
|
||||
public PackageRelationshipCollection(PackageRelationshipCollection coll,
|
||||
String filter) {
|
||||
this();
|
||||
for (PackageRelationship rel : coll.relationshipsByID.values()) {
|
||||
if (filter == null || rel.getRelationshipType().equals(filter))
|
||||
addRelationship(rel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public PackageRelationshipCollection(Package container)
|
||||
throws InvalidFormatException {
|
||||
this(container, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the format of the content part is invalid.
|
||||
*
|
||||
* @throws InvalidOperationException
|
||||
* Throws if the specified part is a relationship part.
|
||||
*/
|
||||
public PackageRelationshipCollection(PackagePart part)
|
||||
throws InvalidFormatException {
|
||||
this(part.container, part);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Parse the existing package relationship part if one exists.
|
||||
*
|
||||
* @param container
|
||||
* The parent package.
|
||||
* @param part
|
||||
* The part that own this relationships collection. If <b>null</b>
|
||||
* then this part is considered as the package root.
|
||||
* @throws InvalidFormatException
|
||||
* If an error occurs during the parsing of the relatinships
|
||||
* part fo the specified part.
|
||||
*/
|
||||
public PackageRelationshipCollection(Package container, PackagePart part)
|
||||
throws InvalidFormatException {
|
||||
this();
|
||||
|
||||
if (container == null)
|
||||
throw new IllegalArgumentException("container");
|
||||
|
||||
// Check if the specified part is not a relationship part
|
||||
if (part != null && part.isRelationshipPart())
|
||||
throw new IllegalArgumentException("part");
|
||||
|
||||
this.container = container;
|
||||
this.sourcePart = part;
|
||||
this.partName = getRelationshipPartName(part);
|
||||
if ((container.getPackageAccess() != PackageAccess.WRITE)
|
||||
&& container.containPart(this.partName)) {
|
||||
relationshipPart = container.getPart(this.partName);
|
||||
parseRelationshipsPart(relationshipPart);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relationship part name of the specified part.
|
||||
*
|
||||
* @param part
|
||||
* The part .
|
||||
* @return The relationship part name of the specified part. Be careful,
|
||||
* only the correct name is returned, this method does not check if
|
||||
* the part really exist in a package !
|
||||
* @throws InvalidOperationException
|
||||
* Throws if the specified part is a relationship part.
|
||||
*/
|
||||
private static PackagePartName getRelationshipPartName(PackagePart part)
|
||||
throws InvalidOperationException {
|
||||
PackagePartName partName;
|
||||
if (part == null) {
|
||||
partName = PackagingURIHelper.PACKAGE_ROOT_PART_NAME;
|
||||
} else {
|
||||
partName = part.getPartName();
|
||||
}
|
||||
return PackagingURIHelper.getRelationshipPartName(partName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specified relationship to the collection.
|
||||
*
|
||||
* @param relPart
|
||||
* The relationship to add.
|
||||
*/
|
||||
public void addRelationship(PackageRelationship relPart) {
|
||||
relationshipsByID.put(relPart.getId(), relPart);
|
||||
relationshipsByType.put(relPart.getRelationshipType(), relPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a relationship to the collection.
|
||||
*
|
||||
* @param targetUri
|
||||
* Target URI.
|
||||
* @param targetMode
|
||||
* The target mode : INTERNAL or EXTERNAL
|
||||
* @param relationshipType
|
||||
* Relationship type.
|
||||
* @param id
|
||||
* Relationship ID.
|
||||
* @return The newly created relationship.
|
||||
* @see PackageAccess
|
||||
*/
|
||||
public PackageRelationship addRelationship(URI targetUri,
|
||||
TargetMode targetMode, String relationshipType, String id) {
|
||||
|
||||
if (id == null) {
|
||||
// Generate a unique ID is id parameter is null.
|
||||
int i = 0;
|
||||
do {
|
||||
id = "rId" + ++i;
|
||||
} while (relationshipsByID.get(id) != null);
|
||||
}
|
||||
|
||||
PackageRelationship rel = new PackageRelationship(container,
|
||||
sourcePart, targetUri, targetMode, relationshipType, id);
|
||||
relationshipsByID.put(rel.getId(), rel);
|
||||
relationshipsByType.put(rel.getRelationshipType(), rel);
|
||||
return rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a relationship by its ID.
|
||||
*
|
||||
* @param id
|
||||
* The relationship ID to remove.
|
||||
*/
|
||||
public void removeRelationship(String id) {
|
||||
if (relationshipsByID != null && relationshipsByType != null) {
|
||||
PackageRelationship rel = relationshipsByID.get(id);
|
||||
if (rel != null) {
|
||||
relationshipsByID.remove(rel.getId());
|
||||
relationshipsByType.values().remove(rel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a relationship by its reference.
|
||||
*
|
||||
* @param rel
|
||||
* The relationship to delete.
|
||||
*/
|
||||
public void removeRelationship(PackageRelationship rel) {
|
||||
if (rel == null)
|
||||
throw new IllegalArgumentException("rel");
|
||||
|
||||
relationshipsByID.values().remove(rel);
|
||||
relationshipsByType.values().remove(rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a relationship by its index in the collection.
|
||||
*
|
||||
* @param index
|
||||
* Must be a value between [0-relationships_count-1]
|
||||
*/
|
||||
public PackageRelationship getRelationship(int index) {
|
||||
if (index < 0 || index > relationshipsByID.values().size())
|
||||
throw new IllegalArgumentException("index");
|
||||
|
||||
PackageRelationship retRel = null;
|
||||
int i = 0;
|
||||
for (PackageRelationship rel : relationshipsByID.values()) {
|
||||
if (index == i++)
|
||||
return rel;
|
||||
}
|
||||
return retRel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a package relationship based on its id.
|
||||
*
|
||||
* @param id
|
||||
* ID of the package relationship to retrieve.
|
||||
* @return The package relationship identified by the specified id.
|
||||
*/
|
||||
public PackageRelationship getRelationshipByID(String id) {
|
||||
return relationshipsByID.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numbe rof relationships in the collection.
|
||||
*/
|
||||
public int size() {
|
||||
return relationshipsByID.values().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the relationship part and add all relationship in this collection.
|
||||
*
|
||||
* @param relPart
|
||||
* The package part to parse.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the relationship part is invalid.
|
||||
*/
|
||||
private void parseRelationshipsPart(PackagePart relPart)
|
||||
throws InvalidFormatException {
|
||||
try {
|
||||
SAXReader reader = new SAXReader();
|
||||
logger.debug("Parsing relationship: " + relPart.getPartName());
|
||||
Document xmlRelationshipsDoc = reader
|
||||
.read(relPart.getInputStream());
|
||||
|
||||
// Browse default types
|
||||
Element root = xmlRelationshipsDoc.getRootElement();
|
||||
|
||||
// Check OPC compliance M4.1 rule
|
||||
boolean fCorePropertiesRelationship = false;
|
||||
|
||||
for (Iterator i = root
|
||||
.elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i
|
||||
.hasNext();) {
|
||||
Element element = (Element) i.next();
|
||||
// Relationship ID
|
||||
String id = element.attribute(
|
||||
PackageRelationship.ID_ATTRIBUTE_NAME).getValue();
|
||||
// Relationship type
|
||||
String type = element.attribute(
|
||||
PackageRelationship.TYPE_ATTRIBUTE_NAME).getValue();
|
||||
|
||||
/* Check OPC Compliance */
|
||||
// Check Rule M4.1
|
||||
if (type.equals(PackageRelationshipTypes.CORE_PROPERTIES))
|
||||
if (!fCorePropertiesRelationship)
|
||||
fCorePropertiesRelationship = true;
|
||||
else
|
||||
throw new InvalidFormatException(
|
||||
"OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !");
|
||||
|
||||
/* End OPC Compliance */
|
||||
|
||||
// TargetMode (default value "Internal")
|
||||
Attribute targetModeAttr = element
|
||||
.attribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME);
|
||||
TargetMode targetMode = TargetMode.INTERNAL;
|
||||
if (targetModeAttr != null) {
|
||||
targetMode = targetModeAttr.getValue().toLowerCase()
|
||||
.equals("internal") ? TargetMode.INTERNAL
|
||||
: TargetMode.EXTERNAL;
|
||||
}
|
||||
|
||||
// Target converted in URI
|
||||
URI target;
|
||||
String value = "";
|
||||
try {
|
||||
value = element.attribute(
|
||||
PackageRelationship.TARGET_ATTRIBUTE_NAME)
|
||||
.getValue();
|
||||
|
||||
if (value.indexOf("\\") != -1) {
|
||||
logger
|
||||
.info("target contains \\ therefore not a valid URI"
|
||||
+ value + " replaced by /");
|
||||
value = value.replaceAll("\\\\", "/");
|
||||
// word can save external relationship with a \ instead
|
||||
// of /
|
||||
}
|
||||
|
||||
target = new URI(value);
|
||||
} catch (URISyntaxException e) {
|
||||
logger.error("Cannot convert " + value
|
||||
+ " in a valid relationship URI-> ignored", e);
|
||||
continue;
|
||||
}
|
||||
addRelationship(target, targetMode, type, id);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
throw new InvalidFormatException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all relations with the specified type.
|
||||
*
|
||||
* @param typeFilter
|
||||
* Relationship type filter. If <b>null</b> then all
|
||||
* relationships are returned.
|
||||
* @return All relationships of the type specified by the filter.
|
||||
*/
|
||||
public PackageRelationshipCollection getRelationships(String typeFilter) {
|
||||
PackageRelationshipCollection coll = new PackageRelationshipCollection(
|
||||
this, typeFilter);
|
||||
return coll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this collection's iterator.
|
||||
*/
|
||||
public Iterator<PackageRelationship> iterator() {
|
||||
return relationshipsByID.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator of a collection with all relationship with the specified
|
||||
* type.
|
||||
*
|
||||
* @param typeFilter
|
||||
* Type filter.
|
||||
* @return An iterator to a collection containing all relationships with the
|
||||
* specified type contain in this collection.
|
||||
*/
|
||||
public Iterator<PackageRelationship> iterator(String typeFilter) {
|
||||
ArrayList<PackageRelationship> retArr = new ArrayList<PackageRelationship>();
|
||||
for (PackageRelationship rel : relationshipsByID.values()) {
|
||||
if (rel.getRelationshipType().equals(typeFilter))
|
||||
retArr.add(rel);
|
||||
}
|
||||
return retArr.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all relationships.
|
||||
*/
|
||||
public void clear() {
|
||||
relationshipsByID.clear();
|
||||
relationshipsByType.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str;
|
||||
if (relationshipsByID == null) {
|
||||
str = "relationshipsByID=null";
|
||||
} else {
|
||||
str = relationshipsByID.size() + " relationship(s) = [";
|
||||
}
|
||||
if ((relationshipPart != null) && (relationshipPart.partName != null)) {
|
||||
str = str + "," + relationshipPart.partName;
|
||||
} else {
|
||||
str = str + ",relationshipPart=null";
|
||||
}
|
||||
|
||||
// Source of this relationship
|
||||
if ((sourcePart != null) && (sourcePart.partName != null)) {
|
||||
str = str + "," + sourcePart.partName;
|
||||
} else {
|
||||
str = str + ",sourcePart=null";
|
||||
}
|
||||
if (partName != null) {
|
||||
str = str + "," + partName;
|
||||
} else {
|
||||
str = str + ",uri=null)";
|
||||
}
|
||||
return str + "]";
|
||||
}
|
||||
}
|
77
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
Executable file
77
src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipTypes.java
Executable file
@ -0,0 +1,77 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
/**
|
||||
* Relationship types.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.2
|
||||
*/
|
||||
public interface PackageRelationshipTypes {
|
||||
|
||||
/**
|
||||
* Core properties relationship type.
|
||||
*/
|
||||
String CORE_PROPERTIES = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||
|
||||
/**
|
||||
* Digital signature relationship type.
|
||||
*/
|
||||
String DIGITAL_SIGNATURE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature";
|
||||
|
||||
/**
|
||||
* Digital signature certificate relationship type.
|
||||
*/
|
||||
String DIGITAL_SIGNATURE_CERTIFICATE = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate";
|
||||
|
||||
/**
|
||||
* Digital signature origin relationship type.
|
||||
*/
|
||||
String DIGITAL_SIGNATURE_ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin";
|
||||
|
||||
/**
|
||||
* Thumbnail relationship type.
|
||||
*/
|
||||
String THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||
|
||||
/**
|
||||
* Extended properties relationship type.
|
||||
*/
|
||||
String EXTENDED_PROPERTIES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
|
||||
|
||||
/**
|
||||
* Core properties relationship type.
|
||||
*/
|
||||
String CORE_DOCUMENT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
|
||||
|
||||
/**
|
||||
* Custom XML relationship type.
|
||||
*/
|
||||
String CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
|
||||
|
||||
/**
|
||||
* Image type.
|
||||
*/
|
||||
String IMAGE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
||||
|
||||
/**
|
||||
* Style type.
|
||||
*/
|
||||
String STYLE_PART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
|
||||
}
|
623
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java
Executable file
623
src/ooxml/java/org/apache/poi/openxml4j/opc/PackagingURIHelper.java
Executable file
@ -0,0 +1,623 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
|
||||
/**
|
||||
* Helper for part and pack URI.
|
||||
*
|
||||
* @author Julien Chable, CDubet, Kim Ung
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class PackagingURIHelper {
|
||||
|
||||
/**
|
||||
* Package root URI.
|
||||
*/
|
||||
private static URI packageRootUri;
|
||||
|
||||
/**
|
||||
* Extension name of a relationship part.
|
||||
*/
|
||||
public static final String RELATIONSHIP_PART_EXTENSION_NAME;
|
||||
|
||||
/**
|
||||
* Segment name of a relationship part.
|
||||
*/
|
||||
public static final String RELATIONSHIP_PART_SEGMENT_NAME;
|
||||
|
||||
/**
|
||||
* Segment name of the package properties folder.
|
||||
*/
|
||||
public static final String PACKAGE_PROPERTIES_SEGMENT_NAME;
|
||||
|
||||
/**
|
||||
* Core package properties art name.
|
||||
*/
|
||||
public static final String PACKAGE_CORE_PROPERTIES_NAME;
|
||||
|
||||
/**
|
||||
* Forward slash URI separator.
|
||||
*/
|
||||
public static final char FORWARD_SLASH_CHAR;
|
||||
|
||||
/**
|
||||
* Forward slash URI separator.
|
||||
*/
|
||||
public static final String FORWARD_SLASH_STRING;
|
||||
|
||||
/**
|
||||
* Package relationships part URI
|
||||
*/
|
||||
public static final URI PACKAGE_RELATIONSHIPS_ROOT_URI;
|
||||
|
||||
/**
|
||||
* Package relationships part name.
|
||||
*/
|
||||
public static final PackagePartName PACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
|
||||
|
||||
/**
|
||||
* Core properties part URI.
|
||||
*/
|
||||
public static final URI CORE_PROPERTIES_URI;
|
||||
|
||||
/**
|
||||
* Core properties partname.
|
||||
*/
|
||||
public static final PackagePartName CORE_PROPERTIES_PART_NAME;
|
||||
|
||||
/**
|
||||
* Root package URI.
|
||||
*/
|
||||
public static final URI PACKAGE_ROOT_URI;
|
||||
|
||||
/**
|
||||
* Root package part name.
|
||||
*/
|
||||
public static final PackagePartName PACKAGE_ROOT_PART_NAME;
|
||||
|
||||
/* Static initialization */
|
||||
static {
|
||||
RELATIONSHIP_PART_SEGMENT_NAME = "_rels";
|
||||
RELATIONSHIP_PART_EXTENSION_NAME = ".rels";
|
||||
FORWARD_SLASH_CHAR = '/';
|
||||
FORWARD_SLASH_STRING = "/";
|
||||
PACKAGE_PROPERTIES_SEGMENT_NAME = "docProps";
|
||||
PACKAGE_CORE_PROPERTIES_NAME = "core.xml";
|
||||
|
||||
// Make URI
|
||||
URI uriPACKAGE_ROOT_URI = null;
|
||||
URI uriPACKAGE_RELATIONSHIPS_ROOT_URI = null;
|
||||
URI uriPACKAGE_PROPERTIES_URI = null;
|
||||
try {
|
||||
uriPACKAGE_ROOT_URI = new URI("/");
|
||||
uriPACKAGE_RELATIONSHIPS_ROOT_URI = new URI(FORWARD_SLASH_CHAR
|
||||
+ RELATIONSHIP_PART_SEGMENT_NAME + FORWARD_SLASH_CHAR
|
||||
+ RELATIONSHIP_PART_EXTENSION_NAME);
|
||||
packageRootUri = new URI("/");
|
||||
uriPACKAGE_PROPERTIES_URI = new URI(FORWARD_SLASH_CHAR
|
||||
+ PACKAGE_PROPERTIES_SEGMENT_NAME + FORWARD_SLASH_CHAR
|
||||
+ PACKAGE_CORE_PROPERTIES_NAME);
|
||||
} catch (URISyntaxException e) {
|
||||
// Should never happen in production as all data are fixed
|
||||
}
|
||||
PACKAGE_ROOT_URI = uriPACKAGE_ROOT_URI;
|
||||
PACKAGE_RELATIONSHIPS_ROOT_URI = uriPACKAGE_RELATIONSHIPS_ROOT_URI;
|
||||
CORE_PROPERTIES_URI = uriPACKAGE_PROPERTIES_URI;
|
||||
|
||||
// Make part name from previous URI
|
||||
PackagePartName tmpPACKAGE_ROOT_PART_NAME = null;
|
||||
PackagePartName tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = null;
|
||||
PackagePartName tmpCORE_PROPERTIES_URI = null;
|
||||
try {
|
||||
tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = createPartName(PACKAGE_RELATIONSHIPS_ROOT_URI);
|
||||
tmpCORE_PROPERTIES_URI = createPartName(CORE_PROPERTIES_URI);
|
||||
tmpPACKAGE_ROOT_PART_NAME = new PackagePartName(PACKAGE_ROOT_URI,
|
||||
false);
|
||||
} catch (InvalidFormatException e) {
|
||||
// Should never happen in production as all data are fixed
|
||||
}
|
||||
PACKAGE_RELATIONSHIPS_ROOT_PART_NAME = tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
|
||||
CORE_PROPERTIES_PART_NAME = tmpCORE_PROPERTIES_URI;
|
||||
PACKAGE_ROOT_PART_NAME = tmpPACKAGE_ROOT_PART_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URI for the package root.
|
||||
*
|
||||
* @return URI of the package root.
|
||||
*/
|
||||
public static URI getPackageRootUri() {
|
||||
return packageRootUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Know if the specified URI is a relationship part name.
|
||||
*
|
||||
* @param partUri
|
||||
* URI to check.
|
||||
* @return <i>true</i> if the URI <i>false</i>.
|
||||
*/
|
||||
public static boolean isRelationshipPartURI(URI partUri) {
|
||||
if (partUri == null)
|
||||
throw new IllegalArgumentException("partUri");
|
||||
|
||||
return partUri.getPath().matches(
|
||||
".*" + RELATIONSHIP_PART_SEGMENT_NAME + ".*"
|
||||
+ RELATIONSHIP_PART_EXTENSION_NAME + "$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file name from the specified URI.
|
||||
*/
|
||||
public static String getFilename(URI uri) {
|
||||
if (uri != null) {
|
||||
String path = uri.getPath();
|
||||
int len = path.length();
|
||||
int num2 = len;
|
||||
while (--num2 >= 0) {
|
||||
char ch1 = path.charAt(num2);
|
||||
if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR)
|
||||
return path.substring(num2 + 1, len);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file name without the trailing extension.
|
||||
*/
|
||||
public static String getFilenameWithoutExtension(URI uri) {
|
||||
String filename = getFilename(uri);
|
||||
int dotIndex = filename.lastIndexOf(".");
|
||||
if (dotIndex == -1)
|
||||
return filename;
|
||||
return filename.substring(0, dotIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directory path from the specified URI.
|
||||
*/
|
||||
public static URI getPath(URI uri) {
|
||||
if (uri != null) {
|
||||
String path = uri.getPath();
|
||||
int len = path.length();
|
||||
int num2 = len;
|
||||
while (--num2 >= 0) {
|
||||
char ch1 = path.charAt(num2);
|
||||
if (ch1 == PackagingURIHelper.FORWARD_SLASH_CHAR) {
|
||||
try {
|
||||
return new URI(path.substring(0, num2));
|
||||
} catch (URISyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine les deux URI.
|
||||
*
|
||||
* @param prefix
|
||||
* L'URI de pr<EFBFBD>fixe.
|
||||
* @param suffix
|
||||
* L'URI de suffixe.
|
||||
* @return
|
||||
*/
|
||||
public static URI combine(URI prefix, URI suffix) {
|
||||
URI retUri = null;
|
||||
try {
|
||||
retUri = new URI(combine(prefix.getPath(), suffix.getPath()));
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Prefix and suffix can't be combine !");
|
||||
}
|
||||
return retUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine a string URI with a prefix and a suffix.
|
||||
*/
|
||||
public static String combine(String prefix, String suffix) {
|
||||
if (!prefix.endsWith("" + FORWARD_SLASH_CHAR)
|
||||
&& !suffix.startsWith("" + FORWARD_SLASH_CHAR))
|
||||
return prefix + FORWARD_SLASH_CHAR + suffix;
|
||||
else if ((!prefix.endsWith("" + FORWARD_SLASH_CHAR)
|
||||
&& suffix.startsWith("" + FORWARD_SLASH_CHAR) || (prefix
|
||||
.endsWith("" + FORWARD_SLASH_CHAR) && !suffix.startsWith(""
|
||||
+ FORWARD_SLASH_CHAR))))
|
||||
return prefix + suffix;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully relativize the source part URI against the target part URI.
|
||||
*
|
||||
* @param sourceURI
|
||||
* The source part URI.
|
||||
* @param targetURI
|
||||
* The target part URI.
|
||||
* @return A fully relativize part name URI ('word/media/image1.gif',
|
||||
* '/word/document.xml' => 'media/image1.gif') else
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public static URI relativizeURI(URI sourceURI, URI targetURI) {
|
||||
StringBuilder retVal = new StringBuilder();
|
||||
String[] segmentsSource = sourceURI.getPath().split("/", -1);
|
||||
String[] segmentsTarget = targetURI.getPath().split("/", -1);
|
||||
|
||||
// If the source URI is empty
|
||||
if (segmentsSource.length == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't relativize an empty source URI !");
|
||||
}
|
||||
|
||||
// If target URI is empty
|
||||
if (segmentsTarget.length == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't relativize an empty target URI !");
|
||||
}
|
||||
|
||||
// If the source is the root, then the relativized
|
||||
// form must actually be an absolute URI
|
||||
if(sourceURI.toString().equals("/")) {
|
||||
return targetURI;
|
||||
}
|
||||
|
||||
|
||||
// Relativize the source URI against the target URI.
|
||||
// First up, figure out how many steps along we can go
|
||||
// and still have them be the same
|
||||
int segmentsTheSame = 0;
|
||||
for (int i = 0; i < segmentsSource.length && i < segmentsTarget.length; i++) {
|
||||
if (segmentsSource[i].equals(segmentsTarget[i])) {
|
||||
// Match so far, good
|
||||
segmentsTheSame++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't have a good match or at least except a first empty element
|
||||
if ((segmentsTheSame == 0 || segmentsTheSame == 1) &&
|
||||
segmentsSource[0].equals("") && segmentsTarget[0].equals("")) {
|
||||
for (int i = 0; i < segmentsSource.length - 2; i++) {
|
||||
retVal.append("../");
|
||||
}
|
||||
for (int i = 0; i < segmentsTarget.length; i++) {
|
||||
if (segmentsTarget[i].equals(""))
|
||||
continue;
|
||||
retVal.append(segmentsTarget[i]);
|
||||
if (i != segmentsTarget.length - 1)
|
||||
retVal.append("/");
|
||||
}
|
||||
|
||||
try {
|
||||
return new URI(retVal.toString());
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Special case for where the two are the same
|
||||
if (segmentsTheSame == segmentsSource.length
|
||||
&& segmentsTheSame == segmentsTarget.length) {
|
||||
retVal.append("");
|
||||
} else {
|
||||
// Matched for so long, but no more
|
||||
|
||||
// Do we need to go up a directory or two from
|
||||
// the source to get here?
|
||||
// (If it's all the way up, then don't bother!)
|
||||
if (segmentsTheSame == 1) {
|
||||
retVal.append("/");
|
||||
} else {
|
||||
for (int j = segmentsTheSame; j < segmentsSource.length - 1; j++) {
|
||||
retVal.append("../");
|
||||
}
|
||||
}
|
||||
|
||||
// Now go from here on down
|
||||
for (int j = segmentsTheSame; j < segmentsTarget.length; j++) {
|
||||
if (retVal.length() > 0
|
||||
&& retVal.charAt(retVal.length() - 1) != '/') {
|
||||
retVal.append("/");
|
||||
}
|
||||
retVal.append(segmentsTarget[j]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return new URI(retVal.toString());
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a source uri against a target.
|
||||
*
|
||||
* @param sourcePartUri
|
||||
* The source URI.
|
||||
* @param targetUri
|
||||
* The target URI.
|
||||
* @return The resolved URI.
|
||||
*/
|
||||
public static URI resolvePartUri(URI sourcePartUri, URI targetUri) {
|
||||
if (sourcePartUri == null || sourcePartUri.isAbsolute()) {
|
||||
throw new IllegalArgumentException("sourcePartUri invalid - "
|
||||
+ sourcePartUri);
|
||||
}
|
||||
|
||||
if (targetUri == null || targetUri.isAbsolute()) {
|
||||
throw new IllegalArgumentException("targetUri invalid - "
|
||||
+ targetUri);
|
||||
}
|
||||
|
||||
return sourcePartUri.resolve(targetUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI from a string path.
|
||||
*/
|
||||
public static URI getURIFromPath(String path) {
|
||||
URI retUri = null;
|
||||
try {
|
||||
retUri = new URI(path);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException("path");
|
||||
}
|
||||
return retUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source part URI from a specified relationships part.
|
||||
*
|
||||
* @param relationshipPartUri
|
||||
* The relationship part use to retrieve the source part.
|
||||
* @return The source part URI from the specified relationships part.
|
||||
*/
|
||||
public static URI getSourcePartUriFromRelationshipPartUri(
|
||||
URI relationshipPartUri) {
|
||||
if (relationshipPartUri == null)
|
||||
throw new IllegalArgumentException(
|
||||
"Le param<61>tre relationshipPartUri ne doit pas <20>tre null !");
|
||||
|
||||
if (!isRelationshipPartURI(relationshipPartUri))
|
||||
throw new IllegalArgumentException(
|
||||
"L'URI ne doit pas <20>tre celle d'une partie de type relation.");
|
||||
|
||||
if (relationshipPartUri.compareTo(PACKAGE_RELATIONSHIPS_ROOT_URI) == 0)
|
||||
return PACKAGE_ROOT_URI;
|
||||
|
||||
String filename = relationshipPartUri.getPath();
|
||||
String filenameWithoutExtension = getFilenameWithoutExtension(relationshipPartUri);
|
||||
filename = filename
|
||||
.substring(0, ((filename.length() - filenameWithoutExtension
|
||||
.length()) - RELATIONSHIP_PART_EXTENSION_NAME.length()));
|
||||
filename = filename.substring(0, filename.length()
|
||||
- RELATIONSHIP_PART_SEGMENT_NAME.length() - 1);
|
||||
filename = combine(filename, filenameWithoutExtension);
|
||||
return getURIFromPath(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an OPC compliant part name by throwing an exception if the URI is
|
||||
* not valid.
|
||||
*
|
||||
* @param partUri
|
||||
* The part name URI to validate.
|
||||
* @return A valid part name object, else <code>null</code>.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the specified URI is not OPC compliant.
|
||||
*/
|
||||
public static PackagePartName createPartName(URI partUri)
|
||||
throws InvalidFormatException {
|
||||
if (partUri == null)
|
||||
throw new IllegalArgumentException("partName");
|
||||
|
||||
return new PackagePartName(partUri, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an OPC compliant part name.
|
||||
*
|
||||
* @param partName
|
||||
* The part name to validate.
|
||||
* @return The correspondant part name if valid, else <code>null</code>.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the specified part name is not OPC compliant.
|
||||
* @see #createPartName(URI)
|
||||
*/
|
||||
public static PackagePartName createPartName(String partName)
|
||||
throws InvalidFormatException {
|
||||
URI partNameURI;
|
||||
try {
|
||||
partNameURI = new URI(partName);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidFormatException(e.getMessage());
|
||||
}
|
||||
return createPartName(partNameURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an OPC compliant part name by resolving it using a base part.
|
||||
*
|
||||
* @param partName
|
||||
* The part name to validate.
|
||||
* @param relativePart
|
||||
* The relative base part.
|
||||
* @return The correspondant part name if valid, else <code>null</code>.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the specified part name is not OPC compliant.
|
||||
* @see #createPartName(URI)
|
||||
*/
|
||||
public static PackagePartName createPartName(String partName,
|
||||
PackagePart relativePart) throws InvalidFormatException {
|
||||
URI newPartNameURI;
|
||||
try {
|
||||
newPartNameURI = resolvePartUri(
|
||||
relativePart.getPartName().getURI(), new URI(partName));
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidFormatException(e.getMessage());
|
||||
}
|
||||
return createPartName(newPartNameURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an OPC compliant part name by resolving it using a base part.
|
||||
*
|
||||
* @param partName
|
||||
* The part name URI to validate.
|
||||
* @param relativePart
|
||||
* The relative base part.
|
||||
* @return The correspondant part name if valid, else <code>null</code>.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the specified part name is not OPC compliant.
|
||||
* @see #createPartName(URI)
|
||||
*/
|
||||
public static PackagePartName createPartName(URI partName,
|
||||
PackagePart relativePart) throws InvalidFormatException {
|
||||
URI newPartNameURI = resolvePartUri(
|
||||
relativePart.getPartName().getURI(), partName);
|
||||
return createPartName(newPartNameURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a part URI by returning a boolean.
|
||||
* ([M1.1],[M1.3],[M1.4],[M1.5],[M1.6])
|
||||
*
|
||||
* (OPC Specifications 8.1.1 Part names) :
|
||||
*
|
||||
* Part Name Syntax
|
||||
*
|
||||
* The part name grammar is defined as follows:
|
||||
*
|
||||
* <i>part_name = 1*( "/" segment )
|
||||
*
|
||||
* segment = 1*( pchar )</i>
|
||||
*
|
||||
*
|
||||
* (pchar is defined in RFC 3986)
|
||||
*
|
||||
* @param partUri
|
||||
* The URI to validate.
|
||||
* @return <b>true</b> if the URI is valid to the OPC Specifications, else
|
||||
* <b>false</b>
|
||||
*
|
||||
* @see #createPartName(URI)
|
||||
*/
|
||||
public static boolean isValidPartName(URI partUri) {
|
||||
if (partUri == null)
|
||||
throw new IllegalArgumentException("partUri");
|
||||
|
||||
try {
|
||||
createPartName(partUri);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a URI by converting all percent encoded character into a String
|
||||
* character.
|
||||
*
|
||||
* @param uri
|
||||
* The URI to decode.
|
||||
* @return The specified URI in a String with converted percent encoded
|
||||
* characters.
|
||||
*/
|
||||
public static String decodeURI(URI uri) {
|
||||
StringBuffer retVal = new StringBuffer();
|
||||
String uriStr = uri.toASCIIString();
|
||||
char c;
|
||||
for (int i = 0; i < uriStr.length(); ++i) {
|
||||
c = uriStr.charAt(i);
|
||||
if (c == '%') {
|
||||
// We certainly found an encoded character, check for length
|
||||
// now ( '%' HEXDIGIT HEXDIGIT)
|
||||
if (((uriStr.length() - i) < 2)) {
|
||||
throw new IllegalArgumentException("The uri " + uriStr
|
||||
+ " contain invalid encoded character !");
|
||||
}
|
||||
|
||||
// Decode the encoded character
|
||||
char decodedChar = (char) Integer.parseInt(uriStr.substring(
|
||||
i + 1, i + 3), 16);
|
||||
retVal.append(decodedChar);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
retVal.append(c);
|
||||
}
|
||||
return retVal.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a part name where the relationship should be stored ((ex
|
||||
* /word/document.xml -> /word/_rels/document.xml.rels)
|
||||
*
|
||||
* @param partName
|
||||
* Source part URI
|
||||
* @return the full path (as URI) of the relation file
|
||||
* @throws InvalidOperationException
|
||||
* Throws if the specified URI is a relationshp part.
|
||||
*/
|
||||
public static PackagePartName getRelationshipPartName(
|
||||
PackagePartName partName) {
|
||||
if (partName == null)
|
||||
throw new IllegalArgumentException("partName");
|
||||
|
||||
if (PackagingURIHelper.PACKAGE_ROOT_URI.getPath() == partName.getURI()
|
||||
.getPath())
|
||||
return PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME;
|
||||
|
||||
if (partName.isRelationshipPartURI())
|
||||
throw new InvalidOperationException("Can't be a relationship part");
|
||||
|
||||
String fullPath = partName.getURI().getPath();
|
||||
String filename = getFilename(partName.getURI());
|
||||
fullPath = fullPath.substring(0, fullPath.length() - filename.length());
|
||||
fullPath = combine(fullPath,
|
||||
PackagingURIHelper.RELATIONSHIP_PART_SEGMENT_NAME);
|
||||
fullPath = combine(fullPath, filename);
|
||||
fullPath = fullPath
|
||||
+ PackagingURIHelper.RELATIONSHIP_PART_EXTENSION_NAME;
|
||||
|
||||
PackagePartName retPartName;
|
||||
try {
|
||||
retPartName = createPartName(fullPath);
|
||||
} catch (InvalidFormatException e) {
|
||||
// Should never happen in production as all data are fixed but in
|
||||
// case of return null:
|
||||
return null;
|
||||
}
|
||||
return retPartName;
|
||||
}
|
||||
}
|
166
src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java
Executable file
166
src/ooxml/java/org/apache/poi/openxml4j/opc/RelationshipSource.java
Executable file
@ -0,0 +1,166 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
|
||||
public interface RelationshipSource {
|
||||
|
||||
/**
|
||||
* Add a relationship to a part (except relationships part).
|
||||
*
|
||||
* @param targetPartName
|
||||
* Name of the target part. This one must be relative to the
|
||||
* source root directory of the part.
|
||||
* @param targetMode
|
||||
* Mode [Internal|External].
|
||||
* @param relationshipType
|
||||
* Type of relationship.
|
||||
* @return The newly created and added relationship
|
||||
*/
|
||||
public abstract PackageRelationship addRelationship(
|
||||
PackagePartName targetPartName, TargetMode targetMode,
|
||||
String relationshipType);
|
||||
|
||||
/**
|
||||
* Add a relationship to a part (except relationships part).
|
||||
*
|
||||
* Check rule M1.25: The Relationships part shall not have relationships to
|
||||
* any other part. Package implementers shall enforce this requirement upon
|
||||
* the attempt to create such a relationship and shall treat any such
|
||||
* relationship as invalid.
|
||||
*
|
||||
* @param targetPartName
|
||||
* Name of the target part. This one must be relative to the
|
||||
* source root directory of the part.
|
||||
* @param targetMode
|
||||
* Mode [Internal|External].
|
||||
* @param relationshipType
|
||||
* Type of relationship.
|
||||
* @param id
|
||||
* Relationship unique id.
|
||||
* @return The newly created and added relationship
|
||||
*
|
||||
* @throws InvalidFormatException
|
||||
* If the URI point to a relationship part URI.
|
||||
*/
|
||||
public abstract PackageRelationship addRelationship(
|
||||
PackagePartName targetPartName, TargetMode targetMode,
|
||||
String relationshipType, String id);
|
||||
|
||||
/**
|
||||
* Adds an external relationship to a part
|
||||
* (except relationships part).
|
||||
*
|
||||
* The targets of external relationships are not
|
||||
* subject to the same validity checks that internal
|
||||
* ones are, as the contents is potentially
|
||||
* any file, URL or similar.
|
||||
*
|
||||
* @param target External target of the relationship
|
||||
* @param relationshipType Type of relationship.
|
||||
* @return The newly created and added relationship
|
||||
* @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public PackageRelationship addExternalRelationship(String target, String relationshipType);
|
||||
|
||||
/**
|
||||
* Adds an external relationship to a part
|
||||
* (except relationships part).
|
||||
*
|
||||
* The targets of external relationships are not
|
||||
* subject to the same validity checks that internal
|
||||
* ones are, as the contents is potentially
|
||||
* any file, URL or similar.
|
||||
*
|
||||
* @param target External target of the relationship
|
||||
* @param relationshipType Type of relationship.
|
||||
* @param id Relationship unique id.
|
||||
* @return The newly created and added relationship
|
||||
* @see org.apache.poi.openxml4j.opc.RelationshipSource#addExternalRelationship(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public PackageRelationship addExternalRelationship(String target, String relationshipType, String id);
|
||||
|
||||
/**
|
||||
* Delete all the relationships attached to this.
|
||||
*/
|
||||
public abstract void clearRelationships();
|
||||
|
||||
/**
|
||||
* Delete the relationship specified by its id.
|
||||
*
|
||||
* @param id
|
||||
* The ID identified the part to delete.
|
||||
*/
|
||||
public abstract void removeRelationship(String id);
|
||||
|
||||
/**
|
||||
* Retrieve all the relationships attached to this.
|
||||
*
|
||||
* @return This part's relationships.
|
||||
* @throws OpenXML4JException
|
||||
*/
|
||||
public abstract PackageRelationshipCollection getRelationships()
|
||||
throws InvalidFormatException, OpenXML4JException;
|
||||
|
||||
/**
|
||||
* Retrieves a package relationship from its id.
|
||||
*
|
||||
* @param id
|
||||
* ID of the package relationship to retrieve.
|
||||
* @return The package relationship
|
||||
*/
|
||||
public abstract PackageRelationship getRelationship(String id);
|
||||
|
||||
/**
|
||||
* Retrieve all relationships attached to this part which have the specified
|
||||
* type.
|
||||
*
|
||||
* @param relationshipType
|
||||
* Relationship type filter.
|
||||
* @return All relationships from this part that have the specified type.
|
||||
* @throws InvalidFormatException
|
||||
* If an error occurs while parsing the part.
|
||||
* @throws InvalidOperationException
|
||||
* If the package is open in write only mode.
|
||||
*/
|
||||
public abstract PackageRelationshipCollection getRelationshipsByType(
|
||||
String relationshipType) throws InvalidFormatException,
|
||||
IllegalArgumentException, OpenXML4JException;
|
||||
|
||||
/**
|
||||
* Knows if the part have any relationships.
|
||||
*
|
||||
* @return <b>true</b> if the part have at least one relationship else
|
||||
* <b>false</b>.
|
||||
*/
|
||||
public abstract boolean hasRelationships();
|
||||
|
||||
/**
|
||||
* Checks if the specified relationship is part of this package part.
|
||||
*
|
||||
* @param rel
|
||||
* The relationship to check.
|
||||
* @return <b>true</b> if the specified relationship exists in this part,
|
||||
* else returns <b>false</b>
|
||||
*/
|
||||
@SuppressWarnings("finally")
|
||||
public abstract boolean isRelationshipExists(PackageRelationship rel);
|
||||
|
||||
}
|
77
src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java
Executable file
77
src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java
Executable file
@ -0,0 +1,77 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
|
||||
public final class StreamHelper {
|
||||
|
||||
private StreamHelper() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Turning the DOM4j object in the specified output stream.
|
||||
*
|
||||
* @param xmlContent
|
||||
* The XML document.
|
||||
* @param outStream
|
||||
* The OutputStream in which the XML document will be written.
|
||||
* @return <b>true</b> if the xml is successfully written in the stream,
|
||||
* else <b>false</b>.
|
||||
*/
|
||||
public static boolean saveXmlInStream(Document xmlContent,
|
||||
OutputStream outStream) {
|
||||
try {
|
||||
OutputFormat outformat = OutputFormat.createPrettyPrint();
|
||||
outformat.setEncoding("UTF-8");
|
||||
XMLWriter writer = new XMLWriter(outStream, outformat);
|
||||
writer.write(xmlContent);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the input stream into the output stream.
|
||||
*
|
||||
* @param inStream
|
||||
* The source stream.
|
||||
* @param outStream
|
||||
* The destination stream.
|
||||
* @return <b>true</b> if the operation succeed, else return <b>false</b>.
|
||||
*/
|
||||
public static boolean copyStream(InputStream inStream, OutputStream outStream) {
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inStream.read(buffer)) >= 0) {
|
||||
outStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
32
src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java
Executable file
32
src/ooxml/java/org/apache/poi/openxml4j/opc/TargetMode.java
Executable file
@ -0,0 +1,32 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.openxml4j.opc;
|
||||
|
||||
/**
|
||||
* Specifies whether the target of a PackageRelationship is inside or outside a
|
||||
* Package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public enum TargetMode {
|
||||
/** The relationship references a resource that is external to the package. */
|
||||
INTERNAL,
|
||||
/** The relationship references a part that is inside the package. */
|
||||
EXTERNAL
|
||||
}
|
464
src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
Executable file
464
src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackage.java
Executable file
@ -0,0 +1,464 @@
|
||||
/* ====================================================================
|
||||
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.net.URI;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
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.ContentTypeManager;
|
||||
import org.apache.poi.openxml4j.opc.internal.FileHelper;
|
||||
import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
|
||||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
||||
import org.apache.poi.openxml4j.opc.internal.ZipContentTypeManager;
|
||||
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
||||
import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPackagePropertiesMarshaller;
|
||||
import org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller;
|
||||
import org.apache.poi.openxml4j.util.ZipEntrySource;
|
||||
import org.apache.poi.openxml4j.util.ZipFileZipEntrySource;
|
||||
import org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource;
|
||||
|
||||
/**
|
||||
* Physical zip package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.2
|
||||
*/
|
||||
public final class ZipPackage extends Package {
|
||||
|
||||
private static Logger logger = Logger.getLogger("org.openxml4j");
|
||||
|
||||
/**
|
||||
* Zip archive, as either a file on disk,
|
||||
* or a stream
|
||||
*/
|
||||
private final ZipEntrySource zipArchive;
|
||||
|
||||
/**
|
||||
* Constructor. Creates a new ZipPackage.
|
||||
*/
|
||||
public ZipPackage() {
|
||||
super(defaultPackageAccess);
|
||||
this.zipArchive = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. <b>Operation not supported.</b>
|
||||
*
|
||||
* @param in
|
||||
* Zip input stream to load.
|
||||
* @param access
|
||||
* @throws IllegalArgumentException
|
||||
* If the specified input stream not an instance of
|
||||
* ZipInputStream.
|
||||
*/
|
||||
ZipPackage(InputStream in, PackageAccess access) throws IOException {
|
||||
super(access);
|
||||
this.zipArchive = new ZipInputStreamZipEntrySource(
|
||||
new ZipInputStream(in)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Opens a Zip based Open XML document.
|
||||
*
|
||||
* @param path
|
||||
* The path of the file to open or create.
|
||||
* @param access
|
||||
* The package access mode.
|
||||
* @throws InvalidFormatException
|
||||
* If the content type part parsing encounters an error.
|
||||
*/
|
||||
ZipPackage(String path, PackageAccess access) throws InvalidFormatException {
|
||||
super(access);
|
||||
|
||||
ZipFile zipFile = ZipHelper.openZipFile(path);
|
||||
if (zipFile == null)
|
||||
throw new InvalidOperationException(
|
||||
"Can't open the specified file: '" + path + "'");
|
||||
this.zipArchive = new ZipFileZipEntrySource(zipFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the parts from this package. We assume that the package has not
|
||||
* been yet inspect to retrieve all the parts, this method will open the
|
||||
* archive and look for all parts contain inside it. If the package part
|
||||
* list is not empty, it will be emptied.
|
||||
*
|
||||
* @return All parts contain in this package.
|
||||
* @throws InvalidFormatException
|
||||
* Throws if the package is not valid.
|
||||
*/
|
||||
@Override
|
||||
protected PackagePart[] getPartsImpl() throws InvalidFormatException {
|
||||
if (this.partList == null) {
|
||||
// The package has just been created, we create an empty part
|
||||
// list.
|
||||
this.partList = new PackagePartCollection();
|
||||
}
|
||||
|
||||
if (this.zipArchive == null) {
|
||||
return this.partList.values().toArray(
|
||||
new PackagePart[this.partList.values().size()]);
|
||||
} else {
|
||||
// First we need to parse the content type part
|
||||
Enumeration<? extends ZipEntry> entries = this.zipArchive.getEntries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if (entry.getName().equals(
|
||||
ContentTypeManager.CONTENT_TYPES_PART_NAME)) {
|
||||
try {
|
||||
this.contentTypeManager = new ZipContentTypeManager(
|
||||
getZipArchive().getInputStream(entry), this);
|
||||
} catch (IOException e) {
|
||||
throw new InvalidFormatException(e.getMessage());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we should have loaded the content type part
|
||||
if (this.contentTypeManager == null) {
|
||||
throw new InvalidFormatException(
|
||||
"Package should contain a content type part [M1.13]");
|
||||
}
|
||||
|
||||
// Now create all the relationships
|
||||
// (Need to create relationships before other
|
||||
// parts, otherwise we might create a part before
|
||||
// its relationship exists, and then it won't tie up)
|
||||
entries = this.zipArchive.getEntries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry) entries.nextElement();
|
||||
PackagePartName partName = buildPartName(entry);
|
||||
if(partName == null) continue;
|
||||
|
||||
// Only proceed for Relationships at this stage
|
||||
String contentType = contentTypeManager.getContentType(partName);
|
||||
if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) {
|
||||
try {
|
||||
partList.put(partName, new ZipPackagePart(this, entry,
|
||||
partName, contentType));
|
||||
} catch (InvalidOperationException e) {
|
||||
throw new InvalidFormatException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then we can go through all the other parts
|
||||
entries = this.zipArchive.getEntries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry) entries.nextElement();
|
||||
PackagePartName partName = buildPartName(entry);
|
||||
if(partName == null) continue;
|
||||
|
||||
String contentType = contentTypeManager
|
||||
.getContentType(partName);
|
||||
if (contentType != null && contentType.equals(ContentTypes.RELATIONSHIPS_PART)) {
|
||||
// Already handled
|
||||
}
|
||||
else if (contentType != null) {
|
||||
try {
|
||||
partList.put(partName, new ZipPackagePart(this, entry,
|
||||
partName, contentType));
|
||||
} catch (InvalidOperationException e) {
|
||||
throw new InvalidFormatException(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
throw new InvalidFormatException(
|
||||
"The part "
|
||||
+ partName.getURI().getPath()
|
||||
+ " does not have any content type ! Rule: Package require content types when retrieving a part from a package. [M.1.14]");
|
||||
}
|
||||
}
|
||||
|
||||
return (ZipPackagePart[]) partList.values().toArray(
|
||||
new ZipPackagePart[partList.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a PackagePartName for the given ZipEntry,
|
||||
* or null if it's the content types / invalid part
|
||||
*/
|
||||
private PackagePartName buildPartName(ZipEntry entry) {
|
||||
try {
|
||||
// We get an error when we parse [Content_Types].xml
|
||||
// because it's not a valid URI.
|
||||
if (entry.getName().equals(
|
||||
ContentTypeManager.CONTENT_TYPES_PART_NAME)) {
|
||||
return null;
|
||||
} else {
|
||||
return PackagingURIHelper.createPartName(ZipHelper
|
||||
.getOPCNameFromZipItemName(entry.getName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// We assume we can continue, even in degraded mode ...
|
||||
logger.warn("Entry "
|
||||
+ entry.getName()
|
||||
+ " is not valid, so this part won't be add to the package.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MemoryPackagePart from the specified URI and content type
|
||||
*
|
||||
*
|
||||
* aram partName The part URI.
|
||||
*
|
||||
* @param contentType
|
||||
* The part content type.
|
||||
* @return The newly created zip package part, else <b>null</b>.
|
||||
*/
|
||||
@Override
|
||||
protected PackagePart createPartImpl(PackagePartName partName,
|
||||
String contentType, boolean loadRelationships) {
|
||||
if (contentType == null)
|
||||
throw new IllegalArgumentException("contentType");
|
||||
|
||||
if (partName == null)
|
||||
throw new IllegalArgumentException("partName");
|
||||
|
||||
try {
|
||||
return new MemoryPackagePart(this, partName, contentType,
|
||||
loadRelationships);
|
||||
} catch (InvalidFormatException e) {
|
||||
System.err.println(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a part from the package
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* Throws if the part URI is nulll or invalid.
|
||||
*/
|
||||
@Override
|
||||
protected void removePartImpl(PackagePartName partName) {
|
||||
if (partName == null)
|
||||
throw new IllegalArgumentException("partUri");
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the package. Do nothing.
|
||||
*/
|
||||
@Override
|
||||
protected void flushImpl() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Close and save the package.
|
||||
*
|
||||
* @see #close()
|
||||
*/
|
||||
@Override
|
||||
protected void closeImpl() throws IOException {
|
||||
// Flush the package
|
||||
flush();
|
||||
|
||||
// Save the content
|
||||
if (this.originalPackagePath != null
|
||||
&& !"".equals(this.originalPackagePath)) {
|
||||
File targetFile = new File(this.originalPackagePath);
|
||||
if (targetFile.exists()) {
|
||||
// Case of a package previously open
|
||||
|
||||
File tempFile = File.createTempFile(
|
||||
generateTempFileName(FileHelper
|
||||
.getDirectory(targetFile)), ".tmp");
|
||||
|
||||
// Save the final package to a temporary file
|
||||
try {
|
||||
save(tempFile);
|
||||
this.zipArchive.close(); // Close the zip archive to be
|
||||
// able to delete it
|
||||
FileHelper.copyFile(tempFile, targetFile);
|
||||
} finally {
|
||||
// Either the save operation succeed or not, we delete the
|
||||
// temporary file
|
||||
if (!tempFile.delete()) {
|
||||
logger
|
||||
.warn("The temporary file: '"
|
||||
+ targetFile.getAbsolutePath()
|
||||
+ "' cannot be deleted ! Make sure that no other application use it.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new InvalidOperationException(
|
||||
"Can't close a package not previously open with the open() method !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a unique identifier to be use as a temp file name.
|
||||
*
|
||||
* @return A unique identifier use to be use as a temp file name.
|
||||
*/
|
||||
private synchronized String generateTempFileName(File directory) {
|
||||
File tmpFilename;
|
||||
do {
|
||||
tmpFilename = new File(directory.getAbsoluteFile() + File.separator
|
||||
+ "OpenXML4J" + System.nanoTime());
|
||||
} while (tmpFilename.exists());
|
||||
return FileHelper.getFilename(tmpFilename.getAbsoluteFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the package without saving the document. Discard all the changes
|
||||
* made to this package.
|
||||
*/
|
||||
@Override
|
||||
protected void revertImpl() {
|
||||
try {
|
||||
if (this.zipArchive != null)
|
||||
this.zipArchive.close();
|
||||
} catch (IOException e) {
|
||||
// Do nothing, user dont have to know
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the getPart() method to retrieve a part from its URI in the
|
||||
* current package
|
||||
*
|
||||
*
|
||||
* @see #getPart(URI)
|
||||
*/
|
||||
@Override
|
||||
protected PackagePart getPartImpl(PackagePartName partName) {
|
||||
if (partList.containsKey(partName)) {
|
||||
return partList.get(partName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save this package into the specified stream
|
||||
*
|
||||
*
|
||||
* @param outputStream
|
||||
* The stream use to save this package.
|
||||
*
|
||||
* @see #save(OutputStream)
|
||||
* @see #saveInZip(ZipOutputStream)
|
||||
*/
|
||||
@Override
|
||||
public void saveImpl(OutputStream outputStream) {
|
||||
// Check that the document was open in write mode
|
||||
throwExceptionIfReadOnly();
|
||||
ZipOutputStream zos = null;
|
||||
|
||||
try {
|
||||
if (!(outputStream instanceof ZipOutputStream))
|
||||
zos = new ZipOutputStream(outputStream);
|
||||
else
|
||||
zos = (ZipOutputStream) outputStream;
|
||||
|
||||
// If the core properties part does not exist in the part list,
|
||||
// we save it as well
|
||||
if (this.getPartsByRelationshipType(
|
||||
PackageRelationshipTypes.CORE_PROPERTIES).size() == 0) {
|
||||
logger.debug("Save core properties part");
|
||||
|
||||
// We have to save the core properties part ...
|
||||
new ZipPackagePropertiesMarshaller().marshall(
|
||||
this.packageProperties, zos);
|
||||
// ... and to add its relationship ...
|
||||
this.relationships.addRelationship(this.packageProperties
|
||||
.getPartName().getURI(), TargetMode.INTERNAL,
|
||||
PackageRelationshipTypes.CORE_PROPERTIES, null);
|
||||
// ... and the content if it has not been added yet.
|
||||
if (!this.contentTypeManager
|
||||
.isContentTypeRegister(ContentTypes.CORE_PROPERTIES_PART)) {
|
||||
this.contentTypeManager.addContentType(
|
||||
this.packageProperties.getPartName(),
|
||||
ContentTypes.CORE_PROPERTIES_PART);
|
||||
}
|
||||
}
|
||||
|
||||
// Save package relationships part.
|
||||
logger.debug("Save package relationships");
|
||||
ZipPartMarshaller.marshallRelationshipPart(this.getRelationships(),
|
||||
PackagingURIHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME,
|
||||
zos);
|
||||
|
||||
// Save content type part.
|
||||
logger.debug("Save content types part");
|
||||
this.contentTypeManager.save(zos);
|
||||
|
||||
// Save parts.
|
||||
for (PackagePart part : getParts()) {
|
||||
// If the part is a relationship part, we don't save it, it's
|
||||
// the source part that will do the job.
|
||||
if (part.isRelationshipPart())
|
||||
continue;
|
||||
|
||||
logger.debug("Save part '"
|
||||
+ ZipHelper.getZipItemNameFromOPCName(part
|
||||
.getPartName().getName()) + "'");
|
||||
PartMarshaller marshaller = partMarshallers
|
||||
.get(part.contentType);
|
||||
if (marshaller != null) {
|
||||
if (!marshaller.marshall(part, zos)) {
|
||||
throw new OpenXML4JException(
|
||||
"The part "
|
||||
+ part.getPartName().getURI()
|
||||
+ " fail to be saved in the stream with marshaller "
|
||||
+ marshaller);
|
||||
}
|
||||
} else {
|
||||
if (!defaultPartMarshaller.marshall(part, zos))
|
||||
throw new OpenXML4JException(
|
||||
"The part "
|
||||
+ part.getPartName().getURI()
|
||||
+ " fail to be saved in the stream with marshaller "
|
||||
+ defaultPartMarshaller);
|
||||
}
|
||||
}
|
||||
zos.close();
|
||||
} catch (Exception e) {
|
||||
logger
|
||||
.error("Fail to save: an error occurs while saving the package : "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the zip archive
|
||||
*
|
||||
* @return The zip archive.
|
||||
*/
|
||||
public ZipEntrySource getZipArchive() {
|
||||
return zipArchive;
|
||||
}
|
||||
}
|
135
src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackagePart.java
Executable file
135
src/ooxml/java/org/apache/poi/openxml4j/opc/ZipPackagePart.java
Executable file
@ -0,0 +1,135 @@
|
||||
/* ====================================================================
|
||||
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(Package 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(Package 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 !");
|
||||
}
|
||||
}
|
224
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java
Executable file
224
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java
Executable file
@ -0,0 +1,224 @@
|
||||
/* ====================================================================
|
||||
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.UnsupportedEncodingException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
|
||||
/**
|
||||
* Represents a immutable MIME ContentType value (RFC 2616 <EFBFBD>3.7)
|
||||
*
|
||||
* media-type = type "/" subtype *( ";" parameter ) type = token<br>
|
||||
* subtype = token<br>
|
||||
*
|
||||
* Rule M1.13 : Package implementers shall only create and only recognize parts
|
||||
* with a content type; format designers shall specify a content type for each
|
||||
* part included in the format. Content types for package parts shall fit the
|
||||
* definition and syntax for media types as specified in RFC 2616,<EFBFBD><EFBFBD>3.7.
|
||||
*
|
||||
* Rule M1.14: Content types shall not use linear white space either between the
|
||||
* type and subtype or between an attribute and its value. Content types also
|
||||
* shall not have leading or trailing white spaces. Package implementers shall
|
||||
* create only such content types and shall require such content types when
|
||||
* retrieving a part from a package; format designers shall specify only such
|
||||
* content types for inclusion in the format.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*
|
||||
* @see http://www.ietf.org/rfc/rfc2045.txt
|
||||
* @see http://www.ietf.org/rfc/rfc2616.txt
|
||||
*/
|
||||
public final class ContentType {
|
||||
|
||||
/**
|
||||
* Type in Type/Subtype.
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* Subtype
|
||||
*/
|
||||
private String subType;
|
||||
|
||||
/**
|
||||
* Parameters
|
||||
*/
|
||||
private Hashtable<String, String> parameters;
|
||||
|
||||
/**
|
||||
* Media type compiled pattern for parameters.
|
||||
*/
|
||||
private final static Pattern patternMediaType;
|
||||
|
||||
static {
|
||||
/*
|
||||
* token = 1*<any CHAR except CTLs or separators>
|
||||
*
|
||||
* separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" |
|
||||
* <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
|
||||
*
|
||||
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||
*
|
||||
* CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||
*/
|
||||
String token = "[\\x21-\\x7E&&[^\\(\\)<>@,;:\\\\/\"\\[\\]\\?={}\\x20\\x09]]";
|
||||
|
||||
/*
|
||||
* parameter = attribute "=" value
|
||||
*
|
||||
* attribute = token
|
||||
*
|
||||
* value = token | quoted-string
|
||||
*/
|
||||
// Keep for future use with parameter:
|
||||
// String parameter = "(" + token + "+)=(\"?" + token + "+\"?)";
|
||||
/*
|
||||
* Pattern for media type.
|
||||
*
|
||||
* Don't allow comment, rule M1.15: The package implementer shall
|
||||
* require a content type that does not include comments and the format
|
||||
* designer shall specify such a content type.
|
||||
*
|
||||
* comment = "(" *( ctext | quoted-pair | comment ) ")"
|
||||
*
|
||||
* ctext = <any TEXT excluding "(" and ")">
|
||||
*
|
||||
* TEXT = <any OCTET except CTLs, but including LWS>
|
||||
*
|
||||
* LWS = [CRLF] 1*( SP | HT )
|
||||
*
|
||||
* CR = <US-ASCII CR, carriage return (13)>
|
||||
*
|
||||
* LF = <US-ASCII LF, linefeed (10)>
|
||||
*
|
||||
* SP = <US-ASCII SP, space (32)>
|
||||
*
|
||||
* HT = <US-ASCII HT, horizontal-tab (9)>
|
||||
*
|
||||
* quoted-pair = "\" CHAR
|
||||
*/
|
||||
|
||||
// Keep for future use with parameter:
|
||||
// patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
|
||||
// + "+)(;" + parameter + ")*$");
|
||||
patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
|
||||
+ "+)$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Check the input with the RFC 2616 grammar.
|
||||
*
|
||||
* @param contentType
|
||||
* The content type to store.
|
||||
* @throws InvalidFormatException
|
||||
* If the specified content type is not valid with RFC 2616.
|
||||
*/
|
||||
public ContentType(String contentType) throws InvalidFormatException {
|
||||
// Conversion en US-ASCII
|
||||
String contentTypeASCII = null;
|
||||
try {
|
||||
contentTypeASCII = new String(contentType.getBytes(), "US-ASCII");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new InvalidFormatException(
|
||||
"The specified content type is not an ASCII value.");
|
||||
}
|
||||
|
||||
Matcher mMediaType = patternMediaType.matcher(contentTypeASCII);
|
||||
if (!mMediaType.matches())
|
||||
throw new InvalidFormatException(
|
||||
"The specified content type '"
|
||||
+ contentType
|
||||
+ "' is not compliant with RFC 2616: malformed content type.");
|
||||
|
||||
// Type/subtype
|
||||
if (mMediaType.groupCount() >= 2) {
|
||||
this.type = mMediaType.group(1);
|
||||
this.subType = mMediaType.group(2);
|
||||
// Parameters
|
||||
this.parameters = new Hashtable<String, String>(1);
|
||||
for (int i = 4; i <= mMediaType.groupCount()
|
||||
&& (mMediaType.group(i) != null); i += 2) {
|
||||
this.parameters.put(mMediaType.group(i), mMediaType
|
||||
.group(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuffer retVal = new StringBuffer();
|
||||
retVal.append(this.getType());
|
||||
retVal.append("/");
|
||||
retVal.append(this.getSubType());
|
||||
// Keep for future implementation if needed
|
||||
// for (String key : parameters.keySet()) {
|
||||
// retVal.append(";");
|
||||
// retVal.append(key);
|
||||
// retVal.append("=");
|
||||
// retVal.append(parameters.get(key));
|
||||
// }
|
||||
return retVal.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (!(obj instanceof ContentType))
|
||||
|| (this.toString().equalsIgnoreCase(obj.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.toString().hashCode();
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
/**
|
||||
* Get the subtype.
|
||||
*
|
||||
* @return The subtype of this content type.
|
||||
*/
|
||||
public String getSubType() {
|
||||
return this.subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
*
|
||||
* @return The type of this content type.
|
||||
*/
|
||||
public String getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value associated to the specified key.
|
||||
*
|
||||
* @param key
|
||||
* The key of the key/value pair.
|
||||
* @return The value associated to the specified key.
|
||||
*/
|
||||
public String getParameters(String key) {
|
||||
return parameters.get(key);
|
||||
}
|
||||
}
|
498
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java
Executable file
498
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java
Executable file
@ -0,0 +1,498 @@
|
||||
/* ====================================================================
|
||||
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 java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
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;
|
||||
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.Package;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePartName;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
|
||||
/**
|
||||
* Manage package content types ([Content_Types].xml part).
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class ContentTypeManager {
|
||||
|
||||
protected static Logger logger = Logger.getLogger("org.openxml4j");
|
||||
|
||||
/**
|
||||
* Reference to the package using this content type manager.
|
||||
*/
|
||||
protected Package container;
|
||||
|
||||
/**
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* 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 archive
|
||||
* 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, Package 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"
|
||||
*
|
||||
* [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<EFBFBD><EFBFBD>9.1.2.3:
|
||||
*
|
||||
* 1. Get the extension from the part name by taking the substring to the
|
||||
* right of the rightmost occurrence of the dot character (.) from the
|
||||
* rightmost segment.
|
||||
*
|
||||
* 2. If a part name has no extension, a corresponding Override element
|
||||
* shall be added to the Content Types stream.
|
||||
*
|
||||
* 3. Compare the resulting extension with the values specified for the
|
||||
* Extension attributes of the Default elements in the Content Types stream.
|
||||
* The comparison shall be case-insensitive ASCII.
|
||||
*
|
||||
* 4. If there is a Default element with a matching Extension attribute,
|
||||
* then the content type of the new part shall be compared with the value of
|
||||
* the ContentType attribute. The comparison might be case-sensitive and
|
||||
* include every character regardless of the role it plays in the
|
||||
* content-type grammar of RFC 2616, or it might follow the grammar of RFC
|
||||
* 2616.
|
||||
*
|
||||
* a. If the content types match, no further action is required.
|
||||
*
|
||||
* b. If the content types do not match, a new Override element shall be
|
||||
* added to the Content Types stream. .
|
||||
*
|
||||
* 5. If there is no Default element with a matching Extension attribute, a
|
||||
* new Default element or Override element shall be added to the Content
|
||||
* Types stream.
|
||||
*
|
||||
*
|
||||
* @param partUri
|
||||
* the uri that will be stored
|
||||
* @return <b>false</b> if an error occured.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a content type based on the specified part name. If the specified
|
||||
* part name is register with an override content type, then this content
|
||||
* type is remove, else the content type is remove in the default content
|
||||
* type list if it exists and if no part is associated with it yet.
|
||||
*
|
||||
* Check rule M2.4: The package implementer shall require that the Content
|
||||
* Types stream contain one of the following for every part in the package:
|
||||
* One matching Default element One matching Override element Both a
|
||||
* matching Default element and a matching Override element, in which case
|
||||
* the Override element takes precedence.
|
||||
*
|
||||
* @param partUri
|
||||
* 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.
|
||||
*
|
||||
* Rule [M2.9]: To get the content type of a part, the package implementer
|
||||
* shall perform the steps described in<EFBFBD><EFBFBD>9.1.2.4:
|
||||
*
|
||||
* 1. Compare the part name with the values specified for the PartName
|
||||
* attribute of the Override elements. The comparison shall be
|
||||
* case-insensitive ASCII.
|
||||
*
|
||||
* 2. If there is an Override element with a matching PartName attribute,
|
||||
* return the value of its ContentType attribute. No further action is
|
||||
* required.
|
||||
*
|
||||
* 3. If there is no Override element with a matching PartName attribute,
|
||||
* then a. Get the extension from the part name by taking the substring to
|
||||
* the right of the rightmost occurrence of the dot character (.) from the
|
||||
* rightmost segment. b. Check the Default elements of the Content Types
|
||||
* stream, comparing the extension with the value of the Extension
|
||||
* attribute. The comparison shall be case-insensitive ASCII.
|
||||
*
|
||||
* 4. If there is a Default element with a matching Extension attribute,
|
||||
* return the value of its ContentType attribute. No further action is
|
||||
* required.
|
||||
*
|
||||
* 5. If neither Override nor Default elements with matching attributes are
|
||||
* found for the specified part name, the implementation shall not map this
|
||||
* part name to a part.
|
||||
*
|
||||
* @param partUri
|
||||
* 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(ZipOutputStream)
|
||||
*/
|
||||
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(ZipOutputStream)
|
||||
*/
|
||||
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);
|
||||
}
|
91
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java
Executable file
91
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/FileHelper.java
Executable file
@ -0,0 +1,91 @@
|
||||
/* ====================================================================
|
||||
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.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
/**
|
||||
* Provide useful method to manage file.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class FileHelper {
|
||||
|
||||
/**
|
||||
* Get the directory part of the specified file path.
|
||||
*
|
||||
* @param f
|
||||
* File to process.
|
||||
* @return The directory path from the specified
|
||||
*/
|
||||
public static File getDirectory(File f) {
|
||||
if (f != null) {
|
||||
String path = f.getPath();
|
||||
int len = path.length();
|
||||
int num2 = len;
|
||||
while (--num2 >= 0) {
|
||||
char ch1 = path.charAt(num2);
|
||||
if (ch1 == File.separatorChar) {
|
||||
return new File(path.substring(0, num2));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a file.
|
||||
*
|
||||
* @param in
|
||||
* The source file.
|
||||
* @param out
|
||||
* The target location.
|
||||
* @throws IOException
|
||||
* If an I/O error occur.
|
||||
*/
|
||||
public static void copyFile(File in, File out) throws IOException {
|
||||
FileChannel sourceChannel = new FileInputStream(in).getChannel();
|
||||
FileChannel destinationChannel = new FileOutputStream(out).getChannel();
|
||||
sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
|
||||
sourceChannel.close();
|
||||
destinationChannel.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file name from the specified File object.
|
||||
*/
|
||||
public static String getFilename(File file) {
|
||||
if (file != null) {
|
||||
String path = file.getPath();
|
||||
int len = path.length();
|
||||
int num2 = len;
|
||||
while (--num2 >= 0) {
|
||||
char ch1 = path.charAt(num2);
|
||||
if (ch1 == File.separatorChar)
|
||||
return path.substring(num2 + 1, len);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
126
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePart.java
Executable file
126
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/MemoryPackagePart.java
Executable file
@ -0,0 +1,126 @@
|
||||
/* ====================================================================
|
||||
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.Package;
|
||||
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(Package 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(Package 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
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/* ====================================================================
|
||||
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.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Build an output stream for MemoryPackagePart.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class MemoryPackagePartOutputStream extends OutputStream {
|
||||
|
||||
private MemoryPackagePart part;
|
||||
|
||||
private ByteArrayOutputStream buff;
|
||||
|
||||
public MemoryPackagePartOutputStream(MemoryPackagePart part) {
|
||||
this.part = part;
|
||||
buff = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
buff.write(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this stream and flush the content.
|
||||
* @see #flush()
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush this output stream. This method is called by the close() method.
|
||||
* Warning : don't call this method for output consistency.
|
||||
* @see #close()
|
||||
*/
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
buff.flush();
|
||||
if (part.data != null) {
|
||||
byte[] newArray = new byte[part.data.length + buff.size()];
|
||||
// copy the previous contents of part.data in newArray
|
||||
System.arraycopy(part.data, 0, newArray, 0, part.data.length);
|
||||
|
||||
// append the newly added data
|
||||
byte[] buffArr = buff.toByteArray();
|
||||
System.arraycopy(buffArr, 0, newArray, part.data.length,
|
||||
buffArr.length);
|
||||
|
||||
// save the result as new data
|
||||
part.data = newArray;
|
||||
} else {
|
||||
// was empty, just fill it
|
||||
part.data = buff.toByteArray();
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear this streams buffer, in case flush() is called a second time
|
||||
* Fix bug 1921637 - provided by Rainer Schwarze
|
||||
*/
|
||||
buff.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
buff.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
buff.write(b);
|
||||
}
|
||||
}
|
621
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java
Executable file
621
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java
Executable file
@ -0,0 +1,621 @@
|
||||
/* ====================================================================
|
||||
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.Package;
|
||||
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(Package 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
|
||||
}
|
||||
}
|
49
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java
Executable file
49
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartMarshaller.java
Executable file
@ -0,0 +1,49 @@
|
||||
/* ====================================================================
|
||||
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.OutputStream;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
/**
|
||||
* Object implemented this interface are considered as part marshaller. A part
|
||||
* marshaller is responsible to marshall a part in order to be save in a
|
||||
* package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public interface PartMarshaller {
|
||||
|
||||
/**
|
||||
* Save the content of the package in the stream
|
||||
*
|
||||
* @param part
|
||||
* Part to marshall.
|
||||
* @param out
|
||||
* The output stream into which the part will be marshall.
|
||||
* @return <b>false</b> if any marshall error occurs, else <b>true</b>
|
||||
* @throws OpenXML4JException
|
||||
* Throws only if any other exceptions are thrown by inner
|
||||
* methods.
|
||||
*/
|
||||
public boolean marshall(PackagePart part, OutputStream out)
|
||||
throws OpenXML4JException;
|
||||
}
|
50
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java
Executable file
50
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PartUnmarshaller.java
Executable file
@ -0,0 +1,50 @@
|
||||
/* ====================================================================
|
||||
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.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.internal.unmarshallers.UnmarshallContext;
|
||||
|
||||
/**
|
||||
* Object implemented this interface are considered as part unmarshaller. A part
|
||||
* unmarshaller is responsible to unmarshall a part in order to load it from a
|
||||
* package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public interface PartUnmarshaller {
|
||||
|
||||
/**
|
||||
* Save the content of the package in the stream
|
||||
*
|
||||
* @param in
|
||||
* The input stream from which the part will be unmarshall.
|
||||
* @return The part freshly unmarshall from the input stream.
|
||||
* @throws OpenXML4JException
|
||||
* Throws only if any other exceptions are thrown by inner
|
||||
* methods.
|
||||
*/
|
||||
public PackagePart unmarshall(UnmarshallContext context, InputStream in)
|
||||
throws InvalidFormatException, IOException;
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/* ====================================================================
|
||||
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.dom4j.Document;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.StreamHelper;
|
||||
|
||||
/**
|
||||
* Zip implementation of the ContentTypeManager.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
* @see ContentTypeManager
|
||||
*/
|
||||
public class ZipContentTypeManager extends ContentTypeManager {
|
||||
|
||||
/**
|
||||
* 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, Package 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.error("Cannot write: " + CONTENT_TYPES_PART_NAME
|
||||
+ " in Zip !", ioe);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
163
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
Executable file
163
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java
Executable file
@ -0,0 +1,163 @@
|
||||
/* ====================================================================
|
||||
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.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.apache.poi.openxml4j.opc.ZipPackage;
|
||||
|
||||
public final class ZipHelper {
|
||||
|
||||
/**
|
||||
* Forward slash use to convert part name between OPC and zip item naming
|
||||
* conventions.
|
||||
*/
|
||||
private final static String FORWARD_SLASH = "/";
|
||||
|
||||
/**
|
||||
* Buffer to read data from file. Use big buffer to improve performaces. the
|
||||
* InputStream class is reading only 8192 bytes per read call (default value
|
||||
* set by sun)
|
||||
*/
|
||||
public static final int READ_WRITE_FILE_BUFFER_SIZE = 8192;
|
||||
|
||||
/**
|
||||
* Prevent this class to be instancied.
|
||||
*/
|
||||
private ZipHelper() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the zip entry of the core properties part.
|
||||
*
|
||||
* @throws OpenXML4JException
|
||||
* Throws if internal error occurs.
|
||||
*/
|
||||
public static ZipEntry getCorePropertiesZipEntry(ZipPackage pkg)
|
||||
throws OpenXML4JException {
|
||||
PackageRelationship corePropsRel = pkg.getRelationshipsByType(
|
||||
PackageRelationshipTypes.CORE_PROPERTIES).getRelationship(0);
|
||||
|
||||
if (corePropsRel == null)
|
||||
return null;
|
||||
|
||||
return new ZipEntry(corePropsRel.getTargetURI().getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Zip entry of the content types part.
|
||||
*/
|
||||
public static ZipEntry getContentTypeZipEntry(ZipPackage pkg) {
|
||||
Enumeration entries = pkg.getZipArchive().getEntries();
|
||||
// Enumerate through the Zip entries until we find the one named
|
||||
// '[Content_Types].xml'.
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry) entries.nextElement();
|
||||
if (entry.getName().equals(
|
||||
ContentTypeManager.CONTENT_TYPES_PART_NAME))
|
||||
return entry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a zip name into an OPC name by adding a leading forward slash to
|
||||
* the specified item name.
|
||||
*
|
||||
* @param zipItemName
|
||||
* Zip item name to convert.
|
||||
* @return An OPC compliant name.
|
||||
*/
|
||||
public static String getOPCNameFromZipItemName(String zipItemName) {
|
||||
if (zipItemName == null)
|
||||
throw new IllegalArgumentException("zipItemName");
|
||||
if (zipItemName.startsWith(FORWARD_SLASH))
|
||||
return zipItemName;
|
||||
else
|
||||
return FORWARD_SLASH + zipItemName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an OPC item name into a zip item name by removing any leading
|
||||
* forward slash if it exist.
|
||||
*
|
||||
* @param opcItemName
|
||||
* The OPC item name to convert.
|
||||
* @return A zip item name without any leading slashes.
|
||||
*/
|
||||
public static String getZipItemNameFromOPCName(String opcItemName) {
|
||||
if (opcItemName == null)
|
||||
throw new IllegalArgumentException("opcItemName");
|
||||
|
||||
String retVal = new String(opcItemName);
|
||||
while (retVal.startsWith(FORWARD_SLASH))
|
||||
retVal = retVal.substring(1);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an OPC item name into a zip URI by removing any leading forward
|
||||
* slash if it exist.
|
||||
*
|
||||
* @param opcItemName
|
||||
* The OPC item name to convert.
|
||||
* @return A zip URI without any leading slashes.
|
||||
*/
|
||||
public static URI getZipURIFromOPCName(String opcItemName) {
|
||||
if (opcItemName == null)
|
||||
throw new IllegalArgumentException("opcItemName");
|
||||
|
||||
String retVal = new String(opcItemName);
|
||||
while (retVal.startsWith(FORWARD_SLASH))
|
||||
retVal = retVal.substring(1);
|
||||
try {
|
||||
return new URI(retVal);
|
||||
} catch (URISyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and open a zip file with the specified path.
|
||||
*
|
||||
* @param path
|
||||
* The file path.
|
||||
* @return The zip archive freshly open.
|
||||
*/
|
||||
public static ZipFile openZipFile(String path) {
|
||||
File f = new File(path);
|
||||
try {
|
||||
if (!f.exists()) {
|
||||
return null;
|
||||
}
|
||||
return new ZipFile(f);
|
||||
} catch (IOException ioe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/* ====================================================================
|
||||
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.marshallers;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
||||
|
||||
/**
|
||||
* Default marshaller that specified that the part is responsible to marshall its content.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
* @see PartMarshaller
|
||||
*/
|
||||
public class DefaultMarshaller implements PartMarshaller {
|
||||
|
||||
/**
|
||||
* Save part in the output stream by using the save() method of the part.
|
||||
*
|
||||
* @throws OpenXML4JException
|
||||
* If any error occur.
|
||||
*/
|
||||
public boolean marshall(PackagePart part, OutputStream out)
|
||||
throws OpenXML4JException {
|
||||
return part.save(out);
|
||||
}
|
||||
}
|
@ -0,0 +1,434 @@
|
||||
/* ====================================================================
|
||||
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.marshallers;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.Namespace;
|
||||
import org.dom4j.QName;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
||||
|
||||
/**
|
||||
* Package properties marshaller.
|
||||
*
|
||||
* @author CDubet, Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||
|
||||
private final static Namespace namespaceDC = new Namespace("dc",
|
||||
PackagePropertiesPart.NAMESPACE_DC_URI);
|
||||
|
||||
private final static Namespace namespaceCoreProperties = new Namespace("",
|
||||
PackagePropertiesPart.NAMESPACE_CP_URI);
|
||||
|
||||
private final static Namespace namespaceDcTerms = new Namespace("dcterms",
|
||||
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
||||
|
||||
private final static Namespace namespaceXSI = new Namespace("xsi",
|
||||
PackagePropertiesPart.NAMESPACE_XSI_URI);
|
||||
|
||||
protected static final String KEYWORD_CATEGORY = "category";
|
||||
|
||||
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
|
||||
|
||||
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
|
||||
|
||||
protected static final String KEYWORD_CREATED = "created";
|
||||
|
||||
protected static final String KEYWORD_CREATOR = "creator";
|
||||
|
||||
protected static final String KEYWORD_DESCRIPTION = "description";
|
||||
|
||||
protected static final String KEYWORD_IDENTIFIER = "identifier";
|
||||
|
||||
protected static final String KEYWORD_KEYWORDS = "keywords";
|
||||
|
||||
protected static final String KEYWORD_LANGUAGE = "language";
|
||||
|
||||
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
|
||||
|
||||
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
|
||||
|
||||
protected static final String KEYWORD_MODIFIED = "modified";
|
||||
|
||||
protected static final String KEYWORD_REVISION = "revision";
|
||||
|
||||
protected static final String KEYWORD_SUBJECT = "subject";
|
||||
|
||||
protected static final String KEYWORD_TITLE = "title";
|
||||
|
||||
protected static final String KEYWORD_VERSION = "version";
|
||||
|
||||
PackagePropertiesPart propsPart;
|
||||
|
||||
// The document
|
||||
Document xmlDoc = null;
|
||||
|
||||
/**
|
||||
* Marshall package core properties to an XML document. Always return
|
||||
* <code>true</code>.
|
||||
*/
|
||||
public boolean marshall(PackagePart part, OutputStream out)
|
||||
throws OpenXML4JException {
|
||||
if (!(part instanceof PackagePropertiesPart))
|
||||
throw new IllegalArgumentException(
|
||||
"'part' must be a PackagePropertiesPart instance.");
|
||||
propsPart = (PackagePropertiesPart) part;
|
||||
|
||||
// Configure the document
|
||||
xmlDoc = DocumentHelper.createDocument();
|
||||
Element rootElem = xmlDoc.addElement(new QName("coreProperties",
|
||||
namespaceCoreProperties));
|
||||
rootElem.addNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
|
||||
rootElem.addNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
||||
rootElem.addNamespace("dcterms",
|
||||
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
||||
rootElem.addNamespace("xsi", PackagePropertiesPart.NAMESPACE_XSI_URI);
|
||||
|
||||
addCategory();
|
||||
addContentStatus();
|
||||
addContentType();
|
||||
addCreated();
|
||||
addCreator();
|
||||
addDescription();
|
||||
addIdentifier();
|
||||
addKeywords();
|
||||
addLanguage();
|
||||
addLastModifiedBy();
|
||||
addLastPrinted();
|
||||
addModified();
|
||||
addRevision();
|
||||
addSubject();
|
||||
addTitle();
|
||||
addVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add category property element if needed.
|
||||
*/
|
||||
private void addCategory() {
|
||||
if (!propsPart.getCategoryProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CATEGORY, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// Missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_CATEGORY, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getCategoryProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content status property element if needed.
|
||||
*/
|
||||
private void addContentStatus() {
|
||||
if (!propsPart.getContentStatusProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// Missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getContentStatusProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content type property element if needed.
|
||||
*/
|
||||
private void addContentType() {
|
||||
if (!propsPart.getContentTypeProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// Missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getContentTypeProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add created property element if needed.
|
||||
*/
|
||||
private void addCreated() {
|
||||
if (!propsPart.getCreatedProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CREATED, namespaceDcTerms));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_CREATED, namespaceDcTerms));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF");
|
||||
elem.addText(propsPart.getCreatedPropertyString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add creator property element if needed.
|
||||
*/
|
||||
private void addCreator() {
|
||||
if (!propsPart.getCreatorProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CREATOR, namespaceDC));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_CREATOR, namespaceDC));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getCreatorProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add description property element if needed.
|
||||
*/
|
||||
private void addDescription() {
|
||||
if (!propsPart.getDescriptionProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_DESCRIPTION, namespaceDC));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_DESCRIPTION, namespaceDC));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getDescriptionProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add identifier property element if needed.
|
||||
*/
|
||||
private void addIdentifier() {
|
||||
if (!propsPart.getIdentifierProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_IDENTIFIER, namespaceDC));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_IDENTIFIER, namespaceDC));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getIdentifierProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add keywords property element if needed.
|
||||
*/
|
||||
private void addKeywords() {
|
||||
if (!propsPart.getKeywordsProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getKeywordsProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add language property element if needed.
|
||||
*/
|
||||
private void addLanguage() {
|
||||
if (!propsPart.getLanguageProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_LANGUAGE, namespaceDC));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_LANGUAGE, namespaceDC));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getLanguageProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'last modified by' property if needed.
|
||||
*/
|
||||
private void addLastModifiedBy() {
|
||||
if (!propsPart.getLastModifiedByProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement()
|
||||
.addElement(
|
||||
new QName(KEYWORD_LAST_MODIFIED_BY,
|
||||
namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getLastModifiedByProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'last printed' property if needed.
|
||||
*
|
||||
*/
|
||||
private void addLastPrinted() {
|
||||
if (!propsPart.getLastPrintedProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getLastPrintedPropertyString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add modified property element if needed.
|
||||
*/
|
||||
private void addModified() {
|
||||
if (!propsPart.getModifiedProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF");
|
||||
elem.addText(propsPart.getModifiedPropertyString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add revision property if needed.
|
||||
*/
|
||||
private void addRevision() {
|
||||
if (!propsPart.getRevisionProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_REVISION, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_REVISION, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getRevisionProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subject property if needed.
|
||||
*/
|
||||
private void addSubject() {
|
||||
if (!propsPart.getSubjectProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_SUBJECT, namespaceDC));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_SUBJECT, namespaceDC));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getSubjectProperty().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add title property if needed.
|
||||
*/
|
||||
private void addTitle() {
|
||||
if (!propsPart.getTitleProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_TITLE, namespaceDC));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_TITLE, namespaceDC));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getTitleProperty().getValue());
|
||||
}
|
||||
|
||||
private void addVersion() {
|
||||
if (!propsPart.getVersionProperty().hasValue())
|
||||
return;
|
||||
|
||||
Element elem = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_VERSION, namespaceCoreProperties));
|
||||
if (elem == null) {
|
||||
// missing, we add it
|
||||
elem = xmlDoc.getRootElement().addElement(
|
||||
new QName(KEYWORD_VERSION, namespaceCoreProperties));
|
||||
} else {
|
||||
elem.clearContent();// clear the old value
|
||||
}
|
||||
elem.addText(propsPart.getVersionProperty().getValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/* ====================================================================
|
||||
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.marshallers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.StreamHelper;
|
||||
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
||||
|
||||
/**
|
||||
* Package core properties marshaller specialized for zipped package.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ZipPackagePropertiesMarshaller extends PackagePropertiesMarshaller {
|
||||
|
||||
@Override
|
||||
public boolean marshall(PackagePart part, OutputStream out)
|
||||
throws OpenXML4JException {
|
||||
if (!(out instanceof ZipOutputStream)) {
|
||||
throw new IllegalArgumentException("ZipOutputStream expected!");
|
||||
}
|
||||
ZipOutputStream zos = (ZipOutputStream) out;
|
||||
|
||||
// Saving the part in the zip file
|
||||
ZipEntry ctEntry = new ZipEntry(ZipHelper
|
||||
.getZipItemNameFromOPCName(part.getPartName().getURI()
|
||||
.toString()));
|
||||
try {
|
||||
// Save in ZIP
|
||||
zos.putNextEntry(ctEntry); // Add entry in ZIP
|
||||
super.marshall(part, out); // Marshall the properties inside a XML
|
||||
// Document
|
||||
if (!StreamHelper.saveXmlInStream(xmlDoc, out)) {
|
||||
return false;
|
||||
}
|
||||
zos.closeEntry();
|
||||
} catch (IOException e) {
|
||||
throw new OpenXML4JException(e.getLocalizedMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
/* ====================================================================
|
||||
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.marshallers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.Namespace;
|
||||
import org.dom4j.QName;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePartName;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
import org.apache.poi.openxml4j.opc.StreamHelper;
|
||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
||||
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
||||
|
||||
/**
|
||||
* Zip part marshaller. This marshaller is use to save any part in a zip stream.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public class ZipPartMarshaller implements PartMarshaller {
|
||||
private static Logger logger = Logger.getLogger("org.openxml4j");
|
||||
|
||||
/**
|
||||
* Save the specified part.
|
||||
*
|
||||
* @throws OpenXML4JException
|
||||
* Throws if an internal exception is thrown.
|
||||
*/
|
||||
public boolean marshall(PackagePart part, OutputStream os)
|
||||
throws OpenXML4JException {
|
||||
if (!(os instanceof ZipOutputStream)) {
|
||||
logger.error("Unexpected class " + os.getClass().getName());
|
||||
throw new OpenXML4JException("ZipOutputStream expected !");
|
||||
// Normally should happen only in developpement phase, so just throw
|
||||
// exception
|
||||
}
|
||||
|
||||
ZipOutputStream zos = (ZipOutputStream) os;
|
||||
ZipEntry partEntry = new ZipEntry(ZipHelper
|
||||
.getZipItemNameFromOPCName(part.getPartName().getURI()
|
||||
.getPath()));
|
||||
try {
|
||||
// Create next zip entry
|
||||
zos.putNextEntry(partEntry);
|
||||
|
||||
// Saving data in the ZIP file
|
||||
InputStream ins = part.getInputStream();
|
||||
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.error("Cannot write: " + part.getPartName() + ": in ZIP",
|
||||
ioe);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Saving relationship part
|
||||
if (part.hasRelationships()) {
|
||||
PackagePartName relationshipPartName = PackagingURIHelper
|
||||
.getRelationshipPartName(part.getPartName());
|
||||
|
||||
marshallRelationshipPart(part.getRelationships(),
|
||||
relationshipPartName, zos);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save relationships into the part.
|
||||
*
|
||||
* @param rels
|
||||
* The relationships collection to marshall.
|
||||
* @param relPartURI
|
||||
* Part name of the relationship part to marshall.
|
||||
* @param zos
|
||||
* Zip output stream in which to save the XML content of the
|
||||
* relationships serialization.
|
||||
*/
|
||||
public static boolean marshallRelationshipPart(
|
||||
PackageRelationshipCollection rels, PackagePartName relPartName,
|
||||
ZipOutputStream zos) {
|
||||
// Building xml
|
||||
Document xmlOutDoc = DocumentHelper.createDocument();
|
||||
// make something like <Relationships
|
||||
// xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
||||
Namespace dfNs = Namespace.get("", PackageNamespaces.RELATIONSHIPS);
|
||||
Element root = xmlOutDoc.addElement(new QName(
|
||||
PackageRelationship.RELATIONSHIPS_TAG_NAME, dfNs));
|
||||
|
||||
// <Relationship
|
||||
// TargetMode="External"
|
||||
// Id="rIdx"
|
||||
// Target="http://www.custom.com/images/pic1.jpg"
|
||||
// Type="http://www.custom.com/external-resource"/>
|
||||
|
||||
URI sourcePartURI = PackagingURIHelper
|
||||
.getSourcePartUriFromRelationshipPartUri(relPartName.getURI());
|
||||
|
||||
for (PackageRelationship rel : rels) {
|
||||
// L'<EFBFBD>l<EFBFBD>ment de la relation
|
||||
Element relElem = root
|
||||
.addElement(PackageRelationship.RELATIONSHIP_TAG_NAME);
|
||||
|
||||
// L'attribut ID
|
||||
relElem.addAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel
|
||||
.getId());
|
||||
|
||||
// L'attribut Type
|
||||
relElem.addAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel
|
||||
.getRelationshipType());
|
||||
|
||||
// L'attribut Target
|
||||
String targetValue;
|
||||
URI uri = rel.getTargetURI();
|
||||
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
|
||||
// Save the target as-is - we don't need to validate it,
|
||||
// alter it etc
|
||||
targetValue = uri.toString();
|
||||
|
||||
// add TargetMode attribut (as it is external link external)
|
||||
relElem.addAttribute(
|
||||
PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME,
|
||||
"External");
|
||||
} else {
|
||||
targetValue = PackagingURIHelper.relativizeURI(
|
||||
sourcePartURI, rel.getTargetURI()).getPath();
|
||||
}
|
||||
relElem.addAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME,
|
||||
targetValue);
|
||||
}
|
||||
|
||||
xmlOutDoc.normalize();
|
||||
|
||||
// String schemaFilename = Configuration.getPathForXmlSchema()+
|
||||
// File.separator + "opc-relationships.xsd";
|
||||
|
||||
// Save part in zip
|
||||
ZipEntry ctEntry = new ZipEntry(ZipHelper.getZipURIFromOPCName(
|
||||
relPartName.getURI().toASCIIString()).getPath());
|
||||
try {
|
||||
// Cr<EFBFBD>ation de l'entr<EFBFBD>e dans le fichier ZIP
|
||||
zos.putNextEntry(ctEntry);
|
||||
if (!StreamHelper.saveXmlInStream(xmlOutDoc, zos)) {
|
||||
return false;
|
||||
}
|
||||
zos.closeEntry();
|
||||
} catch (IOException e) {
|
||||
logger.error("Cannot create zip entry " + relPartName, e);
|
||||
return false;
|
||||
}
|
||||
return true; // success
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/* ====================================================================
|
||||
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.signature;
|
||||
|
||||
import java.io.IOException;
|
||||
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.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.internal.ContentType;
|
||||
|
||||
/**
|
||||
* Digital certificate part.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public final class DigitalCertificatePart extends PackagePart {
|
||||
|
||||
public DigitalCertificatePart() throws InvalidFormatException{
|
||||
super(null, null, new ContentType(""));
|
||||
// Review constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getInputStreamImpl() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream getOutputStreamImpl() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(InputStream ios) throws InvalidFormatException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(OutputStream zos) throws OpenXML4JException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO Introduire le concept de partie typ<EFBFBD>e d<EFBFBD>s cette partie
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/* ====================================================================
|
||||
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.signature;
|
||||
|
||||
/**
|
||||
* Represents a digital signature origin part.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.1
|
||||
*/
|
||||
public class DigitalSignatureOriginPart {
|
||||
|
||||
}
|
@ -0,0 +1,390 @@
|
||||
/* ====================================================================
|
||||
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.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.dom4j.Attribute;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.Namespace;
|
||||
import org.dom4j.QName;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageProperties;
|
||||
import org.apache.poi.openxml4j.opc.ZipPackage;
|
||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
|
||||
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
||||
|
||||
/**
|
||||
* Package properties unmarshaller.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PackagePropertiesUnmarshaller implements PartUnmarshaller {
|
||||
|
||||
private final static Namespace namespaceDC = new Namespace("dc",
|
||||
PackageProperties.NAMESPACE_DC);
|
||||
|
||||
private final static Namespace namespaceCP = new Namespace("cp",
|
||||
PackageNamespaces.CORE_PROPERTIES);
|
||||
|
||||
private final static Namespace namespaceDcTerms = new Namespace("dcterms",
|
||||
PackageProperties.NAMESPACE_DCTERMS);
|
||||
|
||||
private final static Namespace namespaceXML = new Namespace("xml",
|
||||
"http://www.w3.org/XML/1998/namespace");
|
||||
|
||||
private final static Namespace namespaceXSI = new Namespace("xsi",
|
||||
"http://www.w3.org/2001/XMLSchema-instance");
|
||||
|
||||
protected static final String KEYWORD_CATEGORY = "category";
|
||||
|
||||
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
|
||||
|
||||
protected static final String KEYWORD_CONTENT_TYPE = "contentType";
|
||||
|
||||
protected static final String KEYWORD_CREATED = "created";
|
||||
|
||||
protected static final String KEYWORD_CREATOR = "creator";
|
||||
|
||||
protected static final String KEYWORD_DESCRIPTION = "description";
|
||||
|
||||
protected static final String KEYWORD_IDENTIFIER = "identifier";
|
||||
|
||||
protected static final String KEYWORD_KEYWORDS = "keywords";
|
||||
|
||||
protected static final String KEYWORD_LANGUAGE = "language";
|
||||
|
||||
protected static final String KEYWORD_LAST_MODIFIED_BY = "lastModifiedBy";
|
||||
|
||||
protected static final String KEYWORD_LAST_PRINTED = "lastPrinted";
|
||||
|
||||
protected static final String KEYWORD_MODIFIED = "modified";
|
||||
|
||||
protected static final String KEYWORD_REVISION = "revision";
|
||||
|
||||
protected static final String KEYWORD_SUBJECT = "subject";
|
||||
|
||||
protected static final String KEYWORD_TITLE = "title";
|
||||
|
||||
protected static final String KEYWORD_VERSION = "version";
|
||||
|
||||
// TODO Load element with XMLBeans or dynamic table
|
||||
// TODO Check every element/namespace for compliance
|
||||
public PackagePart unmarshall(UnmarshallContext context, InputStream in)
|
||||
throws InvalidFormatException, IOException {
|
||||
PackagePropertiesPart coreProps = new PackagePropertiesPart(context
|
||||
.getPackage(), context.getPartName());
|
||||
|
||||
// If the input stream is null then we try to get it from the
|
||||
// package.
|
||||
if (in == null) {
|
||||
if (context.getZipEntry() != null) {
|
||||
in = ((ZipPackage) context.getPackage()).getZipArchive()
|
||||
.getInputStream(context.getZipEntry());
|
||||
} else if (context.getPackage() != null) {
|
||||
// Try to retrieve the part inputstream from the URI
|
||||
ZipEntry zipEntry;
|
||||
try {
|
||||
zipEntry = ZipHelper
|
||||
.getCorePropertiesZipEntry((ZipPackage) context
|
||||
.getPackage());
|
||||
} catch (OpenXML4JException e) {
|
||||
throw new IOException(
|
||||
"Error while trying to get the part input stream.");
|
||||
}
|
||||
in = ((ZipPackage) context.getPackage()).getZipArchive()
|
||||
.getInputStream(zipEntry);
|
||||
} else
|
||||
throw new IOException(
|
||||
"Error while trying to get the part input stream.");
|
||||
}
|
||||
|
||||
SAXReader xmlReader = new SAXReader();
|
||||
Document xmlDoc;
|
||||
try {
|
||||
xmlDoc = xmlReader.read(in);
|
||||
|
||||
/* Check OPC compliance */
|
||||
|
||||
// Rule M4.2, M4.3, M4.4 and M4.5/
|
||||
checkElementForOPCCompliance(xmlDoc.getRootElement());
|
||||
|
||||
/* End OPC compliance */
|
||||
|
||||
} catch (DocumentException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
|
||||
coreProps.setCategoryProperty(loadCategory(xmlDoc));
|
||||
coreProps.setContentStatusProperty(loadContentStatus(xmlDoc));
|
||||
coreProps.setContentTypeProperty(loadContentType(xmlDoc));
|
||||
coreProps.setCreatedProperty(loadCreated(xmlDoc));
|
||||
coreProps.setCreatorProperty(loadCreator(xmlDoc));
|
||||
coreProps.setDescriptionProperty(loadDescription(xmlDoc));
|
||||
coreProps.setIdentifierProperty(loadIdentifier(xmlDoc));
|
||||
coreProps.setKeywordsProperty(loadKeywords(xmlDoc));
|
||||
coreProps.setLanguageProperty(loadLanguage(xmlDoc));
|
||||
coreProps.setLastModifiedByProperty(loadLastModifiedBy(xmlDoc));
|
||||
coreProps.setLastPrintedProperty(loadLastPrinted(xmlDoc));
|
||||
coreProps.setModifiedProperty(loadModified(xmlDoc));
|
||||
coreProps.setRevisionProperty(loadRevision(xmlDoc));
|
||||
coreProps.setSubjectProperty(loadSubject(xmlDoc));
|
||||
coreProps.setTitleProperty(loadTitle(xmlDoc));
|
||||
coreProps.setVersionProperty(loadVersion(xmlDoc));
|
||||
|
||||
return coreProps;
|
||||
}
|
||||
|
||||
private String loadCategory(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CATEGORY, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadContentStatus(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CONTENT_STATUS, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadContentType(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CONTENT_TYPE, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadCreated(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CREATED, namespaceDcTerms));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadCreator(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_CREATOR, namespaceDC));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadDescription(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_DESCRIPTION, namespaceDC));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadIdentifier(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_IDENTIFIER, namespaceDC));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadKeywords(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_KEYWORDS, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadLanguage(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_LANGUAGE, namespaceDC));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadLastModifiedBy(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadLastPrinted(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_LAST_PRINTED, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadModified(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadRevision(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_REVISION, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadSubject(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_SUBJECT, namespaceDC));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadTitle(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_TITLE, namespaceDC));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private String loadVersion(Document xmlDoc) {
|
||||
Element el = xmlDoc.getRootElement().element(
|
||||
new QName(KEYWORD_VERSION, namespaceCP));
|
||||
if (el != null)
|
||||
return el.getStringValue();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/* OPC Compliance methods */
|
||||
|
||||
/**
|
||||
* Check the element for the following OPC compliance rules:
|
||||
*
|
||||
* Rule M4.2: A format consumer shall consider the use of the Markup
|
||||
* Compatibility namespace to be an error.
|
||||
*
|
||||
* Rule 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.
|
||||
*
|
||||
* Rule 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.
|
||||
*
|
||||
* Rule 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.
|
||||
*/
|
||||
public void checkElementForOPCCompliance(Element el)
|
||||
throws InvalidFormatException {
|
||||
// Check the current element
|
||||
List declaredNamespaces = el.declaredNamespaces();
|
||||
Iterator itNS = declaredNamespaces.iterator();
|
||||
while (itNS.hasNext()) {
|
||||
Namespace ns = (Namespace) itNS.next();
|
||||
|
||||
// Rule M4.2
|
||||
if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY))
|
||||
throw new InvalidFormatException(
|
||||
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.");
|
||||
}
|
||||
|
||||
// Rule M4.3
|
||||
if (el.getNamespace().getURI().equals(
|
||||
PackageProperties.NAMESPACE_DCTERMS)
|
||||
&& !(el.getName().equals(KEYWORD_CREATED) || el.getName()
|
||||
.equals(KEYWORD_MODIFIED)))
|
||||
throw new InvalidFormatException(
|
||||
"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.");
|
||||
|
||||
// Rule M4.4
|
||||
if (el.attribute(new QName("lang", namespaceXML)) != null)
|
||||
throw new InvalidFormatException(
|
||||
"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.");
|
||||
|
||||
// Rule M4.5
|
||||
if (el.getNamespace().getURI().equals(
|
||||
PackageProperties.NAMESPACE_DCTERMS)) {
|
||||
// DCTerms namespace only use with 'created' and 'modified' elements
|
||||
String elName = el.getName();
|
||||
if (!(elName.equals(KEYWORD_CREATED) || elName
|
||||
.equals(KEYWORD_MODIFIED)))
|
||||
throw new InvalidFormatException("Namespace error : " + elName
|
||||
+ " shouldn't have the following naemspace -> "
|
||||
+ PackageProperties.NAMESPACE_DCTERMS);
|
||||
|
||||
// Check for the 'xsi:type' attribute
|
||||
Attribute typeAtt = el.attribute(new QName("type", namespaceXSI));
|
||||
if (typeAtt == null)
|
||||
throw new InvalidFormatException("The element '" + elName
|
||||
+ "' must have the '" + namespaceXSI.getPrefix()
|
||||
+ ":type' attribute present !");
|
||||
|
||||
// Check for the attribute value => 'dcterms:W3CDTF'
|
||||
if (!typeAtt.getValue().equals("dcterms:W3CDTF"))
|
||||
throw new InvalidFormatException("The element '" + elName
|
||||
+ "' must have the '" + namespaceXSI.getPrefix()
|
||||
+ ":type' attribute with the value 'dcterms:W3CDTF' !");
|
||||
}
|
||||
|
||||
// Check its children
|
||||
Iterator itChildren = el.elementIterator();
|
||||
while (itChildren.hasNext())
|
||||
checkElementForOPCCompliance((Element) itChildren.next());
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/* ====================================================================
|
||||
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.Package;
|
||||
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 Package _package;
|
||||
|
||||
private PackagePartName partName;
|
||||
|
||||
private ZipEntry zipEntry;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param targetPackage
|
||||
* Container.
|
||||
* @param partName
|
||||
* Name of the part to unmarshall.
|
||||
*/
|
||||
public UnmarshallContext(Package targetPackage, PackagePartName partName) {
|
||||
this._package = targetPackage;
|
||||
this.partName = partName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the container
|
||||
*/
|
||||
Package getPackage() {
|
||||
return _package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param container
|
||||
* the container to set
|
||||
*/
|
||||
public void setPackage(Package 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/* ====================================================================
|
||||
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.signature;
|
||||
|
||||
import java.io.IOException;
|
||||
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.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.internal.ContentType;
|
||||
|
||||
public class PackageDigitalSignature extends PackagePart {
|
||||
|
||||
public PackageDigitalSignature() throws InvalidFormatException {
|
||||
super(null, null, new ContentType(""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getInputStreamImpl() throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream getOutputStreamImpl() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(InputStream ios) throws InvalidFormatException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(OutputStream zos) throws OpenXML4JException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/* ====================================================================
|
||||
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.signature;
|
||||
|
||||
public class PackageDigitalSignatureManager {
|
||||
|
||||
}
|
71
src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java
Executable file
71
src/ooxml/java/org/apache/poi/openxml4j/util/Nullable.java
Executable file
@ -0,0 +1,71 @@
|
||||
/* ====================================================================
|
||||
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.util;
|
||||
|
||||
/**
|
||||
* An immutable object that could be defined as null.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 0.9
|
||||
*/
|
||||
public final class Nullable<E> {
|
||||
|
||||
private E value;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public Nullable() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param value
|
||||
* The value to set to this nullable.
|
||||
*/
|
||||
public Nullable(E value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the store value if any.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public E getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of this nullable.
|
||||
*
|
||||
* @return <b>true</b> if the nullable store a value (empty string is
|
||||
* considered to be a value) else <b>false</>.
|
||||
*/
|
||||
public boolean hasValue() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the stored value to <i>null</i>.
|
||||
*/
|
||||
public void nullify() {
|
||||
value = null;
|
||||
}
|
||||
}
|
48
src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java
Executable file
48
src/ooxml/java/org/apache/poi/openxml4j/util/ZipEntrySource.java
Executable file
@ -0,0 +1,48 @@
|
||||
/* ====================================================================
|
||||
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.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
* An Interface to make getting the different bits
|
||||
* of a Zip File easy.
|
||||
* Allows you to get at the ZipEntries, without
|
||||
* needing to worry about ZipFile vs ZipInputStream
|
||||
* being annoyingly very different.
|
||||
*/
|
||||
public interface ZipEntrySource {
|
||||
/**
|
||||
* Returns an Enumeration of all the Entries
|
||||
*/
|
||||
public Enumeration<? extends ZipEntry> getEntries();
|
||||
|
||||
/**
|
||||
* Returns an InputStream of the decompressed
|
||||
* data that makes up the entry
|
||||
*/
|
||||
public InputStream getInputStream(ZipEntry entry) throws IOException;
|
||||
|
||||
/**
|
||||
* Indicates we are done with reading, and
|
||||
* resources may be freed
|
||||
*/
|
||||
public void close() throws IOException;
|
||||
}
|
48
src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java
Executable file
48
src/ooxml/java/org/apache/poi/openxml4j/util/ZipFileZipEntrySource.java
Executable file
@ -0,0 +1,48 @@
|
||||
/* ====================================================================
|
||||
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.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* A ZipEntrySource wrapper around a ZipFile.
|
||||
* Should be as low in terms of memory as a
|
||||
* normal ZipFile implementation is.
|
||||
*/
|
||||
public class ZipFileZipEntrySource implements ZipEntrySource {
|
||||
private ZipFile zipArchive;
|
||||
public ZipFileZipEntrySource(ZipFile zipFile) {
|
||||
this.zipArchive = zipFile;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
zipArchive.close();
|
||||
zipArchive = null;
|
||||
}
|
||||
|
||||
public Enumeration<? extends ZipEntry> getEntries() {
|
||||
return zipArchive.entries();
|
||||
}
|
||||
|
||||
public InputStream getInputStream(ZipEntry entry) throws IOException {
|
||||
return zipArchive.getInputStream(entry);
|
||||
}
|
||||
}
|
125
src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
Executable file
125
src/ooxml/java/org/apache/poi/openxml4j/util/ZipInputStreamZipEntrySource.java
Executable file
@ -0,0 +1,125 @@
|
||||
/* ====================================================================
|
||||
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.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* Provides a way to get at all the ZipEntries
|
||||
* from a ZipInputStream, as many times as required.
|
||||
* Allows a ZipInputStream to be treated much like
|
||||
* a ZipFile, for a price in terms of memory.
|
||||
* Be sure to call {@link #close()} as soon as you're
|
||||
* done, to free up that memory!
|
||||
*/
|
||||
public class ZipInputStreamZipEntrySource implements ZipEntrySource {
|
||||
private ArrayList<FakeZipEntry> zipEntries;
|
||||
|
||||
/**
|
||||
* Reads all the entries from the ZipInputStream
|
||||
* into memory, and closes the source stream.
|
||||
* We'll then eat lots of memory, but be able to
|
||||
* work with the entries at-will.
|
||||
*/
|
||||
public ZipInputStreamZipEntrySource(ZipInputStream inp) throws IOException {
|
||||
zipEntries = new ArrayList<FakeZipEntry>();
|
||||
|
||||
boolean going = true;
|
||||
while(going) {
|
||||
ZipEntry zipEntry = inp.getNextEntry();
|
||||
if(zipEntry == null) {
|
||||
going = false;
|
||||
} else {
|
||||
FakeZipEntry entry = new FakeZipEntry(zipEntry, inp);
|
||||
inp.closeEntry();
|
||||
|
||||
zipEntries.add(entry);
|
||||
}
|
||||
}
|
||||
inp.close();
|
||||
}
|
||||
|
||||
public Enumeration<? extends ZipEntry> getEntries() {
|
||||
return new EntryEnumerator();
|
||||
}
|
||||
|
||||
public InputStream getInputStream(ZipEntry zipEntry) {
|
||||
FakeZipEntry entry = (FakeZipEntry)zipEntry;
|
||||
return entry.getInputStream();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
// Free the memory
|
||||
zipEntries = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Why oh why oh why are Iterator and Enumeration
|
||||
* still not compatible?
|
||||
*/
|
||||
private class EntryEnumerator implements Enumeration<ZipEntry> {
|
||||
private Iterator<? extends ZipEntry> iterator;
|
||||
|
||||
private EntryEnumerator() {
|
||||
iterator = zipEntries.iterator();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
public ZipEntry nextElement() {
|
||||
return iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* So we can close the real zip entry and still
|
||||
* effectively work with it.
|
||||
* Holds the (decompressed!) data in memory, so
|
||||
* close this as soon as you can!
|
||||
*/
|
||||
public static class FakeZipEntry extends ZipEntry {
|
||||
private byte[] data;
|
||||
|
||||
public FakeZipEntry(ZipEntry entry, ZipInputStream inp) throws IOException {
|
||||
super(entry.getName());
|
||||
|
||||
// Grab the de-compressed contents for later
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int read = 0;
|
||||
while( (read = inp.read(buffer)) != -1 ) {
|
||||
baos.write(buffer, 0, read);
|
||||
}
|
||||
|
||||
data = baos.toByteArray();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return new ByteArrayInputStream(data);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import org.apache.poi.POIXMLDocument;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
|
||||
/**
|
||||
* Factory for creating the appropriate kind of Workbook
|
||||
|
@ -16,16 +16,12 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.util;
|
||||
|
||||
import org.openxml4j.opc.*;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.internal.PackagePropertiesPart;
|
||||
import org.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.*;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Provides handy methods to work with OOXML packages
|
||||
|
@ -22,12 +22,12 @@ import java.util.LinkedList;
|
||||
|
||||
import org.apache.poi.POIXMLDocument;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
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.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
|
||||
|
@ -23,8 +23,8 @@ 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.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
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;
|
||||
|
@ -25,14 +25,14 @@ 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.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackagePartName;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.openxml4j.opc.PackagingURIHelper;
|
||||
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.PackagePartName;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
|
||||
|
@ -29,8 +29,8 @@ import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
|
||||
/**
|
||||
* Helper class to extract text from an OOXML Excel file
|
||||
|
@ -29,8 +29,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
||||
public class CommentsTable extends POIXMLDocumentPart {
|
||||
protected CTComments comments;
|
||||
|
@ -31,9 +31,8 @@ import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSst;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.SstDocument;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -48,8 +48,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@
|
||||
package org.apache.poi.xssf.model;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFRelation;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
/**
|
||||
* Common interface for XSSF models, which have (typically
|
||||
|
@ -7,7 +7,7 @@ import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.xssf.model.XSSFWritableModel;
|
||||
import org.apache.poi.POIXMLException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
public class XSSFActiveXData implements PictureData, XSSFWritableModel {
|
||||
|
||||
|
@ -17,15 +17,8 @@
|
||||
|
||||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.POIXMLException;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
//YK: TODO: this is only a prototype
|
||||
public class XSSFDialogsheet extends XSSFSheet implements Sheet{
|
||||
|
@ -21,7 +21,7 @@ import org.apache.poi.ss.usermodel.Drawing;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.opc.*;
|
||||
import org.apache.poi.openxml4j.opc.*;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
||||
|
||||
|
@ -22,8 +22,8 @@ import org.apache.poi.POIXMLException;
|
||||
import org.apache.poi.POIXMLRelation;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
|
@ -22,8 +22,8 @@ import org.apache.poi.ss.usermodel.Hyperlink;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
|
||||
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,8 @@ import org.apache.poi.ss.usermodel.Picture;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Element;
|
||||
import javax.imageio.ImageIO;
|
||||
|
@ -24,8 +24,8 @@ import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.POIXMLException;
|
||||
import org.apache.poi.POIXMLRelation;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
||||
/**
|
||||
* Raw picture data, normally attached to a SpreadsheetML Drawing.
|
||||
|
@ -30,12 +30,12 @@ import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackagePartName;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.openxml4j.opc.PackagingURIHelper;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePartName;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -18,7 +18,7 @@ package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.*;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
|
||||
/**
|
||||
* This object specifies a group shape that represents many shapes grouped together. This shape is to be treated
|
||||
|
@ -39,10 +39,10 @@ import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
||||
|
||||
|
@ -50,14 +50,14 @@ import org.apache.poi.xssf.model.StylesTable;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackagePartName;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipTypes;
|
||||
import org.openxml4j.opc.PackagingURIHelper;
|
||||
import org.openxml4j.opc.TargetMode;
|
||||
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;
|
||||
|
@ -29,8 +29,8 @@ import org.apache.poi.xwpf.model.XWPFParagraphDecorator;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
|
||||
/**
|
||||
* Helper class to extract text from an OOXML Word file
|
||||
|
@ -22,7 +22,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFFooter;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFHeader;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
|
||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument;
|
||||
|
@ -27,10 +27,10 @@ import org.apache.poi.util.PackageHelper;
|
||||
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.exceptions.OpenXML4JException;
|
||||
import org.openxml4j.opc.*;
|
||||
import org.openxml4j.opc.Package;
|
||||
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;
|
||||
|
@ -22,8 +22,8 @@ import org.apache.poi.POIXMLException;
|
||||
import org.apache.poi.POIXMLRelation;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
|
@ -25,8 +25,8 @@ import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.xslf.XSLFSlideShow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
@ -20,7 +20,7 @@ import java.io.File;
|
||||
|
||||
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@ -33,7 +33,7 @@ public class TestXMLPropertiesTextExtractor extends TestCase {
|
||||
}
|
||||
|
||||
public void testGetFromMainExtractor() throws Exception {
|
||||
org.openxml4j.opc.Package pkg = Package.open(
|
||||
org.apache.poi.openxml4j.opc.Package pkg = Package.open(
|
||||
(new File(dirname, "ExcelWithAttachments.xlsx")).toString()
|
||||
);
|
||||
XSSFWorkbook wb = new XSSFWorkbook(pkg);
|
||||
@ -54,7 +54,7 @@ public class TestXMLPropertiesTextExtractor extends TestCase {
|
||||
}
|
||||
|
||||
public void testCore() throws Exception {
|
||||
org.openxml4j.opc.Package pkg = Package.open(
|
||||
org.apache.poi.openxml4j.opc.Package pkg = Package.open(
|
||||
(new File(dirname, "ExcelWithAttachments.xlsx")).toString()
|
||||
);
|
||||
XSSFWorkbook wb = new XSSFWorkbook(pkg);
|
||||
@ -71,7 +71,7 @@ public class TestXMLPropertiesTextExtractor extends TestCase {
|
||||
}
|
||||
|
||||
public void testExtended() throws Exception {
|
||||
org.openxml4j.opc.Package pkg = Package.open(
|
||||
org.apache.poi.openxml4j.opc.Package pkg = Package.open(
|
||||
(new File(dirname, "ExcelWithAttachments.xlsx")).toString()
|
||||
);
|
||||
XSSFWorkbook wb = new XSSFWorkbook(pkg);
|
||||
|
@ -33,8 +33,8 @@ import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.openxml4j.exceptions.InvalidOperationException;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
import org.apache.poi.openxml4j.opc.Package;
|
||||
|
||||
/**
|
||||
* Test that the extractor factory plays nicely
|
||||
|
102
src/ooxml/testcases/org/apache/poi/openxml4j/TestCore.java
Executable file
102
src/ooxml/testcases/org/apache/poi/openxml4j/TestCore.java
Executable file
@ -0,0 +1,102 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
|
||||
/**
|
||||
* Core helper for tests.
|
||||
*
|
||||
* @author Julien Chable
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TestCore {
|
||||
|
||||
private String testRootPath; // Test root path
|
||||
|
||||
/**
|
||||
* All sample document are normally located at this place.
|
||||
*/
|
||||
private static String pathRootProject; // Project root path
|
||||
|
||||
/**
|
||||
* Demo logger
|
||||
*/
|
||||
private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");
|
||||
|
||||
static {
|
||||
pathRootProject = System.getProperty("user.dir") + File.separator + "bin";
|
||||
|
||||
// Log4j configuration
|
||||
//PropertyConfigurator.configure(pathRootProject + File.separator
|
||||
// + "config.log4j");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Initialize the demo.
|
||||
*
|
||||
*/
|
||||
public TestCore(Class cl) {
|
||||
init(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the test root path
|
||||
*/
|
||||
public void init(Class cl) {
|
||||
String packageName = cl.getPackage().getName();
|
||||
// replace . by /
|
||||
String sep = File.separator;
|
||||
if (sep.equals("\\")) {
|
||||
sep = "\\\\";
|
||||
}
|
||||
testRootPath = pathRootProject + File.separator
|
||||
+ packageName.replaceAll("\\.", sep)
|
||||
+ File.separator;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
/**
|
||||
* Gets the test root path.
|
||||
*
|
||||
* @return The test root path.
|
||||
*/
|
||||
public String getTestRootPath() {
|
||||
return testRootPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test root path.
|
||||
*
|
||||
* @param testRoot
|
||||
*/
|
||||
public void setTestRootPath(String testRoot) {
|
||||
this.testRootPath = testRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the logger
|
||||
*/
|
||||
public static Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
}
|
38
src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllTests.java
Executable file
38
src/ooxml/testcases/org/apache/poi/openxml4j/opc/AllTests.java
Executable file
@ -0,0 +1,38 @@
|
||||
/* ====================================================================
|
||||
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 junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
public class AllTests {
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite(
|
||||
"Functional tests for org.apache.poi.openxml4j.opc");
|
||||
suite.addTestSuite(TestListParts.class);
|
||||
suite.addTestSuite(TestFileHelper.class);
|
||||
suite.addTestSuite(TestPackage.class);
|
||||
suite.addTestSuite(TestPackageCoreProperties.class);
|
||||
suite.addTestSuite(TestPackagePartName.class);
|
||||
suite.addTestSuite(TestPackagingURIHelper.class);
|
||||
suite.addTestSuite(TestContentType.class);
|
||||
suite.addTestSuite(TestPackageThumbnail.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
BIN
src/ooxml/testcases/org/apache/poi/openxml4j/opc/INPUT/ExcelWithHyperlinks.xlsx
Executable file
BIN
src/ooxml/testcases/org/apache/poi/openxml4j/opc/INPUT/ExcelWithHyperlinks.xlsx
Executable file
Binary file not shown.
BIN
src/ooxml/testcases/org/apache/poi/openxml4j/opc/INPUT/TestOpenPackageINPUT.docx
Executable file
BIN
src/ooxml/testcases/org/apache/poi/openxml4j/opc/INPUT/TestOpenPackageINPUT.docx
Executable file
Binary file not shown.
BIN
src/ooxml/testcases/org/apache/poi/openxml4j/opc/INPUT/TestPackageCommon.docx
Executable file
BIN
src/ooxml/testcases/org/apache/poi/openxml4j/opc/INPUT/TestPackageCommon.docx
Executable file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user