ASF Bugzilla – Attachment 31895 Details for
Bug 56814
Replace use of Dom4J with JAXP
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
56814.patch
56814.patch (text/plain), 89.77 KB, created by
Uwe Schindler (ASF)
on 2014-08-10 21:23:02 UTC
(
hide
)
Description:
56814.patch
Filename:
MIME Type:
Creator:
Uwe Schindler (ASF)
Created:
2014-08-10 21:23:02 UTC
Size:
89.77 KB
patch
obsolete
>Index: .classpath >=================================================================== >--- .classpath (revision 1617151) >+++ .classpath (working copy) >@@ -16,13 +16,12 @@ > <classpathentry kind="src" path="src/excelant/resources"/> > <classpathentry kind="lib" path="lib/ant-1.9.4.jar"/> > <classpathentry kind="lib" path="lib/ant-launcher-1.9.4.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/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"/> >+ <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/xmlbeans-2.6.0.jar"/> >+ <classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/> >+ <classpathentry kind="lib" path="lib/junit-4.11.jar"/> > <classpathentry kind="lib" path="ooxml-lib/ooxml-schemas-1.1.jar" sourcepath="ooxml-lib/ooxml-schemas-src-1.1.jar"/> > <classpathentry kind="lib" path="ooxml-lib/ooxml-encryption-1.1.jar" sourcepath="ooxml-lib/ooxml-encryption-src-1.1.jar"/> > <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> >Index: build.xml >=================================================================== >--- build.xml (revision 1617151) >+++ build.xml (working copy) >@@ -148,8 +148,6 @@ > <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 @@ > </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 @@ > </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 @@ > <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}"/> >@@ -441,10 +436,6 @@ > <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}"/> > </antcall> >@@ -1288,7 +1279,6 @@ > <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 @@ > <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 @@ > <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" /> >Index: legal/LICENSE >=================================================================== >--- legal/LICENSE (revision 1617151) >+++ legal/LICENSE (working copy) >@@ -229,50 +229,6 @@ > [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 >Index: legal/NOTICE >=================================================================== >--- legal/NOTICE (revision 1617151) >+++ legal/NOTICE (working copy) >@@ -4,9 +4,6 @@ > 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/>. > >Index: maven/poi-ooxml.pom >=================================================================== >--- maven/poi-ooxml.pom (revision 1617151) >+++ maven/poi-ooxml.pom (working copy) >@@ -66,13 +66,8 @@ > </dependency> > <dependency> > <groupId>org.apache.poi</groupId> >- <artifactId>poi-ooxml-schemas</artifactId> >- <version>@VERSION@</version> >- </dependency> >- <dependency> >- <groupId>dom4j</groupId> >- <artifactId>dom4j</artifactId> >- <version>1.6.1</version> >- </dependency> >- </dependencies> >-</project> >+ <artifactId>poi-ooxml-schemas</artifactId> >+ <version>@VERSION@</version> >+ </dependency> >+ </dependencies> >+</project> >Index: sonar/ooxml/pom.xml >=================================================================== >--- sonar/ooxml/pom.xml (revision 1617151) >+++ sonar/ooxml/pom.xml (working copy) >@@ -113,18 +113,12 @@ > <dependency> > <groupId>org.apache.xmlbeans</groupId> > <artifactId>xmlbeans</artifactId> >- <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> >+ <version>2.3.0</version> >+ </dependency> >+ >+ <!-- non-test dependency for OOXMLLite --> >+ <dependency> >+ <groupId>junit</groupId> > <artifactId>junit</artifactId> > <version>4.11</version> > </dependency> >Index: src/documentation/content/xdocs/overview.xml >=================================================================== >--- src/documentation/content/xdocs/overview.xml (revision 1617151) >+++ src/documentation/content/xdocs/overview.xml (working copy) >@@ -267,13 +267,13 @@ > <td>poi-scratchpad</td> > <td>poi</td> > <td>poi-scratchpad-version-yyyymmdd.jar</td> >- </tr> >- <tr> >- <td>poi-ooxml</td> >- <td>poi, poi-ooxml-schemas, dom4j</td> >- <td>poi-ooxml-version-yyyymmdd.jar</td> >- </tr> >- <tr> >+ </tr> >+ <tr> >+ <td>poi-ooxml</td> >+ <td>poi, poi-ooxml-schemas</td> >+ <td>poi-ooxml-version-yyyymmdd.jar</td> >+ </tr> >+ <tr> > <td>poi-ooxml-schemas</td> > <td>xmlbeans</td> > <td>poi-ooxml-schemas-version-yyyymmdd.jar</td> >Index: src/documentation/content/xdocs/spreadsheet/excelant.xml >=================================================================== >--- src/documentation/content/xdocs/spreadsheet/excelant.xml (revision 1617151) >+++ src/documentation/content/xdocs/spreadsheet/excelant.xml (working copy) >@@ -50,7 +50,6 @@ > <ul> > <li>poi-ooxml-schemas-$version-YYYYDDMM.jar</li> > <li>xmlbeans.jar</li> >- <li>dom4j.jar</li> > </ul> > <p>For example, if you have these jars in a lib/ dir in your project, your build.xml > might look like this:</p> >Index: src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTask.java >=================================================================== >--- src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTask.java (revision 1617151) >+++ src/excelant/java/org/apache/poi/ss/excelant/ExcelAntTask.java (working copy) >@@ -176,12 +176,12 @@ > Class.forName("org.apache.poi.hssf.usermodel.HSSFWorkbook"); > Class.forName("org.apache.poi.ss.usermodel.WorkbookFactory"); > } catch (Throwable e) { >- 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" , >- e, getLocation()); >- } >- >+ 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" , >+ e, getLocation()); >+ } >+ > } > } >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/Configuration.java (working copy) >@@ -18,13 +18,13 @@ > package org.apache.poi.openxml4j.opc; > > import java.io.File; >- >-/** >- * Storage class for configuration storage parameters. >- * TODO xml syntax checking is no longer done with DOM4j parser -> remove the schema or do it ? >- * >- * @author CDubettier, Julen Chable >- * @version 1.0 >+ >+/** >+ * Storage class for configuration storage parameters. >+ * TODO xml syntax checking is not done with JAXP by default -> remove the schema or do it ? >+ * >+ * @author CDubettier, Julen Chable >+ * @version 1.0 > */ > public final class Configuration { > // TODO configuration by default. should be clearly stated that it should be >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java (working copy) >@@ -14,35 +14,33 @@ > See the License for the specific language governing permissions and > limitations under the License. > ==================================================================== */ >- >-package org.apache.poi.openxml4j.opc.internal; >- >-import java.io.InputStream; >-import java.io.OutputStream; >-import java.net.URI; >-import java.net.URISyntaxException; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Map.Entry; >-import java.util.TreeMap; >- >+ >+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.Map.Entry; >+import java.util.TreeMap; >+ > import org.apache.poi.openxml4j.exceptions.InvalidFormatException; > import org.apache.poi.openxml4j.exceptions.InvalidOperationException; > import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException; > import org.apache.poi.openxml4j.opc.OPCPackage; >-import org.apache.poi.openxml4j.opc.PackagePart; >-import org.apache.poi.openxml4j.opc.PackagePartName; >-import org.apache.poi.openxml4j.opc.PackagingURIHelper; >-import org.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; >- >-/** >- * Manage package content types ([Content_Types].xml part). >+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.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). > * > * @author Julien Chable > */ >@@ -373,44 +371,39 @@ > private void parseContentTypesFile(InputStream in) > throws InvalidFormatException { > try { >- 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(); >- addDefaultContentType(extension, contentType); >- } >- >- // Overriden content types >- List overrideTypes = xmlContentTypetDoc.getRootElement().elements( >- OVERRIDE_TAG_NAME); >- Iterator elementIteratorOverride = overrideTypes.iterator(); >- while (elementIteratorOverride.hasNext()) { >- Element element = (Element) elementIteratorOverride.next(); >- URI uri = new URI(element.attribute(PART_NAME_ATTRIBUTE_NAME) >- .getValue()); >- PackagePartName partName = PackagingURIHelper >- .createPartName(uri); >- String contentType = element.attribute( >- CONTENT_TYPE_ATTRIBUTE_NAME).getValue(); >- addOverrideContentType(partName, contentType); >- } >- } catch (URISyntaxException urie) { >- throw new InvalidFormatException(urie.getMessage()); >- } catch (DocumentException e) { >- throw new InvalidFormatException(e.getMessage()); >- } >- } >- >- /** >- * Save the contents type part. >+ Document xmlContentTypetDoc = SAXHelper.readSAXDocument(in); >+ >+ // Default content types >+ 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 >+ 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 (SAXException e) { >+ throw new InvalidFormatException(e.getMessage()); >+ } catch (IOException e) { >+ throw new InvalidFormatException(e.getMessage()); >+ } >+ } >+ >+ /** >+ * Save the contents type part. > * > * @param outStream > * The output stream use to save the XML content of the content >@@ -418,15 +411,14 @@ > * @return <b>true</b> if the operation success, else <b>false</b>. > */ > public boolean save(OutputStream outStream) { >- Document xmlOutDoc = DocumentHelper.createDocument(); >- >- // Building namespace >- Namespace dfNs = Namespace.get("", TYPES_NAMESPACE_URI); >- Element typesElem = xmlOutDoc >- .addElement(new QName(TYPES_TAG_NAME, dfNs)); >- >- // Adding default types >- for (Entry<String, String> entry : defaultContentType.entrySet()) { >+ Document xmlOutDoc = DocumentHelper.createDocument(); >+ >+ // Building namespace >+ Element typesElem = xmlOutDoc.createElementNS(TYPES_NAMESPACE_URI, TYPES_TAG_NAME); >+ xmlOutDoc.appendChild(typesElem); >+ >+ // Adding default types >+ for (Entry<String, String> entry : defaultContentType.entrySet()) { > appendDefaultType(typesElem, entry); > } > >@@ -451,33 +443,32 @@ > * @param entry > * The values to append. > * @see #save(java.io.OutputStream) >- */ >- private void appendSpecificTypes(Element root, >- Entry<PackagePartName, String> entry) { >- root.addElement(OVERRIDE_TAG_NAME).addAttribute( >- PART_NAME_ATTRIBUTE_NAME, >- entry.getKey().getName()).addAttribute( >- CONTENT_TYPE_ATTRIBUTE_NAME, entry.getValue()); >- } >- >- /** >+ */ >+ private void appendSpecificTypes(Element root, >+ Entry<PackagePartName, String> entry) { >+ 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); >+ } >+ >+ /** > * Use to append default types XML elements, use by the save() metid. > * > * @param root > * XML parent element use to append this default type element. > * @param entry > * The values to append. >- * @see #save(java.io.OutputStream) >- */ >- private void appendDefaultType(Element root, Entry<String, String> entry) { >- root.addElement(DEFAULT_TAG_NAME).addAttribute( >- EXTENSION_ATTRIBUTE_NAME, entry.getKey()) >- .addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, >- entry.getValue()); >- >- } >- >- /** >+ * @see #save(java.io.OutputStream) >+ */ >+ private void appendDefaultType(Element root, Entry<String, String> entry) { >+ 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); >+ } >+ >+ /** > * Specific implementation of the save method. Call by the save() method, > * call before exiting. > * >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/PackagePropertiesMarshaller.java (working copy) >@@ -16,40 +16,41 @@ > ==================================================================== */ > > 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; >- >-/** >- * Package properties marshaller. >- * >+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. >+ * > * @author CDubet, Julien Chable >- */ >-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("", >- PackagePropertiesPart.NAMESPACE_CP_URI); >- >- private final static Namespace namespaceDcTerms = new Namespace("dcterms", >- PackagePropertiesPart.NAMESPACE_DCTERMS_URI); >- >- private final static Namespace namespaceXSI = new Namespace("xsi", >- PackagePropertiesPart.NAMESPACE_XSI_URI); >- >- protected static final String KEYWORD_CATEGORY = "category"; >- >+ >+ 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"; >+ > protected static final String KEYWORD_CONTENT_STATUS = "contentStatus"; > > protected static final String KEYWORD_CONTENT_TYPE = "contentType"; >@@ -95,19 +96,19 @@ > throw new IllegalArgumentException( > "'part' must be a PackagePropertiesPart instance."); > propsPart = (PackagePropertiesPart) part; >- >- // Configure the document >- xmlDoc = DocumentHelper.createDocument(); >- Element rootElem = xmlDoc.addElement(new QName("coreProperties", >- namespaceCoreProperties)); >- rootElem.addNamespace("cp", PackagePropertiesPart.NAMESPACE_CP_URI); >- rootElem.addNamespace("dc", PackagePropertiesPart.NAMESPACE_DC_URI); >- rootElem.addNamespace("dcterms", >- PackagePropertiesPart.NAMESPACE_DCTERMS_URI); >- rootElem.addNamespace("xsi", PackagePropertiesPart.NAMESPACE_XSI_URI); >- >- addCategory(); >- addContentStatus(); >+ >+ // Configure the document >+ xmlDoc = DocumentHelper.createDocument(); >+ 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(); > addContentType(); > addCreated(); > addCreator(); >@@ -122,312 +123,153 @@ > addSubject(); > addTitle(); > addVersion(); >- return true; >- } >- >- /** >- * Add category property element if needed. >- */ >- private void addCategory() { >- if (!propsPart.getCategoryProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CATEGORY, namespaceCoreProperties)); >- if (elem == null) { >- // Missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_CATEGORY, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getCategoryProperty().getValue()); >- } >- >- /** >- * Add content status property element if needed. >- */ >- private void addContentStatus() { >- if (!propsPart.getContentStatusProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties)); >- if (elem == null) { >- // Missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_CONTENT_STATUS, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getContentStatusProperty().getValue()); >- } >- >- /** >- * Add content type property element if needed. >- */ >- private void addContentType() { >- if (!propsPart.getContentTypeProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties)); >- if (elem == null) { >- // Missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_CONTENT_TYPE, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getContentTypeProperty().getValue()); >- } >- >- /** >- * Add created property element if needed. >- */ >- private void addCreated() { >- if (!propsPart.getCreatedProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CREATED, namespaceDcTerms)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_CREATED, namespaceDcTerms)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF"); >- elem.addText(propsPart.getCreatedPropertyString()); >- } >- >- /** >- * Add creator property element if needed. >- */ >- private void addCreator() { >- if (!propsPart.getCreatorProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CREATOR, namespaceDC)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_CREATOR, namespaceDC)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getCreatorProperty().getValue()); >- } >- >- /** >- * Add description property element if needed. >- */ >- private void addDescription() { >- if (!propsPart.getDescriptionProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_DESCRIPTION, namespaceDC)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_DESCRIPTION, namespaceDC)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getDescriptionProperty().getValue()); >- } >- >- /** >- * Add identifier property element if needed. >- */ >- private void addIdentifier() { >- if (!propsPart.getIdentifierProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_IDENTIFIER, namespaceDC)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_IDENTIFIER, namespaceDC)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getIdentifierProperty().getValue()); >- } >- >- /** >- * Add keywords property element if needed. >- */ >- private void addKeywords() { >- if (!propsPart.getKeywordsProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_KEYWORDS, namespaceCoreProperties)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_KEYWORDS, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getKeywordsProperty().getValue()); >- } >- >- /** >- * Add language property element if needed. >- */ >- private void addLanguage() { >- if (!propsPart.getLanguageProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_LANGUAGE, namespaceDC)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_LANGUAGE, namespaceDC)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getLanguageProperty().getValue()); >- } >- >- /** >- * Add 'last modified by' property if needed. >- */ >- private void addLastModifiedBy() { >- if (!propsPart.getLastModifiedByProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement() >- .addElement( >- new QName(KEYWORD_LAST_MODIFIED_BY, >- namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getLastModifiedByProperty().getValue()); >- } >- >- /** >- * Add 'last printed' property if needed. >- * >- */ >- private void addLastPrinted() { >- if (!propsPart.getLastPrintedProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_LAST_PRINTED, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getLastPrintedPropertyString()); >- } >- >- /** >- * Add modified property element if needed. >- */ >- private void addModified() { >- if (!propsPart.getModifiedProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_MODIFIED, namespaceDcTerms)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_MODIFIED, namespaceDcTerms)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addAttribute(new QName("type", namespaceXSI), "dcterms:W3CDTF"); >- elem.addText(propsPart.getModifiedPropertyString()); >- } >- >- /** >- * Add revision property if needed. >- */ >- private void addRevision() { >- if (!propsPart.getRevisionProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_REVISION, namespaceCoreProperties)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_REVISION, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getRevisionProperty().getValue()); >- } >- >- /** >- * Add subject property if needed. >- */ >- private void addSubject() { >- if (!propsPart.getSubjectProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_SUBJECT, namespaceDC)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_SUBJECT, namespaceDC)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getSubjectProperty().getValue()); >- } >- >- /** >- * Add title property if needed. >- */ >- private void addTitle() { >- if (!propsPart.getTitleProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_TITLE, namespaceDC)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_TITLE, namespaceDC)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getTitleProperty().getValue()); >- } >- >- private void addVersion() { >- if (!propsPart.getVersionProperty().hasValue()) >- return; >- >- Element elem = xmlDoc.getRootElement().element( >- new QName(KEYWORD_VERSION, namespaceCoreProperties)); >- if (elem == null) { >- // missing, we add it >- elem = xmlDoc.getRootElement().addElement( >- new QName(KEYWORD_VERSION, namespaceCoreProperties)); >- } else { >- elem.clearContent();// clear the old value >- } >- elem.addText(propsPart.getVersionProperty().getValue()); >- } >-} >+ 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(), namespaceXSI.getPrefix() + ':' + "type", xsiType); >+ } >+ return element; >+ } >+ >+ >+ /** >+ * Add category property element if needed. >+ */ >+ private void addCategory() { >+ setElementTextContent(KEYWORD_CATEGORY, namespaceCoreProperties, propsPart.getCategoryProperty()); >+ } >+ >+ /** >+ * Add content status property element if needed. >+ */ >+ private void addContentStatus() { >+ setElementTextContent(KEYWORD_CONTENT_STATUS, namespaceCoreProperties, propsPart.getContentStatusProperty()); >+ } >+ >+ /** >+ * Add content type property element if needed. >+ */ >+ private void addContentType() { >+ setElementTextContent(KEYWORD_CONTENT_TYPE, namespaceCoreProperties, propsPart.getContentTypeProperty()); >+ } >+ >+ /** >+ * Add created property element if needed. >+ */ >+ private void addCreated() { >+ setElementTextContent(KEYWORD_CREATED, namespaceDcTerms, propsPart.getCreatedProperty(), >+ propsPart.getCreatedPropertyString(), "dcterms:W3CDTF"); >+ } >+ >+ /** >+ * Add creator property element if needed. >+ */ >+ private void addCreator() { >+ setElementTextContent(KEYWORD_CREATOR, namespaceDC, propsPart.getCreatorProperty()); >+ } >+ >+ /** >+ * Add description property element if needed. >+ */ >+ private void addDescription() { >+ setElementTextContent(KEYWORD_DESCRIPTION, namespaceDC, propsPart.getDescriptionProperty()); >+ } >+ >+ /** >+ * Add identifier property element if needed. >+ */ >+ private void addIdentifier() { >+ setElementTextContent(KEYWORD_IDENTIFIER, namespaceDC, propsPart.getIdentifierProperty()); >+ } >+ >+ /** >+ * Add keywords property element if needed. >+ */ >+ private void addKeywords() { >+ setElementTextContent(KEYWORD_KEYWORDS, namespaceCoreProperties, propsPart.getKeywordsProperty()); >+ } >+ >+ /** >+ * Add language property element if needed. >+ */ >+ private void addLanguage() { >+ setElementTextContent(KEYWORD_LANGUAGE, namespaceDC, propsPart.getLanguageProperty()); >+ } >+ >+ /** >+ * Add 'last modified by' property if needed. >+ */ >+ private void addLastModifiedBy() { >+ setElementTextContent(KEYWORD_LAST_MODIFIED_BY, namespaceCoreProperties, propsPart.getLastModifiedByProperty()); >+ } >+ >+ /** >+ * Add 'last printed' property if needed. >+ * >+ */ >+ private void addLastPrinted() { >+ setElementTextContent(KEYWORD_LAST_PRINTED, namespaceCoreProperties, propsPart.getLastPrintedProperty(), propsPart.getLastPrintedPropertyString()); >+ } >+ >+ /** >+ * Add modified property element if needed. >+ */ >+ private void addModified() { >+ setElementTextContent(KEYWORD_MODIFIED, namespaceDcTerms, propsPart.getModifiedProperty(), >+ propsPart.getModifiedPropertyString(), "dcterms:W3CDTF"); >+ } >+ >+ /** >+ * Add revision property if needed. >+ */ >+ private void addRevision() { >+ setElementTextContent(KEYWORD_REVISION, namespaceCoreProperties, propsPart.getRevisionProperty()); >+ } >+ >+ /** >+ * Add subject property if needed. >+ */ >+ private void addSubject() { >+ setElementTextContent(KEYWORD_SUBJECT, namespaceDC, propsPart.getSubjectProperty()); >+ } >+ >+ /** >+ * Add title property if needed. >+ */ >+ private void addTitle() { >+ setElementTextContent(KEYWORD_TITLE, namespaceDC, propsPart.getTitleProperty()); >+ } >+ >+ private void addVersion() { >+ setElementTextContent(KEYWORD_VERSION, namespaceCoreProperties, propsPart.getVersionProperty()); >+ } >+} >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java (working copy) >@@ -21,30 +21,28 @@ > import java.io.InputStream; > import java.io.OutputStream; > 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; >+import java.util.zip.ZipEntry; >+import java.util.zip.ZipOutputStream; >+ >+import org.apache.poi.openxml4j.exceptions.OpenXML4JException; >+import org.apache.poi.openxml4j.opc.PackageNamespaces; >+import org.apache.poi.openxml4j.opc.PackagePart; > import org.apache.poi.openxml4j.opc.PackagePartName; > import org.apache.poi.openxml4j.opc.PackageRelationship; > import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; > import org.apache.poi.openxml4j.opc.PackagingURIHelper; > import org.apache.poi.openxml4j.opc.StreamHelper; >-import org.apache.poi.openxml4j.opc.TargetMode; >-import org.apache.poi.openxml4j.opc.internal.PartMarshaller; >-import org.apache.poi.openxml4j.opc.internal.ZipHelper; >-import org.apache.poi.util.POILogger; >-import org.apache.poi.util.POILogFactory; >- >-/** >- * Zip part marshaller. This marshaller is use to save any part in a zip stream. >+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. > * > * @author Julien Chable > */ >@@ -119,58 +117,52 @@ > PackageRelationshipCollection rels, PackagePartName relPartName, > ZipOutputStream zos) { > // Building xml >- Document xmlOutDoc = DocumentHelper.createDocument(); >- // make something like <Relationships >- // xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> >- Namespace dfNs = Namespace.get("", PackageNamespaces.RELATIONSHIPS); >- Element root = xmlOutDoc.addElement(new QName( >- PackageRelationship.RELATIONSHIPS_TAG_NAME, dfNs)); >- >- // <Relationship >- // TargetMode="External" >+ Document xmlOutDoc = DocumentHelper.createDocument(); >+ // make something like <Relationships >+ // xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> >+ Element root = xmlOutDoc.createElementNS(PackageNamespaces.RELATIONSHIPS, PackageRelationship.RELATIONSHIPS_TAG_NAME); >+ xmlOutDoc.appendChild(root); >+ >+ // <Relationship >+ // TargetMode="External" > // Id="rIdx" > // Target="http://www.custom.com/images/pic1.jpg" > // Type="http://www.custom.com/external-resource"/> > > URI sourcePartURI = PackagingURIHelper > .getSourcePartUriFromRelationshipPartUri(relPartName.getURI()); >- >- for (PackageRelationship rel : rels) { >- // the relationship element >- Element relElem = root >- .addElement(PackageRelationship.RELATIONSHIP_TAG_NAME); >- >- // the relationship ID >- relElem.addAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel >- .getId()); >- >- // the relationship Type >- relElem.addAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel >- .getRelationshipType()); >- >- // the relationship Target >- String targetValue; >+ >+ for (PackageRelationship rel : rels) { >+ // the relationship element >+ Element relElem = xmlOutDoc.createElement(PackageRelationship.RELATIONSHIP_TAG_NAME); >+ root.appendChild(relElem); >+ >+ // the relationship ID >+ relElem.setAttribute(PackageRelationship.ID_ATTRIBUTE_NAME, rel.getId()); >+ >+ // the relationship Type >+ relElem.setAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME, rel.getRelationshipType()); >+ >+ // the relationship Target >+ String targetValue; > URI uri = rel.getTargetURI(); > if (rel.getTargetMode() == TargetMode.EXTERNAL) { > // Save the target as-is - we don't need to validate it, > // alter it etc >- targetValue = uri.toString(); >+ targetValue = uri.toString(); >+ >+ // add TargetMode attribute (as it is external link external) >+ relElem.setAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External"); >+ } else { >+ URI targetURI = rel.getTargetURI(); >+ targetValue = PackagingURIHelper.relativizeURI( >+ sourcePartURI, targetURI, true).toString(); >+ } >+ relElem.setAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME, targetValue); >+ } >+ >+ xmlOutDoc.normalize(); > >- // add TargetMode attribute (as it is external link external) >- relElem.addAttribute( >- 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); >- } >- >- xmlOutDoc.normalize(); >- > // String schemaFilename = Configuration.getPathForXmlSchema()+ > // File.separator + "opc-relationships.xsd"; > >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/PackagePropertiesPart.java (working copy) >@@ -45,14 +45,12 @@ > public final static String NAMESPACE_DC_URI = "http://purl.org/dc/elements/1.1/"; > > public final static String NAMESPACE_CP_URI = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; >- >- public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/"; >- >- public final static String NAMESPACE_XSI_URI = "http://www.w3.org/2001/XMLSchema-instance"; >- >- /** >- * Constructor. >- * >+ >+ public final static String NAMESPACE_DCTERMS_URI = "http://purl.org/dc/terms/"; >+ >+ /** >+ * Constructor. >+ * > * @param pack > * Container package. > * @param partName >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java (working copy) >@@ -16,13 +16,13 @@ > ==================================================================== */ > > 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,39 +32,24 @@ > 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; >- >-/** >- * Package properties unmarshaller. >- * >+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. >+ * > * @author Julien Chable >- */ >-public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { >+ */ >+public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { >+ >+ protected static final String KEYWORD_CATEGORY = "category"; >+ >+ protected static final String KEYWORD_CONTENT_STATUS = "contentStatus"; > >- private final static Namespace namespaceDC = new Namespace("dc", >- PackageProperties.NAMESPACE_DC); >- >- private final static Namespace namespaceCP = new Namespace("cp", >- PackageNamespaces.CORE_PROPERTIES); >- >- private final static Namespace namespaceDcTerms = new Namespace("dcterms", >- PackageProperties.NAMESPACE_DCTERMS); >- >- private final static Namespace namespaceXML = new Namespace("xml", >- "http://www.w3.org/XML/1998/namespace"); >- >- private final static Namespace namespaceXSI = new Namespace("xsi", >- "http://www.w3.org/2001/XMLSchema-instance"); >- >- protected static final String KEYWORD_CATEGORY = "category"; >- >- protected static final String KEYWORD_CONTENT_STATUS = "contentStatus"; >- > protected static final String KEYWORD_CONTENT_TYPE = "contentType"; > > protected static final String KEYWORD_CREATED = "created"; >@@ -122,21 +107,21 @@ > try { > xmlDoc = SAXHelper.readSAXDocument(in); > >- /* Check OPC compliance */ >- >- // Rule M4.2, M4.3, M4.4 and M4.5/ >- checkElementForOPCCompliance(xmlDoc.getRootElement()); >- >- /* End OPC compliance */ >- >- } catch (DocumentException e) { >- throw new IOException(e.getMessage()); >- } >- >- coreProps.setCategoryProperty(loadCategory(xmlDoc)); >- coreProps.setContentStatusProperty(loadContentStatus(xmlDoc)); >- coreProps.setContentTypeProperty(loadContentType(xmlDoc)); >- coreProps.setCreatedProperty(loadCreated(xmlDoc)); >+ /* Check OPC compliance */ >+ >+ // Rule M4.2, M4.3, M4.4 and M4.5/ >+ checkElementForOPCCompliance(xmlDoc.getDocumentElement()); >+ >+ /* End OPC compliance */ >+ >+ } catch (SAXException e) { >+ throw new IOException(e.getMessage()); >+ } >+ >+ coreProps.setCategoryProperty(loadCategory(xmlDoc)); >+ coreProps.setContentStatusProperty(loadContentStatus(xmlDoc)); >+ coreProps.setContentTypeProperty(loadContentType(xmlDoc)); >+ coreProps.setCreatedProperty(loadCreated(xmlDoc)); > coreProps.setCreatorProperty(loadCreator(xmlDoc)); > coreProps.setDescriptionProperty(loadDescription(xmlDoc)); > coreProps.setIdentifierProperty(loadIdentifier(xmlDoc)); >@@ -150,155 +135,83 @@ > coreProps.setTitleProperty(loadTitle(xmlDoc)); > coreProps.setVersionProperty(loadVersion(xmlDoc)); > >- return coreProps; >- } >- >- private String loadCategory(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CATEGORY, namespaceCP)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- 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 loadContentType(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CONTENT_TYPE, namespaceCP)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadCreated(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CREATED, namespaceDcTerms)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadCreator(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_CREATOR, namespaceDC)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadDescription(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_DESCRIPTION, namespaceDC)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadIdentifier(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_IDENTIFIER, namespaceDC)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadKeywords(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_KEYWORDS, namespaceCP)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadLanguage(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_LANGUAGE, namespaceDC)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- 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(); >- } >- >- private String loadLastPrinted(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_LAST_PRINTED, namespaceCP)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadModified(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_MODIFIED, namespaceDcTerms)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadRevision(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_REVISION, namespaceCP)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadSubject(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_SUBJECT, namespaceDC)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadTitle(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_TITLE, namespaceDC)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- private String loadVersion(Document xmlDoc) { >- Element el = xmlDoc.getRootElement().element( >- new QName(KEYWORD_VERSION, namespaceCP)); >- if (el == null) { >- return null; >- } >- return el.getStringValue(); >- } >- >- /* OPC Compliance methods */ >- >+ 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) { >+ return readElement(xmlDoc, KEYWORD_CATEGORY, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadContentStatus(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_CONTENT_STATUS, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadContentType(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_CONTENT_TYPE, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadCreated(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_CREATED, PackageProperties.NAMESPACE_DCTERMS); >+ } >+ >+ private String loadCreator(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_CREATOR, PackageProperties.NAMESPACE_DC); >+ } >+ >+ private String loadDescription(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_DESCRIPTION, PackageProperties.NAMESPACE_DC); >+ } >+ >+ private String loadIdentifier(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_IDENTIFIER, PackageProperties.NAMESPACE_DC); >+ } >+ >+ private String loadKeywords(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_KEYWORDS, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadLanguage(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_LANGUAGE, PackageProperties.NAMESPACE_DC); >+ } >+ >+ private String loadLastModifiedBy(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_LAST_MODIFIED_BY, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadLastPrinted(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_LAST_PRINTED, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadModified(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_MODIFIED, PackageProperties.NAMESPACE_DCTERMS); >+ } >+ >+ private String loadRevision(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_REVISION, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ private String loadSubject(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_SUBJECT, PackageProperties.NAMESPACE_DC); >+ } >+ >+ private String loadTitle(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_TITLE, PackageProperties.NAMESPACE_DC); >+ } >+ >+ private String loadVersion(Document xmlDoc) { >+ return readElement(xmlDoc, KEYWORD_VERSION, PackageNamespaces.CORE_PROPERTIES); >+ } >+ >+ /* OPC Compliance methods */ >+ > /** > * Check the element for the following OPC compliance rules: > * <p> >@@ -322,63 +235,59 @@ > * element that violates this constraint to be an error. > * </p> > */ >- 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(); >+ public void checkElementForOPCCompliance(Element el) >+ throws InvalidFormatException { >+ // Check the current element >+ 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 >+ 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.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.getNamespaceURI().equals(PackageProperties.NAMESPACE_DCTERMS)) { >+ // DCTerms namespace only use with 'created' and 'modified' elements >+ 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 >+ Attr typeAtt = el.getAttributeNodeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"); >+ if (typeAtt == null) >+ throw new InvalidFormatException("The element '" + elName >+ + "' must have the 'xsi:type' attribute present !"); > >- // Rule M4.2 >- if (ns.getURI().equals(PackageNamespaces.MARKUP_COMPATIBILITY)) >- throw new InvalidFormatException( >- "OPC Compliance error [M4.2]: A format consumer shall consider the use of the Markup Compatibility namespace to be an error."); >- } >- >- // Rule M4.3 >- if (el.getNamespace().getURI().equals( >- PackageProperties.NAMESPACE_DCTERMS) >- && !(el.getName().equals(KEYWORD_CREATED) || el.getName() >- .equals(KEYWORD_MODIFIED))) >- throw new InvalidFormatException( >- "OPC Compliance error [M4.3]: Producers shall not create a document element that contains refinements to the Dublin Core elements, except for the two specified in the schema: <dcterms:created> and <dcterms:modified> Consumers shall consider a document element that violates this constraint to be an error."); >- >- // Rule M4.4 >- if (el.attribute(new QName("lang", namespaceXML)) != null) >- throw new InvalidFormatException( >- "OPC Compliance error [M4.4]: Producers shall not create a document element that contains the xml:lang attribute. Consumers shall consider a document element that violates this constraint to be an error."); >- >- // Rule M4.5 >- if (el.getNamespace().getURI().equals( >- PackageProperties.NAMESPACE_DCTERMS)) { >- // DCTerms namespace only use with 'created' and 'modified' elements >- String elName = el.getName(); >- if (!(elName.equals(KEYWORD_CREATED) || elName >- .equals(KEYWORD_MODIFIED))) >- throw new InvalidFormatException("Namespace error : " + elName >- + " shouldn't have the following naemspace -> " >- + PackageProperties.NAMESPACE_DCTERMS); >- >- // Check for the 'xsi:type' attribute >- Attribute typeAtt = el.attribute(new QName("type", namespaceXSI)); >- if (typeAtt == null) >- throw new InvalidFormatException("The element '" + elName >- + "' must have the '" + namespaceXSI.getPrefix() >- + ":type' attribute present !"); >- > // Check for the attribute value => 'dcterms:W3CDTF' > if (!typeAtt.getValue().equals("dcterms:W3CDTF")) > throw new InvalidFormatException("The element '" + elName >- + "' must have the '" + namespaceXSI.getPrefix() >- + ":type' attribute with the value 'dcterms:W3CDTF' !"); >- } >- >- // Check its children >- @SuppressWarnings("unchecked") >- Iterator<Element> itChildren = el.elementIterator(); >- while (itChildren.hasNext()) >- checkElementForOPCCompliance(itChildren.next()); >- } >-} >+ + "' must have the 'xsi:type' attribute with the value 'dcterms:W3CDTF' !"); >+ } >+ >+ // Check its children >+ NodeList childElements = el.getElementsByTagName("*"); >+ int childElementCount = childElements.getLength(); >+ for (int i = 0; i < childElementCount; i++) >+ checkElementForOPCCompliance((Element)childElements.item(i)); >+ } >+} >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipContentTypeManager.java (working copy) >@@ -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,10 +28,10 @@ > import org.apache.poi.openxml4j.opc.StreamHelper; > import org.apache.poi.util.POILogFactory; > import org.apache.poi.util.POILogger; >-import org.dom4j.Document; >- >-/** >- * Zip implementation of the ContentTypeManager. >+import org.w3c.dom.Document; >+ >+/** >+ * Zip implementation of the ContentTypeManager. > * > * @author Julien Chable > * @version 1.0 >@@ -69,17 +67,8 @@ > // 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) { >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java (working copy) >@@ -24,15 +24,13 @@ > > import org.apache.poi.openxml4j.exceptions.InvalidFormatException; > 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; >- >-/** >- * Represents a collection of PackageRelationship elements that are owned by a >+import org.apache.poi.util.POILogFactory; >+import org.apache.poi.util.POILogger; >+import org.apache.poi.util.SAXHelper; >+import org.w3c.dom.*; >+ >+/** >+ * Represents a collection of PackageRelationship elements that are owned by a > * given PackagePart or the Package. > * > * @author Julien Chable, CDubettier >@@ -310,28 +308,25 @@ > throws InvalidFormatException { > try { > logger.log(POILogger.DEBUG, "Parsing relationship: " + relPart.getPartName()); >- Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream()); >- >- // Browse default types >- Element root = xmlRelationshipsDoc.getRootElement(); >- >- // 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(); >- // Relationship ID >- String id = element.attribute( >- PackageRelationship.ID_ATTRIBUTE_NAME).getValue(); >- // Relationship type >- String type = element.attribute( >- PackageRelationship.TYPE_ATTRIBUTE_NAME).getValue(); >- >- /* Check OPC Compliance */ >- // Check Rule M4.1 >+ Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream()); >+ >+ // Browse default types >+ Element root = xmlRelationshipsDoc.getDocumentElement(); >+ >+ // Check OPC compliance M4.1 rule >+ boolean fCorePropertiesRelationship = false; >+ >+ 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.getAttribute(PackageRelationship.ID_ATTRIBUTE_NAME); >+ // Relationship type >+ String type = element.getAttribute(PackageRelationship.TYPE_ATTRIBUTE_NAME); >+ >+ /* Check OPC Compliance */ >+ // Check Rule M4.1 > if (type.equals(PackageRelationshipTypes.CORE_PROPERTIES)) > if (!fCorePropertiesRelationship) > fCorePropertiesRelationship = true; >@@ -339,26 +334,23 @@ > throw new InvalidFormatException( > "OPC Compliance error [M4.1]: there is more than one core properties relationship in the package !"); > >- /* End OPC Compliance */ >- >- // TargetMode (default value "Internal") >- Attribute targetModeAttr = element >- .attribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME); >- TargetMode targetMode = TargetMode.INTERNAL; >- if (targetModeAttr != null) { >- targetMode = targetModeAttr.getValue().toLowerCase() >+ /* End OPC Compliance */ >+ >+ // TargetMode (default value "Internal") >+ Attr targetModeAttr = element.getAttributeNode(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME); >+ TargetMode targetMode = TargetMode.INTERNAL; >+ if (targetModeAttr != null) { >+ targetMode = targetModeAttr.getValue().toLowerCase() > .equals("internal") ? TargetMode.INTERNAL > : TargetMode.EXTERNAL; > } >- >- // Target converted in URI >- URI target = PackagingURIHelper.toURI("http://invalid.uri"); // dummy url >- String value = element.attribute( >- PackageRelationship.TARGET_ATTRIBUTE_NAME) >- .getValue(); >- try { >- // when parsing of the given uri fails, we can either >- // ignore this relationship, which leads to IllegalStateException >+ >+ // Target converted in URI >+ URI target = PackagingURIHelper.toURI("http://invalid.uri"); // dummy url >+ 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 > // later on, or use a dummy value and thus enable processing of the > // package > target = PackagingURIHelper.toURI(value); >Index: src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java >=================================================================== >--- src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/openxml4j/opc/StreamHelper.java (working copy) >@@ -14,45 +14,76 @@ > See the License for the specific language governing permissions and > limitations under the License. > ==================================================================== */ >- >-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.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; > >-public final class StreamHelper { >- >- private StreamHelper() { >+import org.w3c.dom.Document; >+ >+public final class StreamHelper { >+ >+ private StreamHelper() { > // Do nothing > } >- >- /** >- * Turning the DOM4j object in the specified output stream. >- * >- * @param xmlContent >- * The XML document. >+ >+ private static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); >+ >+ private static synchronized Transformer getIdentityTransformer() throws TransformerException { >+ return transformerFactory.newTransformer(); >+ } >+ >+ /** >+ * Save the document object in the specified output stream. >+ * >+ * @param xmlContent >+ * The XML document. > * @param outStream > * The OutputStream in which the XML document will be written. > * @return <b>true</b> if the xml is successfully written in the stream, > * else <b>false</b>. > */ >- public static boolean saveXmlInStream(Document xmlContent, >- OutputStream outStream) { >- try { >- OutputFormat outformat = OutputFormat.createPrettyPrint(); >- outformat.setEncoding("UTF-8"); >- XMLWriter writer = new XMLWriter(outStream, outformat); >- writer.write(xmlContent); >- } catch (Exception e) { >- return false; >- } >- return true; >- } >+ 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. > * >Index: src/ooxml/java/org/apache/poi/util/DocumentHelper.java >=================================================================== >--- src/ooxml/java/org/apache/poi/util/DocumentHelper.java (revision 0) >+++ src/ooxml/java/org/apache/poi/util/DocumentHelper.java (working copy) >@@ -0,0 +1,61 @@ >+/* ==================================================================== >+ 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 { >+ >+ // should only be used without synchronization for creating new empty documents >+ 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()); >+ } >+ >+} >Index: src/ooxml/java/org/apache/poi/util/DocumentHelper.java >=================================================================== >--- src/ooxml/java/org/apache/poi/util/DocumentHelper.java (revision 0) >+++ src/ooxml/java/org/apache/poi/util/DocumentHelper.java (working copy) > >Property changes on: src/ooxml/java/org/apache/poi/util/DocumentHelper.java >___________________________________________________________________ >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:keywords >## -0,0 +1 ## >+Date Author Id Revision HeadURL >\ No newline at end of property >Index: src/ooxml/java/org/apache/poi/util/SAXHelper.java >=================================================================== >--- src/ooxml/java/org/apache/poi/util/SAXHelper.java (revision 1617151) >+++ src/ooxml/java/org/apache/poi/util/SAXHelper.java (working copy) >@@ -20,61 +20,75 @@ > import java.io.IOException; > import java.io.InputStream; > import java.io.StringReader; >-import java.lang.reflect.Method; >+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.w3c.dom.Document; >+import org.xml.sax.EntityResolver; >+import org.xml.sax.InputSource; >+import org.xml.sax.SAXException; > >-import javax.xml.XMLConstants; > >-import org.dom4j.Document; >-import org.dom4j.DocumentException; >-import org.dom4j.io.SAXReader; >-import org.xml.sax.EntityResolver; >-import org.xml.sax.InputSource; >-import org.xml.sax.SAXException; >- >- > /** > * Provides handy methods for working with SAX parsers and readers >- */ >-public final class SAXHelper { >- private static POILogger logger = POILogFactory.getLogger(SAXHelper.class); >- >- /** >- * Creates a new SAX Reader, with sensible defaults >- */ >- public static SAXReader getSAXReader() { >- SAXReader xmlReader = new SAXReader(); >- xmlReader.setValidation(false); >- xmlReader.setEntityResolver(new EntityResolver() { >- public InputSource resolveEntity(String publicId, String systemId) >- throws SAXException, IOException { >- return new InputSource(new StringReader("")); >- } >- }); >- trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING, true); >- trySetXercesSecurityManager(xmlReader); >- return xmlReader; >- } >- private static void trySetSAXFeature(SAXReader xmlReader, String feature, boolean enabled) { >- try { >- xmlReader.setFeature(feature, enabled); >- } catch (Exception e) { >- logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e); >- } >- } >- private static void trySetXercesSecurityManager(SAXReader xmlReader) { >- // Try built-in JVM one first, standalone if not >- for (String securityManagerClassName : new String[] { >- "com.sun.org.apache.xerces.internal.util.SecurityManager", >+ */ >+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 document builder, with sensible defaults >+ */ >+ public static synchronized DocumentBuilder getDocumentBuilder() { >+ try { >+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); >+ documentBuilder.setEntityResolver(IGNORING_ENTITY_RESOLVER); >+ return documentBuilder; >+ } catch (ParserConfigurationException e) { >+ throw new IllegalStateException("cannot create a DocumentBuilder", e); >+ } >+ } >+ >+ private static void trySetSAXFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean enabled) { >+ try { >+ documentBuilderFactory.setFeature(feature, enabled); >+ } catch (Exception e) { >+ logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e); >+ } >+ } >+ 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", > "org.apache.xerces.util.SecurityManager" > }) { > try { >- Object mgr = Class.forName(securityManagerClassName).newInstance(); >- Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); >- setLimit.invoke(mgr, 4096); >- xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr); >- // Stop once one can be setup without error >- return; >- } catch (Exception e) { >+ Object mgr = Class.forName(securityManagerClassName).newInstance(); >+ Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); >+ setLimit.invoke(mgr, 4096); >+ documentBuilderFactory.setAttribute("http://apache.org/xml/properties/security-manager", mgr); >+ // Stop once one can be setup without error >+ return; >+ } catch (Exception e) { > logger.log(POILogger.INFO, "SAX Security Manager could not be setup", e); > } > } >@@ -83,10 +97,10 @@ > /** > * Parses the given stream via the default (sensible) > * SAX Reader >- * @param inp Stream to read the XML data from >- * @return the SAX processed Document >- */ >- public static Document readSAXDocument(InputStream inp) throws DocumentException { >- return getSAXReader().read(inp); >- } >-} >+ * @param inp Stream to read the XML data from >+ * @return the SAX processed Document >+ */ >+ public static Document readSAXDocument(InputStream inp) throws IOException, SAXException { >+ return getDocumentBuilder().parse(inp); >+ } >+} >Index: src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java >=================================================================== >--- src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java (revision 1617151) >+++ src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java (working copy) >@@ -24,35 +24,29 @@ > import java.io.IOException; > import java.io.InputStream; > 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; >+import java.lang.reflect.Field; >+import java.net.URI; >+import java.util.HashMap; >+import java.util.List; >+import java.util.TreeMap; >+import java.util.regex.Pattern; > > import junit.framework.TestCase; > > import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; > import org.apache.poi.openxml4j.exceptions.InvalidFormatException; > import org.apache.poi.openxml4j.exceptions.InvalidOperationException; >-import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; >-import org.apache.poi.openxml4j.opc.internal.FileHelper; >-import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; >-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.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.*; >+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); > >-public final class TestPackage extends TestCase { >- private static final POILogger logger = POILogFactory.getLogger(TestPackage.class); >- > /** > * Test that just opening and closing the file doesn't alter the document. > */ >@@ -124,25 +118,24 @@ > PackagePart corePart = pkg > .createPart( > corePartName, >- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); >+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); >+ >+ Document doc = DocumentHelper.createDocument(); >+ 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(); > >- Document doc = DocumentHelper.createDocument(); >- Namespace nsWordprocessinML = new Namespace("w", >- "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); >- Element elDocument = doc.addElement(new QName("document", >- nsWordprocessinML)); >- Element elBody = elDocument.addElement(new QName("body", >- nsWordprocessinML)); >- Element elParagraph = elBody.addElement(new QName("p", >- nsWordprocessinML)); >- Element elRun = elParagraph >- .addElement(new QName("r", nsWordprocessinML)); >- Element elText = elRun.addElement(new QName("t", nsWordprocessinML)); >- elText.setText("Hello Open XML !"); >- >- StreamHelper.saveXmlInStream(doc, corePart.getOutputStream()); >- pkg.close(); >- > ZipFileAssert.assertEquals(expectedFile, targetFile); > assertTrue(targetFile.delete()); > } >@@ -220,22 +213,20 @@ > private void assertMSCompatibility(OPCPackage pkg) throws Exception { > PackagePartName relName = PackagingURIHelper.createPartName(PackageRelationship.getContainerPartRelationship()); > PackagePart relPart = pkg.getPart(relName); >+ >+ Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream()); >+ >+ 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) != '/'); >+ } >+ >+ } > >- 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) != '/'); >- } >- >- } >- > /** > * Test package opening. > */ >@@ -265,24 +256,23 @@ > .resolvePartUri(corePart.getPartName().getURI(), rel > .getTargetURI()))); > } >- >- // Create a content >- Document doc = DocumentHelper.createDocument(); >- Namespace nsWordprocessinML = new Namespace("w", >- "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); >- Element elDocument = doc.addElement(new QName("document", >- nsWordprocessinML)); >- Element elBody = elDocument.addElement(new QName("body", >- nsWordprocessinML)); >- Element elParagraph = elBody.addElement(new QName("p", >- nsWordprocessinML)); >- Element elRun = elParagraph >- .addElement(new QName("r", nsWordprocessinML)); >- Element elText = elRun.addElement(new QName("t", nsWordprocessinML)); >- elText.setText("Hello Open XML !"); >- >- StreamHelper.saveXmlInStream(doc, corePart.getOutputStream()); >- >+ >+ // Create a content >+ Document doc = DocumentHelper.createDocument(); >+ 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()); >+ > // Save and close > try { > pkg.close();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 56814
:
31890
|
31893
|
31894
|
31895
|
31898