]> source.dussan.org Git - poi.git/commitdiff
bug 22195 ClassID support, by Michael Zalewski, sync from branch, pls verify
authorAvik Sengupta <avik@apache.org>
Fri, 31 Oct 2003 16:39:05 +0000 (16:39 +0000)
committerAvik Sengupta <avik@apache.org>
Fri, 31 Oct 2003 16:39:05 +0000 (16:39 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353429 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hpsf/ClassID.java
src/java/org/apache/poi/poifs/property/Property.java
src/testcases/org/apache/poi/hpsf/basic/TestClassID.java [new file with mode: 0644]
src/testcases/org/apache/poi/poifs/property/TestDocumentProperty.java
src/testcases/org/apache/poi/poifs/property/TestRootProperty.java

index ddd52c686ed0150f3ca62d91f0542c2a43980aff..549cad05b65576ec42c0a49febefcdb9f042326f 100644 (file)
  */
 package org.apache.poi.hpsf;
 
+import java.io.*;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+
 /**
  *  <p>Represents a class ID (16 bytes). Unlike other little-endian
  *  type the {@link ClassID} is not just 16 bytes stored in the wrong
@@ -229,7 +233,25 @@ public class ClassID
         return true;
     }
 
-
+    /**
+     * Returns a human readable representation of the Class ID
+     *   in standard format <code>"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"</code>
+     * @return String representation of the Class ID represented
+     *   by this object.
+     */
+    public String toString()
+    {
+        StringBuffer sbClassId = new StringBuffer( 38);
+        sbClassId.append( '{');
+        for( int i=0; i < 16; i++) {
+            sbClassId.append( HexDump.toHex( bytes[ i]));
+            if( i == 3 || i == 5 || i == 7 || i == 9) {
+                sbClassId.append( '-');
+            }
+        }
+        sbClassId.append( '}');
+        return sbClassId.toString();
+    }
 
     /**
      * @see Object#hashCode()
index 6811a72508df686c1fa52e17af018a6b43f96dc7..c09c25619bafdc180f3ac6c448608b30dad7844c 100644 (file)
@@ -59,6 +59,8 @@ import java.io.*;
 
 import java.util.*;
 
+import org.apache.poi.hpsf.ClassID;
+
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.dev.POIFSViewable;
 import org.apache.poi.util.ByteField;
@@ -87,6 +89,8 @@ public abstract class Property
     static final private int    _previous_property_offset = 0x44;
     static final private int    _next_property_offset     = 0x48;
     static final private int    _child_property_offset    = 0x4C;
+    static final private int    _storage_clsid_offset     = 0x50;
+    static final private int    _user_flags_offset        = 0x60;
     static final private int    _seconds_1_offset         = 0x64;
     static final private int    _days_1_offset            = 0x68;
     static final private int    _seconds_2_offset         = 0x6C;
@@ -107,6 +111,8 @@ public abstract class Property
     private IntegerField        _previous_property;
     private IntegerField        _next_property;
     private IntegerField        _child_property;
+    private ClassID             _storage_clsid;
+    private IntegerField        _user_flags;
     private IntegerField        _seconds_1;
     private IntegerField        _days_1;
     private IntegerField        _seconds_2;
@@ -136,6 +142,8 @@ public abstract class Property
                                               _NO_INDEX, _raw_data);
         _child_property    = new IntegerField(_child_property_offset,
                                               _NO_INDEX, _raw_data);
+        _storage_clsid     = new ClassID(_raw_data,_storage_clsid_offset);
+        _user_flags        = new IntegerField(_user_flags_offset, 0, _raw_data);
         _seconds_1         = new IntegerField(_seconds_1_offset, 0,
                                               _raw_data);
         _days_1            = new IntegerField(_days_1_offset, 0, _raw_data);
@@ -173,6 +181,8 @@ public abstract class Property
                                               _raw_data);
         _child_property    = new IntegerField(_child_property_offset,
                                               _raw_data);
+        _storage_clsid     = new ClassID(_raw_data,_storage_clsid_offset);
+        _user_flags        = new IntegerField(_user_flags_offset, 0, _raw_data);
         _seconds_1         = new IntegerField(_seconds_1_offset, _raw_data);
         _days_1            = new IntegerField(_days_1_offset, _raw_data);
         _seconds_2         = new IntegerField(_seconds_2_offset, _raw_data);
@@ -295,12 +305,21 @@ public abstract class Property
 
     abstract public boolean isDirectory();
 
+    /**
+     * Sets the storage clsid, which is the Class ID of a COM object which
+     *   reads and writes this stream
+     * @return storage Class ID for this property stream
+     */
+    public ClassID getStorageClsid()
+    {
+        return _storage_clsid;
+    }
+
     /**
      * Set the name; silently truncates the name if it's too long.
      *
      * @param name the new name
      */
-
     protected final void setName(final String name)
     {
         char[] char_array = name.toCharArray();
@@ -327,6 +346,20 @@ public abstract class Property
                             * LittleEndianConsts.SHORT_SIZE), _raw_data);
     }
 
