]> source.dussan.org Git - poi.git/commitdiff
improved API for OOXML custom properties
authorYegor Kozlov <yegor@apache.org>
Sun, 4 Oct 2009 10:00:52 +0000 (10:00 +0000)
committerYegor Kozlov <yegor@apache.org>
Sun, 4 Oct 2009 10:00:52 +0000 (10:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@821496 13f79535-47bb-0310-9956-ffa450edef68

src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkbookProperties.java
src/ooxml/java/org/apache/poi/POIXMLProperties.java
src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java

index 0e00c7d94bc6717ce21dab066ac695ed4500cfdc..3a8fd56d00a3b6720fccbc5d2c447aa07b37cf89 100755 (executable)
@@ -47,24 +47,15 @@ public class WorkbookProperties {
         ext.getUnderlyingProperties().setTemplate("XSSF");
 
         /**
-         * Custom properties enable users to define custom metadata properties
-         * through a set of well-defined data types. For example, a custom
-         * OLE Editor property of type string can be defined as follows:
-         *
-         *  <property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="Editor">
-         *    <vt:lpwstr>John Smith</vt:lpwstr>
-         *  </property>
+         * Custom properties enable users to define custom metadata properties.
          */
         
         POIXMLProperties.CustomProperties cust =  props.getCustomProperties();
-        org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty
-                property = cust.getUnderlyingProperties().addNewProperty();
+        cust.addProperty("Author", "John Smith");
+        cust.addProperty("Year", 2009);
+        cust.addProperty("Price", 45.50);
+        cust.addProperty("Available", true);
 
-        property.setFmtid("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
-        property.setPid(2);
-        property.setName("Editor");
-        property.setLpwstr("John Smith");
-        
         FileOutputStream out = new FileOutputStream("workbook.xlsx");
         workbook.write(out);
         out.close();
index 1ccf7367448dc4f41172fc46a44d35efdb520a9c..c62b57db36ccb05595603646336b769fe3e4c1c6 100644 (file)
@@ -34,6 +34,7 @@ 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.customProperties.CTProperty;
 
 /**
  * Wrapper around the two different kinds of OOXML properties 
@@ -150,8 +151,14 @@ public class POIXMLProperties {
             out.close();
         }
         if(custPart != null){
+            XmlOptions xmlOptions = new XmlOptions(POIXMLDocumentPart.DEFAULT_XML_OPTIONS);
+
+            Map<String, String> map = new HashMap<String, String>();
+            map.put("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "vt");
+            xmlOptions.setSaveSuggestedPrefixes(map);
+
             OutputStream out = custPart.getOutputStream();
-            cust.props.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS);
+            cust.props.save(out, xmlOptions);
             out.close();
         }
        }
@@ -271,10 +278,16 @@ public class POIXMLProperties {
        }
        
        /**
-        * Custom document properties
+        *  Custom document properties
         */
        public class CustomProperties {
-               private org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props;
+        /**
+         *  Each custom property element contains an fmtid attribute
+         *  with the same GUID value ({D5CDD505-2E9C-101B-9397-08002B2CF9AE}).
+         */
+        public static final String FORMAT_ID = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}";
+
+        private org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props;
                private CustomProperties(org.openxmlformats.schemas.officeDocument.x2006.customProperties.PropertiesDocument props) {
                        this.props = props;
                }
@@ -282,5 +295,91 @@ public class POIXMLProperties {
                public org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties getUnderlyingProperties() {
                        return props.getProperties();
                }
-       }
+
+        /**
+         * Add a new property
+         *
+         * @param name the property name
+         * @throws IllegalArgumentException if a property with this name already exists
+         */
+        private CTProperty add(String name) {
+            if(contains(name)) {
+                throw new IllegalArgumentException("A property with this name " +
+                        "already exists in the custom properties");
+            }
+
+            CTProperty p = props.getProperties().addNewProperty();
+            int pid = nextPid();
+            p.setPid(pid);
+            p.setFmtid(FORMAT_ID);
+            p.setName(name);
+            return p;
+        }
+
+        /**
+         * Add a new string property
+         *
+         * @throws IllegalArgumentException if a property with this name already exists
+         */
+         public void addProperty(String name, String value){
+            CTProperty p = add(name);
+            p.setLpwstr(value);
+        }
+
+        /**
+         * Add a new double property
+         *
+         * @throws IllegalArgumentException if a property with this name already exists
+         */
+        public void addProperty(String name, double value){
+            CTProperty p = add(name);
+            p.setR8(value);
+        }
+
+        /**
+         * Add a new integer property
+         *
+         * @throws IllegalArgumentException if a property with this name already exists
+         */
+        public void addProperty(String name, int value){
+            CTProperty p = add(name);
+            p.setI4(value);
+        }
+
+        /**
+         * Add a new boolean property
+         *
+         * @throws IllegalArgumentException if a property with this name already exists
+         */
+        public void addProperty(String name, boolean value){
+            CTProperty p = add(name);
+            p.setBool(value);
+        }
+
+        /**
+         * Generate next id that uniquely relates a custom property
+         *
+         * @return next property id starting with 2
+         */
+        protected int nextPid(){
+            int propid = 1;
+            for(CTProperty p : props.getProperties().getPropertyArray()){
+                if(p.getPid() > propid) propid = p.getPid();
+            }
+            return propid + 1;
+        }
+
+        /**
+         * Check if a property with this name already exists in the collection of custom properties
+         *
+         * @param name the name to check
+         * @return whether a property with the given name exists in the custom properties
+         */
+        public boolean contains(String name){
+            for(CTProperty p : props.getProperties().getPropertyArray()){
+                if(p.getName().equals(name)) return true;
+            }
+            return false;
+        }
+    }
 }
index ba9cfe92afda8c450b33f6ab4a538133ecf9041b..1aac08740bfaa7990eeac87f118eb4a6f383eec8 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties;
 
 /**
  * Test setting extended and custom OOXML properties
@@ -85,69 +86,57 @@ public final class TestPOIXMLProperties extends TestCase {
        }
 
 
-       public void testWorkbookCustomProperties() {
-               XSSFWorkbook workbook = new XSSFWorkbook();
-               POIXMLProperties props = workbook.getProperties();
-               assertNotNull(props);
-
-               org.apache.poi.POIXMLProperties.CustomProperties properties =
-                               props.getCustomProperties();
-
-               org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties
-                               ctProps = properties.getUnderlyingProperties();
-
-
-               org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty
-                               property = ctProps.addNewProperty();
-
-
-               String fmtid =
-                               "{A1A1A1A1A1A1A1A1-A1A1A1A1-A1A1A1A1-A1A1A1A1-A1A1A1A1A1A1A1A1}";
-               int pId = 1;
-               String name = "testProperty";
-               String stringValue = "testValue";
-
-
-               property.setFmtid(fmtid);
-               property.setPid(pId);
-               property.setName(name);
-               property.setBstr(stringValue);
-
-
-               property = null;
-               ctProps = null;
-               properties = null;
-               props = null;
-
-               XSSFWorkbook newWorkbook =
-                               XSSFTestDataSamples.writeOutAndReadBack(workbook);
-
-               assertTrue(workbook != newWorkbook);
-
-
-               POIXMLProperties newProps = newWorkbook.getProperties();
-               assertNotNull(newProps);
-               org.apache.poi.POIXMLProperties.CustomProperties newProperties =
-                               newProps.getCustomProperties();
-
-               org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties
-                               newCtProps = newProperties.getUnderlyingProperties();
-
-               assertEquals(1, newCtProps.getPropertyArray().length);
-
-
-               org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty
-                               newpProperty = newCtProps.getPropertyArray()[0];
-
-               assertEquals(fmtid, newpProperty.getFmtid());
-               assertEquals(pId, newpProperty.getPid());
-               assertEquals(name, newpProperty.getName());
-               assertEquals(stringValue, newpProperty.getBstr());
-
-
-       }
-
-       public void testDocumentProperties() {
+    /**
+     * Test usermodel API for setting custom properties
+     */
+    public void testCustomProperties() {
+        POIXMLDocument wb = new XSSFWorkbook();
+
+        POIXMLProperties.CustomProperties customProps = wb.getProperties().getCustomProperties();
+        customProps.addProperty("test-1", "string val");
+        customProps.addProperty("test-2", 1974);
+        customProps.addProperty("test-3", 36.6);
+        //adding a duplicate
+        try {
+            customProps.addProperty("test-3", 36.6);
+            fail("expected exception");
+        } catch(IllegalArgumentException e){
+            assertEquals("A property with this name already exists in the custom properties", e.getMessage());
+        }
+        customProps.addProperty("test-4", true);
+
+        wb = XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)wb);
+        org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperties ctProps =
+                wb.getProperties().getCustomProperties().getUnderlyingProperties();
+        assertEquals(4, ctProps.sizeOfPropertyArray());
+        org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty p;
+
+        p = ctProps.getPropertyArray(0);
+        assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
+        assertEquals("test-1", p.getName());
+        assertEquals("string val", p.getLpwstr());
+        assertEquals(2, p.getPid());
+
+        p = ctProps.getPropertyArray(1);
+        assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
+        assertEquals("test-2", p.getName());
+        assertEquals(1974, p.getI4());
+        assertEquals(3, p.getPid());
+
+        p = ctProps.getPropertyArray(2);
+        assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
+        assertEquals("test-3", p.getName());
+        assertEquals(36.6, p.getR8());
+        assertEquals(4, p.getPid());
+
+        p = ctProps.getPropertyArray(3);
+        assertEquals("{D5CDD505-2E9C-101B-9397-08002B2CF9AE}", p.getFmtid());
+        assertEquals("test-4", p.getName());
+        assertEquals(true, p.getBool());
+        assertEquals(5, p.getPid());
+    }
+
+    public void testDocumentProperties() {
                String category = _coreProperties.getCategory();
                assertEquals("test", category);
                String contentStatus = "Draft";