Fix bug #56814 - Switch from dom4j to JAXP

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1617428 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2014-08-12 07:19:51 +00:00
parent 549f7bc0e6
commit fed01cb1ad
19 changed files with 388 additions and 644 deletions

View File

@ -19,7 +19,6 @@
<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"/>

View File

@ -148,8 +148,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"/>
@ -221,7 +219,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"/>
@ -251,7 +248,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"/>
@ -429,7 +425,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}"/>
@ -440,10 +435,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}"/>
@ -1288,7 +1279,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}">
@ -1316,7 +1306,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"/>
@ -1449,7 +1438,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.1.jar" /> <auxClasspath path="ooxml-lib/ooxml-encryption-1.1.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" />

View File

@ -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

View File

@ -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/>.

View File

@ -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>

View File

@ -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>

View File

@ -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());
} }

View File

@ -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

View File

@ -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

View File

@ -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.
@ -40,18 +55,34 @@ public final class StreamHelper {
* @return <b>true</b> if the xml is successfully written in the stream, * @return <b>true</b> if the xml is successfully written in the stream,
* else <b>false</b>. * else <b>false</b>.
*/ */
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) {
return false; @Override
} public void write(byte b[], int off, int len)
return true; 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 true;
}
/** /**
* Copy the input stream into the output stream. * Copy the input stream into the output stream.

View File

@ -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).
@ -376,38 +374,33 @@ 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()); throw new InvalidFormatException(e.getMessage());
} } catch (IOException e) {
} throw new InvalidFormatException(e.getMessage());
}
}
/** /**
* Save the contents type part. * Save the contents type part.
@ -421,9 +414,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()) {
@ -454,10 +446,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);
} }
/** /**
@ -470,11 +462,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);
} }
/** /**

View File

@ -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.
* *

View File

@ -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) {

View File

@ -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());
} }
} }

View File

@ -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();

View File

@ -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,15 +110,15 @@ 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());
} }
coreProps.setCategoryProperty(loadCategory(xmlDoc)); coreProps.setCategoryProperty(loadCategory(xmlDoc));
coreProps.setContentStatusProperty(loadContentStatus(xmlDoc)); coreProps.setContentStatusProperty(loadContentStatus(xmlDoc));
coreProps.setContentTypeProperty(loadContentType(xmlDoc)); coreProps.setContentTypeProperty(loadContentType(xmlDoc));
coreProps.setCreatedProperty(loadCreated(xmlDoc)); coreProps.setCreatedProperty(loadCreated(xmlDoc));
@ -153,148 +138,76 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller {
return coreProps; return coreProps;
} }
private String readElement(Document xmlDoc, String localName, String namespaceURI) {
Element el = (Element)xmlDoc.getDocumentElement().getElementsByTagNameNS(namespaceURI, localName).item(0);
if (el == null) {
return null;
}
return el.getTextContent();
}
private String loadCategory(Document xmlDoc) { private String loadCategory(Document xmlDoc) {
Element el = xmlDoc.getRootElement().element( return readElement(xmlDoc, KEYWORD_CATEGORY, PackageNamespaces.CORE_PROPERTIES);
new QName(KEYWORD_CATEGORY, namespaceCP));
if (el == null) {
return null;
}
return el.getStringValue();
} }
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();
// Rule M4.2 if (attr.getNamespaceURI().equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY)) // Rule M4.2
throw new InvalidFormatException( if (attr.getValue().equals(PackageNamespaces.MARKUP_COMPATIBILITY))
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error."); throw new InvalidFormatException(
} "OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error.");
}
}
// Rule M4.3 // 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));
} }
} }

View 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());
}
}

View File

@ -23,10 +23,11 @@ import java.io.StringReader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;
@ -38,30 +39,43 @@ 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);
/** private static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
* Creates a new SAX Reader, with sensible defaults @Override
*/ public InputSource resolveEntity(String publicId, String systemId)
public static SAXReader getSAXReader() { throws SAXException, IOException {
SAXReader xmlReader = new SAXReader(); return new InputSource(new StringReader(""));
xmlReader.setValidation(false); }
xmlReader.setEntityResolver(new EntityResolver() { };
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException { private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
return new InputSource(new StringReader("")); static {
} documentBuilderFactory.setNamespaceAware(true);
}); documentBuilderFactory.setValidating(false);
trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING, true); trySetSAXFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySetXercesSecurityManager(xmlReader); trySetXercesSecurityManager(documentBuilderFactory);
return xmlReader;
} }
private static void trySetSAXFeature(SAXReader xmlReader, String feature, boolean enabled) {
/**
* Creates a new document builder, with sensible defaults
*/
public static synchronized DocumentBuilder getDocumentBuilder() {
try { try {
xmlReader.setFeature(feature, enabled); 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) {
try {
documentBuilderFactory.setFeature(feature, enabled);
} catch (Exception e) { } catch (Exception e) {
logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e); logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e);
} }
} }
private static void trySetXercesSecurityManager(SAXReader xmlReader) { private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) {
// Try built-in JVM one first, standalone if not // Try built-in JVM one first, standalone if not
for (String securityManagerClassName : new String[] { for (String securityManagerClassName : new String[] {
"com.sun.org.apache.xerces.internal.util.SecurityManager", "com.sun.org.apache.xerces.internal.util.SecurityManager",
@ -71,7 +85,7 @@ public final class SAXHelper {
Object mgr = Class.forName(securityManagerClassName).newInstance(); Object mgr = Class.forName(securityManagerClassName).newInstance();
Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
setLimit.invoke(mgr, 4096); setLimit.invoke(mgr, 4096);
xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr); documentBuilderFactory.setAttribute("http://apache.org/xml/properties/security-manager", mgr);
// Stop once one can be setup without error // Stop once one can be setup without error
return; return;
} catch (Exception e) { } catch (Exception e) {
@ -86,7 +100,7 @@ public final class SAXHelper {
* @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 Document readSAXDocument(InputStream inp) throws DocumentException { public static Document readSAXDocument(InputStream inp) throws IOException, SAXException {
return getSAXReader().read(inp); return getDocumentBuilder().parse(inp);
} }
} }

View File

@ -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());