You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2012/07/08 20:50:12 UTC

svn commit: r1358813 - in /poi/trunk/src: java/org/apache/poi/util/ scratchpad/src/org/apache/poi/hsmf/datatypes/ scratchpad/src/org/apache/poi/hsmf/dev/ scratchpad/src/org/apache/poi/hsmf/parsers/

Author: nick
Date: Sun Jul  8 18:50:11 2012
New Revision: 1358813

URL: http://svn.apache.org/viewvc?rev=1358813&view=rev
Log:
Start on the code to process properties, and wire it up. No properties reading code exists yet

Added:
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java
Modified:
    poi/trunk/src/java/org/apache/poi/util/LittleEndian.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java

Modified: poi/trunk/src/java/org/apache/poi/util/LittleEndian.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/LittleEndian.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/util/LittleEndian.java (original)
+++ poi/trunk/src/java/org/apache/poi/util/LittleEndian.java Sun Jul  8 18:50:11 2012
@@ -724,6 +724,24 @@ public class LittleEndian implements Lit
         }
         return ( ch4 << 24 ) + ( ch3 << 16 ) + ( ch2 << 8 ) + ( ch1 << 0 );
     }
+    
+    /**
+     * get an unsigned int value from an InputStream
+     * 
+     * @param stream
+     *            the InputStream from which the int is to be read
+     * @return the unsigned int (32-bit) value
+     * @exception IOException
+     *                will be propagated back to the caller
+     * @exception BufferUnderrunException
+     *                if the stream cannot provide enough bytes
+     */
+    public static long readUInt( InputStream stream ) throws IOException,
+            BufferUnderrunException
+    {
+       long retNum = readInt(stream);
+       return retNum & 0x00FFFFFFFFl;
+    }
 
     /**
      * get a long value from an InputStream

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java Sun Jul  8 18:50:11 2012
@@ -1026,6 +1026,8 @@ public class MAPIProperty {
       new MAPIProperty(-1, Types.UNKNOWN, "Unknown", null);
    
    // 0x8??? ones are outlook specific, and not standard MAPI
+   // TODO See http://msdn.microsoft.com/en-us/library/ee157150%28v=exchg.80%29 for some
+   //  info on how we might decode them properly in the future
    private static final int ID_FIRST_CUSTOM = 0x8000;
    private static final int ID_LAST_CUSTOM = 0xFFFE;
    

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java?rev=1358813&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java Sun Jul  8 18:50:11 2012
@@ -0,0 +1,89 @@
+/* ====================================================================
+   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;
+
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * A {@link PropertiesChunk} for a Message or Embedded-Message.
+ * This has a 32 byte header
+ */
+public class MessagePropertiesChunk extends PropertiesChunk {
+   private long nextRecipientId;
+   private long nextAttachmentId;
+   private long recipientCount;
+   private long attachmentCount;
+
+   public MessagePropertiesChunk() {
+      super();
+   }
+   
+   public long getNextRecipientId() {
+      return nextRecipientId;
+   }
+   public long getNextAttachmentId() {
+      return nextAttachmentId;
+   }
+
+   public long getRecipientCount() {
+      return recipientCount;
+   }
+   public long getAttachmentCount() {
+      return attachmentCount;
+   }
+
+   @Override
+   public void readValue(InputStream stream) throws IOException {
+      // 8 bytes of reserved zeros
+      LittleEndian.readLong(stream);
+      
+      // Nexts and counts
+      nextRecipientId = LittleEndian.readUInt(stream);
+      nextAttachmentId = LittleEndian.readUInt(stream);
+      recipientCount = LittleEndian.readUInt(stream);
+      attachmentCount = LittleEndian.readUInt(stream);
+      
+      // 8 bytes of reserved zeros
+      LittleEndian.readLong(stream);
+      
+      // Now properties
+      readProperties(stream);
+   }
+
+   @Override
+   public void writeValue(OutputStream out) throws IOException {
+      // 8 bytes of reserved zeros
+      out.write(new byte[8]);
+      
+      // Nexts and counts
+      LittleEndian.putUInt(nextRecipientId, out);
+      LittleEndian.putUInt(nextAttachmentId, out);
+      LittleEndian.putUInt(recipientCount, out);
+      LittleEndian.putUInt(attachmentCount, out);
+      
+      // 8 bytes of reserved zeros
+      out.write(new byte[8]);
+      
+      // Now properties
+      writeProperties(out);
+   }
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java Sun Jul  8 18:50:11 2012
@@ -26,7 +26,7 @@ import java.util.List;
  *  NameID part of an outlook file
  */
 public final class NameIdChunks implements ChunkGroup {
-   public static final String PREFIX = "__nameid_version1.0";
+   public static final String NAME = "__nameid_version1.0";
    
    /** Holds all the chunks that were found. */
    private List<Chunk> allChunks = new ArrayList<Chunk>();

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/PropertiesChunk.java Sun Jul  8 18:50:11 2012
@@ -20,31 +20,68 @@ package org.apache.poi.hsmf.datatypes;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * A Chunk which holds fixed-length properties, and pointer
- *  to the variable length ones (which get their own chunk)
+ *  to the variable length ones (which get their own chunk).
+ * There are two kinds of PropertiesChunks, which differ only in 
+ *  their headers.
  */
-public class PropertiesChunk extends Chunk {
-   public static final String PREFIX = "__properties_version1.0";
+public abstract class PropertiesChunk extends Chunk {
+   public static final String NAME = "__properties_version1.0";
+   
+   /**
+    * Holds properties, indexed by type. Properties can be multi-valued
+    */
+   private Map<MAPIProperty, List<PropertyValue>> properties = 
+         new HashMap<MAPIProperty, List<PropertyValue>>();
 
 	/**
 	 * Creates a Properties Chunk.
 	 */
-	public PropertiesChunk() {
-		super(PREFIX, -1, Types.UNKNOWN);
+	protected PropertiesChunk() {
+		super(NAME, -1, Types.UNKNOWN);
 	}
 
 	@Override
    public String getEntryName() {
-	   return PREFIX;
+	   return NAME;
    }
+	
+	/**
+	 * Returns all the properties in the chunk
+	 */
+	public Map<MAPIProperty, List<PropertyValue>> getProperties() {
+	   return properties;
+	}
+	
+	/**
+	 * Returns all values for the given property, of null if none exist
+	 */
+	public List<PropertyValue> getValues(MAPIProperty property) {
+	   return properties.get(property);
+	}
+	
+	/**
+	 * Returns the (first/only) value for the given property, or
+	 *  null if none exist
+	 */
+	public PropertyValue getValue(MAPIProperty property) {
+	   List<PropertyValue> values = properties.get(property);
+	   if (values != null && values.size() > 0) {
+	      return values.get(0);
+	   }
+	   return null;
+	}
 
-   public void readValue(InputStream value) throws IOException {
+   protected void readProperties(InputStream value) throws IOException {
       // TODO
 	}
 	
-	public void writeValue(OutputStream out) throws IOException {
+	protected void writeProperties(OutputStream out) throws IOException {
 	   // TODO
 	}
 }

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java?rev=1358813&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java Sun Jul  8 18:50:11 2012
@@ -0,0 +1,53 @@
+/* ====================================================================
+   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;
+
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * A {@link PropertiesChunk} for a Storage Properties, such as
+ *  Attachments and Recipients.
+ * This only has a 8 byte header
+ */
+public class StoragePropertiesChunk extends PropertiesChunk {
+   public StoragePropertiesChunk() {
+      super();
+   }
+   
+   @Override
+   public void readValue(InputStream stream) throws IOException {
+      // 8 bytes of reserved zeros
+      LittleEndian.readLong(stream);
+      
+      // Now properties
+      readProperties(stream);
+   }
+
+   @Override
+   public void writeValue(OutputStream out) throws IOException {
+      // 8 bytes of reserved zeros
+      out.write(new byte[8]);
+      
+      // Now properties
+      writeProperties(out);
+   }
+}
\ No newline at end of file

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java Sun Jul  8 18:50:11 2012
@@ -22,7 +22,6 @@ import java.io.InputStream;
 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;

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java Sun Jul  8 18:50:11 2012
@@ -26,6 +26,7 @@ import java.util.Map;
  */
 public final class Types {
    private static Map<Integer, MAPIType> builtInTypes = new HashMap<Integer, MAPIType>();
+   private static Map<Integer, MAPIType> customTypes = new HashMap<Integer, Types.MAPIType>();
 
    /** Unspecified */
    public static final MAPIType UNSPECIFIED = new MAPIType(0x0000, "Unspecified", -1);
@@ -95,6 +96,7 @@ public final class Types {
          this.id = id;
          this.name = asCustomName(id);
          this.length = length;
+         customTypes.put(id, this);
       }
       
       /**
@@ -150,6 +152,24 @@ public final class Types {
    }
    
    public static MAPIType createCustom(int typeId) {
-      return new MAPIType(typeId, -1);
+      // Check they're not being silly, and asking for a built-in one...
+      if (getById(typeId) != null) {
+         return getById(typeId);
+      }
+      
+      // Try to get an existing definition of this
+      MAPIType type = customTypes.get(typeId);
+      
+      // If none, do a thread-safe creation
+      if (type == null) {
+         synchronized (customTypes) {
+            type = customTypes.get(typeId);
+            if (type == null) {
+               type = new MAPIType(typeId, -1);
+            }
+         }
+      }
+      
+      return type;
    }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java Sun Jul  8 18:50:11 2012
@@ -23,6 +23,8 @@ 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.PropertiesChunk;
+import org.apache.poi.hsmf.datatypes.PropertyValue;
 import org.apache.poi.hsmf.parsers.POIFSChunkParser;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
@@ -42,17 +44,35 @@ public class HSMFDump {
          for(Chunk chunk : chunks.getChunks()) {
             MAPIProperty attr = MAPIProperty.get(chunk.getChunkId());
             
-            String idName = attr.id + " - " + attr.name;
-            if(attr == MAPIProperty.UNKNOWN) {
-               idName = chunk.getChunkId() + " - (unknown)";
+            if (chunk instanceof PropertiesChunk) {
+               PropertiesChunk props = (PropertiesChunk)chunk;
+               System.out.println(
+                     "   Properties - " + props.getProperties().size() + ":"
+               );
+               
+               for (MAPIProperty prop : props.getProperties().keySet()) {
+                  System.out.println(
+                        "       * " + prop
+                  );
+                  for (PropertyValue v : props.getValues(prop)) {
+                     System.out.println(
+                           "        = " + v.toString()
+                     );
+                  }
+               }
+            } else {
+               String idName = attr.id + " - " + attr.name;
+               if(attr == MAPIProperty.UNKNOWN) {
+                  idName = chunk.getChunkId() + " - (unknown)";
+               }
+               
+               System.out.println(
+                     "   " + idName + " - " + chunk.getType().getName()
+               );
+               System.out.println(
+                     "       " + chunk.toString()
+               );
             }
-            
-            System.out.println(
-                  "   " + idName + " - " + chunk.getType().getName()
-            );
-            System.out.println(
-                  "       " + chunk.toString()
-            );
          }
          System.out.println();
       }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java?rev=1358813&r1=1358812&r2=1358813&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java Sun Jul  8 18:50:11 2012
@@ -27,9 +27,12 @@ import org.apache.poi.hsmf.datatypes.Chu
 import org.apache.poi.hsmf.datatypes.Chunks;
 import org.apache.poi.hsmf.datatypes.DirectoryChunk;
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
+import org.apache.poi.hsmf.datatypes.MessagePropertiesChunk;
 import org.apache.poi.hsmf.datatypes.MessageSubmissionChunk;
 import org.apache.poi.hsmf.datatypes.NameIdChunks;
+import org.apache.poi.hsmf.datatypes.PropertiesChunk;
 import org.apache.poi.hsmf.datatypes.RecipientChunks;
+import org.apache.poi.hsmf.datatypes.StoragePropertiesChunk;
 import org.apache.poi.hsmf.datatypes.StringChunk;
 import org.apache.poi.hsmf.datatypes.Types;
 import org.apache.poi.hsmf.datatypes.Types.MAPIType;
@@ -66,7 +69,7 @@ public final class POIFSChunkParser {
             if(dir.getName().startsWith(AttachmentChunks.PREFIX)) {
                group = new AttachmentChunks(dir.getName());
             }
-            if(dir.getName().startsWith(NameIdChunks.PREFIX)) {
+            if(dir.getName().startsWith(NameIdChunks.NAME)) {
                group = new NameIdChunks();
             }
             if(dir.getName().startsWith(RecipientChunks.PREFIX)) {
@@ -110,87 +113,98 @@ public final class POIFSChunkParser {
     */
    protected static void process(Entry entry, ChunkGroup grouping) {
       String entryName = entry.getName();
+      Chunk chunk = null;
       
-      if(entryName.length() < 9) {
-         // Name in the wrong format
-         return;
-      }
-      if(entryName.indexOf('_') == -1) {
-         // Name in the wrong format
-         return;
-      }
-      
-      // Split it into its parts
-      int splitAt = entryName.lastIndexOf('_');
-      String namePrefix = entryName.substring(0, splitAt+1);
-      String ids = entryName.substring(splitAt+1);
-      
-      // Make sure we got what we expected, should be of 
-      //  the form __<name>_<id><type>
-      if(namePrefix.equals("Olk10SideProps") ||
-         namePrefix.equals("Olk10SideProps_")) {
-         // This is some odd Outlook 2002 thing, skip
-         return;
-      } else if(splitAt <= entryName.length()-8) {
-         // In the right form for a normal chunk
-         // We'll process this further in a little bit
+      // Is it a properties chunk? (They have special names)
+      if (entryName.equals(PropertiesChunk.NAME)) {
+         if (grouping instanceof Chunks) {
+            // These should be the properties for the message itself
+            chunk = new MessagePropertiesChunk();
+         } else {
+            // Will be properties on an attachment or recipient
+            chunk = new StoragePropertiesChunk();
+         }
       } else {
-         // Underscores not the right place, something's wrong
-         throw new IllegalArgumentException("Invalid chunk name " + entryName);
-      }
-      
-      // Now try to turn it into id + type
-      try {
-         int chunkId = Integer.parseInt(ids.substring(0, 4), 16);
-         int typeId  = Integer.parseInt(ids.substring(4, 8), 16);
-         
-         MAPIType type = Types.getById(typeId);
-         if (type == null) {
-            type = Types.createCustom(typeId);
+         // Check it's a regular chunk
+         if(entryName.length() < 9) {
+            // Name in the wrong format
+            return;
+         }
+         if(entryName.indexOf('_') == -1) {
+            // Name in the wrong format
+            return;
          }
          
-         Chunk chunk = null;
+         // Split it into its parts
+         int splitAt = entryName.lastIndexOf('_');
+         String namePrefix = entryName.substring(0, splitAt+1);
+         String ids = entryName.substring(splitAt+1);
          
-         // Special cases based on the ID
-         if(chunkId == MAPIProperty.MESSAGE_SUBMISSION_ID.id) {
-            chunk = new MessageSubmissionChunk(namePrefix, chunkId, type);
-         } 
-         else {
-            // Nothing special about this ID
-            // So, do the usual thing which is by type
-            if (type == Types.BINARY) {
-               chunk = new ByteChunk(namePrefix, chunkId, type);
-            }
-            else if (type == Types.DIRECTORY) {
-               if(entry instanceof DirectoryNode) {
-                   chunk = new DirectoryChunk((DirectoryNode)entry, namePrefix, chunkId, type);
-               }
+         // Make sure we got what we expected, should be of 
+         //  the form __<name>_<id><type>
+         if(namePrefix.equals("Olk10SideProps") ||
+            namePrefix.equals("Olk10SideProps_")) {
+            // This is some odd Outlook 2002 thing, skip
+            return;
+         } else if(splitAt <= entryName.length()-8) {
+            // In the right form for a normal chunk
+            // We'll process this further in a little bit
+         } else {
+            // Underscores not the right place, something's wrong
+            throw new IllegalArgumentException("Invalid chunk name " + entryName);
+         }
+         
+         // Now try to turn it into id + type
+         try {
+            int chunkId = Integer.parseInt(ids.substring(0, 4), 16);
+            int typeId  = Integer.parseInt(ids.substring(4, 8), 16);
+            
+            MAPIType type = Types.getById(typeId);
+            if (type == null) {
+               type = Types.createCustom(typeId);
             }
-            else if (type == Types.ASCII_STRING ||
-                     type == Types.UNICODE_STRING) {
-               chunk = new StringChunk(namePrefix, chunkId, type);
+            
+            // Special cases based on the ID
+            if(chunkId == MAPIProperty.MESSAGE_SUBMISSION_ID.id) {
+               chunk = new MessageSubmissionChunk(namePrefix, chunkId, type);
             } 
             else {
-               // Type of an unsupported type! Skipping... 
+               // Nothing special about this ID
+               // So, do the usual thing which is by type
+               if (type == Types.BINARY) {
+                  chunk = new ByteChunk(namePrefix, chunkId, type);
+               }
+               else if (type == Types.DIRECTORY) {
+                  if(entry instanceof DirectoryNode) {
+                      chunk = new DirectoryChunk((DirectoryNode)entry, namePrefix, chunkId, type);
+                  }
+               }
+               else if (type == Types.ASCII_STRING ||
+                        type == Types.UNICODE_STRING) {
+                  chunk = new StringChunk(namePrefix, chunkId, type);
+               } 
+               else {
+                  // Type of an unsupported type! Skipping... 
+               }
             }
+         } catch(NumberFormatException e) {
+            // Name in the wrong format
+            return;
          }
+      }
          
-         if(chunk != null) {
-             if(entry instanceof DocumentNode) {
-                try {
-                   DocumentInputStream inp = new DocumentInputStream((DocumentNode)entry);
-                   chunk.readValue(inp);
-                   grouping.record(chunk);
-                } catch(IOException e) {
-                   System.err.println("Error reading from part " + entry.getName() + " - " + e.toString());
-                }
-             } else {
+      if(chunk != null) {
+          if(entry instanceof DocumentNode) {
+             try {
+                DocumentInputStream inp = new DocumentInputStream((DocumentNode)entry);
+                chunk.readValue(inp);
                 grouping.record(chunk);
+             } catch(IOException e) {
+                System.err.println("Error reading from part " + entry.getName() + " - " + e.toString());
              }
-         }
-      } catch(NumberFormatException e) {
-         // Name in the wrong format
-         return;
+          } else {
+             grouping.record(chunk);
+          }
       }
    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org