+    /**
+     * Sets the storage class ID for this property stream. This is the Class ID
+     *   of the COM object which can read and write this property stream
+     * @param clsidStorage Storage Class ID
+     */
+    public void setStorageClsid( ClassID clsidStorage)
+    {
+        _storage_clsid = clsidStorage;
+        if( clsidStorage == null) {
+            Arrays.fill( _raw_data, _storage_clsid_offset, _storage_clsid_offset + ClassID.LENGTH, (byte) 0);
+        } else {
+            clsidStorage.write( _raw_data, _storage_clsid_offset);
+        }
+    }
     /**
      * Set the property type. Makes no attempt to validate the value.
      *
diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestClassID.java b/src/testcases/org/apache/poi/hpsf/basic/TestClassID.java
new file mode 100644 (file)
index 0000000..c36f816
--- /dev/null
@@ -0,0 +1,171 @@
+/* ====================================================================\r
+ * The Apache Software License, Version 1.1\r
+ *\r
+ * Copyright (c) 2003 The Apache Software Foundation.  All rights\r
+ * reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ *    notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ *    notice, this list of conditions and the following disclaimer in\r
+ *    the documentation and/or other materials provided with the\r
+ *    distribution.\r
+ *\r
+ * 3. The end-user documentation included with the redistribution,\r
+ *    if any, must include the following acknowledgment:\r
+ *       "This product includes software developed by the\r
+ *        Apache Software Foundation (http://www.apache.org/)."\r
+ *    Alternately, this acknowledgment may appear in the software itself,\r
+ *    if and wherever such third-party acknowledgments normally appear.\r
+ *\r
+ * 4. The names "Apache" and "Apache Software Foundation" and\r
+ *    "Apache POI" must not be used to endorse or promote products\r
+ *    derived from this software without prior written permission. For\r
+ *    written permission, please contact apache@apache.org.\r
+ *\r
+ * 5. Products derived from this software may not be called "Apache",\r
+ *    "Apache POI", nor may "Apache" appear in their name, without\r
+ *    prior written permission of the Apache Software Foundation.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR\r
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\r
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ * ====================================================================\r
+ *\r
+ * This software consists of voluntary contributions made by many\r
+ * individuals on behalf of the Apache Software Foundation.  For more\r
+ * information on the Apache Software Foundation, please see\r
+ * <http://www.apache.org/>.\r
+ */\r
+\r
+package org.apache.poi.hpsf.basic;\r
+\r
+import junit.framework.Assert;\r
+import junit.framework.TestCase;\r
+\r
+import org.apache.poi.hpsf.ClassID;\r
+\r
+/**\r
+ * <p>Tests ClassID structure.</p>\r
+ *\r
+ * @author Michael Zalewski (zalewski@optonline.net)\r
+ */\r
+public class TestClassID extends TestCase\r
+{\r
+    /**\r
+     * <p>Constructor</p>\r
+     * \r
+     * @param name the test case's name\r
+     */\r
+    public TestClassID(final String name)\r
+    {\r
+        super(name);\r
+    }\r
+\r
+    /**\r
+     * Various tests of overridden .equals()\r
+     */\r
+    public void testEquals()\r
+    {\r
+        ClassID clsidTest1 = new ClassID(\r
+              new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08\r
+                         , 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }\r
+            , 0\r
+        );\r
+        ClassID clsidTest2 = new ClassID(\r
+              new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08\r
+                         , 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }\r
+            , 0\r
+        );\r
+        ClassID clsidTest3 = new ClassID(\r
+              new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08\r
+                         , 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11 }\r
+            , 0\r
+        );\r
+        Assert.assertEquals( clsidTest1, clsidTest1);\r
+        Assert.assertEquals( clsidTest1, clsidTest2);\r
+        Assert.assertFalse( clsidTest1.equals( clsidTest3));\r
+        Assert.assertFalse( clsidTest1.equals( null));\r
+    }\r
+    /**\r
+     * Try to write to a buffer that is too small. This should\r
+     *   throw an Exception\r
+     */\r
+    public void testWriteArrayStoreException()\r
+    {\r
+        ClassID clsidTest = new ClassID(\r
+              new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08\r
+                         , 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }\r
+            , 0\r
+        );\r
+        boolean bExceptionOccurred = false;\r
+        try {\r
+            clsidTest.write( new byte[ 15], 0);\r
+        } catch( Exception e) {\r
+            bExceptionOccurred = true;\r
+        }\r
+        Assert.assertTrue( bExceptionOccurred);\r
+\r
+        bExceptionOccurred = false;\r
+        try {\r
+            clsidTest.write( new byte[ 16], 1);\r
+        } catch( Exception e) {\r
+            bExceptionOccurred = true;\r
+        }\r
+        Assert.assertTrue( bExceptionOccurred);\r
+\r
+        // These should work without throwing an Exception\r
+        bExceptionOccurred = false;\r
+        try {\r
+            clsidTest.write( new byte[ 16], 0);\r
+            clsidTest.write( new byte[ 17], 1);\r
+        } catch( Exception e) {\r
+            bExceptionOccurred = true;\r
+        }\r
+        Assert.assertFalse( bExceptionOccurred);\r
+    }\r
+    /**\r
+     * <p>Tests the {@link PropertySet} methods. The test file has two\r
+     * property set: the first one is a {@link SummaryInformation},\r
+     * the second one is a {@link DocumentSummaryInformation}.</p>\r
+     */\r
+    public void testClassID()\r
+    {\r
+        ClassID clsidTest = new ClassID(\r
+              new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08\r
+                         , 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }\r
+            , 0\r
+        );\r
+        Assert.assertEquals( \r
+              clsidTest.toString().toUpperCase()\r
+            , "{04030201-0605-0807-090A-0B0C0D0E0F10}"\r
+        );\r
+    }\r
+\r
+\r
+\r
+    /**\r
+     * <p>Runs the test cases stand-alone.</p>\r
+     */\r
+    public static void main(final String[] args)\r
+    {\r
+        System.setProperty("HPSF.testdata.path",\r
+                           "./src/testcases/org/apache/poi/hpsf/data");\r
+        junit.textui.TestRunner.run(TestClassID.class);\r
+    }\r
+\r
+}\r
index 74a3807562be34db5cc17faa5ed2be43b7316629..e677a7983ef0dbaff652a39b31d46bf7c4421ba9 100644 (file)
@@ -150,6 +150,7 @@ public class TestDocumentProperty
             ( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
             ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
             ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
+
             ( byte ) 0x57, ( byte ) 0x00, ( byte ) 0x6F, ( byte ) 0x00,
             ( byte ) 0x72, ( byte ) 0x00, ( byte ) 0x6B, ( byte ) 0x00,
             ( byte ) 0x62, ( byte ) 0x00, ( byte ) 0x6F, ( byte ) 0x00,
@@ -182,6 +183,7 @@ public class TestDocumentProperty
             ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
             ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
             ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
+
             ( byte ) 0x05, ( byte ) 0x00, ( byte ) 0x53, ( byte ) 0x00,
             ( byte ) 0x75, ( byte ) 0x00, ( byte ) 0x6D, ( byte ) 0x00,
             ( byte ) 0x6D, ( byte ) 0x00, ( byte ) 0x61, ( byte ) 0x00,
@@ -214,6 +216,7 @@ public class TestDocumentProperty
             ( byte ) 0x08, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
             ( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
             ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
+
             ( byte ) 0x05, ( byte ) 0x00, ( byte ) 0x44, ( byte ) 0x00,
             ( byte ) 0x6F, ( byte ) 0x00, ( byte ) 0x63, ( byte ) 0x00,
             ( byte ) 0x75, ( byte ) 0x00, ( byte ) 0x6D, ( byte ) 0x00,
index 430c521479eff65a7db3da8680a11fb02440308f..8357a0a4663ec07f19a0901bf1129151f72d5390 100644 (file)
@@ -217,11 +217,11 @@ public class TestRootProperty
             ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00
         };
 
-        verifyReadingProperty(0, input, 0, "Root Entry");
+        verifyReadingProperty(0, input, 0, "Root Entry", "{00020820-0000-0000-C000-000000000046}");
     }
 
     private void verifyReadingProperty(int index, byte [] input, int offset,
-                                       String name)
+                                       String name, String sClsId)
         throws IOException
     {
         RootProperty          property = new RootProperty(index, input,
@@ -242,6 +242,7 @@ public class TestRootProperty
         assertEquals(index, property.getIndex());
         assertEquals(name, property.getName());
         assertTrue(!property.getChildren().hasNext());
+        assertEquals(property.getStorageClsid().toString(), sClsId);
     }
 
     /**