sync merge to trunk
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1617624 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
commit
c378d75e51
@ -19,12 +19,12 @@
|
|||||||
<classpathentry kind="lib" path="lib/commons-codec-1.9.jar"/>
|
<classpathentry kind="lib" path="lib/commons-codec-1.9.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/commons-logging-1.1.3.jar"/>
|
<classpathentry kind="lib" path="lib/commons-logging-1.1.3.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
|
<classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
|
||||||
<classpathentry kind="lib" path="ooxml-lib/dom4j-1.6.1.jar"/>
|
|
||||||
<classpathentry kind="lib" path="ooxml-lib/xmlbeans-2.6.0.jar"/>
|
<classpathentry kind="lib" path="ooxml-lib/xmlbeans-2.6.0.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
|
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/junit-4.11.jar"/>
|
<classpathentry kind="lib" path="lib/junit-4.11.jar"/>
|
||||||
<classpathentry kind="lib" path="ooxml-lib/ooxml-schemas-1.1.jar" sourcepath="ooxml-lib/ooxml-schemas-src-1.1.jar"/>
|
<classpathentry kind="lib" path="ooxml-lib/ooxml-schemas-1.1.jar" sourcepath="ooxml-lib/ooxml-schemas-src-1.1.jar"/>
|
||||||
<classpathentry kind="lib" path="ooxml-lib/ooxml-encryption-1.2.jar" sourcepath="ooxml-lib/ooxml-encryption-src-1.2.jar"/>
|
<classpathentry kind="lib" path="ooxml-lib/ooxml-encryption-1.2.jar" sourcepath="ooxml-lib/ooxml-encryption-src-1.2.jar"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="lib" path="lib/mockito-core-1.9.5.jar" sourcepath="E:/tmp/mavenRepo/org/mockito/mockito-core/1.9.5/mockito-core-1.9.5-sources.jar"/>
|
||||||
<classpathentry kind="output" path="build/eclipse"/>
|
<classpathentry kind="output" path="build/eclipse"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
6
.settings/org.sonar.ide.eclipse.core.prefs
Normal file
6
.settings/org.sonar.ide.eclipse.core.prefs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
extraProperties=
|
||||||
|
lastAnalysisDate=1394235544000
|
||||||
|
projectKey=org.apache.poi\:poi-main
|
||||||
|
serverUrl=http\://nemo.sonarqube.org
|
||||||
|
version=2
|
12
build.xml
12
build.xml
@ -147,8 +147,6 @@ under the License.
|
|||||||
<property name="main.antlauncher.url" value="${repository.m2}/maven2/org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar"/>
|
<property name="main.antlauncher.url" value="${repository.m2}/maven2/org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar"/>
|
||||||
|
|
||||||
<!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
|
<!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
|
||||||
<property name="ooxml.dom4j.jar" location="${ooxml.lib}/dom4j-1.6.1.jar"/>
|
|
||||||
<property name="ooxml.dom4j.url" value="${repository.m2}/maven2/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar"/>
|
|
||||||
<property name="ooxml.xmlbeans23.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
|
<property name="ooxml.xmlbeans23.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
|
||||||
<property name="ooxml.xmlbeans23.url"
|
<property name="ooxml.xmlbeans23.url"
|
||||||
value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.3.0/xmlbeans-2.3.0.jar"/>
|
value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.3.0/xmlbeans-2.3.0.jar"/>
|
||||||
@ -233,7 +231,6 @@ under the License.
|
|||||||
</path>
|
</path>
|
||||||
|
|
||||||
<path id="ooxml.classpath">
|
<path id="ooxml.classpath">
|
||||||
<pathelement location="${ooxml.dom4j.jar}"/>
|
|
||||||
<pathelement location="${ooxml.xmlbeans26.jar}"/>
|
<pathelement location="${ooxml.xmlbeans26.jar}"/>
|
||||||
<pathelement location="${ooxml.xsds.jar}"/>
|
<pathelement location="${ooxml.xsds.jar}"/>
|
||||||
<path refid="main.classpath"/>
|
<path refid="main.classpath"/>
|
||||||
@ -263,7 +260,6 @@ under the License.
|
|||||||
</path>
|
</path>
|
||||||
|
|
||||||
<path id="ooxml-lite.classpath">
|
<path id="ooxml-lite.classpath">
|
||||||
<pathelement location="${ooxml.dom4j.jar}"/>
|
|
||||||
<pathelement location="${ooxml.xmlbeans26.jar}"/>
|
<pathelement location="${ooxml.xmlbeans26.jar}"/>
|
||||||
<pathelement location="build/ooxml-xsds-lite"/> <!-- instead of ooxml-xsds.jar use the filtered classes-->
|
<pathelement location="build/ooxml-xsds-lite"/> <!-- instead of ooxml-xsds.jar use the filtered classes-->
|
||||||
<path refid="main.classpath"/>
|
<path refid="main.classpath"/>
|
||||||
@ -441,7 +437,6 @@ under the License.
|
|||||||
<condition property="ooxml.jars.present">
|
<condition property="ooxml.jars.present">
|
||||||
<or>
|
<or>
|
||||||
<and>
|
<and>
|
||||||
<available file="${ooxml.dom4j.jar}"/>
|
|
||||||
<available file="${ooxml.xmlbeans23.jar}"/>
|
<available file="${ooxml.xmlbeans23.jar}"/>
|
||||||
<available file="${ooxml.xmlbeans26.jar}"/>
|
<available file="${ooxml.xmlbeans26.jar}"/>
|
||||||
<available file="${ooxml.xsds.jar}"/>
|
<available file="${ooxml.xsds.jar}"/>
|
||||||
@ -452,10 +447,6 @@ under the License.
|
|||||||
</target>
|
</target>
|
||||||
<target name="fetch-ooxml-jars" depends="check-ooxml-jars" unless="ooxml.jars.present">
|
<target name="fetch-ooxml-jars" depends="check-ooxml-jars" unless="ooxml.jars.present">
|
||||||
<mkdir dir="${ooxml.lib}"/>
|
<mkdir dir="${ooxml.lib}"/>
|
||||||
<antcall target="downloadfile">
|
|
||||||
<param name="sourcefile" value="${ooxml.dom4j.url}"/>
|
|
||||||
<param name="destfile" value="${ooxml.dom4j.jar}"/>
|
|
||||||
</antcall>
|
|
||||||
<antcall target="downloadfile">
|
<antcall target="downloadfile">
|
||||||
<param name="sourcefile" value="${ooxml.xmlbeans23.url}"/>
|
<param name="sourcefile" value="${ooxml.xmlbeans23.url}"/>
|
||||||
<param name="destfile" value="${ooxml.xmlbeans23.jar}"/>
|
<param name="destfile" value="${ooxml.xmlbeans23.jar}"/>
|
||||||
@ -1306,7 +1297,6 @@ under the License.
|
|||||||
<include name="log4j-*.jar"/>
|
<include name="log4j-*.jar"/>
|
||||||
</zipfileset>
|
</zipfileset>
|
||||||
<zipfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib">
|
<zipfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib">
|
||||||
<include name="dom4j-*.jar"/>
|
|
||||||
<include name="xmlbeans-2.6*.jar"/>
|
<include name="xmlbeans-2.6*.jar"/>
|
||||||
</zipfileset>
|
</zipfileset>
|
||||||
<zipfileset dir="${dist.dir}" prefix="${zipdir}">
|
<zipfileset dir="${dist.dir}" prefix="${zipdir}">
|
||||||
@ -1334,7 +1324,6 @@ under the License.
|
|||||||
<include name="log4j-*.jar"/>
|
<include name="log4j-*.jar"/>
|
||||||
</zipfileset>
|
</zipfileset>
|
||||||
<tarfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib">
|
<tarfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib">
|
||||||
<include name="dom4j-*.jar"/>
|
|
||||||
<include name="xmlbeans-2.6*.jar"/>
|
<include name="xmlbeans-2.6*.jar"/>
|
||||||
</tarfileset>
|
</tarfileset>
|
||||||
<tarfileset dir="${build.site}" prefix="${zipdir}/docs"/>
|
<tarfileset dir="${build.site}" prefix="${zipdir}/docs"/>
|
||||||
@ -1467,7 +1456,6 @@ under the License.
|
|||||||
<auxClasspath path="ooxml-lib/ooxml-schemas-1.1.jar" />
|
<auxClasspath path="ooxml-lib/ooxml-schemas-1.1.jar" />
|
||||||
<auxClasspath path="ooxml-lib/ooxml-encryption-1.2.jar" />
|
<auxClasspath path="ooxml-lib/ooxml-encryption-1.2.jar" />
|
||||||
<auxClasspath path="ooxml-lib/xmlbeans-2.6.0.jar" />
|
<auxClasspath path="ooxml-lib/xmlbeans-2.6.0.jar" />
|
||||||
<auxClasspath path="ooxml-lib/dom4j-1.6.1.jar" />
|
|
||||||
<auxClasspath path="lib/commons-codec-1.9.jar" />
|
<auxClasspath path="lib/commons-codec-1.9.jar" />
|
||||||
<auxClasspath path="lib/commons-logging-1.1.3.jar" />
|
<auxClasspath path="lib/commons-logging-1.1.3.jar" />
|
||||||
<auxClasspath path="lib/junit-4.11.jar" />
|
<auxClasspath path="lib/junit-4.11.jar" />
|
||||||
|
@ -229,50 +229,6 @@ Office Open XML schemas (ooxml-schemas-1.1.jar)
|
|||||||
[5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf
|
[5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf
|
||||||
|
|
||||||
|
|
||||||
DOM4J library (dom4j-1.6.1.jar)
|
|
||||||
|
|
||||||
Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
|
|
||||||
|
|
||||||
Redistribution and use of this software and associated documentation
|
|
||||||
("Software"), with or without modification, are permitted provided
|
|
||||||
that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain copyright
|
|
||||||
statements and notices. Redistributions must also contain a
|
|
||||||
copy of this document.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the
|
|
||||||
above copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other
|
|
||||||
materials provided with the distribution.
|
|
||||||
|
|
||||||
3. The name "DOM4J" must not be used to endorse or promote
|
|
||||||
products derived from this Software without prior written
|
|
||||||
permission of MetaStuff, Ltd. For written permission,
|
|
||||||
please contact dom4j-info@metastuff.com.
|
|
||||||
|
|
||||||
4. Products derived from this Software may not be called "DOM4J"
|
|
||||||
nor may "DOM4J" appear in their names without prior written
|
|
||||||
permission of MetaStuff, Ltd. DOM4J is a registered
|
|
||||||
trademark of MetaStuff, Ltd.
|
|
||||||
|
|
||||||
5. Due credit should be given to the DOM4J Project -
|
|
||||||
http://www.dom4j.org
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
|
|
||||||
``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
||||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
||||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
|
|
||||||
JUnit test library (junit-4.11.jar)
|
JUnit test library (junit-4.11.jar)
|
||||||
|
|
||||||
Common Public License - v 1.0
|
Common Public License - v 1.0
|
||||||
|
@ -4,9 +4,6 @@ Copyright 2003-2014 The Apache Software Foundation
|
|||||||
This product includes software developed by
|
This product includes software developed by
|
||||||
The Apache Software Foundation (http://www.apache.org/).
|
The Apache Software Foundation (http://www.apache.org/).
|
||||||
|
|
||||||
This product contains the DOM4J library (http://www.dom4j.org).
|
|
||||||
Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
|
|
||||||
|
|
||||||
This product contains parts that were originally based on software from BEA.
|
This product contains parts that were originally based on software from BEA.
|
||||||
Copyright (c) 2000-2003, BEA Systems, <http://www.bea.com/>.
|
Copyright (c) 2000-2003, BEA Systems, <http://www.bea.com/>.
|
||||||
|
|
||||||
|
@ -69,10 +69,5 @@
|
|||||||
<artifactId>poi-ooxml-schemas</artifactId>
|
<artifactId>poi-ooxml-schemas</artifactId>
|
||||||
<version>@VERSION@</version>
|
<version>@VERSION@</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>dom4j</groupId>
|
|
||||||
<artifactId>dom4j</artifactId>
|
|
||||||
<version>1.6.1</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -116,12 +116,6 @@
|
|||||||
<version>2.3.0</version>
|
<version>2.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>dom4j</groupId>
|
|
||||||
<artifactId>dom4j</artifactId>
|
|
||||||
<version>1.6.1</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- non-test dependency for OOXMLLite -->
|
<!-- non-test dependency for OOXMLLite -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
@ -179,7 +179,7 @@ public class ExcelAntTask extends Task {
|
|||||||
throw new BuildException(
|
throw new BuildException(
|
||||||
"The <classpath> for <excelant> must include poi.jar and poi-ooxml.jar " +
|
"The <classpath> for <excelant> must include poi.jar and poi-ooxml.jar " +
|
||||||
"if not in Ant's own classpath. Processing .xlsx spreadsheets requires " +
|
"if not in Ant's own classpath. Processing .xlsx spreadsheets requires " +
|
||||||
"additional poi-ooxml-schemas.jar, xmlbeans.jar and dom4j.jar" ,
|
"additional poi-ooxml-schemas.jar, xmlbeans.jar" ,
|
||||||
e, getLocation());
|
e, getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import java.io.File;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage class for configuration storage parameters.
|
* Storage class for configuration storage parameters.
|
||||||
* TODO xml syntax checking is no longer done with DOM4j parser -> remove the schema or do it ?
|
* TODO xml syntax checking is not done with JAXP by default -> remove the schema or do it ?
|
||||||
*
|
*
|
||||||
* @author CDubettier, Julen Chable
|
* @author CDubettier, Julen Chable
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
|
@ -27,9 +27,10 @@ import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
|||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.util.SAXHelper;
|
import org.apache.poi.util.SAXHelper;
|
||||||
import org.dom4j.Attribute;
|
import org.w3c.dom.Attr;
|
||||||
import org.dom4j.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.dom4j.Element;
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a collection of PackageRelationship elements that are owned by a
|
* Represents a collection of PackageRelationship elements that are owned by a
|
||||||
@ -313,22 +314,19 @@ public final class PackageRelationshipCollection implements
|
|||||||
Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream());
|
Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream());
|
||||||
|
|
||||||
// Browse default types
|
// Browse default types
|
||||||
Element root = xmlRelationshipsDoc.getRootElement();
|
Element root = xmlRelationshipsDoc.getDocumentElement();
|
||||||
|
|
||||||
// Check OPC compliance M4.1 rule
|
// Check OPC compliance M4.1 rule
|
||||||
boolean fCorePropertiesRelationship = false;
|
boolean fCorePropertiesRelationship = false;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
NodeList nodeList = root.getElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME);
|
||||||
Iterator<Element> iter = (Iterator<Element>)
|
int nodeCount = nodeList.getLength();
|
||||||
root.elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME);
|
for (int i = 0; i < nodeCount; i++) {
|
||||||
while (iter.hasNext()) {
|
Element element = (Element)nodeList.item(i);
|
||||||
Element element = iter.next();
|
|
||||||
// Relationship ID
|
// Relationship ID
|
||||||
String id = element.attribute(
|
String id = element.getAttribute(PackageRelationship.ID_ATTRIBUTE_NAME);
|
||||||
PackageRelationship.ID_ATTRIBUTE_NAME).getValue();
|
|
||||||
// Relationship type
|
// Relationship type
|
||||||
String type = element.attribute(
|
String type = element.getAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME);
|
||||||
PackageRelationship.TYPE_ATTRIBUTE_NAME).getValue();
|
|
||||||
|
|
||||||
/* Check OPC Compliance */
|
/* Check OPC Compliance */
|
||||||
// Check Rule M4.1
|
// Check Rule M4.1
|
||||||
@ -342,8 +340,7 @@ public final class PackageRelationshipCollection implements
|
|||||||
/* End OPC Compliance */
|
/* End OPC Compliance */
|
||||||
|
|
||||||
// TargetMode (default value "Internal")
|
// TargetMode (default value "Internal")
|
||||||
Attribute targetModeAttr = element
|
Attr targetModeAttr = element.getAttributeNode(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME);
|
||||||
.attribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME);
|
|
||||||
TargetMode targetMode = TargetMode.INTERNAL;
|
TargetMode targetMode = TargetMode.INTERNAL;
|
||||||
if (targetModeAttr != null) {
|
if (targetModeAttr != null) {
|
||||||
targetMode = targetModeAttr.getValue().toLowerCase()
|
targetMode = targetModeAttr.getValue().toLowerCase()
|
||||||
@ -353,9 +350,7 @@ public final class PackageRelationshipCollection implements
|
|||||||
|
|
||||||
// Target converted in URI
|
// Target converted in URI
|
||||||
URI target = PackagingURIHelper.toURI("http://invalid.uri"); // dummy url
|
URI target = PackagingURIHelper.toURI("http://invalid.uri"); // dummy url
|
||||||
String value = element.attribute(
|
String value = element.getAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME);
|
||||||
PackageRelationship.TARGET_ATTRIBUTE_NAME)
|
|
||||||
.getValue();
|
|
||||||
try {
|
try {
|
||||||
// when parsing of the given uri fails, we can either
|
// when parsing of the given uri fails, we can either
|
||||||
// ignore this relationship, which leads to IllegalStateException
|
// ignore this relationship, which leads to IllegalStateException
|
||||||
|
@ -17,12 +17,21 @@
|
|||||||
|
|
||||||
package org.apache.poi.openxml4j.opc;
|
package org.apache.poi.openxml4j.opc;
|
||||||
|
|
||||||
|
import java.io.FilterOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import javax.xml.transform.OutputKeys;
|
||||||
import org.dom4j.io.OutputFormat;
|
import javax.xml.transform.Result;
|
||||||
import org.dom4j.io.XMLWriter;
|
import javax.xml.transform.Source;
|
||||||
|
import javax.xml.transform.Transformer;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.transform.TransformerFactory;
|
||||||
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
public final class StreamHelper {
|
public final class StreamHelper {
|
||||||
|
|
||||||
@ -30,8 +39,14 @@ public final class StreamHelper {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
|
|
||||||
|
private static synchronized Transformer getIdentityTransformer() throws TransformerException {
|
||||||
|
return transformerFactory.newTransformer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turning the DOM4j object in the specified output stream.
|
* Save the document object in the specified output stream.
|
||||||
*
|
*
|
||||||
* @param xmlContent
|
* @param xmlContent
|
||||||
* The XML document.
|
* The XML document.
|
||||||
@ -43,11 +58,27 @@ public final class StreamHelper {
|
|||||||
public static boolean saveXmlInStream(Document xmlContent,
|
public static boolean saveXmlInStream(Document xmlContent,
|
||||||
OutputStream outStream) {
|
OutputStream outStream) {
|
||||||
try {
|
try {
|
||||||
OutputFormat outformat = OutputFormat.createPrettyPrint();
|
Transformer trans = getIdentityTransformer();
|
||||||
outformat.setEncoding("UTF-8");
|
Source xmlSource = new DOMSource(xmlContent);
|
||||||
XMLWriter writer = new XMLWriter(outStream, outformat);
|
// prevent close of stream by transformer:
|
||||||
writer.write(xmlContent);
|
Result outputTarget = new StreamResult(new FilterOutputStream(
|
||||||
} catch (Exception e) {
|
outStream) {
|
||||||
|
@Override
|
||||||
|
public void write(byte b[], int off, int len)
|
||||||
|
throws IOException {
|
||||||
|
out.write(b, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
out.flush(); // only flush, don't close!
|
||||||
|
}
|
||||||
|
});
|
||||||
|
trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||||
|
trans.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
|
trans.setOutputProperty(OutputKeys.STANDALONE, "yes");
|
||||||
|
trans.transform(xmlSource, outputTarget);
|
||||||
|
} catch (TransformerException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -17,12 +17,11 @@
|
|||||||
|
|
||||||
package org.apache.poi.openxml4j.opc.internal;
|
package org.apache.poi.openxml4j.opc.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@ -33,13 +32,12 @@ import org.apache.poi.openxml4j.opc.OPCPackage;
|
|||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePartName;
|
import org.apache.poi.openxml4j.opc.PackagePartName;
|
||||||
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
|
||||||
|
import org.apache.poi.util.DocumentHelper;
|
||||||
import org.apache.poi.util.SAXHelper;
|
import org.apache.poi.util.SAXHelper;
|
||||||
import org.dom4j.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.dom4j.DocumentException;
|
import org.w3c.dom.Element;
|
||||||
import org.dom4j.DocumentHelper;
|
import org.w3c.dom.NodeList;
|
||||||
import org.dom4j.Element;
|
import org.xml.sax.SAXException;
|
||||||
import org.dom4j.Namespace;
|
|
||||||
import org.dom4j.QName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage package content types ([Content_Types].xml part).
|
* Manage package content types ([Content_Types].xml part).
|
||||||
@ -375,35 +373,30 @@ public abstract class ContentTypeManager {
|
|||||||
Document xmlContentTypetDoc = SAXHelper.readSAXDocument(in);
|
Document xmlContentTypetDoc = SAXHelper.readSAXDocument(in);
|
||||||
|
|
||||||
// Default content types
|
// Default content types
|
||||||
List defaultTypes = xmlContentTypetDoc.getRootElement().elements(
|
NodeList defaultTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagName(DEFAULT_TAG_NAME);
|
||||||
DEFAULT_TAG_NAME);
|
int defaultTypeCount = defaultTypes.getLength();
|
||||||
Iterator elementIteratorDefault = defaultTypes.iterator();
|
for (int i = 0; i < defaultTypeCount; i++) {
|
||||||
while (elementIteratorDefault.hasNext()) {
|
Element element = (Element) defaultTypes.item(i);
|
||||||
Element element = (Element) elementIteratorDefault.next();
|
String extension = element.getAttribute(EXTENSION_ATTRIBUTE_NAME);
|
||||||
String extension = element.attribute(EXTENSION_ATTRIBUTE_NAME)
|
String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME);
|
||||||
.getValue();
|
|
||||||
String contentType = element.attribute(
|
|
||||||
CONTENT_TYPE_ATTRIBUTE_NAME).getValue();
|
|
||||||
addDefaultContentType(extension, contentType);
|
addDefaultContentType(extension, contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overriden content types
|
// Overriden content types
|
||||||
List overrideTypes = xmlContentTypetDoc.getRootElement().elements(
|
NodeList overrideTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagName(OVERRIDE_TAG_NAME);
|
||||||
OVERRIDE_TAG_NAME);
|
int overrideTypeCount = overrideTypes.getLength();
|
||||||
Iterator elementIteratorOverride = overrideTypes.iterator();
|
for (int i = 0; i < overrideTypeCount; i++) {
|
||||||
while (elementIteratorOverride.hasNext()) {
|
Element element = (Element) overrideTypes.item(i);
|
||||||
Element element = (Element) elementIteratorOverride.next();
|
URI uri = new URI(element.getAttribute(PART_NAME_ATTRIBUTE_NAME));
|
||||||
URI uri = new URI(element.attribute(PART_NAME_ATTRIBUTE_NAME)
|
PackagePartName partName = PackagingURIHelper.createPartName(uri);
|
||||||
.getValue());
|
String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME);
|
||||||
PackagePartName partName = PackagingURIHelper
|
|
||||||
.createPartName(uri);
|
|
||||||
String contentType = element.attribute(
|
|
||||||
CONTENT_TYPE_ATTRIBUTE_NAME).getValue();
|
|
||||||
addOverrideContentType(partName, contentType);
|
addOverrideContentType(partName, contentType);
|
||||||
}
|
}
|
||||||
} catch (URISyntaxException urie) {
|
} catch (URISyntaxException urie) {
|
||||||
throw new InvalidFormatException(urie.getMessage());
|
throw new InvalidFormatException(urie.getMessage());
|
||||||
} catch (DocumentException e) {
|
} catch (SAXException e) {
|
||||||
|
throw new InvalidFormatException(e.getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
throw new InvalidFormatException(e.getMessage());
|
throw new InvalidFormatException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,9 +413,8 @@ public abstract class ContentTypeManager {
|
|||||||
Document xmlOutDoc = DocumentHelper.createDocument();
|
Document xmlOutDoc = DocumentHelper.createDocument();
|
||||||
|
|
||||||
// Building namespace
|
// Building namespace
|
||||||
Namespace dfNs = Namespace.get("", TYPES_NAMESPACE_URI);
|
Element typesElem = xmlOutDoc.createElementNS(TYPES_NAMESPACE_URI, TYPES_TAG_NAME);
|
||||||
Element typesElem = xmlOutDoc
|
xmlOutDoc.appendChild(typesElem);
|
||||||
.addElement(new QName(TYPES_TAG_NAME, dfNs));
|
|
||||||
|
|
||||||
// Adding default types
|
// Adding default types
|
||||||
for (Entry<String, String> entry : defaultContentType.entrySet()) {
|
for (Entry<String, String> entry : defaultContentType.entrySet()) {
|
||||||
@ -453,10 +445,10 @@ public abstract class ContentTypeManager {
|
|||||||
*/
|
*/
|
||||||
private void appendSpecificTypes(Element root,
|
private void appendSpecificTypes(Element root,
|
||||||
Entry<PackagePartName, String> entry) {
|
Entry<PackagePartName, String> entry) {
|
||||||
root.addElement(OVERRIDE_TAG_NAME).addAttribute(
|
Element specificType = root.getOwnerDocument().createElement(OVERRIDE_TAG_NAME);
|
||||||
PART_NAME_ATTRIBUTE_NAME,
|
specificType.setAttribute(PART_NAME_ATTRIBUTE_NAME, entry.getKey().getName());
|
||||||
entry.getKey().getName()).addAttribute(
|
specificType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue());
|
||||||
CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue());
|
root.appendChild(specificType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -469,11 +461,10 @@ public abstract class ContentTypeManager {
|
|||||||
* @see #save(java.io.OutputStream)
|
* @see #save(java.io.OutputStream)
|
||||||
*/
|
*/
|
||||||
private void appendDefaultType(Element root, Entry<String, String> entry) {
|
private void appendDefaultType(Element root, Entry<String, String> entry) {
|
||||||
root.addElement(DEFAULT_TAG_NAME).addAttribute(
|
Element defaultType = root.getOwnerDocument().createElement(DEFAULT_TAG_NAME);
|
||||||
EXTENSION_ATTRIBUTE_NAME, entry.getKey())
|
defaultType.setAttribute(EXTENSION_ATTRIBUTE_NAME, entry.getKey());
|
||||||
.addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME,
|
defaultType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue());
|
||||||
entry.getValue());
|
root.appendChild(defaultType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,8 +48,6 @@ public final class PackagePropertiesPart extends PackagePart implements
|
|||||||
|
|
||||||
public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/";
|
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.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package org.apache.poi.openxml4j.opc.internal;
|
package org.apache.poi.openxml4j.opc.internal;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -30,7 +28,7 @@ import org.apache.poi.openxml4j.opc.OPCPackage;
|
|||||||
import org.apache.poi.openxml4j.opc.StreamHelper;
|
import org.apache.poi.openxml4j.opc.StreamHelper;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.dom4j.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zip implementation of the ContentTypeManager.
|
* Zip implementation of the ContentTypeManager.
|
||||||
@ -69,17 +67,8 @@ public class ZipContentTypeManager extends ContentTypeManager {
|
|||||||
// Referenced in ZIP
|
// Referenced in ZIP
|
||||||
zos.putNextEntry(partEntry);
|
zos.putNextEntry(partEntry);
|
||||||
// Saving data in the ZIP file
|
// Saving data in the ZIP file
|
||||||
ByteArrayOutputStream outTemp = new ByteArrayOutputStream();
|
if (!StreamHelper.saveXmlInStream(content, zos)) {
|
||||||
StreamHelper.saveXmlInStream(content, out);
|
return false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
zos.write(buff, 0, resultRead);
|
|
||||||
}
|
}
|
||||||
zos.closeEntry();
|
zos.closeEntry();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
|
@ -19,15 +19,18 @@ package org.apache.poi.openxml4j.opc.internal.marshallers;
|
|||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import javax.xml.XMLConstants;
|
||||||
import org.dom4j.DocumentHelper;
|
import javax.xml.stream.XMLEventFactory;
|
||||||
import org.dom4j.Element;
|
import javax.xml.stream.events.Namespace;
|
||||||
import org.dom4j.Namespace;
|
|
||||||
import org.dom4j.QName;
|
|
||||||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
||||||
|
import org.apache.poi.openxml4j.util.Nullable;
|
||||||
|
import org.apache.poi.util.DocumentHelper;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package properties marshaller.
|
* Package properties marshaller.
|
||||||
@ -36,17 +39,15 @@ import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
|||||||
*/
|
*/
|
||||||
public class PackagePropertiesMarshaller implements PartMarshaller {
|
public class PackagePropertiesMarshaller implements PartMarshaller {
|
||||||
|
|
||||||
private final static Namespace namespaceDC = new Namespace("dc",
|
|
||||||
PackagePropertiesPart.NAMESPACE_DC_URI);
|
|
||||||
|
|
||||||
private final static Namespace namespaceCoreProperties = new Namespace("",
|
private final static Namespace namespaceDC, namespaceCoreProperties, namespaceDcTerms, namespaceXSI;
|
||||||
PackagePropertiesPart.NAMESPACE_CP_URI);
|
static {
|
||||||
|
final XMLEventFactory f = XMLEventFactory.newFactory();
|
||||||
private final static Namespace namespaceDcTerms = new Namespace("dcterms",
|
namespaceDC = f.createNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
||||||
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
namespaceCoreProperties = f.createNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
|
||||||
|
namespaceDcTerms = f.createNamespace("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
||||||
private final static Namespace namespaceXSI = new Namespace("xsi",
|
namespaceXSI = f.createNamespace("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
|
||||||
PackagePropertiesPart.NAMESPACE_XSI_URI);
|
}
|
||||||
|
|
||||||
protected static final String KEYWORD_CATEGORY = "category";
|
protected static final String KEYWORD_CATEGORY = "category";
|
||||||
|
|
||||||
@ -98,13 +99,13 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
|||||||
|
|
||||||
// Configure the document
|
// Configure the document
|
||||||
xmlDoc = DocumentHelper.createDocument();
|
xmlDoc = DocumentHelper.createDocument();
|
||||||
Element rootElem = xmlDoc.addElement(new QName("coreProperties",
|
Element rootElem = xmlDoc.createElementNS(namespaceCoreProperties.getNamespaceURI(),
|
||||||
namespaceCoreProperties));
|
getQName("coreProperties", namespaceCoreProperties));
|
||||||
rootElem.addNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI);
|
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceCoreProperties);
|
||||||
rootElem.addNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI);
|
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDC);
|
||||||
rootElem.addNamespace("dcterms",
|
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDcTerms);
|
||||||
PackagePropertiesPart.NAMESPACE_DCTERMS_URI);
|
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceXSI);
|
||||||
rootElem.addNamespace("xsi", PackagePropertiesPart.NAMESPACE_XSI_URI);
|
xmlDoc.appendChild(rootElem);
|
||||||
|
|
||||||
addCategory();
|
addCategory();
|
||||||
addContentStatus();
|
addContentStatus();
|
||||||
@ -125,197 +126,110 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the given element's text content, creating it if necessary.
|
||||||
|
*/
|
||||||
|
private Element setElementTextContent(String localName, Namespace namespace, Nullable<String> property) {
|
||||||
|
return setElementTextContent(localName, namespace, property, property.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getQName(String localName, Namespace namespace) {
|
||||||
|
return namespace.getPrefix().isEmpty() ? localName : namespace.getPrefix() + ':' + localName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element setElementTextContent(String localName, Namespace namespace, Nullable<?> property, String propertyValue) {
|
||||||
|
if (!property.hasValue())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Element root = xmlDoc.getDocumentElement();
|
||||||
|
Element elem = (Element) root.getElementsByTagNameNS(namespace.getNamespaceURI(), localName).item(0);
|
||||||
|
if (elem == null) {
|
||||||
|
// missing, we add it
|
||||||
|
elem = xmlDoc.createElementNS(namespace.getNamespaceURI(), getQName(localName, namespace));
|
||||||
|
root.appendChild(elem);
|
||||||
|
}
|
||||||
|
elem.setTextContent(propertyValue);
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element setElementTextContent(String localName, Namespace namespace, Nullable<?> property, String propertyValue, String xsiType) {
|
||||||
|
Element element = setElementTextContent(localName, namespace, property, propertyValue);
|
||||||
|
if (element != null) {
|
||||||
|
element.setAttributeNS(namespaceXSI.getNamespaceURI(), getQName("type", namespaceXSI), xsiType);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add category property element if needed.
|
* Add category property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addCategory() {
|
private void addCategory() {
|
||||||
if (!propsPart.getCategoryProperty().hasValue())
|
setElementTextContent(KEYWORD_CATEGORY, namespaceCoreProperties, propsPart.getCategoryProperty());
|
||||||
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.
|
* Add content status property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addContentStatus() {
|
private void addContentStatus() {
|
||||||
if (!propsPart.getContentStatusProperty().hasValue())
|
setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty());
|
||||||
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.
|
* Add content type property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addContentType() {
|
private void addContentType() {
|
||||||
if (!propsPart.getContentTypeProperty().hasValue())
|
setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty());
|
||||||
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.
|
* Add created property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addCreated() {
|
private void addCreated() {
|
||||||
if (!propsPart.getCreatedProperty().hasValue())
|
setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(),
|
||||||
return;
|
propsPart.getCreatedPropertyString(), "dcterms:W3CDTF");
|
||||||
|
|
||||||
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.
|
* Add creator property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addCreator() {
|
private void addCreator() {
|
||||||
if (!propsPart.getCreatorProperty().hasValue())
|
setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty());
|
||||||
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.
|
* Add description property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addDescription() {
|
private void addDescription() {
|
||||||
if (!propsPart.getDescriptionProperty().hasValue())
|
setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty());
|
||||||
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.
|
* Add identifier property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addIdentifier() {
|
private void addIdentifier() {
|
||||||
if (!propsPart.getIdentifierProperty().hasValue())
|
setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty());
|
||||||
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.
|
* Add keywords property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addKeywords() {
|
private void addKeywords() {
|
||||||
if (!propsPart.getKeywordsProperty().hasValue())
|
setElementTextContent(KEYWORD_KEYWORDS, namespaceCoreProperties, propsPart.getKeywordsProperty());
|
||||||
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.
|
* Add language property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addLanguage() {
|
private void addLanguage() {
|
||||||
if (!propsPart.getLanguageProperty().hasValue())
|
setElementTextContent(KEYWORD_LANGUAGE, namespaceDC, propsPart.getLanguageProperty());
|
||||||
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.
|
* Add 'last modified by' property if needed.
|
||||||
*/
|
*/
|
||||||
private void addLastModifiedBy() {
|
private void addLastModifiedBy() {
|
||||||
if (!propsPart.getLastModifiedByProperty().hasValue())
|
setElementTextContent(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties, propsPart.getLastModifiedByProperty());
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -323,111 +237,39 @@ public class PackagePropertiesMarshaller implements PartMarshaller {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void addLastPrinted() {
|
private void addLastPrinted() {
|
||||||
if (!propsPart.getLastPrintedProperty().hasValue())
|
setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString());
|
||||||
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.
|
* Add modified property element if needed.
|
||||||
*/
|
*/
|
||||||
private void addModified() {
|
private void addModified() {
|
||||||
if (!propsPart.getModifiedProperty().hasValue())
|
setElementTextContent(KEYWORD_MODIFIED, namespaceDcTerms, propsPart.getModifiedProperty(),
|
||||||
return;
|
propsPart.getModifiedPropertyString(), "dcterms:W3CDTF");
|
||||||
|
|
||||||
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.
|
* Add revision property if needed.
|
||||||
*/
|
*/
|
||||||
private void addRevision() {
|
private void addRevision() {
|
||||||
if (!propsPart.getRevisionProperty().hasValue())
|
setElementTextContent(KEYWORD_REVISION, namespaceCoreProperties, propsPart.getRevisionProperty());
|
||||||
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.
|
* Add subject property if needed.
|
||||||
*/
|
*/
|
||||||
private void addSubject() {
|
private void addSubject() {
|
||||||
if (!propsPart.getSubjectProperty().hasValue())
|
setElementTextContent(KEYWORD_SUBJECT, namespaceDC, propsPart.getSubjectProperty());
|
||||||
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.
|
* Add title property if needed.
|
||||||
*/
|
*/
|
||||||
private void addTitle() {
|
private void addTitle() {
|
||||||
if (!propsPart.getTitleProperty().hasValue())
|
setElementTextContent(KEYWORD_TITLE, namespaceDC, propsPart.getTitleProperty());
|
||||||
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() {
|
private void addVersion() {
|
||||||
if (!propsPart.getVersionProperty().hasValue())
|
setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty());
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,6 @@ import java.net.URI;
|
|||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
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.exceptions.OpenXML4JException;
|
||||||
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
@ -40,8 +35,11 @@ import org.apache.poi.openxml4j.opc.StreamHelper;
|
|||||||
import org.apache.poi.openxml4j.opc.TargetMode;
|
import org.apache.poi.openxml4j.opc.TargetMode;
|
||||||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
import org.apache.poi.openxml4j.opc.internal.PartMarshaller;
|
||||||
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
||||||
|
import org.apache.poi.util.DocumentHelper;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zip part marshaller. This marshaller is use to save any part in a zip stream.
|
* Zip part marshaller. This marshaller is use to save any part in a zip stream.
|
||||||
@ -122,9 +120,8 @@ public final class ZipPartMarshaller implements PartMarshaller {
|
|||||||
Document xmlOutDoc = DocumentHelper.createDocument();
|
Document xmlOutDoc = DocumentHelper.createDocument();
|
||||||
// make something like <Relationships
|
// make something like <Relationships
|
||||||
// xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
// xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
||||||
Namespace dfNs = Namespace.get("", PackageNamespaces.RELATIONSHIPS);
|
Element root = xmlOutDoc.createElementNS(PackageNamespaces.RELATIONSHIPS, PackageRelationship.RELATIONSHIPS_TAG_NAME);
|
||||||
Element root = xmlOutDoc.addElement(new QName(
|
xmlOutDoc.appendChild(root);
|
||||||
PackageRelationship.RELATIONSHIPS_TAG_NAME, dfNs));
|
|
||||||
|
|
||||||
// <Relationship
|
// <Relationship
|
||||||
// TargetMode="External"
|
// TargetMode="External"
|
||||||
@ -137,16 +134,14 @@ public final class ZipPartMarshaller implements PartMarshaller {
|
|||||||
|
|
||||||
for (PackageRelationship rel : rels) {
|
for (PackageRelationship rel : rels) {
|
||||||
// the relationship element
|
// the relationship element
|
||||||
Element relElem = root
|
Element relElem = xmlOutDoc.createElement(PackageRelationship.RELATIONSHIP_TAG_NAME);
|
||||||
.addElement(PackageRelationship.RELATIONSHIP_TAG_NAME);
|
root.appendChild(relElem);
|
||||||
|
|
||||||
// the relationship ID
|
// the relationship ID
|
||||||
relElem.addAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel
|
relElem.setAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel.getId());
|
||||||
.getId());
|
|
||||||
|
|
||||||
// the relationship Type
|
// the relationship Type
|
||||||
relElem.addAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel
|
relElem.setAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel.getRelationshipType());
|
||||||
.getRelationshipType());
|
|
||||||
|
|
||||||
// the relationship Target
|
// the relationship Target
|
||||||
String targetValue;
|
String targetValue;
|
||||||
@ -157,16 +152,13 @@ public final class ZipPartMarshaller implements PartMarshaller {
|
|||||||
targetValue = uri.toString();
|
targetValue = uri.toString();
|
||||||
|
|
||||||
// add TargetMode attribute (as it is external link external)
|
// add TargetMode attribute (as it is external link external)
|
||||||
relElem.addAttribute(
|
relElem.setAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External");
|
||||||
PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME,
|
|
||||||
"External");
|
|
||||||
} else {
|
} else {
|
||||||
URI targetURI = rel.getTargetURI();
|
URI targetURI = rel.getTargetURI();
|
||||||
targetValue = PackagingURIHelper.relativizeURI(
|
targetValue = PackagingURIHelper.relativizeURI(
|
||||||
sourcePartURI, targetURI, true).toString();
|
sourcePartURI, targetURI, true).toString();
|
||||||
}
|
}
|
||||||
relElem.addAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME,
|
relElem.setAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME, targetValue);
|
||||||
targetValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlOutDoc.normalize();
|
xmlOutDoc.normalize();
|
||||||
|
@ -19,10 +19,10 @@ package org.apache.poi.openxml4j.opc.internal.unmarshallers;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
|
||||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
import org.apache.poi.openxml4j.opc.PackageNamespaces;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
@ -32,12 +32,12 @@ import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
|||||||
import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
|
import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller;
|
||||||
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
|
||||||
import org.apache.poi.util.SAXHelper;
|
import org.apache.poi.util.SAXHelper;
|
||||||
import org.dom4j.Attribute;
|
import org.w3c.dom.Attr;
|
||||||
import org.dom4j.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.dom4j.DocumentException;
|
import org.w3c.dom.Element;
|
||||||
import org.dom4j.Element;
|
import org.w3c.dom.NamedNodeMap;
|
||||||
import org.dom4j.Namespace;
|
import org.w3c.dom.NodeList;
|
||||||
import org.dom4j.QName;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package properties unmarshaller.
|
* Package properties unmarshaller.
|
||||||
@ -46,21 +46,6 @@ import org.dom4j.QName;
|
|||||||
*/
|
*/
|
||||||
public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {
|
public final 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_CATEGORY = "category";
|
||||||
|
|
||||||
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
|
protected static final String KEYWORD_CONTENT_STATUS = "contentStatus";
|
||||||
@ -125,11 +110,11 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {
|
|||||||
/* Check OPC compliance */
|
/* Check OPC compliance */
|
||||||
|
|
||||||
// Rule M4.2, M4.3, M4.4 and M4.5/
|
// Rule M4.2, M4.3, M4.4 and M4.5/
|
||||||
checkElementForOPCCompliance(xmlDoc.getRootElement());
|
checkElementForOPCCompliance(xmlDoc.getDocumentElement());
|
||||||
|
|
||||||
/* End OPC compliance */
|
/* End OPC compliance */
|
||||||
|
|
||||||
} catch (DocumentException e) {
|
} catch (SAXException e) {
|
||||||
throw new IOException(e.getMessage());
|
throw new IOException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,148 +138,76 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {
|
|||||||
return coreProps;
|
return coreProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadCategory(Document xmlDoc) {
|
private String readElement(Document xmlDoc, String localName, String namespaceURI) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
Element el = (Element)xmlDoc.getDocumentElement().getElementsByTagNameNS(namespaceURI, localName).item(0);
|
||||||
new QName(KEYWORD_CATEGORY, namespaceCP));
|
|
||||||
if (el == null) {
|
if (el == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return el.getStringValue();
|
return el.getTextContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String loadCategory(Document xmlDoc) {
|
||||||
|
return readElement(xmlDoc, KEYWORD_CATEGORY, PackageNamespaces.CORE_PROPERTIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadContentStatus(Document xmlDoc) {
|
private String loadContentStatus(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_CONTENT_STATUS, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_CONTENT_STATUS, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadContentType(Document xmlDoc) {
|
private String loadContentType(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_CONTENT_TYPE, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_CONTENT_TYPE, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadCreated(Document xmlDoc) {
|
private String loadCreated(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_CREATED, PackageProperties.NAMESPACE_DCTERMS);
|
||||||
new QName(KEYWORD_CREATED, namespaceDcTerms));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadCreator(Document xmlDoc) {
|
private String loadCreator(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_CREATOR, PackageProperties.NAMESPACE_DC);
|
||||||
new QName(KEYWORD_CREATOR, namespaceDC));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadDescription(Document xmlDoc) {
|
private String loadDescription(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_DESCRIPTION, PackageProperties.NAMESPACE_DC);
|
||||||
new QName(KEYWORD_DESCRIPTION, namespaceDC));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadIdentifier(Document xmlDoc) {
|
private String loadIdentifier(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_IDENTIFIER, PackageProperties.NAMESPACE_DC);
|
||||||
new QName(KEYWORD_IDENTIFIER, namespaceDC));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadKeywords(Document xmlDoc) {
|
private String loadKeywords(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_KEYWORDS, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_KEYWORDS, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadLanguage(Document xmlDoc) {
|
private String loadLanguage(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_LANGUAGE, PackageProperties.NAMESPACE_DC);
|
||||||
new QName(KEYWORD_LANGUAGE, namespaceDC));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadLastModifiedBy(Document xmlDoc) {
|
private String loadLastModifiedBy(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_LAST_MODIFIED_BY, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadLastPrinted(Document xmlDoc) {
|
private String loadLastPrinted(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_LAST_PRINTED, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_LAST_PRINTED, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadModified(Document xmlDoc) {
|
private String loadModified(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_MODIFIED, PackageProperties.NAMESPACE_DCTERMS);
|
||||||
new QName(KEYWORD_MODIFIED, namespaceDcTerms));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadRevision(Document xmlDoc) {
|
private String loadRevision(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_REVISION, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_REVISION, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadSubject(Document xmlDoc) {
|
private String loadSubject(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_SUBJECT, PackageProperties.NAMESPACE_DC);
|
||||||
new QName(KEYWORD_SUBJECT, namespaceDC));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadTitle(Document xmlDoc) {
|
private String loadTitle(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_TITLE, PackageProperties.NAMESPACE_DC);
|
||||||
new QName(KEYWORD_TITLE, namespaceDC));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadVersion(Document xmlDoc) {
|
private String loadVersion(Document xmlDoc) {
|
||||||
Element el = xmlDoc.getRootElement().element(
|
return readElement(xmlDoc, KEYWORD_VERSION, PackageNamespaces.CORE_PROPERTIES);
|
||||||
new QName(KEYWORD_VERSION, namespaceCP));
|
|
||||||
if (el == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return el.getStringValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OPC Compliance methods */
|
/* OPC Compliance methods */
|
||||||
@ -325,60 +238,56 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {
|
|||||||
public void checkElementForOPCCompliance(Element el)
|
public void checkElementForOPCCompliance(Element el)
|
||||||
throws InvalidFormatException {
|
throws InvalidFormatException {
|
||||||
// Check the current element
|
// Check the current element
|
||||||
@SuppressWarnings("unchecked")
|
NamedNodeMap namedNodeMap = el.getAttributes();
|
||||||
List<Namespace> declaredNamespaces = el.declaredNamespaces();
|
int namedNodeCount = namedNodeMap.getLength();
|
||||||
Iterator<Namespace> itNS = declaredNamespaces.iterator();
|
for (int i = 0; i < namedNodeCount; i++) {
|
||||||
while (itNS.hasNext()) {
|
Attr attr = (Attr)namedNodeMap.item(0);
|
||||||
Namespace ns = itNS.next();
|
|
||||||
|
|
||||||
|
if (attr.getNamespaceURI().equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
|
||||||
// Rule M4.2
|
// Rule M4.2
|
||||||
if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY))
|
if (attr.getValue().equals(PackageNamespaces.MARKUP_COMPATIBILITY))
|
||||||
throw new InvalidFormatException(
|
throw new InvalidFormatException(
|
||||||
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.");
|
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rule M4.3
|
// Rule M4.3
|
||||||
if (el.getNamespace().getURI().equals(
|
String elName = el.getLocalName();
|
||||||
PackageProperties.NAMESPACE_DCTERMS)
|
if (el.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS))
|
||||||
&& !(el.getName().equals(KEYWORD_CREATED) || el.getName()
|
if (!(elName.equals(KEYWORD_CREATED) || elName.equals(KEYWORD_MODIFIED)))
|
||||||
.equals(KEYWORD_MODIFIED)))
|
|
||||||
throw new InvalidFormatException(
|
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.");
|
"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
|
// Rule M4.4
|
||||||
if (el.attribute(new QName("lang", namespaceXML)) != null)
|
if (el.getAttributeNodeNS(XMLConstants.XML_NS_URI, "lang") != null)
|
||||||
throw new InvalidFormatException(
|
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.");
|
"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
|
// Rule M4.5
|
||||||
if (el.getNamespace().getURI().equals(
|
if (el.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS)) {
|
||||||
PackageProperties.NAMESPACE_DCTERMS)) {
|
|
||||||
// DCTerms namespace only use with 'created' and 'modified' elements
|
// DCTerms namespace only use with 'created' and 'modified' elements
|
||||||
String elName = el.getName();
|
if (!(elName.equals(KEYWORD_CREATED) || elName.equals(KEYWORD_MODIFIED)))
|
||||||
if (!(elName.equals(KEYWORD_CREATED) || elName
|
|
||||||
.equals(KEYWORD_MODIFIED)))
|
|
||||||
throw new InvalidFormatException("Namespace error : " + elName
|
throw new InvalidFormatException("Namespace error : " + elName
|
||||||
+ " shouldn't have the following naemspace -> "
|
+ " shouldn't have the following naemspace -> "
|
||||||
+ PackageProperties.NAMESPACE_DCTERMS);
|
+ PackageProperties.NAMESPACE_DCTERMS);
|
||||||
|
|
||||||
// Check for the 'xsi:type' attribute
|
// Check for the 'xsi:type' attribute
|
||||||
Attribute typeAtt = el.attribute(new QName("type", namespaceXSI));
|
Attr typeAtt = el.getAttributeNodeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
|
||||||
if (typeAtt == null)
|
if (typeAtt == null)
|
||||||
throw new InvalidFormatException("The element '" + elName
|
throw new InvalidFormatException("The element '" + elName
|
||||||
+ "' must have the '" + namespaceXSI.getPrefix()
|
+ "' must have the 'xsi:type' attribute present !");
|
||||||
+ ":type' attribute present !");
|
|
||||||
|
|
||||||
// Check for the attribute value => 'dcterms:W3CDTF'
|
// Check for the attribute value => 'dcterms:W3CDTF'
|
||||||
if (!typeAtt.getValue().equals("dcterms:W3CDTF"))
|
if (!typeAtt.getValue().equals("dcterms:W3CDTF"))
|
||||||
throw new InvalidFormatException("The element '" + elName
|
throw new InvalidFormatException("The element '" + elName
|
||||||
+ "' must have the '" + namespaceXSI.getPrefix()
|
+ "' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF' !");
|
||||||
+ ":type' attribute with the value 'dcterms:W3CDTF' !");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check its children
|
// Check its children
|
||||||
@SuppressWarnings("unchecked")
|
NodeList childElements = el.getElementsByTagName("*");
|
||||||
Iterator<Element> itChildren = el.elementIterator();
|
int childElementCount = childElements.getLength();
|
||||||
while (itChildren.hasNext())
|
for (int i = 0; i < childElementCount; i++)
|
||||||
checkElementForOPCCompliance(itChildren.next());
|
checkElementForOPCCompliance((Element)childElements.item(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,7 @@ public interface HorribleProxies {
|
|||||||
public interface OCSPRespIf extends ProxyIf {
|
public interface OCSPRespIf extends ProxyIf {
|
||||||
String delegateClass = "org.bouncycastle.cert.ocsp.OCSPResp";
|
String delegateClass = "org.bouncycastle.cert.ocsp.OCSPResp";
|
||||||
BasicOCSPRespIf getResponseObject();
|
BasicOCSPRespIf getResponseObject();
|
||||||
|
byte[] getEncoded() throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface PKIFailureInfoIf extends ProxyIf {
|
public interface PKIFailureInfoIf extends ProxyIf {
|
||||||
|
@ -171,7 +171,7 @@ public class SignatureInfo {
|
|||||||
KeyInfoKeySelector keySelector = new KeyInfoKeySelector();
|
KeyInfoKeySelector keySelector = new KeyInfoKeySelector();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Document doc = SAXHelper.readSAXDocumentW3C(signaturePart.getInputStream());
|
Document doc = SAXHelper.readSAXDocument(signaturePart.getInputStream());
|
||||||
// dummy call to createSignatureService to tweak document afterwards
|
// dummy call to createSignatureService to tweak document afterwards
|
||||||
createSignatureService(HashAlgorithm.sha1, pkg).registerIds(doc);
|
createSignatureService(HashAlgorithm.sha1, pkg).registerIds(doc);
|
||||||
|
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
package org.apache.poi.poifs.crypt.dsig.facets;
|
||||||
|
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||||
|
import javax.xml.crypto.dsig.DigestMethod;
|
||||||
|
import javax.xml.crypto.dsig.Reference;
|
||||||
|
import javax.xml.crypto.dsig.Transform;
|
||||||
|
import javax.xml.crypto.dsig.XMLObject;
|
||||||
|
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||||
|
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||||
|
|
||||||
|
import org.apache.poi.poifs.crypt.HashAlgorithm;
|
||||||
|
import org.w3.x2000.x09.xmldsig.SignatureType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature Facet implementation to create enveloped signatures.
|
||||||
|
*
|
||||||
|
* @author Frank Cornelis
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EnvelopedSignatureFacet implements SignatureFacet {
|
||||||
|
|
||||||
|
private final HashAlgorithm hashAlgo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor. Digest algorithm will be SHA-1.
|
||||||
|
*/
|
||||||
|
public EnvelopedSignatureFacet() {
|
||||||
|
this(HashAlgorithm.sha1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main constructor.
|
||||||
|
*
|
||||||
|
* @param hashAlgo
|
||||||
|
* the digest algorithm to be used within the ds:Reference
|
||||||
|
* element. Possible values: "SHA-1", "SHA-256, or "SHA-512".
|
||||||
|
*/
|
||||||
|
public EnvelopedSignatureFacet(HashAlgorithm hashAlgo) {
|
||||||
|
this.hashAlgo = hashAlgo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postSign(SignatureType signatureElement
|
||||||
|
, List<X509Certificate> signingCertificateChain) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preSign(XMLSignatureFactory signatureFactory,
|
||||||
|
String signatureId,
|
||||||
|
List<X509Certificate> signingCertificateChain,
|
||||||
|
List<Reference> references, List<XMLObject> objects)
|
||||||
|
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||||
|
DigestMethod digestMethod = signatureFactory.newDigestMethod(
|
||||||
|
this.hashAlgo.xmlSignUri, null);
|
||||||
|
|
||||||
|
List<Transform> transforms = new LinkedList<Transform>();
|
||||||
|
Transform envelopedTransform = signatureFactory
|
||||||
|
.newTransform(CanonicalizationMethod.ENVELOPED,
|
||||||
|
(TransformParameterSpec) null);
|
||||||
|
transforms.add(envelopedTransform);
|
||||||
|
Transform exclusiveTransform = signatureFactory
|
||||||
|
.newTransform(CanonicalizationMethod.EXCLUSIVE,
|
||||||
|
(TransformParameterSpec) null);
|
||||||
|
transforms.add(exclusiveTransform);
|
||||||
|
|
||||||
|
Reference reference = signatureFactory.newReference("", digestMethod,
|
||||||
|
transforms, null, null);
|
||||||
|
|
||||||
|
references.add(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String,String> getNamespacePrefixMapping() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -174,8 +174,10 @@ public class XmlSignatureService implements SignatureService {
|
|||||||
*
|
*
|
||||||
* @param signatureFacet
|
* @param signatureFacet
|
||||||
*/
|
*/
|
||||||
protected void addSignatureFacet(SignatureFacet signatureFacet) {
|
public void addSignatureFacet(SignatureFacet... signatureFacets) {
|
||||||
this.signatureFacets.add(signatureFacet);
|
for (SignatureFacet sf : signatureFacets) {
|
||||||
|
this.signatureFacets.add(sf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
60
src/ooxml/java/org/apache/poi/util/DocumentHelper.java
Normal file
60
src/ooxml/java/org/apache/poi/util/DocumentHelper.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.util;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.stream.events.Namespace;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
public class DocumentHelper {
|
||||||
|
|
||||||
|
private static final DocumentBuilder newDocumentBuilder;
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
newDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
throw new IllegalStateException("cannot create a DocumentBuilder", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized Document createDocument() {
|
||||||
|
return newDocumentBuilder.newDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a namespace declaration attribute to the given element.
|
||||||
|
*/
|
||||||
|
public static void addNamespaceDeclaration(Element element, String namespacePrefix, String namespaceURI) {
|
||||||
|
element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
|
||||||
|
XMLConstants.XMLNS_ATTRIBUTE + ':' + namespacePrefix,
|
||||||
|
namespaceURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a namespace declaration attribute to the given element.
|
||||||
|
*/
|
||||||
|
public static void addNamespaceDeclaration(Element element, Namespace namespace) {
|
||||||
|
addNamespaceDeclaration(element, namespace.getPrefix(), namespace.getNamespaceURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,9 +27,7 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.dom4j.DocumentException;
|
|
||||||
import org.dom4j.io.SAXReader;
|
|
||||||
import org.xml.sax.EntityResolver;
|
import org.xml.sax.EntityResolver;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
@ -41,58 +39,6 @@ import org.xml.sax.SAXException;
|
|||||||
public final class SAXHelper {
|
public final class SAXHelper {
|
||||||
private static POILogger logger = POILogFactory.getLogger(SAXHelper.class);
|
private static POILogger logger = POILogFactory.getLogger(SAXHelper.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new SAX Reader, with sensible defaults
|
|
||||||
*/
|
|
||||||
public static SAXReader getSAXReader() {
|
|
||||||
SAXReader xmlReader = new SAXReader();
|
|
||||||
xmlReader.setValidation(false);
|
|
||||||
xmlReader.setEntityResolver(new EntityResolver() {
|
|
||||||
public InputSource resolveEntity(String publicId, String systemId)
|
|
||||||
throws SAXException, IOException {
|
|
||||||
return new InputSource(new StringReader(""));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
||||||
trySetXercesSecurityManager(xmlReader);
|
|
||||||
return xmlReader;
|
|
||||||
}
|
|
||||||
private static void trySetSAXFeature(SAXReader xmlReader, String feature, boolean enabled) {
|
|
||||||
try {
|
|
||||||
xmlReader.setFeature(feature, enabled);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static void trySetXercesSecurityManager(SAXReader xmlReader) {
|
|
||||||
// Try built-in JVM one first, standalone if not
|
|
||||||
for (String securityManagerClassName : new String[] {
|
|
||||||
"com.sun.org.apache.xerces.internal.util.SecurityManager",
|
|
||||||
"org.apache.xerces.util.SecurityManager"
|
|
||||||
}) {
|
|
||||||
try {
|
|
||||||
Object mgr = Class.forName(securityManagerClassName).newInstance();
|
|
||||||
Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
|
|
||||||
setLimit.invoke(mgr, 4096);
|
|
||||||
xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr);
|
|
||||||
// Stop once one can be setup without error
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.log(POILogger.INFO, "SAX Security Manager could not be setup", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given stream via the default (sensible)
|
|
||||||
* SAX Reader
|
|
||||||
* @param inp Stream to read the XML data from
|
|
||||||
* @return the SAX processed Document
|
|
||||||
*/
|
|
||||||
public static Document readSAXDocument(InputStream inp) throws DocumentException {
|
|
||||||
return getSAXReader().read(inp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
|
private static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
|
||||||
@Override
|
@Override
|
||||||
public InputSource resolveEntity(String publicId, String systemId)
|
public InputSource resolveEntity(String publicId, String systemId)
|
||||||
@ -101,6 +47,27 @@ public final class SAXHelper {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
static {
|
||||||
|
documentBuilderFactory.setNamespaceAware(true);
|
||||||
|
documentBuilderFactory.setValidating(false);
|
||||||
|
trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
trySetXercesSecurityManager(documentBuilderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new document builder, with sensible defaults
|
||||||
|
*/
|
||||||
|
public static synchronized DocumentBuilder getDocumentBuilder() {
|
||||||
|
try {
|
||||||
|
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||||
|
documentBuilder.setEntityResolver(IGNORING_ENTITY_RESOLVER);
|
||||||
|
return documentBuilder;
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
throw new IllegalStateException("cannot create a DocumentBuilder", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
|
private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) {
|
||||||
try {
|
try {
|
||||||
documentBuilderFactory.setFeature(feature, enabled);
|
documentBuilderFactory.setFeature(feature, enabled);
|
||||||
@ -127,37 +94,13 @@ public final class SAXHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final ThreadLocal<DocumentBuilder> documentBuilder = new ThreadLocal<DocumentBuilder>() {
|
|
||||||
@Override
|
|
||||||
protected DocumentBuilder initialValue() {
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
||||||
factory.setNamespaceAware(true);
|
|
||||||
factory.setValidating(false);
|
|
||||||
trySetSAXFeature(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
|
||||||
trySetXercesSecurityManager(factory);
|
|
||||||
try {
|
|
||||||
return factory.newDocumentBuilder();
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
throw new IllegalStateException("cannot create a DocumentBuilder", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocumentBuilder get() {
|
|
||||||
DocumentBuilder documentBuilder = super.get();
|
|
||||||
documentBuilder.reset();
|
|
||||||
documentBuilder.setEntityResolver(IGNORING_ENTITY_RESOLVER);
|
|
||||||
return documentBuilder;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the given stream via the default (sensible)
|
* Parses the given stream via the default (sensible)
|
||||||
* SAX Reader
|
* SAX Reader
|
||||||
* @param inp Stream to read the XML data from
|
* @param inp Stream to read the XML data from
|
||||||
* @return the SAX processed Document
|
* @return the SAX processed Document
|
||||||
*/
|
*/
|
||||||
public static org.w3c.dom.Document readSAXDocumentW3C(InputStream inp) throws IOException, SAXException {
|
public static Document readSAXDocument(InputStream inp) throws IOException, SAXException {
|
||||||
return documentBuilder.get().parse(inp);
|
return getDocumentBuilder().parse(inp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import java.io.OutputStream;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -40,15 +39,14 @@ import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
|||||||
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
|
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
|
||||||
import org.apache.poi.openxml4j.opc.internal.FileHelper;
|
import org.apache.poi.openxml4j.opc.internal.FileHelper;
|
||||||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
|
||||||
|
import org.apache.poi.util.DocumentHelper;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.util.SAXHelper;
|
import org.apache.poi.util.SAXHelper;
|
||||||
import org.apache.poi.util.TempFile;
|
import org.apache.poi.util.TempFile;
|
||||||
import org.dom4j.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.dom4j.DocumentHelper;
|
import org.w3c.dom.Element;
|
||||||
import org.dom4j.Element;
|
import org.w3c.dom.NodeList;
|
||||||
import org.dom4j.Namespace;
|
|
||||||
import org.dom4j.QName;
|
|
||||||
|
|
||||||
public final class TestPackage extends TestCase {
|
public final class TestPackage extends TestCase {
|
||||||
private static final POILogger logger = POILogFactory.getLogger(TestPackage.class);
|
private static final POILogger logger = POILogFactory.getLogger(TestPackage.class);
|
||||||
@ -127,18 +125,17 @@ public final class TestPackage extends TestCase {
|
|||||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");
|
||||||
|
|
||||||
Document doc = DocumentHelper.createDocument();
|
Document doc = DocumentHelper.createDocument();
|
||||||
Namespace nsWordprocessinML = new Namespace("w",
|
Element elDocument = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:document");
|
||||||
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
doc.appendChild(elDocument);
|
||||||
Element elDocument = doc.addElement(new QName("document",
|
Element elBody = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:body");
|
||||||
nsWordprocessinML));
|
elDocument.appendChild(elBody);
|
||||||
Element elBody = elDocument.addElement(new QName("body",
|
Element elParagraph = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:p");
|
||||||
nsWordprocessinML));
|
elBody.appendChild(elParagraph);
|
||||||
Element elParagraph = elBody.addElement(new QName("p",
|
Element elRun = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:r");
|
||||||
nsWordprocessinML));
|
elParagraph.appendChild(elRun);
|
||||||
Element elRun = elParagraph
|
Element elText = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:t");
|
||||||
.addElement(new QName("r", nsWordprocessinML));
|
elRun.appendChild(elText);
|
||||||
Element elText = elRun.addElement(new QName("t", nsWordprocessinML));
|
elText.setTextContent("Hello Open XML !");
|
||||||
elText.setText("Hello Open XML !");
|
|
||||||
|
|
||||||
StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());
|
StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());
|
||||||
pkg.close();
|
pkg.close();
|
||||||
@ -223,15 +220,13 @@ public final class TestPackage extends TestCase {
|
|||||||
|
|
||||||
Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream());
|
Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream());
|
||||||
|
|
||||||
Element root = xmlRelationshipsDoc.getRootElement();
|
Element root = xmlRelationshipsDoc.getDocumentElement();
|
||||||
for (Iterator i = root
|
NodeList nodeList = root.getElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME);
|
||||||
.elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i
|
int nodeCount = nodeList.getLength();
|
||||||
.hasNext();) {
|
for (int i = 0; i < nodeCount; i++) {
|
||||||
Element element = (Element) i.next();
|
Element element = (Element) nodeList.item(i);
|
||||||
String value = element.attribute(
|
String value = element.getAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME);
|
||||||
PackageRelationship.TARGET_ATTRIBUTE_NAME)
|
assertTrue("Root target must not start with a leading slash ('/'): " + value, value.charAt(0) != '/');
|
||||||
.getValue();
|
|
||||||
assertTrue("Root target must not start with a leadng slash ('/'): " + value, value.charAt(0) != '/');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -268,18 +263,17 @@ public final class TestPackage extends TestCase {
|
|||||||
|
|
||||||
// Create a content
|
// Create a content
|
||||||
Document doc = DocumentHelper.createDocument();
|
Document doc = DocumentHelper.createDocument();
|
||||||
Namespace nsWordprocessinML = new Namespace("w",
|
Element elDocument = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:document");
|
||||||
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
|
doc.appendChild(elDocument);
|
||||||
Element elDocument = doc.addElement(new QName("document",
|
Element elBody = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:body");
|
||||||
nsWordprocessinML));
|
elDocument.appendChild(elBody);
|
||||||
Element elBody = elDocument.addElement(new QName("body",
|
Element elParagraph = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:p");
|
||||||
nsWordprocessinML));
|
elBody.appendChild(elParagraph);
|
||||||
Element elParagraph = elBody.addElement(new QName("p",
|
Element elRun = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:r");
|
||||||
nsWordprocessinML));
|
elParagraph.appendChild(elRun);
|
||||||
Element elRun = elParagraph
|
Element elText = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:t");
|
||||||
.addElement(new QName("r", nsWordprocessinML));
|
elRun.appendChild(elText);
|
||||||
Element elText = elRun.addElement(new QName("t", nsWordprocessinML));
|
elText.setTextContent("Hello Open XML !");
|
||||||
elText.setText("Hello Open XML !");
|
|
||||||
|
|
||||||
StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());
|
StreamHelper.saveXmlInStream(doc, corePart.getOutputStream());
|
||||||
|
|
||||||
|
@ -26,6 +26,10 @@ package org.apache.poi.poifs.crypt;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -40,7 +44,9 @@ import java.security.KeyPair;
|
|||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -53,8 +59,17 @@ import org.apache.poi.POIDataSamples;
|
|||||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||||
import org.apache.poi.openxml4j.opc.PackageAccess;
|
import org.apache.poi.openxml4j.opc.PackageAccess;
|
||||||
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.KeyUsageIf;
|
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.KeyUsageIf;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespIf;
|
||||||
import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
|
import org.apache.poi.poifs.crypt.dsig.HorribleProxy;
|
||||||
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
|
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.facets.SignaturePolicyService;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;
|
||||||
|
import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
|
||||||
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;
|
import org.apache.poi.poifs.crypt.dsig.services.XmlSignatureService;
|
||||||
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
|
import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
@ -62,6 +77,8 @@ import org.apache.poi.util.POILogFactory;
|
|||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
public class TestSignatureInfo {
|
public class TestSignatureInfo {
|
||||||
private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class);
|
private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class);
|
||||||
@ -171,6 +188,64 @@ public class TestSignatureInfo {
|
|||||||
pkg.close();
|
pkg.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignEnvelopingDocument() throws Exception {
|
||||||
|
String testFile = "hello-world-unsigned.xlsx";
|
||||||
|
OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
|
||||||
|
|
||||||
|
// setup
|
||||||
|
EnvelopedSignatureFacet envelopedSignatureFacet = new EnvelopedSignatureFacet();
|
||||||
|
KeyInfoSignatureFacet keyInfoSignatureFacet = new KeyInfoSignatureFacet(true, false, false);
|
||||||
|
SignaturePolicyService signaturePolicyService = null;
|
||||||
|
XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(null, null, signaturePolicyService);
|
||||||
|
|
||||||
|
|
||||||
|
TimeStampService mockTimeStampService = mock(TimeStampService.class);
|
||||||
|
RevocationDataService mockRevocationDataService = mock(RevocationDataService.class);
|
||||||
|
|
||||||
|
XAdESXLSignatureFacet xadesXLSignatureFacet = new XAdESXLSignatureFacet(
|
||||||
|
mockTimeStampService, mockRevocationDataService);
|
||||||
|
XmlSignatureService testedInstance = new XmlSignatureService(HashAlgorithm.sha1, pkg);
|
||||||
|
testedInstance.addSignatureFacet(envelopedSignatureFacet, keyInfoSignatureFacet,
|
||||||
|
xadesSignatureFacet, xadesXLSignatureFacet);
|
||||||
|
|
||||||
|
initKeyPair("Test", "CN=Test");
|
||||||
|
List<X509Certificate> certificateChain = new ArrayList<X509Certificate>();
|
||||||
|
/*
|
||||||
|
* We need at least 2 certificates for the XAdES-C complete certificate
|
||||||
|
* refs construction.
|
||||||
|
*/
|
||||||
|
certificateChain.add(x509);
|
||||||
|
certificateChain.add(x509);
|
||||||
|
|
||||||
|
RevocationData revocationData = new RevocationData();
|
||||||
|
final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate());
|
||||||
|
revocationData.addCRL(crl);
|
||||||
|
OCSPRespIf ocspResp = PkiTestUtils.createOcspResp(x509, false,
|
||||||
|
x509, x509, keyPair.getPrivate(), "SHA1withRSA");
|
||||||
|
revocationData.addOCSP(ocspResp.getEncoded());
|
||||||
|
|
||||||
|
when(mockTimeStampService.timeStamp(any(byte[].class), any(RevocationData.class)))
|
||||||
|
.thenAnswer(new Answer<byte[]>(){
|
||||||
|
public byte[] answer(InvocationOnMock invocation) throws Throwable {
|
||||||
|
Object[] arguments = invocation.getArguments();
|
||||||
|
RevocationData revocationData = (RevocationData) arguments[1];
|
||||||
|
revocationData.addCRL(crl);
|
||||||
|
return "time-stamp-token".getBytes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
when(mockRevocationDataService.getRevocationData(eq(certificateChain)))
|
||||||
|
.thenReturn(revocationData);
|
||||||
|
|
||||||
|
// operate
|
||||||
|
DigestInfo digestInfo = testedInstance.preSign(null, certificateChain, null, null, null);
|
||||||
|
|
||||||
|
// verify
|
||||||
|
assertNotNull(digestInfo);
|
||||||
|
assertEquals("SHA-1", digestInfo.hashAlgo);
|
||||||
|
assertNotNull(digestInfo.digestValue);
|
||||||
|
}
|
||||||
|
|
||||||
private OPCPackage sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {
|
private OPCPackage sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {
|
||||||
/*** TODO : set cal to now ... only set to fixed date for debugging ... */
|
/*** TODO : set cal to now ... only set to fixed date for debugging ... */
|
||||||
|
@ -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.xwpf.extractor;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.xwpf.XWPFTestDataSamples;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||||
|
|
||||||
|
public class TestExternalEntities extends TestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get text out of the simple file
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void testFile() throws IOException {
|
||||||
|
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("ExternalEntityInText.docx");
|
||||||
|
XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
|
||||||
|
|
||||||
|
String text = extractor.getText();
|
||||||
|
|
||||||
|
assertTrue(text.length() > 0);
|
||||||
|
|
||||||
|
// Check contents, they should not contain the text from POI web site after colon!
|
||||||
|
assertEquals("Here should not be the POI web site: \"\"", text.trim());
|
||||||
|
|
||||||
|
extractor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
test-data/document/ExternalEntityInText.docx
Normal file
BIN
test-data/document/ExternalEntityInText.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user