git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1617428 13f79535-47bb-0310-9956-ffa450edef68pull/11/head
@@ -19,7 +19,6 @@ | |||
<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/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="lib/hamcrest-core-1.3.jar"/> | |||
<classpathentry kind="lib" path="lib/junit-4.11.jar"/> |
@@ -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"/> | |||
<!-- 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.url" | |||
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 id="ooxml.classpath"> | |||
<pathelement location="${ooxml.dom4j.jar}"/> | |||
<pathelement location="${ooxml.xmlbeans26.jar}"/> | |||
<pathelement location="${ooxml.xsds.jar}"/> | |||
<path refid="main.classpath"/> | |||
@@ -251,7 +248,6 @@ under the License. | |||
</path> | |||
<path id="ooxml-lite.classpath"> | |||
<pathelement location="${ooxml.dom4j.jar}"/> | |||
<pathelement location="${ooxml.xmlbeans26.jar}"/> | |||
<pathelement location="build/ooxml-xsds-lite"/> <!-- instead of ooxml-xsds.jar use the filtered classes--> | |||
<path refid="main.classpath"/> | |||
@@ -429,7 +425,6 @@ under the License. | |||
<condition property="ooxml.jars.present"> | |||
<or> | |||
<and> | |||
<available file="${ooxml.dom4j.jar}"/> | |||
<available file="${ooxml.xmlbeans23.jar}"/> | |||
<available file="${ooxml.xmlbeans26.jar}"/> | |||
<available file="${ooxml.xsds.jar}"/> | |||
@@ -440,10 +435,6 @@ under the License. | |||
</target> | |||
<target name="fetch-ooxml-jars" depends="check-ooxml-jars" unless="ooxml.jars.present"> | |||
<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"> | |||
<param name="sourcefile" value="${ooxml.xmlbeans23.url}"/> | |||
<param name="destfile" value="${ooxml.xmlbeans23.jar}"/> | |||
@@ -1288,7 +1279,6 @@ under the License. | |||
<include name="log4j-*.jar"/> | |||
</zipfileset> | |||
<zipfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib"> | |||
<include name="dom4j-*.jar"/> | |||
<include name="xmlbeans-2.6*.jar"/> | |||
</zipfileset> | |||
<zipfileset dir="${dist.dir}" prefix="${zipdir}"> | |||
@@ -1316,7 +1306,6 @@ under the License. | |||
<include name="log4j-*.jar"/> | |||
</zipfileset> | |||
<tarfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib"> | |||
<include name="dom4j-*.jar"/> | |||
<include name="xmlbeans-2.6*.jar"/> | |||
</tarfileset> | |||
<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-encryption-1.1.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-logging-1.1.3.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 | |||
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) | |||
Common Public License - v 1.0 |
@@ -4,9 +4,6 @@ Copyright 2003-2014 The Apache Software Foundation | |||
This product includes software developed by | |||
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. | |||
Copyright (c) 2000-2003, BEA Systems, <http://www.bea.com/>. | |||
@@ -69,10 +69,5 @@ | |||
<artifactId>poi-ooxml-schemas</artifactId> | |||
<version>@VERSION@</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>dom4j</groupId> | |||
<artifactId>dom4j</artifactId> | |||
<version>1.6.1</version> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -116,12 +116,6 @@ | |||
<version>2.3.0</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>dom4j</groupId> | |||
<artifactId>dom4j</artifactId> | |||
<version>1.6.1</version> | |||
</dependency> | |||
<!-- non-test dependency for OOXMLLite --> | |||
<dependency> | |||
<groupId>junit</groupId> |
@@ -179,7 +179,7 @@ public class ExcelAntTask extends Task { | |||
throw new BuildException( | |||
"The <classpath> for <excelant> must include poi.jar and poi-ooxml.jar " + | |||
"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()); | |||
} | |||
@@ -21,7 +21,7 @@ import java.io.File; | |||
/** | |||
* Storage class for configuration storage parameters. | |||
* TODO xml syntax checking is no longer done with DOM4j parser -> remove the schema or do it ? | |||
* TODO xml syntax checking is not done with JAXP by default -> remove the schema or do it ? | |||
* | |||
* @author CDubettier, Julen Chable | |||
* @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.POILogger; | |||
import org.apache.poi.util.SAXHelper; | |||
import org.dom4j.Attribute; | |||
import org.dom4j.Document; | |||
import org.dom4j.Element; | |||
import org.w3c.dom.Attr; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.NodeList; | |||
/** | |||
* 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()); | |||
// Browse default types | |||
Element root = xmlRelationshipsDoc.getRootElement(); | |||
Element root = xmlRelationshipsDoc.getDocumentElement(); | |||
// Check OPC compliance M4.1 rule | |||
boolean fCorePropertiesRelationship = false; | |||
@SuppressWarnings("unchecked") | |||
Iterator<Element> iter = (Iterator<Element>) | |||
root.elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); | |||
while (iter.hasNext()) { | |||
Element element = iter.next(); | |||
NodeList nodeList = root.getElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME); | |||
int nodeCount = nodeList.getLength(); | |||
for (int i = 0; i < nodeCount; i++) { | |||
Element element = (Element)nodeList.item(i); | |||
// Relationship ID | |||
String id = element.attribute( | |||
PackageRelationship.ID_ATTRIBUTE_NAME).getValue(); | |||
String id = element.getAttribute(PackageRelationship.ID_ATTRIBUTE_NAME); | |||
// Relationship type | |||
String type = element.attribute( | |||
PackageRelationship.TYPE_ATTRIBUTE_NAME).getValue(); | |||
String type = element.getAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME); | |||
/* Check OPC Compliance */ | |||
// Check Rule M4.1 | |||
@@ -342,8 +340,7 @@ public final class PackageRelationshipCollection implements | |||
/* End OPC Compliance */ | |||
// TargetMode (default value "Internal") | |||
Attribute targetModeAttr = element | |||
.attribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME); | |||
Attr targetModeAttr = element.getAttributeNode(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME); | |||
TargetMode targetMode = TargetMode.INTERNAL; | |||
if (targetModeAttr != null) { | |||
targetMode = targetModeAttr.getValue().toLowerCase() | |||
@@ -353,9 +350,7 @@ public final class PackageRelationshipCollection implements | |||
// Target converted in URI | |||
URI target = PackagingURIHelper.toURI("http://invalid.uri"); // dummy url | |||
String value = element.attribute( | |||
PackageRelationship.TARGET_ATTRIBUTE_NAME) | |||
.getValue(); | |||
String value = element.getAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME); | |||
try { | |||
// when parsing of the given uri fails, we can either | |||
// ignore this relationship, which leads to IllegalStateException |
@@ -17,21 +17,36 @@ | |||
package org.apache.poi.openxml4j.opc; | |||
import java.io.FilterOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import org.dom4j.Document; | |||
import org.dom4j.io.OutputFormat; | |||
import org.dom4j.io.XMLWriter; | |||
import javax.xml.transform.OutputKeys; | |||
import javax.xml.transform.Result; | |||
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 { | |||
private StreamHelper() { | |||
// 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 | |||
* The XML document. | |||
@@ -40,18 +55,34 @@ public final class StreamHelper { | |||
* @return <b>true</b> if the xml is successfully written in the stream, | |||
* else <b>false</b>. | |||
*/ | |||
public static boolean saveXmlInStream(Document xmlContent, | |||
OutputStream outStream) { | |||
try { | |||
OutputFormat outformat = OutputFormat.createPrettyPrint(); | |||
outformat.setEncoding("UTF-8"); | |||
XMLWriter writer = new XMLWriter(outStream, outformat); | |||
writer.write(xmlContent); | |||
} catch (Exception e) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
public static boolean saveXmlInStream(Document xmlContent, | |||
OutputStream outStream) { | |||
try { | |||
Transformer trans = getIdentityTransformer(); | |||
Source xmlSource = new DOMSource(xmlContent); | |||
// prevent close of stream by transformer: | |||
Result outputTarget = new StreamResult(new FilterOutputStream( | |||
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 true; | |||
} | |||
/** | |||
* Copy the input stream into the output stream. |
@@ -17,12 +17,11 @@ | |||
package org.apache.poi.openxml4j.opc.internal; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.net.URI; | |||
import java.net.URISyntaxException; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map.Entry; | |||
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.PackagePartName; | |||
import org.apache.poi.openxml4j.opc.PackagingURIHelper; | |||
import org.apache.poi.util.DocumentHelper; | |||
import org.apache.poi.util.SAXHelper; | |||
import org.dom4j.Document; | |||
import org.dom4j.DocumentException; | |||
import org.dom4j.DocumentHelper; | |||
import org.dom4j.Element; | |||
import org.dom4j.Namespace; | |||
import org.dom4j.QName; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.NodeList; | |||
import org.xml.sax.SAXException; | |||
/** | |||
* Manage package content types ([Content_Types].xml part). | |||
@@ -376,38 +374,33 @@ public abstract class ContentTypeManager { | |||
Document xmlContentTypetDoc = SAXHelper.readSAXDocument(in); | |||
// Default content types | |||
List defaultTypes = xmlContentTypetDoc.getRootElement().elements( | |||
DEFAULT_TAG_NAME); | |||
Iterator elementIteratorDefault = defaultTypes.iterator(); | |||
while (elementIteratorDefault.hasNext()) { | |||
Element element = (Element) elementIteratorDefault.next(); | |||
String extension = element.attribute(EXTENSION_ATTRIBUTE_NAME) | |||
.getValue(); | |||
String contentType = element.attribute( | |||
CONTENT_TYPE_ATTRIBUTE_NAME).getValue(); | |||
NodeList defaultTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagName(DEFAULT_TAG_NAME); | |||
int defaultTypeCount = defaultTypes.getLength(); | |||
for (int i = 0; i < defaultTypeCount; i++) { | |||
Element element = (Element) defaultTypes.item(i); | |||
String extension = element.getAttribute(EXTENSION_ATTRIBUTE_NAME); | |||
String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME); | |||
addDefaultContentType(extension, contentType); | |||
} | |||
// Overriden content types | |||
List overrideTypes = xmlContentTypetDoc.getRootElement().elements( | |||
OVERRIDE_TAG_NAME); | |||
Iterator elementIteratorOverride = overrideTypes.iterator(); | |||
while (elementIteratorOverride.hasNext()) { | |||
Element element = (Element) elementIteratorOverride.next(); | |||
URI uri = new URI(element.attribute(PART_NAME_ATTRIBUTE_NAME) | |||
.getValue()); | |||
PackagePartName partName = PackagingURIHelper | |||
.createPartName(uri); | |||
String contentType = element.attribute( | |||
CONTENT_TYPE_ATTRIBUTE_NAME).getValue(); | |||
NodeList overrideTypes = xmlContentTypetDoc.getDocumentElement().getElementsByTagName(OVERRIDE_TAG_NAME); | |||
int overrideTypeCount = overrideTypes.getLength(); | |||
for (int i = 0; i < overrideTypeCount; i++) { | |||
Element element = (Element) overrideTypes.item(i); | |||
URI uri = new URI(element.getAttribute(PART_NAME_ATTRIBUTE_NAME)); | |||
PackagePartName partName = PackagingURIHelper.createPartName(uri); | |||
String contentType = element.getAttribute(CONTENT_TYPE_ATTRIBUTE_NAME); | |||
addOverrideContentType(partName, contentType); | |||
} | |||
} catch (URISyntaxException urie) { | |||
throw new InvalidFormatException(urie.getMessage()); | |||
} catch (DocumentException e) { | |||
throw new InvalidFormatException(e.getMessage()); | |||
} | |||
} | |||
} catch (SAXException e) { | |||
throw new InvalidFormatException(e.getMessage()); | |||
} catch (IOException e) { | |||
throw new InvalidFormatException(e.getMessage()); | |||
} | |||
} | |||
/** | |||
* Save the contents type part. | |||
@@ -421,9 +414,8 @@ public abstract class ContentTypeManager { | |||
Document xmlOutDoc = DocumentHelper.createDocument(); | |||
// Building namespace | |||
Namespace dfNs = Namespace.get("", TYPES_NAMESPACE_URI); | |||
Element typesElem = xmlOutDoc | |||
.addElement(new QName(TYPES_TAG_NAME, dfNs)); | |||
Element typesElem = xmlOutDoc.createElementNS(TYPES_NAMESPACE_URI, TYPES_TAG_NAME); | |||
xmlOutDoc.appendChild(typesElem); | |||
// Adding default types | |||
for (Entry<String, String> entry : defaultContentType.entrySet()) { | |||
@@ -454,10 +446,10 @@ public abstract class ContentTypeManager { | |||
*/ | |||
private void appendSpecificTypes(Element root, | |||
Entry<PackagePartName, String> entry) { | |||
root.addElement(OVERRIDE_TAG_NAME).addAttribute( | |||
PART_NAME_ATTRIBUTE_NAME, | |||
entry.getKey().getName()).addAttribute( | |||
CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue()); | |||
Element specificType = root.getOwnerDocument().createElement(OVERRIDE_TAG_NAME); | |||
specificType.setAttribute(PART_NAME_ATTRIBUTE_NAME, entry.getKey().getName()); | |||
specificType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue()); | |||
root.appendChild(specificType); | |||
} | |||
/** | |||
@@ -470,11 +462,10 @@ public abstract class ContentTypeManager { | |||
* @see #save(java.io.OutputStream) | |||
*/ | |||
private void appendDefaultType(Element root, Entry<String, String> entry) { | |||
root.addElement(DEFAULT_TAG_NAME).addAttribute( | |||
EXTENSION_ATTRIBUTE_NAME, entry.getKey()) | |||
.addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, | |||
entry.getValue()); | |||
Element defaultType = root.getOwnerDocument().createElement(DEFAULT_TAG_NAME); | |||
defaultType.setAttribute(EXTENSION_ATTRIBUTE_NAME, entry.getKey()); | |||
defaultType.setAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, 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_XSI_URI = "http://www.w3.org/2001/XMLSchema-instance"; | |||
/** | |||
* Constructor. | |||
* |
@@ -17,8 +17,6 @@ | |||
package org.apache.poi.openxml4j.opc.internal; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
@@ -30,7 +28,7 @@ import org.apache.poi.openxml4j.opc.OPCPackage; | |||
import org.apache.poi.openxml4j.opc.StreamHelper; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.dom4j.Document; | |||
import org.w3c.dom.Document; | |||
/** | |||
* Zip implementation of the ContentTypeManager. | |||
@@ -69,17 +67,8 @@ public class ZipContentTypeManager extends ContentTypeManager { | |||
// Referenced in ZIP | |||
zos.putNextEntry(partEntry); | |||
// Saving data in the ZIP file | |||
ByteArrayOutputStream outTemp = new ByteArrayOutputStream(); | |||
StreamHelper.saveXmlInStream(content, out); | |||
InputStream ins = new ByteArrayInputStream(outTemp.toByteArray()); | |||
byte[] buff = new byte[ZipHelper.READ_WRITE_FILE_BUFFER_SIZE]; | |||
while (ins.available() > 0) { | |||
int resultRead = ins.read(buff); | |||
if (resultRead == -1) { | |||
// end of file reached | |||
break; | |||
} | |||
zos.write(buff, 0, resultRead); | |||
if (!StreamHelper.saveXmlInStream(content, zos)) { | |||
return false; | |||
} | |||
zos.closeEntry(); | |||
} catch (IOException ioe) { |
@@ -19,15 +19,18 @@ package org.apache.poi.openxml4j.opc.internal.marshallers; | |||
import java.io.OutputStream; | |||
import org.dom4j.Document; | |||
import org.dom4j.DocumentHelper; | |||
import org.dom4j.Element; | |||
import org.dom4j.Namespace; | |||
import org.dom4j.QName; | |||
import javax.xml.XMLConstants; | |||
import javax.xml.stream.XMLEventFactory; | |||
import javax.xml.stream.events.Namespace; | |||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; | |||
import org.apache.poi.openxml4j.opc.internal.PartMarshaller; | |||
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. | |||
@@ -36,17 +39,15 @@ import org.apache.poi.openxml4j.opc.internal.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("", | |||
PackagePropertiesPart.NAMESPACE_CP_URI); | |||
private final static Namespace namespaceDcTerms = new Namespace("dcterms", | |||
PackagePropertiesPart.NAMESPACE_DCTERMS_URI); | |||
private final static Namespace namespaceXSI = new Namespace("xsi", | |||
PackagePropertiesPart.NAMESPACE_XSI_URI); | |||
private final static Namespace namespaceDC, namespaceCoreProperties, namespaceDcTerms, namespaceXSI; | |||
static { | |||
final XMLEventFactory f = XMLEventFactory.newFactory(); | |||
namespaceDC = f.createNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI); | |||
namespaceCoreProperties = f.createNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI); | |||
namespaceDcTerms = f.createNamespace("dcterms", PackagePropertiesPart.NAMESPACE_DCTERMS_URI); | |||
namespaceXSI = f.createNamespace("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); | |||
} | |||
protected static final String KEYWORD_CATEGORY = "category"; | |||
@@ -98,13 +99,13 @@ public class PackagePropertiesMarshaller implements PartMarshaller { | |||
// Configure the document | |||
xmlDoc = DocumentHelper.createDocument(); | |||
Element rootElem = xmlDoc.addElement(new QName("coreProperties", | |||
namespaceCoreProperties)); | |||
rootElem.addNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI); | |||
rootElem.addNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI); | |||
rootElem.addNamespace("dcterms", | |||
PackagePropertiesPart.NAMESPACE_DCTERMS_URI); | |||
rootElem.addNamespace("xsi", PackagePropertiesPart.NAMESPACE_XSI_URI); | |||
Element rootElem = xmlDoc.createElementNS(namespaceCoreProperties.getNamespaceURI(), | |||
getQName("coreProperties", namespaceCoreProperties)); | |||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceCoreProperties); | |||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDC); | |||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceDcTerms); | |||
DocumentHelper.addNamespaceDeclaration(rootElem, namespaceXSI); | |||
xmlDoc.appendChild(rootElem); | |||
addCategory(); | |||
addContentStatus(); | |||
@@ -125,197 +126,110 @@ public class PackagePropertiesMarshaller implements PartMarshaller { | |||
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. | |||
*/ | |||
private void addCategory() { | |||
if (!propsPart.getCategoryProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CATEGORY, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// Missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_CATEGORY, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getCategoryProperty().getValue()); | |||
setElementTextContent(KEYWORD_CATEGORY, namespaceCoreProperties, propsPart.getCategoryProperty()); | |||
} | |||
/** | |||
* Add content status property element if needed. | |||
*/ | |||
private void addContentStatus() { | |||
if (!propsPart.getContentStatusProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// Missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getContentStatusProperty().getValue()); | |||
setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty()); | |||
} | |||
/** | |||
* Add content type property element if needed. | |||
*/ | |||
private void addContentType() { | |||
if (!propsPart.getContentTypeProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// Missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getContentTypeProperty().getValue()); | |||
setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty()); | |||
} | |||
/** | |||
* Add created property element if needed. | |||
*/ | |||
private void addCreated() { | |||
if (!propsPart.getCreatedProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CREATED, namespaceDcTerms)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_CREATED, namespaceDcTerms)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF"); | |||
elem.addText(propsPart.getCreatedPropertyString()); | |||
setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(), | |||
propsPart.getCreatedPropertyString(), "dcterms:W3CDTF"); | |||
} | |||
/** | |||
* Add creator property element if needed. | |||
*/ | |||
private void addCreator() { | |||
if (!propsPart.getCreatorProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CREATOR, namespaceDC)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_CREATOR, namespaceDC)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getCreatorProperty().getValue()); | |||
setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty()); | |||
} | |||
/** | |||
* Add description property element if needed. | |||
*/ | |||
private void addDescription() { | |||
if (!propsPart.getDescriptionProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_DESCRIPTION, namespaceDC)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_DESCRIPTION, namespaceDC)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getDescriptionProperty().getValue()); | |||
setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty()); | |||
} | |||
/** | |||
* Add identifier property element if needed. | |||
*/ | |||
private void addIdentifier() { | |||
if (!propsPart.getIdentifierProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_IDENTIFIER, namespaceDC)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_IDENTIFIER, namespaceDC)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getIdentifierProperty().getValue()); | |||
setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty()); | |||
} | |||
/** | |||
/** | |||
* Add keywords property element if needed. | |||
*/ | |||
private void addKeywords() { | |||
if (!propsPart.getKeywordsProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_KEYWORDS, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getKeywordsProperty().getValue()); | |||
setElementTextContent(KEYWORD_KEYWORDS, namespaceCoreProperties, propsPart.getKeywordsProperty()); | |||
} | |||
/** | |||
* Add language property element if needed. | |||
*/ | |||
private void addLanguage() { | |||
if (!propsPart.getLanguageProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_LANGUAGE, namespaceDC)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_LANGUAGE, namespaceDC)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getLanguageProperty().getValue()); | |||
setElementTextContent(KEYWORD_LANGUAGE, namespaceDC, propsPart.getLanguageProperty()); | |||
} | |||
/** | |||
* Add 'last modified by' property if needed. | |||
*/ | |||
private void addLastModifiedBy() { | |||
if (!propsPart.getLastModifiedByProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement() | |||
.addElement( | |||
new QName(KEYWORD_LAST_MODIFIED_BY, | |||
namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getLastModifiedByProperty().getValue()); | |||
setElementTextContent(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties, propsPart.getLastModifiedByProperty()); | |||
} | |||
/** | |||
@@ -323,111 +237,39 @@ public class PackagePropertiesMarshaller implements PartMarshaller { | |||
* | |||
*/ | |||
private void addLastPrinted() { | |||
if (!propsPart.getLastPrintedProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getLastPrintedPropertyString()); | |||
setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString()); | |||
} | |||
/** | |||
* Add modified property element if needed. | |||
*/ | |||
private void addModified() { | |||
if (!propsPart.getModifiedProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_MODIFIED, namespaceDcTerms)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_MODIFIED, namespaceDcTerms)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF"); | |||
elem.addText(propsPart.getModifiedPropertyString()); | |||
} | |||
setElementTextContent(KEYWORD_MODIFIED, namespaceDcTerms, propsPart.getModifiedProperty(), | |||
propsPart.getModifiedPropertyString(), "dcterms:W3CDTF"); | |||
} | |||
/** | |||
* Add revision property if needed. | |||
*/ | |||
private void addRevision() { | |||
if (!propsPart.getRevisionProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_REVISION, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_REVISION, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getRevisionProperty().getValue()); | |||
setElementTextContent(KEYWORD_REVISION, namespaceCoreProperties, propsPart.getRevisionProperty()); | |||
} | |||
/** | |||
* Add subject property if needed. | |||
*/ | |||
private void addSubject() { | |||
if (!propsPart.getSubjectProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_SUBJECT, namespaceDC)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_SUBJECT, namespaceDC)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getSubjectProperty().getValue()); | |||
setElementTextContent(KEYWORD_SUBJECT, namespaceDC, propsPart.getSubjectProperty()); | |||
} | |||
/** | |||
* Add title property if needed. | |||
*/ | |||
private void addTitle() { | |||
if (!propsPart.getTitleProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_TITLE, namespaceDC)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_TITLE, namespaceDC)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getTitleProperty().getValue()); | |||
setElementTextContent(KEYWORD_TITLE, namespaceDC, propsPart.getTitleProperty()); | |||
} | |||
private void addVersion() { | |||
if (!propsPart.getVersionProperty().hasValue()) | |||
return; | |||
Element elem = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_VERSION, namespaceCoreProperties)); | |||
if (elem == null) { | |||
// missing, we add it | |||
elem = xmlDoc.getRootElement().addElement( | |||
new QName(KEYWORD_VERSION, namespaceCoreProperties)); | |||
} else { | |||
elem.clearContent();// clear the old value | |||
} | |||
elem.addText(propsPart.getVersionProperty().getValue()); | |||
setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty()); | |||
} | |||
} |
@@ -24,11 +24,6 @@ import java.net.URI; | |||
import java.util.zip.ZipEntry; | |||
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.opc.PackageNamespaces; | |||
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.internal.PartMarshaller; | |||
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.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. | |||
@@ -122,9 +120,8 @@ public final class ZipPartMarshaller implements PartMarshaller { | |||
Document xmlOutDoc = DocumentHelper.createDocument(); | |||
// make something like <Relationships | |||
// xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> | |||
Namespace dfNs = Namespace.get("", PackageNamespaces.RELATIONSHIPS); | |||
Element root = xmlOutDoc.addElement(new QName( | |||
PackageRelationship.RELATIONSHIPS_TAG_NAME, dfNs)); | |||
Element root = xmlOutDoc.createElementNS(PackageNamespaces.RELATIONSHIPS, PackageRelationship.RELATIONSHIPS_TAG_NAME); | |||
xmlOutDoc.appendChild(root); | |||
// <Relationship | |||
// TargetMode="External" | |||
@@ -137,16 +134,14 @@ public final class ZipPartMarshaller implements PartMarshaller { | |||
for (PackageRelationship rel : rels) { | |||
// the relationship element | |||
Element relElem = root | |||
.addElement(PackageRelationship.RELATIONSHIP_TAG_NAME); | |||
Element relElem = xmlOutDoc.createElement(PackageRelationship.RELATIONSHIP_TAG_NAME); | |||
root.appendChild(relElem); | |||
// the relationship ID | |||
relElem.addAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel | |||
.getId()); | |||
relElem.setAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel.getId()); | |||
// the relationship Type | |||
relElem.addAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel | |||
.getRelationshipType()); | |||
relElem.setAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel.getRelationshipType()); | |||
// the relationship Target | |||
String targetValue; | |||
@@ -157,16 +152,13 @@ public final class ZipPartMarshaller implements PartMarshaller { | |||
targetValue = uri.toString(); | |||
// add TargetMode attribute (as it is external link external) | |||
relElem.addAttribute( | |||
PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, | |||
"External"); | |||
relElem.setAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External"); | |||
} else { | |||
URI targetURI = rel.getTargetURI(); | |||
targetValue = PackagingURIHelper.relativizeURI( | |||
sourcePartURI, targetURI, true).toString(); | |||
} | |||
relElem.addAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME, | |||
targetValue); | |||
relElem.setAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME, targetValue); | |||
} | |||
xmlOutDoc.normalize(); |
@@ -19,10 +19,10 @@ package org.apache.poi.openxml4j.opc.internal.unmarshallers; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.zip.ZipEntry; | |||
import javax.xml.XMLConstants; | |||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |||
import org.apache.poi.openxml4j.opc.PackageNamespaces; | |||
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.ZipHelper; | |||
import org.apache.poi.util.SAXHelper; | |||
import org.dom4j.Attribute; | |||
import org.dom4j.Document; | |||
import org.dom4j.DocumentException; | |||
import org.dom4j.Element; | |||
import org.dom4j.Namespace; | |||
import org.dom4j.QName; | |||
import org.w3c.dom.Attr; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.NamedNodeMap; | |||
import org.w3c.dom.NodeList; | |||
import org.xml.sax.SAXException; | |||
/** | |||
* Package properties unmarshaller. | |||
@@ -46,21 +46,6 @@ import org.dom4j.QName; | |||
*/ | |||
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_CONTENT_STATUS = "contentStatus"; | |||
@@ -125,15 +110,15 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { | |||
/* Check OPC compliance */ | |||
// Rule M4.2, M4.3, M4.4 and M4.5/ | |||
checkElementForOPCCompliance(xmlDoc.getRootElement()); | |||
checkElementForOPCCompliance(xmlDoc.getDocumentElement()); | |||
/* End OPC compliance */ | |||
} catch (DocumentException e) { | |||
throw new IOException(e.getMessage()); | |||
} | |||
} catch (SAXException e) { | |||
throw new IOException(e.getMessage()); | |||
} | |||
coreProps.setCategoryProperty(loadCategory(xmlDoc)); | |||
coreProps.setCategoryProperty(loadCategory(xmlDoc)); | |||
coreProps.setContentStatusProperty(loadContentStatus(xmlDoc)); | |||
coreProps.setContentTypeProperty(loadContentType(xmlDoc)); | |||
coreProps.setCreatedProperty(loadCreated(xmlDoc)); | |||
@@ -153,148 +138,76 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { | |||
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) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CATEGORY, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_CATEGORY, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadContentStatus(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CONTENT_STATUS, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
private String loadContentStatus(Document xmlDoc) { | |||
return readElement(xmlDoc, KEYWORD_CONTENT_STATUS, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadContentType(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CONTENT_TYPE, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_CONTENT_TYPE, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadCreated(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CREATED, namespaceDcTerms)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_CREATED, PackageProperties.NAMESPACE_DCTERMS); | |||
} | |||
private String loadCreator(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_CREATOR, namespaceDC)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_CREATOR, PackageProperties.NAMESPACE_DC); | |||
} | |||
private String loadDescription(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_DESCRIPTION, namespaceDC)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_DESCRIPTION, PackageProperties.NAMESPACE_DC); | |||
} | |||
private String loadIdentifier(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_IDENTIFIER, namespaceDC)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_IDENTIFIER, PackageProperties.NAMESPACE_DC); | |||
} | |||
private String loadKeywords(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_KEYWORDS, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_KEYWORDS, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadLanguage(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_LANGUAGE, namespaceDC)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_LANGUAGE, PackageProperties.NAMESPACE_DC); | |||
} | |||
private String loadLastModifiedBy(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_LAST_MODIFIED_BY, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadLastPrinted(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_LAST_PRINTED, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_LAST_PRINTED, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadModified(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_MODIFIED, namespaceDcTerms)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_MODIFIED, PackageProperties.NAMESPACE_DCTERMS); | |||
} | |||
private String loadRevision(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_REVISION, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_REVISION, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
private String loadSubject(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_SUBJECT, namespaceDC)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_SUBJECT, PackageProperties.NAMESPACE_DC); | |||
} | |||
private String loadTitle(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_TITLE, namespaceDC)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_TITLE, PackageProperties.NAMESPACE_DC); | |||
} | |||
private String loadVersion(Document xmlDoc) { | |||
Element el = xmlDoc.getRootElement().element( | |||
new QName(KEYWORD_VERSION, namespaceCP)); | |||
if (el == null) { | |||
return null; | |||
} | |||
return el.getStringValue(); | |||
return readElement(xmlDoc, KEYWORD_VERSION, PackageNamespaces.CORE_PROPERTIES); | |||
} | |||
/* OPC Compliance methods */ | |||
@@ -325,60 +238,56 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { | |||
public void checkElementForOPCCompliance(Element el) | |||
throws InvalidFormatException { | |||
// Check the current element | |||
@SuppressWarnings("unchecked") | |||
List<Namespace> declaredNamespaces = el.declaredNamespaces(); | |||
Iterator<Namespace> itNS = declaredNamespaces.iterator(); | |||
while (itNS.hasNext()) { | |||
Namespace ns = itNS.next(); | |||
// Rule M4.2 | |||
if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY)) | |||
throw new InvalidFormatException( | |||
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error."); | |||
} | |||
NamedNodeMap namedNodeMap = el.getAttributes(); | |||
int namedNodeCount = namedNodeMap.getLength(); | |||
for (int i = 0; i < namedNodeCount; i++) { | |||
Attr attr = (Attr)namedNodeMap.item(0); | |||
if (attr.getNamespaceURI().equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) { | |||
// Rule M4.2 | |||
if (attr.getValue().equals(PackageNamespaces.MARKUP_COMPATIBILITY)) | |||
throw new InvalidFormatException( | |||
"OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error."); | |||
} | |||
} | |||
// Rule M4.3 | |||
if (el.getNamespace().getURI().equals( | |||
PackageProperties.NAMESPACE_DCTERMS) | |||
&& !(el.getName().equals(KEYWORD_CREATED) || el.getName() | |||
.equals(KEYWORD_MODIFIED))) | |||
throw new InvalidFormatException( | |||
"OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error."); | |||
String elName = el.getLocalName(); | |||
if (el.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS)) | |||
if (!(elName.equals(KEYWORD_CREATED) || elName.equals(KEYWORD_MODIFIED))) | |||
throw new InvalidFormatException( | |||
"OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error."); | |||
// Rule M4.4 | |||
if (el.attribute(new QName("lang", namespaceXML)) != null) | |||
if (el.getAttributeNodeNS(XMLConstants.XML_NS_URI, "lang") != null) | |||
throw new InvalidFormatException( | |||
"OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error."); | |||
// Rule M4.5 | |||
if (el.getNamespace().getURI().equals( | |||
PackageProperties.NAMESPACE_DCTERMS)) { | |||
if (el.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS)) { | |||
// DCTerms namespace only use with 'created' and 'modified' elements | |||
String elName = el.getName(); | |||
if (!(elName.equals(KEYWORD_CREATED) || elName | |||
.equals(KEYWORD_MODIFIED))) | |||
if (!(elName.equals(KEYWORD_CREATED) || elName.equals(KEYWORD_MODIFIED))) | |||
throw new InvalidFormatException("Namespace error : " + elName | |||
+ " shouldn't have the following naemspace -> " | |||
+ PackageProperties.NAMESPACE_DCTERMS); | |||
// Check for the 'xsi:type' attribute | |||
Attribute typeAtt = el.attribute(new QName("type", namespaceXSI)); | |||
Attr typeAtt = el.getAttributeNodeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"); | |||
if (typeAtt == null) | |||
throw new InvalidFormatException("The element '" + elName | |||
+ "' must have the '" + namespaceXSI.getPrefix() | |||
+ ":type' attribute present !"); | |||
+ "' must have the 'xsi:type' attribute present !"); | |||
// Check for the attribute value => 'dcterms:W3CDTF' | |||
if (!typeAtt.getValue().equals("dcterms:W3CDTF")) | |||
throw new InvalidFormatException("The element '" + elName | |||
+ "' must have the '" + namespaceXSI.getPrefix() | |||
+ ":type' attribute with the value 'dcterms:W3CDTF' !"); | |||
+ "' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF' !"); | |||
} | |||
// Check its children | |||
@SuppressWarnings("unchecked") | |||
Iterator<Element> itChildren = el.elementIterator(); | |||
while (itChildren.hasNext()) | |||
checkElementForOPCCompliance(itChildren.next()); | |||
NodeList childElements = el.getElementsByTagName("*"); | |||
int childElementCount = childElements.getLength(); | |||
for (int i = 0; i < childElementCount; i++) | |||
checkElementForOPCCompliance((Element)childElements.item(i)); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -23,10 +23,11 @@ import java.io.StringReader; | |||
import java.lang.reflect.Method; | |||
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.dom4j.DocumentException; | |||
import org.dom4j.io.SAXReader; | |||
import org.w3c.dom.Document; | |||
import org.xml.sax.EntityResolver; | |||
import org.xml.sax.InputSource; | |||
import org.xml.sax.SAXException; | |||
@@ -37,31 +38,44 @@ import org.xml.sax.SAXException; | |||
*/ | |||
public final class SAXHelper { | |||
private static POILogger logger = POILogFactory.getLogger(SAXHelper.class); | |||
private static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() { | |||
@Override | |||
public InputSource resolveEntity(String publicId, String systemId) | |||
throws SAXException, IOException { | |||
return new InputSource(new StringReader("")); | |||
} | |||
}; | |||
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 SAX Reader, with sensible defaults | |||
* Creates a new document builder, 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; | |||
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(SAXReader xmlReader, String feature, boolean enabled) { | |||
private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) { | |||
try { | |||
xmlReader.setFeature(feature, enabled); | |||
documentBuilderFactory.setFeature(feature, enabled); | |||
} catch (Exception 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 | |||
for (String securityManagerClassName : new String[] { | |||
"com.sun.org.apache.xerces.internal.util.SecurityManager", | |||
@@ -71,7 +85,7 @@ public final class SAXHelper { | |||
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); | |||
documentBuilderFactory.setAttribute("http://apache.org/xml/properties/security-manager", mgr); | |||
// Stop once one can be setup without error | |||
return; | |||
} catch (Exception e) { | |||
@@ -86,7 +100,7 @@ public final class SAXHelper { | |||
* @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); | |||
public static Document readSAXDocument(InputStream inp) throws IOException, SAXException { | |||
return getDocumentBuilder().parse(inp); | |||
} | |||
} |
@@ -27,7 +27,6 @@ import java.io.OutputStream; | |||
import java.lang.reflect.Field; | |||
import java.net.URI; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.TreeMap; | |||
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.FileHelper; | |||
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.POILogger; | |||
import org.apache.poi.util.SAXHelper; | |||
import org.apache.poi.util.TempFile; | |||
import org.dom4j.Document; | |||
import org.dom4j.DocumentHelper; | |||
import org.dom4j.Element; | |||
import org.dom4j.Namespace; | |||
import org.dom4j.QName; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.NodeList; | |||
public final class TestPackage extends TestCase { | |||
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"); | |||
Document doc = DocumentHelper.createDocument(); | |||
Namespace nsWordprocessinML = new Namespace("w", | |||
"http://schemas.openxmlformats.org/wordprocessingml/2006/main"); | |||
Element elDocument = doc.addElement(new QName("document", | |||
nsWordprocessinML)); | |||
Element elBody = elDocument.addElement(new QName("body", | |||
nsWordprocessinML)); | |||
Element elParagraph = elBody.addElement(new QName("p", | |||
nsWordprocessinML)); | |||
Element elRun = elParagraph | |||
.addElement(new QName("r", nsWordprocessinML)); | |||
Element elText = elRun.addElement(new QName("t", nsWordprocessinML)); | |||
elText.setText("Hello Open XML !"); | |||
Element elDocument = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:document"); | |||
doc.appendChild(elDocument); | |||
Element elBody = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:body"); | |||
elDocument.appendChild(elBody); | |||
Element elParagraph = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:p"); | |||
elBody.appendChild(elParagraph); | |||
Element elRun = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:r"); | |||
elParagraph.appendChild(elRun); | |||
Element elText = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:t"); | |||
elRun.appendChild(elText); | |||
elText.setTextContent("Hello Open XML !"); | |||
StreamHelper.saveXmlInStream(doc, corePart.getOutputStream()); | |||
pkg.close(); | |||
@@ -223,15 +220,13 @@ public final class TestPackage extends TestCase { | |||
Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream()); | |||
Element root = xmlRelationshipsDoc.getRootElement(); | |||
for (Iterator i = root | |||
.elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i | |||
.hasNext();) { | |||
Element element = (Element) i.next(); | |||
String value = element.attribute( | |||
PackageRelationship.TARGET_ATTRIBUTE_NAME) | |||
.getValue(); | |||
assertTrue("Root target must not start with a leadng slash ('/'): " + value, value.charAt(0) != '/'); | |||
Element root = xmlRelationshipsDoc.getDocumentElement(); | |||
NodeList nodeList = root.getElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME); | |||
int nodeCount = nodeList.getLength(); | |||
for (int i = 0; i < nodeCount; i++) { | |||
Element element = (Element) nodeList.item(i); | |||
String value = element.getAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME); | |||
assertTrue("Root target must not start with a leading slash ('/'): " + value, value.charAt(0) != '/'); | |||
} | |||
} | |||
@@ -268,18 +263,17 @@ public final class TestPackage extends TestCase { | |||
// Create a content | |||
Document doc = DocumentHelper.createDocument(); | |||
Namespace nsWordprocessinML = new Namespace("w", | |||
"http://schemas.openxmlformats.org/wordprocessingml/2006/main"); | |||
Element elDocument = doc.addElement(new QName("document", | |||
nsWordprocessinML)); | |||
Element elBody = elDocument.addElement(new QName("body", | |||
nsWordprocessinML)); | |||
Element elParagraph = elBody.addElement(new QName("p", | |||
nsWordprocessinML)); | |||
Element elRun = elParagraph | |||
.addElement(new QName("r", nsWordprocessinML)); | |||
Element elText = elRun.addElement(new QName("t", nsWordprocessinML)); | |||
elText.setText("Hello Open XML !"); | |||
Element elDocument = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:document"); | |||
doc.appendChild(elDocument); | |||
Element elBody = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:body"); | |||
elDocument.appendChild(elBody); | |||
Element elParagraph = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:p"); | |||
elBody.appendChild(elParagraph); | |||
Element elRun = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:r"); | |||
elParagraph.appendChild(elRun); | |||
Element elText = doc.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w:t"); | |||
elRun.appendChild(elText); | |||
elText.setTextContent("Hello Open XML !"); | |||
StreamHelper.saveXmlInStream(doc, corePart.getOutputStream()); | |||