]> source.dussan.org Git - poi.git/commitdiff
In preparation for reading the HSMF __properties stream, improve the Types support...
authorNick Burch <nick@apache.org>
Sun, 8 Jul 2012 18:05:17 +0000 (18:05 +0000)
committerNick Burch <nick@apache.org>
Sun, 8 Jul 2012 18:05:17 +0000 (18:05 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1358802 13f79535-47bb-0310-9956-ffa450edef68

19 files changed:
src/documentation/content/xdocs/status.xml
src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java
src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java
src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java
src/scratchpad/src/org/apache/poi/hsmf/dev/TypesLister.java
src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java
src/scratchpad/testcases/org/apache/poi/hsmf/datatypes/TestChunkData.java
src/scratchpad/testcases/org/apache/poi/hsmf/datatypes/TestMAPIProperty.java
src/scratchpad/testcases/org/apache/poi/hsmf/datatypes/TestTypes.java

index 9d9aebd1e597df4b923593143832f084b7da19b4..1369190d9fe56748bf202f108a0e3a9b7439e0d5 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.9-beta1" date="2012-??-??">
+          <action dev="poi-developers" type="add">Change HSMF Types to have full data on ID, Name and Length, rather than just being a simple ID</action>
           <action dev="poi-developers" type="add">48469 - Updated case study</action>
           <action dev="poi-developers" type="add">53476 - Support Complex Name in formulas </action>
           <action dev="poi-developers" type="fix">53414 - properly update sheet dimensions when adding column </action>
index 31c3cbb88513fd1a5930983ece276f8988e7b83b..f4e9fab559109d09b233ebe179e2c1f4fb8bbda6 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.poi.hmef.Attachment;
 import org.apache.poi.hmef.HMEFMessage;
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
 import org.apache.poi.hsmf.datatypes.Types;
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
@@ -109,16 +110,22 @@ public class MAPIAttribute {
          // Is it either Multi-Valued or Variable-Length?
          boolean isMV = false;
          boolean isVL = false;
-         int type = typeAndMV;
+         int typeId = typeAndMV;
          if( (typeAndMV & Types.MULTIVALUED_FLAG) > 0 ) {
             isMV = true;
-            type -= Types.MULTIVALUED_FLAG;
+            typeId -= Types.MULTIVALUED_FLAG;
          }
-         if(type == Types.ASCII_STRING || type == Types.UNICODE_STRING ||
-               type == Types.BINARY || type == Types.DIRECTORY) {
+         if(typeId == Types.ASCII_STRING.getId() || typeId == Types.UNICODE_STRING.getId() ||
+               typeId == Types.BINARY.getId() || typeId == Types.DIRECTORY.getId()) {
             isVL = true;
          }
          
+         // Turn the type ID into a strongly typed thing
+         MAPIType type = Types.getById(typeId);
+         if (type == null) {
+            type = Types.createCustom(typeId);
+         }
+         
          // If it's a named property, rather than a standard
          //  MAPI property, grab the details of it
          MAPIProperty prop = MAPIProperty.get(id);
@@ -164,13 +171,13 @@ public class MAPIAttribute {
             // Create
             MAPIAttribute attr;
             if(type == Types.UNICODE_STRING || type == Types.ASCII_STRING) {
-               attr = new MAPIStringAttribute(prop, type, data);
+               attr = new MAPIStringAttribute(prop, typeId, data);
             } else if(type == Types.APP_TIME || type == Types.TIME) {
-               attr = new MAPIDateAttribute(prop, type, data);
+               attr = new MAPIDateAttribute(prop, typeId, data);
             } else if(id == MAPIProperty.RTF_COMPRESSED.id) {
-               attr = new MAPIRtfAttribute(prop, type, data);
+               attr = new MAPIRtfAttribute(prop, typeId, data);
             } else {
-               attr = new MAPIAttribute(prop, type, data);
+               attr = new MAPIAttribute(prop, typeId, data);
             }
             attrs.add(attr);
          }
@@ -179,32 +186,17 @@ public class MAPIAttribute {
       // All done
       return attrs;
    }
-   private static int getLength(int type, InputStream inp) throws IOException {
-      switch(type) {
-         case Types.NULL:
-            return 0;
-         case Types.BOOLEAN:
-         case Types.SHORT:
-            return 2;
-         case Types.LONG:
-         case Types.FLOAT:
-         case Types.ERROR:
-            return 4;
-         case Types.LONG_LONG:
-         case Types.DOUBLE:
-         case Types.APP_TIME:
-         case Types.TIME:
-         case Types.CURRENCY:
-            return 8;
-         case Types.CLS_ID:
-            return 16;
-         case Types.ASCII_STRING:
-         case Types.UNICODE_STRING:
-         case Types.DIRECTORY:
-         case Types.BINARY:
+   private static int getLength(MAPIType type, InputStream inp) throws IOException {
+      if (type.isFixedLength()) {
+         return type.getLength();
+      }
+      if (type == Types.ASCII_STRING ||
+          type == Types.UNICODE_STRING ||
+          type == Types.DIRECTORY ||
+          type == Types.BINARY) {
             // Need to read the length, as it varies
             return LittleEndian.readInt(inp);
-         default:
+      } else {
             throw new IllegalArgumentException("Unknown type " + type);
       }
    }
index d53e59c7d51e66acefd07b3265b82398b0877d71..b48651c0943c17935632ad7c1cbc227532d04b86 100644 (file)
@@ -37,13 +37,13 @@ public final class MAPIStringAttribute extends MAPIAttribute {
       super(property, type, data);
       
       String tmpData = null;
-      if(type == Types.ASCII_STRING) {
+      if(type == Types.ASCII_STRING.getId()) {
          try {
             tmpData = new String(data, CODEPAGE);
          } catch(UnsupportedEncodingException e) {
             throw new RuntimeException("JVM Broken - core encoding " + CODEPAGE + " missing");
          }
-      } else if(type == Types.UNICODE_STRING) {
+      } else if(type == Types.UNICODE_STRING.getId()) {
          tmpData = StringUtil.getFromUnicodeLE(data);
       } else {
          throw new IllegalArgumentException("Not a string type " + type);
index 7c600e70145ebbf1388c008fb60ca33f4f1e3d17..8e26b48c946d621b33f42a29c0d3d8856d91e686 100644 (file)
@@ -39,9 +39,9 @@ import org.apache.poi.hsmf.datatypes.Chunks;
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
 import org.apache.poi.hsmf.datatypes.NameIdChunks;
 import org.apache.poi.hsmf.datatypes.RecipientChunks;
-import org.apache.poi.hsmf.datatypes.Types;
 import org.apache.poi.hsmf.datatypes.RecipientChunks.RecipientChunksSorter;
 import org.apache.poi.hsmf.datatypes.StringChunk;
+import org.apache.poi.hsmf.datatypes.Types;
 import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
 import org.apache.poi.hsmf.parsers.POIFSChunkParser;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
@@ -214,7 +214,7 @@ public class MAPIMessage extends POIDocument {
       
       try {
          MAPIRtfAttribute rtf = new MAPIRtfAttribute(
-               MAPIProperty.RTF_COMPRESSED, Types.BINARY, chunk.getValue()
+               MAPIProperty.RTF_COMPRESSED, Types.BINARY.getId(), chunk.getValue()
          );
          return rtf.getDataString();
       } catch(IOException e) {
index fc84d3731b514118d7b71af94a3549478485303d..d8b26b39528353d584f3c9eb20187a29eb1433ec 100644 (file)
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
 import org.apache.poi.util.IOUtils;
 
 /**
@@ -36,14 +37,14 @@ public class ByteChunk extends Chunk {
        /**
         * Creates a Byte Chunk.
         */
-   public ByteChunk(String namePrefix, int chunkId, int type) {
+   public ByteChunk(String namePrefix, int chunkId, MAPIType type) {
       super(namePrefix, chunkId, type);
    }
        /**
         * Create a Byte Chunk, with the specified
         *  type.
         */
-       public ByteChunk(int chunkId, int type) {
+       public ByteChunk(int chunkId, MAPIType type) {
           super(chunkId, type);
        }
 
index 7fcb252c96b17444cae76072930b728824239901..a111eb32a54341a79c308942568e586ea6757381 100644 (file)
@@ -21,19 +21,21 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
+
 abstract public class Chunk {
    public static final String DEFAULT_NAME_PREFIX = "__substg1.0_";
    
        protected int chunkId;
-       protected int type;
+       protected MAPIType type;
        protected String namePrefix;
        
-   protected Chunk(String namePrefix, int chunkId, int type) {
+   protected Chunk(String namePrefix, int chunkId, MAPIType type) {
       this.namePrefix = namePrefix;
       this.chunkId = chunkId;
       this.type = type;
    }
-       protected Chunk(int chunkId, int type) {
+       protected Chunk(int chunkId, MAPIType type) {
           this(DEFAULT_NAME_PREFIX, chunkId, type);
        }
 
@@ -47,7 +49,7 @@ abstract public class Chunk {
        /**
         * Gets the numeric type of this chunk.
         */
-       public int getType() {
+       public MAPIType getType() {
                return this.type;
        }
 
@@ -55,8 +57,7 @@ abstract public class Chunk {
         * Creates a string to use to identify this chunk in the POI file system object.
         */
        public String getEntryName() {
-               String type = Integer.toHexString(this.type);
-               while(type.length() < 4) type = "0" + type;
+               String type = this.type.asFileEnding();
 
                String chunkId = Integer.toHexString(this.chunkId);
                while(chunkId.length() < 4) chunkId = "0" + chunkId;
index 156c6f2602956dc5fecfc3f81a6491fcd2b5d815..5365a632592477c48051ef638bd2656bc01b2f3c 100644 (file)
@@ -21,6 +21,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import org.apache.poi.hsmf.MAPIMessage;
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 
 /**
@@ -33,7 +34,7 @@ import org.apache.poi.poifs.filesystem.DirectoryNode;
 public class DirectoryChunk extends Chunk {
     private DirectoryNode dir;
     
-    public DirectoryChunk(DirectoryNode dir, String namePrefix, int chunkId, int type) {
+    public DirectoryChunk(DirectoryNode dir, String namePrefix, int chunkId, MAPIType type) {
         super(namePrefix, chunkId, type);
         this.dir = dir;
     }
index d5b274a498711039b40b3d7eee128fe2cc957838..2f43c6bf9e10b6fd5ad0cd8935aa9b39d685dd01 100644 (file)
@@ -20,8 +20,11 @@ package org.apache.poi.hsmf.datatypes;
 import static org.apache.poi.hsmf.datatypes.Types.ASCII_STRING;
 import static org.apache.poi.hsmf.datatypes.Types.BINARY;
 import static org.apache.poi.hsmf.datatypes.Types.BOOLEAN;
+import static org.apache.poi.hsmf.datatypes.Types.CLS_ID;
 import static org.apache.poi.hsmf.datatypes.Types.DIRECTORY;
 import static org.apache.poi.hsmf.datatypes.Types.LONG;
+import static org.apache.poi.hsmf.datatypes.Types.LONG_LONG;
+import static org.apache.poi.hsmf.datatypes.Types.SHORT;
 import static org.apache.poi.hsmf.datatypes.Types.TIME;
 
 import java.util.Collection;
@@ -29,6 +32,8 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
+
 /**
  * Holds the list of MAPI Attributes, and allows lookup
  *  by friendly name, ID and MAPI Property Name.
@@ -49,7 +54,7 @@ public class MAPIProperty {
    public static final MAPIProperty AB_PROVIDERS =
       new MAPIProperty(0x3d01, BINARY, "AbProviders", "PR_AB_PROVIDERS");
    public static final MAPIProperty AB_SEARCH_PATH =
-      new MAPIProperty(0x3d05, 4354, "AbSearchPath", "PR_AB_SEARCH_PATH");
+      new MAPIProperty(0x3d05, Types.createCustom(4354), "AbSearchPath", "PR_AB_SEARCH_PATH");
    public static final MAPIProperty AB_SEARCH_PATH_UPDATE =
       new MAPIProperty(0x3d11, BINARY, "AbSearchPathUpdate", "PR_AB_SEARCH_PATH_UPDATE");
    public static final MAPIProperty ACCESS =
@@ -75,15 +80,15 @@ public class MAPIProperty {
    public static final MAPIProperty ATTACH_ADDITIONAL_INFO =
       new MAPIProperty(0x370f, BINARY, "AttachAdditionalInfo", "PR_ATTACH_ADDITIONAL_INFO");
    public static final MAPIProperty ATTACH_CONTENT_BASE =
-      new MAPIProperty(0x3711, -1, "AttachContentBase", "PR_ATTACH_CONTENT_BASE");
+      new MAPIProperty(0x3711, Types.UNKNOWN,  "AttachContentBase", "PR_ATTACH_CONTENT_BASE");
    public static final MAPIProperty ATTACH_CONTENT_ID =
-      new MAPIProperty(0x3712, -1, "AttachContentId", "PR_ATTACH_CONTENT_ID");
+      new MAPIProperty(0x3712, Types.UNKNOWN,  "AttachContentId", "PR_ATTACH_CONTENT_ID");
    public static final MAPIProperty ATTACH_CONTENT_LOCATION =
-      new MAPIProperty(0x3713, -1, "AttachContentLocation", "PR_ATTACH_CONTENT_LOCATION");
+      new MAPIProperty(0x3713, Types.UNKNOWN,  "AttachContentLocation", "PR_ATTACH_CONTENT_LOCATION");
    public static final MAPIProperty ATTACH_DATA =
       new MAPIProperty(0x3701, BINARY, "AttachData", "PR_ATTACH_DATA_OBJ");
    public static final MAPIProperty ATTACH_DISPOSITION =
-      new MAPIProperty(0x3716, -1, "AttachDisposition", "PR_ATTACH_DISPOSITION");
+      new MAPIProperty(0x3716, Types.UNKNOWN,  "AttachDisposition", "PR_ATTACH_DISPOSITION");
    public static final MAPIProperty ATTACH_ENCODING =
       new MAPIProperty(0x3702, BINARY, "AttachEncoding", "PR_ATTACH_ENCODING");
    public static final MAPIProperty ATTACH_EXTENSION =
@@ -91,7 +96,7 @@ public class MAPIProperty {
    public static final MAPIProperty ATTACH_FILENAME =
       new MAPIProperty(0x3704, ASCII_STRING, "AttachFilename", "PR_ATTACH_FILENAME");
    public static final MAPIProperty ATTACH_FLAGS =
-      new MAPIProperty(0x3714, -1, "AttachFlags", "PR_ATTACH_FLAGS");
+      new MAPIProperty(0x3714, Types.UNKNOWN,  "AttachFlags", "PR_ATTACH_FLAGS");
    public static final MAPIProperty ATTACH_LONG_FILENAME =
       new MAPIProperty(0x3707, ASCII_STRING, "AttachLongFilename", "PR_ATTACH_LONG_FILENAME");
    public static final MAPIProperty ATTACH_LONG_PATHNAME =
@@ -99,11 +104,11 @@ public class MAPIProperty {
    public static final MAPIProperty ATTACH_METHOD =
       new MAPIProperty(0x3705, LONG, "AttachMethod", "PR_ATTACH_METHOD");
    public static final MAPIProperty ATTACH_MIME_SEQUENCE =
-      new MAPIProperty(0x3710, -1, "AttachMimeSequence", "PR_ATTACH_MIME_SEQUENCE");
+      new MAPIProperty(0x3710, Types.UNKNOWN,  "AttachMimeSequence", "PR_ATTACH_MIME_SEQUENCE");
    public static final MAPIProperty ATTACH_MIME_TAG =
       new MAPIProperty(0x370e, ASCII_STRING, "AttachMimeTag", "PR_ATTACH_MIME_TAG");
    public static final MAPIProperty ATTACH_NETSCAPE_MAC_INFO =
-      new MAPIProperty(0x3715, -1, "AttachNetscapeMacInfo", "PR_ATTACH_NETSCAPE_MAC_INFO");
+      new MAPIProperty(0x3715, Types.UNKNOWN,  "AttachNetscapeMacInfo", "PR_ATTACH_NETSCAPE_MAC_INFO");
    public static final MAPIProperty ATTACH_NUM =
       new MAPIProperty(0xe21, LONG, "AttachNum", "PR_ATTACH_NUM");
    public static final MAPIProperty ATTACH_PATHNAME =
@@ -125,19 +130,19 @@ public class MAPIProperty {
    public static final MAPIProperty AUTO_FORWARDED =
       new MAPIProperty(5, BOOLEAN, "AutoForwarded", "PR_AUTO_FORWARDED");
    public static final MAPIProperty AUTO_RESPONSE_SUPPRESS =
-      new MAPIProperty(0x3fdf, -1, "AutoResponseSuppress", "PR_AUTO_RESPONSE_SUPPRESS");
+      new MAPIProperty(0x3fdf, Types.UNKNOWN,  "AutoResponseSuppress", "PR_AUTO_RESPONSE_SUPPRESS");
    public static final MAPIProperty BIRTHDAY =
       new MAPIProperty(0x3a42, TIME, "Birthday", "PR_BIRTHDAY");
    public static final MAPIProperty BODY =
       new MAPIProperty(0x1000, ASCII_STRING, "Body", "PR_BODY");
    public static final MAPIProperty BODY_CONTENT_ID =
-      new MAPIProperty(0x1015, -1, "BodyContentId", "PR_BODY_CONTENT_ID");
+      new MAPIProperty(0x1015, Types.UNKNOWN,  "BodyContentId", "PR_BODY_CONTENT_ID");
    public static final MAPIProperty BODY_CONTENT_LOCATION =
-      new MAPIProperty(0x1014, -1, "BodyContentLocation", "PR_BODY_CONTENT_LOCATION");
+      new MAPIProperty(0x1014, Types.UNKNOWN,  "BodyContentLocation", "PR_BODY_CONTENT_LOCATION");
    public static final MAPIProperty BODY_CRC =
       new MAPIProperty(0xe1c, LONG, "BodyCrc", "PR_BODY_CRC");
    public static final MAPIProperty BODY_HTML =
-      new MAPIProperty(0x1013, -1, "BodyHtml", "data");
+      new MAPIProperty(0x1013, Types.UNKNOWN,  "BodyHtml", "data");
    public static final MAPIProperty BUSINESS_FAX_NUMBER =
       new MAPIProperty(0x3a24, ASCII_STRING, "BusinessFaxNumber", "PR_BUSINESS_FAX_NUMBER");
    public static final MAPIProperty BUSINESS_HOME_PAGE =
@@ -147,7 +152,7 @@ public class MAPIProperty {
    public static final MAPIProperty CAR_TELEPHONE_NUMBER =
       new MAPIProperty(0x3a1e, ASCII_STRING, "CarTelephoneNumber", "PR_CAR_TELEPHONE_NUMBER");
    public static final MAPIProperty CHILDRENS_NAMES =
-      new MAPIProperty(0x3a58, 4126, "ChildrensNames", "PR_CHILDRENS_NAMES");
+      new MAPIProperty(0x3a58, Types.createCustom(4126), "ChildrensNames", "PR_CHILDRENS_NAMES");
    public static final MAPIProperty CLIENT_SUBMIT_TIME =
       new MAPIProperty(0x39, TIME, "ClientSubmitTime", "PR_CLIENT_SUBMIT_TIME");
    public static final MAPIProperty COMMENT =
@@ -161,15 +166,15 @@ public class MAPIProperty {
    public static final MAPIProperty COMPUTER_NETWORK_NAME =
       new MAPIProperty(0x3a49, ASCII_STRING, "ComputerNetworkName", "PR_COMPUTER_NETWORK_NAME");
    public static final MAPIProperty CONTACT_ADDRTYPES =
-      new MAPIProperty(0x3a54, 4126, "ContactAddrtypes", "PR_CONTACT_ADDRTYPES");
+      new MAPIProperty(0x3a54, Types.createCustom(4126), "ContactAddrtypes", "PR_CONTACT_ADDRTYPES");
    public static final MAPIProperty CONTACT_DEFAULT_ADDRESS_INDEX =
       new MAPIProperty(0x3a55, LONG, "ContactDefaultAddressIndex", "PR_CONTACT_DEFAULT_ADDRESS_INDEX");
    public static final MAPIProperty CONTACT_EMAIL_ADDRESSES =
-      new MAPIProperty(0x3a56, 4126, "ContactEmailAddresses", "PR_CONTACT_EMAIL_ADDRESSES");
+      new MAPIProperty(0x3a56, Types.createCustom(4126), "ContactEmailAddresses", "PR_CONTACT_EMAIL_ADDRESSES");
    public static final MAPIProperty CONTACT_ENTRY_IDS =
-      new MAPIProperty(0x3a53, 4354, "ContactEntryIds", "PR_CONTACT_ENTRYIDS");
+      new MAPIProperty(0x3a53, Types.createCustom(4354), "ContactEntryIds", "PR_CONTACT_ENTRYIDS");
    public static final MAPIProperty CONTACT_VERSION =
-      new MAPIProperty(0x3a52, 72, "ContactVersion", "PR_CONTACT_VERSION");
+      new MAPIProperty(0x3a52, CLS_ID, "ContactVersion", "PR_CONTACT_VERSION");
    public static final MAPIProperty CONTAINER_CLASS =
       new MAPIProperty(0x3613, ASCII_STRING, "ContainerClass", "PR_CONTAINER_CLASS");
    public static final MAPIProperty CONTAINER_CONTENTS =
@@ -179,7 +184,7 @@ public class MAPIProperty {
    public static final MAPIProperty CONTAINER_HIERARCHY =
       new MAPIProperty(0x360e, DIRECTORY, "ContainerHierarchy", "PR_CONTAINER_HIERARCHY");
    public static final MAPIProperty CONTAINER_MODIFY_VERSION =
-      new MAPIProperty(0x3614, 20, "ContainerModifyVersion", "PR_CONTAINER_MODIFY_VERSION");
+      new MAPIProperty(0x3614, LONG_LONG, "ContainerModifyVersion", "PR_CONTAINER_MODIFY_VERSION");
    public static final MAPIProperty CONTENT_CONFIDENTIALITY_ALGORITHM_ID =
       new MAPIProperty(6, BINARY, "ContentConfidentialityAlgorithmId", "PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID");
    public static final MAPIProperty CONTENT_CORRELATOR =
@@ -197,7 +202,7 @@ public class MAPIProperty {
    public static final MAPIProperty CONTENT_UNREAD =
       new MAPIProperty(0x3603, LONG, "ContentUnread", "PR_CONTENT_UNREAD");
    public static final MAPIProperty CONTENTS_SORT_ORDER =
-      new MAPIProperty(0x360d, 4099, "ContentsSortOrder", "PR_CONTENTS_SORT_ORDER");
+      new MAPIProperty(0x360d, Types.createCustom(4099), "ContentsSortOrder", "PR_CONTENTS_SORT_ORDER");
    public static final MAPIProperty CONTROL_FLAGS =
       new MAPIProperty(0x3f00, LONG, "ControlFlags", "PR_CONTROL_FLAGS");
    public static final MAPIProperty CONTROL_ID =
@@ -231,9 +236,9 @@ public class MAPIProperty {
    public static final MAPIProperty CREATION_TIME =
       new MAPIProperty(0x3007, TIME, "CreationTime", "PR_CREATION_TIME");
    public static final MAPIProperty CREATION_VERSION =
-      new MAPIProperty(0xe19, 20, "CreationVersion", "PR_CREATION_VERSION");
+      new MAPIProperty(0xe19, LONG_LONG, "CreationVersion", "PR_CREATION_VERSION");
    public static final MAPIProperty CURRENT_VERSION =
-      new MAPIProperty(0xe00, 20, "CurrentVersion", "PR_CURRENT_VERSION");
+      new MAPIProperty(0xe00, LONG_LONG, "CurrentVersion", "PR_CURRENT_VERSION");
    public static final MAPIProperty CUSTOMER_ID =
       new MAPIProperty(0x3a4a, ASCII_STRING, "CustomerId", "PR_CUSTOMER_ID");
    public static final MAPIProperty DEF_CREATE_DL =
@@ -299,13 +304,13 @@ public class MAPIProperty {
    public static final MAPIProperty ENTRY_ID =
       new MAPIProperty(0xfff, BINARY, "EntryId", "PR_ENTRYID");
    public static final MAPIProperty EXPAND_BEGIN_TIME =
-      new MAPIProperty(0x3618, -1, "ExpandBeginTime", "PR_EXPAND_BEGIN_TIME");
+      new MAPIProperty(0x3618, Types.UNKNOWN,  "ExpandBeginTime", "PR_EXPAND_BEGIN_TIME");
    public static final MAPIProperty EXPAND_END_TIME =
-      new MAPIProperty(0x3619, -1, "ExpandEndTime", "PR_EXPAND_END_TIME");
+      new MAPIProperty(0x3619, Types.UNKNOWN,  "ExpandEndTime", "PR_EXPAND_END_TIME");
    public static final MAPIProperty EXPANDED_BEGIN_TIME =
-      new MAPIProperty(0x361a, -1, "ExpandedBeginTime", "PR_EXPANDED_BEGIN_TIME");
+      new MAPIProperty(0x361a, Types.UNKNOWN,  "ExpandedBeginTime", "PR_EXPANDED_BEGIN_TIME");
    public static final MAPIProperty EXPANDED_END_TIME =
-      new MAPIProperty(0x361b, -1, "ExpandedEndTime", "PR_EXPANDED_END_TIME");
+      new MAPIProperty(0x361b, Types.UNKNOWN,  "ExpandedEndTime", "PR_EXPANDED_END_TIME");
    public static final MAPIProperty EXPIRY_TIME =
       new MAPIProperty(0x15, TIME, "ExpiryTime", "PR_EXPIRY_TIME");
    public static final MAPIProperty EXPLICIT_CONVERSION =
@@ -323,17 +328,17 @@ public class MAPIProperty {
    public static final MAPIProperty FORM_CATEGORY_SUB =
       new MAPIProperty(0x3305, ASCII_STRING, "FormCategorySub", "PR_FORM_CATEGORY_SUB");
    public static final MAPIProperty FORM_CLSID =
-      new MAPIProperty(0x3302, 72, "FormClsid", "PR_FORM_ClsID");
+      new MAPIProperty(0x3302, CLS_ID, "FormClsid", "PR_FORM_ClsID");
    public static final MAPIProperty FORM_CONTACT_NAME =
       new MAPIProperty(0x3303, ASCII_STRING, "FormContactName", "PR_FORM_CONTACT_NAME");
    public static final MAPIProperty FORM_DESIGNER_GUID =
-      new MAPIProperty(0x3309, 72, "FormDesignerGuid", "PR_FORM_DESIGNER_GUID");
+      new MAPIProperty(0x3309, CLS_ID, "FormDesignerGuid", "PR_FORM_DESIGNER_GUID");
    public static final MAPIProperty FORM_DESIGNER_NAME =
       new MAPIProperty(0x3308, ASCII_STRING, "FormDesignerName", "PR_FORM_DESIGNER_NAME");
    public static final MAPIProperty FORM_HIDDEN =
       new MAPIProperty(0x3307, BOOLEAN, "FormHidden", "PR_FORM_HIDDEN");
    public static final MAPIProperty FORM_HOST_MAP =
-      new MAPIProperty(0x3306, 4099, "FormHostMap", "PR_FORM_HOST_MAP");
+      new MAPIProperty(0x3306, Types.createCustom(4099), "FormHostMap", "PR_FORM_HOST_MAP");
    public static final MAPIProperty FORM_MESSAGE_BEHAVIOR =
       new MAPIProperty(0x330a, LONG, "FormMessageBehavior", "PR_FORM_MESSAGE_BEHAVIOR");
    public static final MAPIProperty FORM_VERSION =
@@ -341,7 +346,7 @@ public class MAPIProperty {
    public static final MAPIProperty FTP_SITE =
       new MAPIProperty(0x3a4c, ASCII_STRING, "FtpSite", "PR_FTP_SITE");
    public static final MAPIProperty GENDER =
-      new MAPIProperty(0x3a4d, 2, "Gender", "PR_GENDER");
+      new MAPIProperty(0x3a4d, SHORT, "Gender", "PR_GENDER");
    public static final MAPIProperty GENERATION =
       new MAPIProperty(0x3a05, ASCII_STRING, "Generation", "PR_GENERATION");
    public static final MAPIProperty GIVEN_NAME =
@@ -373,9 +378,9 @@ public class MAPIProperty {
    public static final MAPIProperty HOME_TELEPHONE_NUMBER =
       new MAPIProperty(0x3a09, ASCII_STRING, "HomeTelephoneNumber", "PR_HOME_TELEPHONE_NUMBER");
    public static final MAPIProperty INET_MAIL_OVERRIDE_CHARSET =
-      new MAPIProperty(0x5903, -1, "INetMailOverrideCharset", "Charset");
+      new MAPIProperty(0x5903, Types.UNKNOWN,  "INetMailOverrideCharset", "Charset");
    public static final MAPIProperty INET_MAIL_OVERRIDE_FORMAT =
-      new MAPIProperty(0x5902, -1, "INetMailOverrideFormat", "Format");
+      new MAPIProperty(0x5902, Types.UNKNOWN,  "INetMailOverrideFormat", "Format");
    public static final MAPIProperty ICON =
       new MAPIProperty(0xffd, BINARY, "Icon", "PR_ICON");
    public static final MAPIProperty IDENTITY_DISPLAY =
@@ -389,7 +394,7 @@ public class MAPIProperty {
    public static final MAPIProperty IMPORTANCE =
       new MAPIProperty(0x17, LONG, "Importance", "PR_IMPORTANCE");
    public static final MAPIProperty IN_REPLY_TO_ID =
-      new MAPIProperty(0x1042, -1, "InReplyToId", "PR_IN_REPLY_TO_ID");
+      new MAPIProperty(0x1042, Types.UNKNOWN,  "InReplyToId", "PR_IN_REPLY_TO_ID");
    public static final MAPIProperty INCOMPLETE_COPY =
       new MAPIProperty(0x35, BOOLEAN, "IncompleteCopy", "PR_INCOMPLETE_COPY");
    public static final MAPIProperty INITIAL_DETAILS_PANE =
@@ -403,7 +408,7 @@ public class MAPIProperty {
    public static final MAPIProperty INTERNET_ARTICLE_NUMBER =
       new MAPIProperty(0xe23, LONG, "InternetArticleNumber", "PR_INTERNET_ARTICLE_NUMBER");
    public static final MAPIProperty INTERNET_CPID =
-      new MAPIProperty(0x3fde, -1, "InternetCPID", "PR_INTERNET_CPID");
+      new MAPIProperty(0x3fde, Types.UNKNOWN,  "InternetCPID", "PR_INTERNET_CPID");
    public static final MAPIProperty INTERNET_CONTROL =
       new MAPIProperty(0x1031, ASCII_STRING, "InternetControl", "PR_INTERNET_CONTROL");
    public static final MAPIProperty INTERNET_DISTRIBUTION =
@@ -457,39 +462,39 @@ public class MAPIProperty {
    public static final MAPIProperty LATEST_DELIVERY_TIME =
       new MAPIProperty(0x19, TIME, "LatestDeliveryTime", "PR_LATEST_DELIVERY_TIME");
    public static final MAPIProperty LIST_HELP =
-      new MAPIProperty(0x1043, -1, "ListHelp", "PR_LIST_HELP");
+      new MAPIProperty(0x1043, Types.UNKNOWN,  "ListHelp", "PR_LIST_HELP");
    public static final MAPIProperty LIST_SUBSCRIBE =
-      new MAPIProperty(0x1044, -1, "ListSubscribe", "PR_LIST_SUBSCRIBE");
+      new MAPIProperty(0x1044, Types.UNKNOWN,  "ListSubscribe", "PR_LIST_SUBSCRIBE");
    public static final MAPIProperty LIST_UNSUBSCRIBE =
-      new MAPIProperty(0x1045, -1, "ListUnsubscribe", "PR_LIST_UNSUBSCRIBE");
+      new MAPIProperty(0x1045, Types.UNKNOWN,  "ListUnsubscribe", "PR_LIST_UNSUBSCRIBE");
    public static final MAPIProperty LOCALITY =
       new MAPIProperty(0x3a27, ASCII_STRING, "Locality", "PR_LOCALITY");
    public static final MAPIProperty LOCALLY_DELIVERED =
-      new MAPIProperty(0x6745, -1, "LocallyDelivered", "ptagLocallyDelivered");
+      new MAPIProperty(0x6745, Types.UNKNOWN,  "LocallyDelivered", "ptagLocallyDelivered");
    public static final MAPIProperty LOCATION =
       new MAPIProperty(0x3a0d, ASCII_STRING, "Location", "PR_LOCATION");
    public static final MAPIProperty LOCK_BRANCH_ID =
-      new MAPIProperty(0x3800, -1, "LockBranchId", "PR_LOCK_BRANCH_ID");
+      new MAPIProperty(0x3800, Types.UNKNOWN,  "LockBranchId", "PR_LOCK_BRANCH_ID");
    public static final MAPIProperty LOCK_DEPTH =
-      new MAPIProperty(0x3808, -1, "LockDepth", "PR_LOCK_DEPTH");
+      new MAPIProperty(0x3808, Types.UNKNOWN,  "LockDepth", "PR_LOCK_DEPTH");
    public static final MAPIProperty LOCK_ENLISTMENT_CONTEXT =
-      new MAPIProperty(0x3804, -1, "LockEnlistmentContext", "PR_LOCK_ENLISTMENT_CONTEXT");
+      new MAPIProperty(0x3804, Types.UNKNOWN,  "LockEnlistmentContext", "PR_LOCK_ENLISTMENT_CONTEXT");
    public static final MAPIProperty LOCK_EXPIRY_TIME =
-      new MAPIProperty(0x380a, -1, "LockExpiryTime", "PR_LOCK_EXPIRY_TIME");
+      new MAPIProperty(0x380a, Types.UNKNOWN,  "LockExpiryTime", "PR_LOCK_EXPIRY_TIME");
    public static final MAPIProperty LOCK_PERSISTENT =
-      new MAPIProperty(0x3807, -1, "LockPersistent", "PR_LOCK_PERSISTENT");
+      new MAPIProperty(0x3807, Types.UNKNOWN,  "LockPersistent", "PR_LOCK_PERSISTENT");
    public static final MAPIProperty LOCK_RESOURCE_DID =
-      new MAPIProperty(0x3802, -1, "LockResourceDid", "PR_LOCK_RESOURCE_DID");
+      new MAPIProperty(0x3802, Types.UNKNOWN,  "LockResourceDid", "PR_LOCK_RESOURCE_DID");
    public static final MAPIProperty LOCK_RESOURCE_FID =
-      new MAPIProperty(0x3801, -1, "LockResourceFid", "PR_LOCK_RESOURCE_FID");
+      new MAPIProperty(0x3801, Types.UNKNOWN,  "LockResourceFid", "PR_LOCK_RESOURCE_FID");
    public static final MAPIProperty LOCK_RESOURCE_MID =
-      new MAPIProperty(0x3803, -1, "LockResourceMid", "PR_LOCK_RESOURCE_MID");
+      new MAPIProperty(0x3803, Types.UNKNOWN,  "LockResourceMid", "PR_LOCK_RESOURCE_MID");
    public static final MAPIProperty LOCK_SCOPE =
-      new MAPIProperty(0x3806, -1, "LockScope", "PR_LOCK_SCOPE");
+      new MAPIProperty(0x3806, Types.UNKNOWN,  "LockScope", "PR_LOCK_SCOPE");
    public static final MAPIProperty LOCK_TIMEOUT =
-      new MAPIProperty(0x3809, -1, "LockTimeout", "PR_LOCK_TIMEOUT");
+      new MAPIProperty(0x3809, Types.UNKNOWN,  "LockTimeout", "PR_LOCK_TIMEOUT");
    public static final MAPIProperty LOCK_TYPE =
-      new MAPIProperty(0x3805, -1, "LockType", "PR_LOCK_TYPE");
+      new MAPIProperty(0x3805, Types.UNKNOWN,  "LockType", "PR_LOCK_TYPE");
    public static final MAPIProperty MAIL_PERMISSION =
       new MAPIProperty(0x3a0e, BOOLEAN, "MailPermission", "PR_MAIL_PERMISSION");
    public static final MAPIProperty MANAGER_NAME =
@@ -505,7 +510,7 @@ public class MAPIProperty {
    public static final MAPIProperty MESSAGE_CLASS =
       new MAPIProperty(0x1a, ASCII_STRING, "MessageClass", "PR_MESSAGE_CLASS");
    public static final MAPIProperty MESSAGE_CODEPAGE =
-      new MAPIProperty(0x3ffd, -1, "MessageCodepage", "PR_MESSAGE_CODEPAGE");
+      new MAPIProperty(0x3ffd, Types.UNKNOWN,  "MessageCodepage", "PR_MESSAGE_CODEPAGE");
    public static final MAPIProperty MESSAGE_DELIVERY_ID =
       new MAPIProperty(0x1b, BINARY, "MessageDeliveryId", "PR_MESSAGE_DELIVERY_ID");
    public static final MAPIProperty MESSAGE_DELIVERY_TIME =
@@ -537,7 +542,7 @@ public class MAPIProperty {
    public static final MAPIProperty MOBILE_TELEPHONE_NUMBER =
       new MAPIProperty(0x3a1c, ASCII_STRING, "MobileTelephoneNumber", "PR_MOBILE_TELEPHONE_NUMBER");
    public static final MAPIProperty MODIFY_VERSION =
-      new MAPIProperty(0xe1a, 20, "ModifyVersion", "PR_MODIFY_VERSION");
+      new MAPIProperty(0xe1a, LONG_LONG, "ModifyVersion", "PR_MODIFY_VERSION");
    public static final MAPIProperty MSG_STATUS =
       new MAPIProperty(0xe17, LONG, "MsgStatus", "PR_MSG_STATUS");
    public static final MAPIProperty NDR_DIAG_CODE =
@@ -545,7 +550,7 @@ public class MAPIProperty {
    public static final MAPIProperty NDR_REASON_CODE =
       new MAPIProperty(0xc04, LONG, "NdrReasonCode", "PR_NDR_REASON_CODE");
    public static final MAPIProperty NDR_STATUS_CODE =
-      new MAPIProperty(0xc20, -1, "NdrStatusCode", "PR_NDR_STATUS_CODE");
+      new MAPIProperty(0xc20, Types.UNKNOWN,  "NdrStatusCode", "PR_NDR_STATUS_CODE");
    public static final MAPIProperty NEWSGROUP_NAME =
       new MAPIProperty(0xe24, ASCII_STRING, "NewsgroupName", "PR_NEWSGROUP_NAME");
    public static final MAPIProperty NICKNAME =
@@ -559,7 +564,7 @@ public class MAPIProperty {
    public static final MAPIProperty NORMALIZED_SUBJECT =
       new MAPIProperty(0xe1d, ASCII_STRING, "NormalizedSubject", "PR_NORMALIZED_SUBJECT");
    public static final MAPIProperty NT_SECURITY_DESCRIPTOR =
-      new MAPIProperty(0xe27, -1, "NtSecurityDescriptor", "PR_NT_SECURITY_DESCRIPTOR");
+      new MAPIProperty(0xe27, Types.UNKNOWN,  "NtSecurityDescriptor", "PR_NT_SECURITY_DESCRIPTOR");
    public static final MAPIProperty NULL =
       new MAPIProperty(1, LONG, "Null", "PR_NULL");
    public static final MAPIProperty OBJECT_TYPE =
@@ -573,11 +578,11 @@ public class MAPIProperty {
    public static final MAPIProperty OFFICE_TELEPHONE_NUMBER =
       new MAPIProperty(0x3a08, ASCII_STRING, "OfficeTelephoneNumber", "PR_OFFICE_TELEPHONE_NUMBER");
    public static final MAPIProperty OOF_REPLY_TYPE =
-      new MAPIProperty(0x4080, -1, "OofReplyType", "PR_OOF_REPLY_TYPE");
+      new MAPIProperty(0x4080, Types.UNKNOWN,  "OofReplyType", "PR_OOF_REPLY_TYPE");
    public static final MAPIProperty ORGANIZATIONAL_ID_NUMBER =
       new MAPIProperty(0x3a10, ASCII_STRING, "OrganizationalIdNumber", "PR_ORGANIZATIONAL_ID_NUMBER");
    public static final MAPIProperty ORIG_ENTRY_ID =
-      new MAPIProperty(0x300f, -1, "OrigEntryId", "PR_ORIG_ENTRYID");
+      new MAPIProperty(0x300f, Types.UNKNOWN,  "OrigEntryId", "PR_ORIG_ENTRYID");
    public static final MAPIProperty ORIG_MESSAGE_CLASS =
       new MAPIProperty(0x4b, ASCII_STRING, "OrigMessageClass", "PR_ORIG_MESSAGE_CLASS");
    public static final MAPIProperty ORIGIN_CHECK =
@@ -737,9 +742,9 @@ public class MAPIProperty {
    public static final MAPIProperty PROOF_OF_SUBMISSION_REQUESTED =
       new MAPIProperty(40, BOOLEAN, "ProofOfSubmissionRequested", "PR_PROOF_OF_SUBMISSION_REQUESTED");
    public static final MAPIProperty PROP_ID_SECURE_MAX =
-      new MAPIProperty(0x67ff, -1, "PropIdSecureMax", "PROP_ID_SECURE_MAX");
+      new MAPIProperty(0x67ff, Types.UNKNOWN,  "PropIdSecureMax", "PROP_ID_SECURE_MAX");
    public static final MAPIProperty PROP_ID_SECURE_MIN =
-      new MAPIProperty(0x67f0, -1, "PropIdSecureMin", "PROP_ID_SECURE_MIN");
+      new MAPIProperty(0x67f0, Types.UNKNOWN,  "PropIdSecureMin", "PROP_ID_SECURE_MIN");
    public static final MAPIProperty PROVIDER_DISPLAY =
       new MAPIProperty(0x3006, ASCII_STRING, "ProviderDisplay", "PR_PROVIDER_DISPLAY");
    public static final MAPIProperty PROVIDER_DLL_NAME =
@@ -751,7 +756,7 @@ public class MAPIProperty {
    public static final MAPIProperty PROVIDER_UID =
       new MAPIProperty(0x300c, BINARY, "ProviderUid", "PR_PROVIDER_UID");
    public static final MAPIProperty PUID =
-      new MAPIProperty(0x300e, -1, "Puid", "PR_PUID");
+      new MAPIProperty(0x300e, Types.UNKNOWN, "Puid", "PR_PUID");
    public static final MAPIProperty RADIO_TELEPHONE_NUMBER =
       new MAPIProperty(0x3a1d, ASCII_STRING, "RadioTelephoneNumber", "PR_RADIO_TELEPHONE_NUMBER");
    public static final MAPIProperty RCVD_REPRESENTING_ADDRTYPE =
@@ -783,11 +788,11 @@ public class MAPIProperty {
    public static final MAPIProperty RECEIVED_BY_NAME =
       new MAPIProperty(0x40, ASCII_STRING, "ReceivedByName", "PR_RECEIVED_BY_NAME");
    public static final MAPIProperty RECIPIENT_DISPLAY_NAME =
-      new MAPIProperty(0x5ff6, -1, "RecipientDisplayName", null);
+      new MAPIProperty(0x5ff6, Types.UNKNOWN, "RecipientDisplayName", null);
    public static final MAPIProperty RECIPIENT_ENTRY_ID =
-      new MAPIProperty(0x5ff7, -1, "RecipientEntryId", null);
+      new MAPIProperty(0x5ff7, Types.UNKNOWN, "RecipientEntryId", null);
    public static final MAPIProperty RECIPIENT_FLAGS =
-      new MAPIProperty(0x5ffd, -1, "RecipientFlags", null);
+      new MAPIProperty(0x5ffd, Types.UNKNOWN, "RecipientFlags", null);
    public static final MAPIProperty RECEIVED_BY_SEARCH_KEY =
       new MAPIProperty(0x51, BINARY, "ReceivedBySearchKey", "PR_RECEIVED_BY_SEARCH_KEY");
    public static final MAPIProperty RECIPIENT_CERTIFICATE =
@@ -887,7 +892,7 @@ public class MAPIProperty {
    public static final MAPIProperty SEND_INTERNET_ENCODING =
       new MAPIProperty(0x3a71, LONG, "SendInternetEncoding", "PR_SEND_INTERNET_ENCODING");
    public static final MAPIProperty SEND_RECALL_REPORT =
-      new MAPIProperty(0x6803, -1, "SendRecallReport", "messages");
+      new MAPIProperty(0x6803, Types.UNKNOWN, "SendRecallReport", "messages");
    public static final MAPIProperty SEND_RICH_INFO =
       new MAPIProperty(0x3a40, BOOLEAN, "SendRichInfo", "PR_SEND_RICH_INFO");
    public static final MAPIProperty SENDER_ADDRTYPE =
@@ -915,7 +920,7 @@ public class MAPIProperty {
    public static final MAPIProperty SENTMAIL_ENTRY_ID =
       new MAPIProperty(0xe0a, BINARY, "SentmailEntryId", "PR_SENTMAIL_ENTRYID");
    public static final MAPIProperty SERVICE_DELETE_FILES =
-      new MAPIProperty(0x3d10, 4126, "ServiceDeleteFiles", "PR_SERVICE_DELETE_FILES");
+      new MAPIProperty(0x3d10, Types.createCustom(4126), "ServiceDeleteFiles", "PR_SERVICE_DELETE_FILES");
    public static final MAPIProperty SERVICE_DLL_NAME =
       new MAPIProperty(0x3d0a, ASCII_STRING, "ServiceDllName", "PR_SERVICE_DLL_NAME");
    public static final MAPIProperty SERVICE_ENTRY_NAME =
@@ -925,7 +930,7 @@ public class MAPIProperty {
    public static final MAPIProperty SERVICE_NAME =
       new MAPIProperty(0x3d09, ASCII_STRING, "ServiceName", "PR_SERVICE_NAME");
    public static final MAPIProperty SERVICE_SUPPORT_FILES =
-      new MAPIProperty(0x3d0f, 4126, "ServiceSupportFiles", "PR_SERVICE_SUPPORT_FILES");
+      new MAPIProperty(0x3d0f, Types.createCustom(4126), "ServiceSupportFiles", "PR_SERVICE_SUPPORT_FILES");
    public static final MAPIProperty SERVICE_UID =
       new MAPIProperty(0x3d0c, BINARY, "ServiceUid", "PR_SERVICE_UID");
    public static final MAPIProperty SERVICES =
@@ -933,7 +938,7 @@ public class MAPIProperty {
    public static final MAPIProperty SEVEN_BIT_DISPLAY_NAME =
       new MAPIProperty(0x39ff, ASCII_STRING, "SevenBitDisplayName", "PR_SEVEN_BIT_DISPLAY_NAME");
    public static final MAPIProperty SMTP_ADDRESS =
-      new MAPIProperty(0x39fe, -1, "SmtpAddress", "PR_SMTP_ADDRESS");
+      new MAPIProperty(0x39fe, Types.UNKNOWN, "SmtpAddress", "PR_SMTP_ADDRESS");
    public static final MAPIProperty SPOOLER_STATUS =
       new MAPIProperty(0xe10, LONG, "SpoolerStatus", "PR_SPOOLER_STATUS");
    public static final MAPIProperty SPOUSE_NAME =
@@ -1001,7 +1006,7 @@ public class MAPIProperty {
    public static final MAPIProperty USER_CERTIFICATE =
       new MAPIProperty(0x3a22, BINARY, "UserCertificate", "PR_USER_CERTIFICATE");
    public static final MAPIProperty USER_X509_CERTIFICATE =
-      new MAPIProperty(0x3a70, 4354, "UserX509Certificate", "PR_USER_X509_CERTIFICATE");
+      new MAPIProperty(0x3a70, Types.createCustom(4354), "UserX509Certificate", "PR_USER_X509_CERTIFICATE");
    public static final MAPIProperty VALID_FOLDER_MASK =
       new MAPIProperty(0x35df, LONG, "ValidFolderMask", "PR_VALID_FOLDER_MASK");
    public static final MAPIProperty VIEWS_ENTRY_ID =
@@ -1018,7 +1023,7 @@ public class MAPIProperty {
       new MAPIProperty(0x3f06, LONG, "Ypos", "PR_YPOS");
    
    public static final MAPIProperty UNKNOWN =
-      new MAPIProperty(-1, -1, "Unknown", null);
+      new MAPIProperty(-1, Types.UNKNOWN, "Unknown", null);
    
    // 0x8??? ones are outlook specific, and not standard MAPI
    private static final int ID_FIRST_CUSTOM = 0x8000;
@@ -1027,11 +1032,11 @@ public class MAPIProperty {
    /* ---------------------------------------------------------------------  */
    
    public final int id;
-   public final int usualType;
+   public final MAPIType usualType;
    public final String name;
    public final String mapiProperty;
    
-   private MAPIProperty(int id, int usualType, String name, String mapiProperty) {
+   private MAPIProperty(int id, MAPIType usualType, String name, String mapiProperty) {
       this.id = id;
       this.usualType = usualType;
       this.name = name;
@@ -1077,12 +1082,12 @@ public class MAPIProperty {
       return Collections.unmodifiableCollection( attributes.values() );
    }
    
-   public static MAPIProperty createCustom(int id, int type, String name) {
+   public static MAPIProperty createCustom(int id, MAPIType type, String name) {
       return new CustomMAPIProperty(id, type, name, null);
    }
    
    private static class CustomMAPIProperty extends MAPIProperty {
-      private CustomMAPIProperty(int id, int usualType, String name, String mapiProperty) {
+      private CustomMAPIProperty(int id, MAPIType usualType, String name, String mapiProperty) {
          super(id, usualType, name, mapiProperty);
       }
    }
index 902549c1f0327a9971d42d2c5496f37881d5c9f4..397717c7fabb195999aa1483326a8728e6d41b70 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Calendar;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
 import org.apache.poi.util.IOUtils;
 
 /**
@@ -44,7 +45,7 @@ public class MessageSubmissionChunk extends Chunk {
        /**
         * Creates a Byte Chunk.
         */
-       public MessageSubmissionChunk(String namePrefix, int chunkId, int type) {
+       public MessageSubmissionChunk(String namePrefix, int chunkId, MAPIType type) {
                super(namePrefix, chunkId, type);
        }
        
@@ -52,7 +53,7 @@ public class MessageSubmissionChunk extends Chunk {
         * Create a Byte Chunk, with the specified
         *  type.
         */
-       public MessageSubmissionChunk(int chunkId, int type) {
+       public MessageSubmissionChunk(int chunkId, MAPIType type) {
           super(chunkId, type);
        }
 
diff --git a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java
new file mode 100644 (file)
index 0000000..846c3d2
--- /dev/null
@@ -0,0 +1,50 @@
+/* ====================================================================
+   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.hsmf.datatypes;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * A Chunk which holds fixed-length properties, and pointer
+ *  to the variable length ones (which get their own chunk)
+ */
+public class PropertiesChunk extends Chunk {
+   public static final String PREFIX = "__properties_version1.0";
+
+       /**
+        * Creates a Properties Chunk.
+        */
+       public PropertiesChunk() {
+               super(PREFIX, -1, Types.UNKNOWN);
+       }
+
+       @Override
+   public String getEntryName() {
+          return PREFIX;
+   }
+
+   public void readValue(InputStream value) throws IOException {
+      // TODO
+       }
+       
+       public void writeValue(OutputStream out) throws IOException {
+          // TODO
+       }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java b/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertyValue.java
new file mode 100644 (file)
index 0000000..42c3887
--- /dev/null
@@ -0,0 +1,31 @@
+/* ====================================================================
+   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.hsmf.datatypes;
+
+/**
+ * An instance of a {@link MAPIProperty} inside a {@link PropertiesChunk}.
+ * Where the {@link Types} type is a fixed length one, this will contain the
+ *  actual value.
+ * Where the {@link Types} type is a variable length one, this will contain
+ *  the length of the property, and the value will be in the associated {@link Chunk}.
+ */
+public class PropertyValue {
+   private MAPIProperty property;
+   private long flags;
+   private byte[] data;
+}
index 133389bbcc7a3f4e98410eae16cbbc0d72d84ba1..f45989a7ea8784f0aef9d9e52a4822453556ac9f 100644 (file)
@@ -23,6 +23,7 @@ import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 
 import org.apache.poi.hsmf.datatypes.Types;
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.StringUtil;
 
@@ -38,7 +39,7 @@ public class StringChunk extends Chunk {
        /**
         * Creates a String Chunk.
         */
-       public StringChunk(String namePrefix, int chunkId, int type) {
+       public StringChunk(String namePrefix, int chunkId, MAPIType type) {
                super(namePrefix, chunkId, type);
        }
        
@@ -46,7 +47,7 @@ public class StringChunk extends Chunk {
         * Create a String Chunk, with the specified
         *  type.
         */
-       public StringChunk(int chunkId, int type) {
+       public StringChunk(int chunkId, MAPIType type) {
           super(chunkId, type);
        }
        
@@ -81,14 +82,11 @@ public class StringChunk extends Chunk {
        }
        private void parseString() {
           String tmpValue;
-          switch(type) {
-          case Types.ASCII_STRING:
+          if (type == Types.ASCII_STRING) {
              tmpValue = parseAs7BitData(rawValue, encoding7Bit);
-             break;
-          case Types.UNICODE_STRING:
+          } else if (type == Types.UNICODE_STRING) {
              tmpValue = StringUtil.getFromUnicodeLE(rawValue);
-             break;
-          default:
+          } else {
              throw new IllegalArgumentException("Invalid type " + type + " for String Chunk");
           }
 
@@ -100,19 +98,16 @@ public class StringChunk extends Chunk {
           out.write(rawValue);
        }
        private void storeString() {
-      switch(type) {
-      case Types.ASCII_STRING:
+      if (type == Types.ASCII_STRING) {
          try {
             rawValue = value.getBytes(encoding7Bit);
          } catch (UnsupportedEncodingException e) {
             throw new RuntimeException("Encoding not found - " + encoding7Bit, e);
          }
-         break;
-      case Types.UNICODE_STRING:
+      } else if (type == Types.UNICODE_STRING) {
          rawValue = new byte[value.length()*2];
          StringUtil.putUnicodeLE(value, rawValue, 0);
-         break;
-      default:
+      } else {
          throw new IllegalArgumentException("Invalid type " + type + " for String Chunk");
       }
        }
index bd76e14f9c52e18af71abdae949f328f6c6729e2..aa2864660ec5f245dd92ce8aa7baa9b524ec5321 100644 (file)
 
 package org.apache.poi.hsmf.datatypes;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * The types list and details are available from
  *  http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertytype%28v=EXCHG.140%29.aspx
  */
 public final class Types {
+   private static Map<Integer, MAPIType> builtInTypes = new HashMap<Integer, MAPIType>();
+
    /** Unspecified */
-   public static final int UNSPECIFIED = 0x0000;
+   public static final MAPIType UNSPECIFIED = new MAPIType(0x0000, "Unspecified", -1);
+   /** Unknown */
+   public static final MAPIType UNKNOWN = new MAPIType(-1, "Unknown", -1);
 
    /** Null - NULL property value */
-   public static final int NULL = 0x0001;
+   public static final MAPIType NULL = new MAPIType(0x0001, "Null", 0);
    /** I2 - signed 16-bit value */
-   public static final int SHORT = 0x0002;
+   public static final MAPIType SHORT = new MAPIType(0x0002, "Short", 2);
    /** Long - signed 32-bit value */
-   public static final int LONG = 0x0003;
+   public static final MAPIType LONG = new MAPIType(0x0003, "Long", 4);
    /** R4 - 4-byte floating point value */
-   public static final int FLOAT = 0x0004;
+   public static final MAPIType FLOAT = new MAPIType(0x0004, "Float", 4);
    /** Double - floating point double */
-   public static final int DOUBLE = 0x0005;
+   public static final MAPIType DOUBLE = new MAPIType(0x0005, "Double", 8);
    /** Currency - signed 64-bit integer that represents a base ten decimal with four digits to the right of the decimal point */
-   public static final int CURRENCY = 0x0006;
+   public static final MAPIType CURRENCY = new MAPIType(0x0006, "Currency", 8);
    /** AppTime - application time value */
-   public static final int APP_TIME = 0x0007;
+   public static final MAPIType APP_TIME = new MAPIType(0x0007, "Application Time", 8);
    /** Error - 32-bit error value */
-   public static final int ERROR = 0x000A;
+   public static final MAPIType ERROR = new MAPIType(0x000A, "Error", 4);
    /** Boolean - 16-bit Boolean value. '0' is false. Non-zero is true */
-   public static final int BOOLEAN = 0x000B;
+   public static final MAPIType BOOLEAN = new MAPIType(0x000B, "Boolean", 2);
    /** Object/Directory - embedded object in a property */
-   public static final int DIRECTORY = 0x000D;
+   public static final MAPIType DIRECTORY = new MAPIType(0x000D, "Directory", -1);
    /** I8 - 8-byte signed integer */
-   public static final int LONG_LONG = 0x0014;
+   public static final MAPIType LONG_LONG = new MAPIType(0x0014, "Long Long", 8);
    /** SysTime - FILETIME 64-bit integer specifying the number of 100ns periods since Jan 1, 1601 */
-   public static final int TIME = 0x0040;
+   public static final MAPIType TIME = new MAPIType(0x0040, "Time", 8);
    /** ClassId - OLE GUID */
-   public static final int CLS_ID = 0x0048;
+   public static final MAPIType CLS_ID = new MAPIType(0x0048, "CLS ID GUID", 16);
 
    /** Binary - counted byte array */
-   public static final int BINARY = 0x0102;
+   public static final MAPIType BINARY = new MAPIType(0x0102, "Binary", -1);
 
    /** 
     * An 8-bit string, probably in CP1252, but don't quote us...
     * Normally used for everything before Outlook 3.0, and some
     *  fields in Outlook 3.0.
     */
-   public static final int ASCII_STRING = 0x001E;
+   public static final MAPIType ASCII_STRING = new MAPIType(0x001E, "ASCII String", -1);
    /** A string, from Outlook 3.0 onwards. Normally unicode */
-   public static final int UNICODE_STRING = 0x001F;
+   public static final MAPIType UNICODE_STRING = new MAPIType(0x001F, "Unicode String", -1);
 
    /** MultiValued - Value part contains multiple values */
    public static final int MULTIVALUED_FLAG = 0x1000;
 
+   public static final class MAPIType {
+      private final int id;
+      private final String name;
+      private final int length;
+   
+      /**
+       * Creates a standard, built-in type
+       */
+      private MAPIType(int id, String name, int length) {
+         this.id = id;
+         this.name = name;
+         this.length = length;
+         builtInTypes.put(id, this);
+      }
+      /**
+       * Creates a custom type
+       */
+      private MAPIType(int id, int length) {
+         this.id = id;
+         this.name = asCustomName(id);
+         this.length = length;
+      }
+      
+      /**
+       * Returns the length, in bytes, of values of this type, or
+       *  -1 if it is a variable length type.
+       */
+      public int getLength() {
+         return length;
+      }
+      /**
+       * Is this type a fixed-length type, or a variable-length one?
+       */
+      public boolean isFixedLength() {
+         return (length != -1);
+      }
+      
+      public int getId() {
+         return id;
+      }
+      public String getName() {
+         return name;
+      }
+      
+      /**
+       * Return the 4 character hex encoded version,
+       *  as used in file endings
+       */
+      public String asFileEnding() {
+         return Types.asFileEnding(id);
+      }
+   }
+   
+   public static MAPIType getById(int typeId) {
+      return builtInTypes.get(typeId);
+   }
 
    public static String asFileEnding(int type) {
       String str = Integer.toHexString(type).toUpperCase();
@@ -75,45 +138,18 @@ public final class Types {
       }
       return str;
    }
-   public static String asName(int type) {
-      switch(type) {
-      case BINARY:
-         return "Binary";
-      case ASCII_STRING:
-         return "ASCII String";
-      case UNICODE_STRING:
-         return "Unicode String";
-      case UNSPECIFIED:
-         return "Unspecified";
-      case NULL:
-         return "Null";
-      case SHORT:
-         return "Short";
-      case LONG:
-         return "Long";
-      case LONG_LONG:
-         return "Long Long";
-      case FLOAT:
-         return "Float";
-      case DOUBLE:
-         return "Double";
-      case CURRENCY:
-         return "Currency";
-      case APP_TIME:
-         return "Application Time";
-      case ERROR:
-         return "Error";
-      case TIME:
-         return "Time";
-      case BOOLEAN:
-         return "Boolean";
-      case CLS_ID:
-         return "CLS ID GUID";
-      case DIRECTORY:
-         return "Directory";
-      case -1:
-         return "Unknown";
+   public static String asName(int typeId) {
+      MAPIType type = builtInTypes.get(typeId);
+      if (type != null) {
+         return type.name;
       }
-      return "0x" + Integer.toHexString(type);
+      return asCustomName(typeId);
+   }
+   private static String asCustomName(int typeId) {
+      return "0x" + Integer.toHexString(typeId);
+   }
+   
+   public static MAPIType createCustom(int typeId) {
+      return new MAPIType(typeId, -1);
    }
 }
index 43edf9212151a64a0bc4480b11cb4c4729b54519..8091e71780bb79b2db43fc70e4cac0b6503a904e 100644 (file)
@@ -23,7 +23,6 @@ import java.io.IOException;
 import org.apache.poi.hsmf.datatypes.Chunk;
 import org.apache.poi.hsmf.datatypes.ChunkGroup;
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
-import org.apache.poi.hsmf.datatypes.Types;
 import org.apache.poi.hsmf.parsers.POIFSChunkParser;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
@@ -49,8 +48,7 @@ public class HSMFDump {
             }
             
             System.out.println(
-                  "   " + idName + " - " + 
-                  Types.asName(chunk.getType())
+                  "   " + idName + " - " + chunk.getType().getName()
             );
             System.out.println(
                   "       " + chunk.toString()
index fda6513d61a66a85305644c98ab5155263624f19..39b0ebce5aa1948f38165e5d52700c0e3550c581 100644 (file)
@@ -23,7 +23,6 @@ import java.util.Collections;
 import java.util.Comparator;
 
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
-import org.apache.poi.hsmf.datatypes.Types;
 
 /**
  * Lists the different MAPI types
@@ -56,9 +55,15 @@ public class TypesLister {
          String id = Integer.toHexString(attr.id);
          while(id.length() < 4) { id = "0"+id; }
          
+         int typeId = attr.usualType.getId();
+         String typeIdStr = Integer.toString(typeId);
+         if (typeId > 0) {
+            typeIdStr = typeIdStr + " / 0x" + Integer.toHexString(typeId);
+         }
+         
          out.println("0x" + id + " - " + attr.name);
-         out.println("   " + attr.id + " - " + Types.asName(attr.usualType) + 
-               " (" + attr.usualType + ") - " + attr.mapiProperty);
+         out.println("   " + attr.id + " - " + attr.usualType.getName() + 
+                     " (" + typeIdStr + ") - " + attr.mapiProperty);
       }
    }
    
index 6f542c5ed7a58bc88c3c39e2f0cfa0c21fe2528d..b412fad05d2eb099a2ba2ed026250fb0b25adbbd 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.poi.hsmf.datatypes.NameIdChunks;
 import org.apache.poi.hsmf.datatypes.RecipientChunks;
 import org.apache.poi.hsmf.datatypes.StringChunk;
 import org.apache.poi.hsmf.datatypes.Types;
+import org.apache.poi.hsmf.datatypes.Types.MAPIType;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
 import org.apache.poi.poifs.filesystem.DocumentNode;
@@ -97,7 +98,7 @@ public final class POIFSChunkParser {
          if(entry instanceof DocumentNode) {
             process(entry, grouping);
          } else if(entry instanceof DirectoryNode) {
-             if(entry.getName().endsWith(Types.asFileEnding(Types.DIRECTORY))) {
+             if(entry.getName().endsWith(Types.DIRECTORY.asFileEnding())) {
                  process(entry, grouping);
              }
          }
@@ -141,7 +142,12 @@ public final class POIFSChunkParser {
       // Now try to turn it into id + type
       try {
          int chunkId = Integer.parseInt(ids.substring(0, 4), 16);
-         int type    = Integer.parseInt(ids.substring(4, 8), 16);
+         int typeId  = Integer.parseInt(ids.substring(4, 8), 16);
+         
+         MAPIType type = Types.getById(typeId);
+         if (type == null) {
+            type = Types.createCustom(typeId);
+         }
          
          Chunk chunk = null;
          
@@ -152,19 +158,20 @@ public final class POIFSChunkParser {
          else {
             // Nothing special about this ID
             // So, do the usual thing which is by type
-            switch(type) {
-            case Types.BINARY:
+            if (type == Types.BINARY) {
                chunk = new ByteChunk(namePrefix, chunkId, type);
-               break;
-            case Types.DIRECTORY:
+            }
+            else if (type == Types.DIRECTORY) {
                if(entry instanceof DirectoryNode) {
                    chunk = new DirectoryChunk((DirectoryNode)entry, namePrefix, chunkId, type);
                }
-               break;
-            case Types.ASCII_STRING:
-            case Types.UNICODE_STRING:
+            }
+            else if (type == Types.ASCII_STRING ||
+                     type == Types.UNICODE_STRING) {
                chunk = new StringChunk(namePrefix, chunkId, type);
-               break;
+            } 
+            else {
+               // Type of an unsupported type! Skipping... 
             }
          }
          
index 2303ccc0d008a927edfd723a40886320464db409..ea6f8be81bffe237895120beb629cd56fe2acdff 100644 (file)
@@ -30,24 +30,29 @@ public final class TestChunkData extends TestCase {
        public void testChunkCreate() {
           Chunk chunk;
           
-               chunk = new StringChunk(0x0200, 0x001E);
+               chunk = new StringChunk(0x0200, Types.createCustom(0x001E));
                assertEquals("__substg1.0_0200001E", chunk.getEntryName());
                assertEquals(0x0200, chunk.getChunkId());
-               assertEquals(0x001E, chunk.getType());
+               assertEquals(0x001E, chunk.getType().getId());
 
-      chunk = new StringChunk("__substg1.0_", 0x0200, 0x001E);
+      chunk = new StringChunk("__substg1.0_", 0x0200, Types.createCustom(0x001E));
       assertEquals("__substg1.0_0200001E", chunk.getEntryName());
       assertEquals(0x0200, chunk.getChunkId());
-      assertEquals(0x001E, chunk.getType());
+      assertEquals(0x001E, chunk.getType().getId());
+      
+      chunk = new StringChunk("__substg1.0_", 0x0200, Types.getById(0x001E));
+      assertEquals("__substg1.0_0200001E", chunk.getEntryName());
+      assertEquals(0x0200, chunk.getChunkId());
+      assertEquals(0x001E, chunk.getType().getId());
       
                /* test the lower and upper limits of the chunk ids */
-               chunk = new StringChunk(0x0000, 0x001E);
+               chunk = new StringChunk(0x0000, Types.createCustom(0x001E));
                assertEquals("__substg1.0_0000001E", chunk.getEntryName());
 
-               chunk = new StringChunk(0xFFFF, 0x001E);
+               chunk = new StringChunk(0xFFFF, Types.createCustom(0x001E));
                assertEquals("__substg1.0_FFFF001E", chunk.getEntryName());
 
-               chunk = new StringChunk(0xFFFF, 0x001F);
+               chunk = new StringChunk(0xFFFF, Types.createCustom(0x001F));
                assertEquals("__substg1.0_FFFF001F", chunk.getEntryName());
        }
 
index 56c8859cca73a488d2920cca81ff8c0d99dd7932..55369e8dcda67bb0b2183cd36883ad00f5a0bd2f 100644 (file)
@@ -37,16 +37,16 @@ public final class TestMAPIProperty extends TestCase {
       assertEquals(true, all.contains(MAPIProperty.DISPLAY_CC));
       
       // Won't contain custom
-      assertEquals(false, all.contains(MAPIProperty.createCustom(1, 1, "")));
+      assertEquals(false, all.contains(MAPIProperty.createCustom(1, Types.UNSPECIFIED, "")));
       
       // Won't contain unknown
       assertEquals(false, all.contains(MAPIProperty.UNKNOWN));
    }
    
    public void testCustom() throws Exception {
-      MAPIProperty c1 = MAPIProperty.createCustom(1, 1, "");
-      MAPIProperty c2a = MAPIProperty.createCustom(2, 1, "2");
-      MAPIProperty c2b = MAPIProperty.createCustom(2, 1, "2");
+      MAPIProperty c1 = MAPIProperty.createCustom(1, Types.UNSPECIFIED, "");
+      MAPIProperty c2a = MAPIProperty.createCustom(2, Types.UNSPECIFIED, "2");
+      MAPIProperty c2b = MAPIProperty.createCustom(2, Types.UNSPECIFIED, "2");
       
       // New object each time
       assertNotSame(c1, c2a);
index 152ca4dee06eab6bea5ef1a54d682d123ed96b69..8a58639d79ed82a793ea4feaab069afd02244576 100644 (file)
@@ -28,13 +28,21 @@ import junit.framework.TestCase;
  */
 public final class TestTypes extends TestCase {
    public void testTypeIds() {
-      assertEquals(0x1e, Types.ASCII_STRING);
-      assertEquals(0x1f, Types.UNICODE_STRING);
+      assertEquals(0x1e, Types.ASCII_STRING.getId());
+      assertEquals(0x1f, Types.UNICODE_STRING.getId());
       
-      assertEquals(0x0102, Types.BINARY);
-      assertEquals(0x000B, Types.BOOLEAN);
-      assertEquals(0x0003, Types.LONG);
-      assertEquals(0x0040, Types.TIME);
+      assertEquals(0x0102, Types.BINARY.getId());
+      assertEquals(0x000B, Types.BOOLEAN.getId());
+      assertEquals(0x0003, Types.LONG.getId());
+      assertEquals(0x0040, Types.TIME.getId());
+      
+      assertEquals(Types.ASCII_STRING, Types.getById(0x1e));
+      assertEquals(Types.UNICODE_STRING, Types.getById(0x1f));
+      
+      assertEquals(Types.BINARY, Types.getById(0x0102));
+      assertEquals(Types.BOOLEAN, Types.getById(0x000B));
+      assertEquals(Types.LONG, Types.getById(0x0003));
+      assertEquals(Types.TIME, Types.getById(0x0040));
    }
    
    public void testTypeFormatting() {
@@ -45,7 +53,7 @@ public final class TestTypes extends TestCase {
    }
    
    public void testName() {
-      assertEquals("ASCII String", Types.asName(Types.ASCII_STRING));
-      assertEquals("Boolean", Types.asName(Types.BOOLEAN));
+      assertEquals("ASCII String", Types.ASCII_STRING.getName());
+      assertEquals("Boolean", Types.BOOLEAN.getName());
    }
 }