Author: nick
Date: Fri Feb  1 11:45:31 2013
New Revision: 1441398

URL: http://svn.apache.org/viewvc?rev=1441398&view=rev
Log:
Start on decoding fixed sized HSMF properties, and linking the variable sized 
ones with their matching chunks

Added:
    
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java
Modified:
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.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/RecipientChunks.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java?rev=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java Fri Feb  
1 11:45:31 2013
@@ -418,14 +418,14 @@ public class MAPIMessage extends POIDocu
     * @see #guess7BitEncoding()
     */
    public void set7BitEncoding(String charset) {
-      for(Chunk c : mainChunks.getAll()) {
+      for(Chunk c : mainChunks.getChunks()) {
          if(c instanceof StringChunk) {
             ((StringChunk)c).set7BitEncoding(charset);
          }
       }
 
       if (nameIdChunks!=null) {
-         for(Chunk c : nameIdChunks.getAll()) {
+         for(Chunk c : nameIdChunks.getChunks()) {
             if(c instanceof StringChunk) {
                 ((StringChunk)c).set7BitEncoding(charset);
             }
@@ -446,7 +446,7 @@ public class MAPIMessage extends POIDocu
     *  are stored as 7 bit rather than unicode?
     */
    public boolean has7BitEncodingStrings() {
-      for(Chunk c : mainChunks.getAll()) {
+      for(Chunk c : mainChunks.getChunks()) {
          if(c instanceof StringChunk) {
             if( ((StringChunk)c).getType() == Types.ASCII_STRING ) {
                return true;
@@ -455,7 +455,7 @@ public class MAPIMessage extends POIDocu
       }
       
       if (nameIdChunks!=null) {
-         for(Chunk c : nameIdChunks.getAll()) {
+         for(Chunk c : nameIdChunks.getChunks()) {
             if(c instanceof StringChunk) {
                if( ((StringChunk)c).getType() == Types.ASCII_STRING ) {
                   return true;

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java?rev=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java
 (original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java
 Fri Feb  1 11:45:31 2013
@@ -171,7 +171,17 @@ public class AttachmentChunks implements
       // And add to the main list
       allChunks.add(chunk);
    }
-   
+
+   /**
+    * Used to flag that all the chunks of the attachment
+    *  have now been located.
+    */
+   public void chunksComplete() {
+      // Currently, we don't need to do anything special once
+      //  all the chunks have been located
+   }
+
+
    /**
     * Orders by the attachment number.
     */

Added: 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java?rev=1441398&view=auto
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java
 (added)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkBasedPropertyValue.java
 Fri Feb  1 11:45:31 2013
@@ -0,0 +1,44 @@
+/* ====================================================================
+   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;
+
+
+/**
+ * A variable length {@link PropertyValue} that is
+ *  backed by a {@link Chunk}
+ * TODO Provide a way to link these up with the chunks
+ */
+public class ChunkBasedPropertyValue extends PropertyValue {
+   public ChunkBasedPropertyValue(MAPIProperty property, long flags, byte[] 
offsetData) {
+      super(property, flags, offsetData);
+   }
+
+   @Override
+   public Chunk getValue() {
+      // TODO Decode the value into an offset
+      // TODO Look up the chunk based on that
+      return null;
+   }
+   
+   /**
+    * Stores the offset of the chunk as the property value
+    */
+   public void setValue(Chunk chunk) {
+      // TODO
+   }
+}

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java?rev=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ChunkGroup.java 
Fri Feb  1 11:45:31 2013
@@ -33,4 +33,9 @@ public interface ChunkGroup {
         * Called by the parser whenever a chunk is found.
         */
        public void record(Chunk chunk);
+       
+       /**
+        * Called by the parser when all chunks have been found.
+        */
+       public void chunksComplete();
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java?rev=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java Fri 
Feb  1 11:45:31 2013
@@ -18,7 +18,9 @@
 package org.apache.poi.hsmf.datatypes;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -30,8 +32,8 @@ import java.util.List;
  *  http://msdn.microsoft.com/en-us/library/ms526356%28v=exchg.10%29.aspx
  */
 public final class Chunks implements ChunkGroup {
-   /** Holds all the chunks that were found. */
-   private List<Chunk> allChunks = new ArrayList<Chunk>();
+   /** Holds all the chunks that were found, indexed by their MAPIProperty */
+   private Map<MAPIProperty,List<Chunk>> allChunks = new 
HashMap<MAPIProperty,List<Chunk>>();
    
    /** Type of message that the MSG represents (ie. IPM.Note) */
    public StringChunk messageClass;
@@ -70,65 +72,72 @@ public final class Chunks implements Chu
    /** The message properties */
    public MessagePropertiesChunk messageProperties;
 
-
-   public Chunk[] getAll() {
-      return allChunks.toArray(new Chunk[allChunks.size()]);
+   public Map<MAPIProperty,List<Chunk>> getAll() {
+      return allChunks;
    }
    public Chunk[] getChunks() {
-      return getAll();
+      ArrayList<Chunk> chunks = new ArrayList<Chunk>(allChunks.size());
+      for (List<Chunk> c : allChunks.values()) {
+         chunks.addAll(c);
+      }
+      return chunks.toArray(new Chunk[chunks.size()]);
    }
        
    /**
     * Called by the parser whenever a chunk is found.
     */
    public void record(Chunk chunk) {
-      if(chunk.getChunkId() == MAPIProperty.MESSAGE_CLASS.id) {
+      // Work out what MAPIProperty this corresponds to
+      MAPIProperty prop = MAPIProperty.get(chunk.getChunkId());
+      
+      // Assign it for easy lookup, as best we can
+      if(prop == MAPIProperty.MESSAGE_CLASS) {
          messageClass = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.INTERNET_MESSAGE_ID.id) {
+      else if(prop == MAPIProperty.INTERNET_MESSAGE_ID) {
          messageId = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.MESSAGE_SUBMISSION_ID.id) {
+      else if(prop == MAPIProperty.MESSAGE_SUBMISSION_ID) {
          // TODO - parse
          submissionChunk = (MessageSubmissionChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.RECEIVED_BY_ADDRTYPE.id) {
+      else if(prop == MAPIProperty.RECEIVED_BY_ADDRTYPE) {
          sentByServerType = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.TRANSPORT_MESSAGE_HEADERS.id) 
{
+      else if(prop == MAPIProperty.TRANSPORT_MESSAGE_HEADERS) {
          messageHeaders = (StringChunk)chunk;
       }
       
-      else if(chunk.getChunkId() == MAPIProperty.CONVERSATION_TOPIC.id) {
+      else if(prop == MAPIProperty.CONVERSATION_TOPIC) {
          conversationTopic = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.SUBJECT.id) {
+      else if(prop == MAPIProperty.SUBJECT) {
          subjectChunk = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.ORIGINAL_SUBJECT.id) {
+      else if(prop == MAPIProperty.ORIGINAL_SUBJECT) {
          // TODO
       }
       
-      else if(chunk.getChunkId() == MAPIProperty.DISPLAY_TO.id) {
+      else if(prop == MAPIProperty.DISPLAY_TO) {
          displayToChunk = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.DISPLAY_CC.id) {
+      else if(prop == MAPIProperty.DISPLAY_CC) {
          displayCCChunk = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.DISPLAY_BCC.id) {
+      else if(prop == MAPIProperty.DISPLAY_BCC) {
          displayBCCChunk = (StringChunk)chunk;
       }
       
-      else if(chunk.getChunkId() == MAPIProperty.SENDER_EMAIL_ADDRESS.id) {
+      else if(prop == MAPIProperty.SENDER_EMAIL_ADDRESS) {
          emailFromChunk = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.SENDER_NAME.id) {
+      else if(prop == MAPIProperty.SENDER_NAME) {
          displayFromChunk = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.BODY.id) {
+      else if(prop == MAPIProperty.BODY) {
          textBodyChunk = (StringChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.BODY_HTML.id) {
+      else if(prop == MAPIProperty.BODY_HTML) {
          if(chunk instanceof StringChunk) {
             htmlBodyChunkString = (StringChunk)chunk;
          }
@@ -136,16 +145,21 @@ public final class Chunks implements Chu
             htmlBodyChunkBinary = (ByteChunk)chunk;
          }
       }
-      else if(chunk.getChunkId() == MAPIProperty.RTF_COMPRESSED.id) {
+      else if(prop == MAPIProperty.RTF_COMPRESSED) {
          rtfBodyChunk = (ByteChunk)chunk;
       }
-      else if(chunk.getChunkId() == MAPIProperty.UNKNOWN.id &&
-              chunk instanceof MessagePropertiesChunk) {
-         // TODO Should we maybe collect the contents of this?
+      else if(chunk instanceof MessagePropertiesChunk) {
          messageProperties = (MessagePropertiesChunk) chunk;
       }
       
       // And add to the main list
-      allChunks.add(chunk);
+      if (allChunks.get(prop) == null) {
+         allChunks.put(prop, new ArrayList<Chunk>());
+      }
+      allChunks.get(prop).add(chunk);
+   }
+   
+   public void chunksComplete() {
+      // TODO Match variable sized properties to their chunks + index
    }
 }

Modified: 
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=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java
 (original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessagePropertiesChunk.java
 Fri Feb  1 11:45:31 2013
@@ -33,8 +33,8 @@ public class MessagePropertiesChunk exte
    private long recipientCount;
    private long attachmentCount;
 
-   public MessagePropertiesChunk() {
-      super();
+   public MessagePropertiesChunk(ChunkGroup parentGroup) {
+      super(parentGroup);
    }
    
    public long getNextRecipientId() {

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=1441398&r1=1441397&r2=1441398&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 
Fri Feb  1 11:45:31 2013
@@ -44,4 +44,13 @@ public final class NameIdChunks implemen
    public void record(Chunk chunk) {
       allChunks.add(chunk);
    }
+   
+   /**
+    * Used to flag that all the chunks of the NameID
+    *  have now been located.
+    */
+   public void chunksComplete() {
+      // Currently, we don't need to do anything special once
+      //  all the chunks have been located
+   }
 }

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=1441398&r1=1441397&r2=1441398&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 
Fri Feb  1 11:45:31 2013
@@ -25,8 +25,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.poi.hsmf.datatypes.PropertyValue.LongLongPropertyValue;
+import org.apache.poi.hsmf.datatypes.PropertyValue.TimePropertyValue;
 import org.apache.poi.hsmf.datatypes.Types.MAPIType;
-import org.apache.poi.hsmf.datatypes.PropertyValue.*;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndian.BufferUnderrunException;
@@ -52,11 +53,19 @@ public abstract class PropertiesChunk ex
    private Map<MAPIProperty, List<PropertyValue>> properties = 
          new HashMap<MAPIProperty, List<PropertyValue>>();
 
+   /**
+    * The ChunkGroup that these properties apply to. Used when
+    *  matching chunks to variable sized properties
+    * TODO Make use of this
+    */
+   private ChunkGroup parentGroup;
+   
        /**
         * Creates a Properties Chunk.
         */
-       protected PropertiesChunk() {
+       protected PropertiesChunk(ChunkGroup parentGroup) {
                super(NAME, -1, Types.UNKNOWN);
+               this.parentGroup = parentGroup;
        }
 
        @Override
@@ -132,7 +141,7 @@ public abstract class PropertiesChunk ex
             // Wrap and store
             PropertyValue propVal = null;
             if (isPointer) {
-               // TODO Pointer type which can do lookup
+               propVal = new ChunkBasedPropertyValue(prop, flags, data);
             }
             else if (type == Types.LONG_LONG) {
                propVal = new LongLongPropertyValue(prop, flags, data);

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/RecipientChunks.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/RecipientChunks.java?rev=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/RecipientChunks.java 
(original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/RecipientChunks.java 
Fri Feb  1 11:45:31 2013
@@ -77,7 +77,11 @@ public final class RecipientChunks imple
     *  as in recipientNameChunk
     */
    public StringChunk recipientDisplayNameChunk;
-   
+   /**
+    * Holds the fixed sized properties, and the
+    *  pointers to the data of variable sized ones
+    */
+   private PropertiesChunk recipientProperties;
    
    public RecipientChunks(String name) {
       recipientNumber = -1;
@@ -191,11 +195,18 @@ public final class RecipientChunks imple
       else if(chunk.getChunkId() == DELIVERY_TYPE.id) {
          deliveryTypeChunk = (StringChunk)chunk;
       }
+      else if(chunk instanceof PropertiesChunk) {
+         recipientProperties = (PropertiesChunk) chunk;
+      }
 
       // And add to the main list
       allChunks.add(chunk);
    }
    
+   public void chunksComplete() {
+      // TODO Match variable sized properties to their chunks + index
+   }
+
    /**
     * Orders by the recipient number.
     */

Modified: 
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=1441398&r1=1441397&r2=1441398&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java
 (original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StoragePropertiesChunk.java
 Fri Feb  1 11:45:31 2013
@@ -29,8 +29,8 @@ import org.apache.poi.util.LittleEndian;
  * This only has a 8 byte header
  */
 public class StoragePropertiesChunk extends PropertiesChunk {
-   public StoragePropertiesChunk() {
-      super();
+   public StoragePropertiesChunk(ChunkGroup parentGroup) {
+      super(parentGroup);
    }
    
    @Override

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=1441398&r1=1441397&r2=1441398&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 
Fri Feb  1 11:45:31 2013
@@ -92,6 +92,12 @@ public final class POIFSChunkParser {
       // Now do the top level chunks
       processChunks(node, mainChunks);
       
+      // All chunks are now processed, have the ChunkGroup
+      // match up variable-length properties and their chunks
+      for (ChunkGroup group : groups) {
+         // TODO
+      }
+      
       // Finish
       return groups.toArray(new ChunkGroup[groups.size()]);
    }
@@ -123,10 +129,10 @@ public final class POIFSChunkParser {
       if (entryName.equals(PropertiesChunk.NAME)) {
          if (grouping instanceof Chunks) {
             // These should be the properties for the message itself
-            chunk = new MessagePropertiesChunk();
+            chunk = new MessagePropertiesChunk(grouping);
          } else {
             // Will be properties on an attachment or recipient
-            chunk = new StoragePropertiesChunk();
+            chunk = new StoragePropertiesChunk(grouping);
          }
       } else {
          // Check it's a regular chunk



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to