From 15e434d6849f0fae2d53e2e1e509e8cf0e0b46da Mon Sep 17 00:00:00 2001 From: Paolo Mottadelli Date: Tue, 21 Jul 2009 10:23:05 +0000 Subject: [PATCH] POIXMLproperties: created, creator, modified, lastprinted, identifier, revision + test git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@796239 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/POIXMLProperties.java | 89 ++++++++++++++++-- .../org/apache/poi/TestPOIXMLProperties.java | 59 ++++++++---- .../poi/hwpf/data/documentProperties.docx | Bin 23514 -> 23503 bytes 3 files changed, 123 insertions(+), 25 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/POIXMLProperties.java b/src/ooxml/java/org/apache/poi/POIXMLProperties.java index ca2ca808b..1ccf73674 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLProperties.java +++ b/src/ooxml/java/org/apache/poi/POIXMLProperties.java @@ -18,16 +18,22 @@ package org.apache.poi; import java.io.IOException; import java.io.OutputStream; -import java.util.Map; +import java.util.Date; import java.util.HashMap; +import java.util.Map; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.poi.openxml4j.opc.*; +import org.apache.poi.openxml4j.exceptions.OpenXML4JException; +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.PackageRelationshipCollection; +import org.apache.poi.openxml4j.opc.PackagingURIHelper; +import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; +import org.apache.poi.openxml4j.util.Nullable; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlOptions; -import org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument; /** * Wrapper around the two different kinds of OOXML properties @@ -159,11 +165,32 @@ public class POIXMLProperties { this.part = part; } - public void setTitle(String title) { - part.setTitleProperty(title); + public String getCategory() { + return part.getCategoryProperty().getValue(); } - public String getTitle() { - return part.getTitleProperty().getValue(); + public void setCategory(String category) { + part.setCategoryProperty(category); + } + public String getContentStatus() { + return part.getContentStatusProperty().getValue(); + } + public void setContentStatus(String contentStatus) { + part.setContentStatusProperty(contentStatus); + } + public String getContentType() { + return part.getContentTypeProperty().getValue(); + } + public void setContentType(String contentType) { + part.setContentTypeProperty(contentType); + } + public Date getCreated() { + return part.getCreatedProperty().getValue(); + } + public void setCreated(Nullable date) { + part.setCreatedProperty(date); + } + public void setCreated(String date) { + part.setCreatedProperty(date); } public String getCreator() { return part.getCreatorProperty().getValue(); @@ -171,12 +198,58 @@ public class POIXMLProperties { public void setCreator(String creator) { part.setCreatorProperty(creator); } + public String getDescription() { + return part.getDescriptionProperty().getValue(); + } + public void setDescription(String description) { + part.setDescriptionProperty(description); + } + public String getIdentifier() { + return part.getIdentifierProperty().getValue(); + } + public void setIdentifier(String identifier) { + part.setIdentifierProperty(identifier); + } + public Date getLastPrinted() { + return part.getLastPrintedProperty().getValue(); + } + public void setLastPrinted(Nullable date) { + part.setLastPrintedProperty(date); + } + public void setLastPrinted(String date) { + part.setLastPrintedProperty(date); + } + public Date getModified() { + return part.getModifiedProperty().getValue(); + } + public void setModified(Nullable date) { + part.setModifiedProperty(date); + } + public void setModified(String date) { + part.setModifiedProperty(date); + } public String getSubject() { return part.getSubjectProperty().getValue(); } public void setSubjectProperty(String subject) { part.setSubjectProperty(subject); } + public void setTitle(String title) { + part.setTitleProperty(title); + } + public String getTitle() { + return part.getTitleProperty().getValue(); + } + public String getRevision() { + return part.getRevisionProperty().getValue(); + } + public void setRevision(String revision) { + try { + new Long(revision); + part.setRevisionProperty(revision); + } + catch (NumberFormatException e) {} + } public PackagePropertiesPart getUnderlyingProperties() { return part; diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java index c27619cec..75d87105a 100755 --- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java +++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java @@ -19,10 +19,12 @@ package org.apache.poi; import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; import junit.framework.TestCase; -import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.POIXMLProperties.CoreProperties; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.usermodel.XWPFDocument; @@ -31,6 +33,23 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument; * Test setting extended and custom OOXML properties */ public class TestPOIXMLProperties extends TestCase { + POIXMLProperties props; + CoreProperties coreProperties; + + public void setUp() throws Exception{ + File sampleFile = new File( + System.getProperty("HWPF.testdata.path") + + File.separator + "documentProperties.docx" + ); + assertTrue(sampleFile.exists()); + XWPFDocument sampleDoc; + sampleDoc = new XWPFDocument( + POIXMLDocument.openPackage(sampleFile.toString()) + ); + props = sampleDoc.getProperties(); + coreProperties = props.getCoreProperties(); + assertNotNull(props); + } public void testWorkbookExtendedProperties() throws Exception { XSSFWorkbook workbook = new XSSFWorkbook(); @@ -137,23 +156,29 @@ public class TestPOIXMLProperties extends TestCase { } - public void testDocumentProperties() throws Exception { - File sampleFile = new File( - System.getProperty("HWPF.testdata.path") + - File.separator + "documentProperties.docx" - ); - assertTrue(sampleFile.exists()); - XWPFDocument sampleDoc; - sampleDoc = new XWPFDocument( - POIXMLDocument.openPackage(sampleFile.toString()) - ); - POIXMLProperties props = sampleDoc.getProperties(); - assertNotNull(props); - String title = props.getCoreProperties().getTitle(); - assertEquals("Hello World", title); - String creator = props.getCoreProperties().getCreator(); + public void testDocumentProperties() { + String category = coreProperties.getCategory(); + assertEquals("test", category); + String contentStatus = "Draft"; + coreProperties.setContentStatus(contentStatus); + assertEquals("Draft", contentStatus); + Date created = coreProperties.getCreated(); + SimpleDateFormat formatter = new SimpleDateFormat("EEE, MMM d, ''yy"); + assertEquals("Mon, Jul 20, '09", formatter.format(created)); + String creator = coreProperties.getCreator(); assertEquals("Paolo Mottadelli", creator); - String subject = props.getCoreProperties().getSubject(); + String subject = coreProperties.getSubject(); assertEquals("Greetings", subject); + String title = coreProperties.getTitle(); + assertEquals("Hello World", title); + } + + public void testGetSetRevision() { + String revision = coreProperties.getRevision(); + assertTrue("Revision number is 1", new Integer(coreProperties.getRevision()).intValue() > 1); + coreProperties.setRevision("20"); + assertEquals("20", coreProperties.getRevision()); + coreProperties.setRevision("20xx"); + assertEquals("20", coreProperties.getRevision()); } } \ No newline at end of file diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/data/documentProperties.docx b/src/scratchpad/testcases/org/apache/poi/hwpf/data/documentProperties.docx index d18b31e2ce53c24cb5bddd2d974a0decbb471296..4ec577ee93ba32a1b1dc8b4b99b674dbe31cfdcf 100644 GIT binary patch literal 23503 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 SV_^m`b*^{!9 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 DFcP*z