You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by be...@apache.org on 2012/08/05 15:05:49 UTC

svn commit: r1369572 [3/4] - in /poi/branches/gsoc2012: ./ src/documentation/ src/documentation/content/xdocs/ src/documentation/content/xdocs/spreadsheet/ src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/aggregates/ src/java/org...

Modified: poi/branches/gsoc2012/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java (original)
+++ poi/branches/gsoc2012/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java Sun Aug  5 13:05:44 2012
@@ -26,7 +26,11 @@ import junit.framework.TestCase;
 
 import org.apache.poi.xwpf.XWPFTestDataSamples;
 
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException;
 
 public class TestXWPFStyles extends TestCase {
 
@@ -82,4 +86,36 @@ public class TestXWPFStyles extends Test
       assertNotNull(styles);
 	}
 
+
+    /**
+     * YK: tests below don't make much sense,
+     * they exist only to copy xml beans to pi-ooxml-schemas.jar
+     */
+    public void testLanguages(){
+        XWPFDocument docOut = new XWPFDocument();
+        XWPFStyles styles = docOut.createStyles();
+        styles.setEastAsia("Chinese");
+
+        styles.setSpellingLanguage("English");
+
+        CTFonts def = CTFonts.Factory.newInstance();
+        styles.setDefaultFonts(def);
+    }
+
+    public void testType() {
+        CTStyle ctStyle = CTStyle.Factory.newInstance();
+        XWPFStyle style = new XWPFStyle(ctStyle);
+
+        style.setType(STStyleType.PARAGRAPH);
+        assertEquals(STStyleType.PARAGRAPH, style.getType());
+    }
+
+    public void testLatentStyles() {
+        CTLatentStyles latentStyles = CTLatentStyles.Factory.newInstance();
+        CTLsdException ex = latentStyles.addNewLsdException();
+        ex.setName("ex1");
+        XWPFLatentStyles ls = new XWPFLatentStyles(latentStyles);
+        assertEquals(true, ls.isLatentStyle("ex1"));
+
+    }
 }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java Sun Aug  5 13:05:44 2012
@@ -161,70 +161,76 @@ public final class Chunk {
 				continue;
 			}
 
-			// Process
-			switch(type) {
-			// Types 0->7 = a flat at bit 0->7
-			case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
-				int val = contents[offset] & (1<<type);
-				command.value = Boolean.valueOf(val > 0);
-				break;
-			case 8:
-				command.value = Byte.valueOf(contents[offset]);
-				break;
-			case 9:
-				command.value = new Double(
-						LittleEndian.getDouble(contents, offset)
-				);
-				break;
-			case 12:
-				// A Little Endian String
-				// Starts 8 bytes into the data segment
-				// Ends at end of data, or 00 00
-			   
-				// Ensure we have enough data
-				if(contents.length < 8) {
-					command.value = "";
+			try {
+				// Process
+				switch(type) {
+				// Types 0->7 = a flat at bit 0->7
+				case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+					int val = contents[offset] & (1<<type);
+					command.value = Boolean.valueOf(val > 0);
 					break;
-				}
-			   
-				// Find the end point
-				int startsAt = 8;
-				int endsAt = startsAt;
-				for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
-					if(contents[j] == 0 && contents[j+1] == 0) {
-						endsAt = j;
+				case 8:
+					command.value = Byte.valueOf(contents[offset]);
+					break;
+				case 9:
+					command.value = new Double(
+							LittleEndian.getDouble(contents, offset)
+					);
+					break;
+				case 12:
+					// A Little Endian String
+					// Starts 8 bytes into the data segment
+					// Ends at end of data, or 00 00
+
+					// Ensure we have enough data
+					if(contents.length < 8) {
+						command.value = "";
+						break;
+					}
+
+					// Find the end point
+					int startsAt = 8;
+					int endsAt = startsAt;
+					for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
+						if(contents[j] == 0 && contents[j+1] == 0) {
+							endsAt = j;
+						}
+					}
+					if(endsAt == startsAt) {
+						endsAt = contents.length;
 					}
-				}
-				if(endsAt == startsAt) {
-					endsAt = contents.length;
-				}
-				
-				int strLen = (endsAt-startsAt) / 2;
-				command.value = StringUtil.getFromUnicodeLE(contents, startsAt, strLen);
-				break;
-			case 25:
-				command.value = Short.valueOf(
-					LittleEndian.getShort(contents, offset)
-				);
-				break;
-			case 26:
-				command.value = Integer.valueOf(
-						LittleEndian.getInt(contents, offset)
-				);
-				break;
-
-			// Types 11 and 21 hold the offset to the blocks
-			case 11: case 21:
-				if(offset < contents.length - 3) {
-					int bOffset = (int)LittleEndian.getUInt(contents, offset);
-					BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
-					bcmd.setOffset(bOffset);
-				}
-				break;
 
-			default:
-				logger.log(POILogger.INFO,
-						"Command of type " + type + " not processed!");
+					int strLen = endsAt - startsAt;
+					command.value = new String(contents, startsAt, strLen, header.getChunkCharset().name());
+					break;
+				case 25:
+					command.value = Short.valueOf(
+						LittleEndian.getShort(contents, offset)
+					);
+					break;
+				case 26:
+					command.value = Integer.valueOf(
+							LittleEndian.getInt(contents, offset)
+					);
+					break;
+
+				// Types 11 and 21 hold the offset to the blocks
+				case 11: case 21:
+					if(offset < contents.length - 3) {
+						int bOffset = (int)LittleEndian.getUInt(contents, offset);
+						BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
+						bcmd.setOffset(bOffset);
+					}
+					break;
+
+				default:
+					logger.log(POILogger.INFO,
+							"Command of type " + type + " not processed!");
+				}
+			}
+			catch (Exception e) {
+				logger.log(POILogger.ERROR, "Unexpected error processing command, ignoring and continuing. Command: " +
+						command, e);
 			}
 
 			// Add to the array

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeader.java Sun Aug  5 13:05:44 2012
@@ -19,6 +19,8 @@ package org.apache.poi.hdgf.chunks;
 
 import org.apache.poi.util.LittleEndian;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header
  */
@@ -80,6 +82,7 @@ public abstract class ChunkHeader {
 	public abstract int getSizeInBytes();
 	public abstract boolean hasTrailer();
 	public abstract boolean hasSeparator();
+	public abstract Charset getChunkCharset();
 
 	/**
 	 * Returns the ID/IX of the chunk

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV11.java Sun Aug  5 13:05:44 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hdgf.chunks;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header from v11+
  */
@@ -42,4 +44,9 @@ public final class ChunkHeaderV11 extend
 
 		return false;
 	}
+
+	@Override
+	public Charset getChunkCharset() {
+		return Charset.forName("UTF-16LE");
+	}
 }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV4V5.java Sun Aug  5 13:05:44 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hdgf.chunks;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header from v4 or v5
  */
@@ -54,4 +56,9 @@ public final class ChunkHeaderV4V5 exten
 		// V4 and V5 never has separators
 		return false;
 	}
+
+	@Override
+	public Charset getChunkCharset() {
+		return Charset.forName("ASCII");
+	}
 }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkHeaderV6.java Sun Aug  5 13:05:44 2012
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hdgf.chunks;
 
+import java.nio.charset.Charset;
+
 /**
  * A chunk header from v6
  */
@@ -59,4 +61,9 @@ public class ChunkHeaderV6 extends Chunk
 		// V6 never has separators
 		return false;
 	}
+
+	@Override
+	public Charset getChunkCharset() {
+		return Charset.forName("ASCII");
+	}
 }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hdgf/streams/ChunkStream.java Sun Aug  5 13:05:44 2012
@@ -52,19 +52,25 @@ public final class ChunkStream extends S
 
 		int pos = 0;
 		byte[] contents = getStore().getContents();
-		while(pos < contents.length) {
-			// Ensure we have enough data to create a chunk from
-			int headerSize = ChunkHeader.getHeaderSize(chunkFactory.getVersion());
-			if(pos+headerSize <= contents.length) {
-				Chunk chunk = chunkFactory.createChunk(contents, pos);
-				chunksA.add(chunk);
+		try {
+			while(pos < contents.length) {
+				// Ensure we have enough data to create a chunk from
+				int headerSize = ChunkHeader.getHeaderSize(chunkFactory.getVersion());
+				if(pos+headerSize <= contents.length) {
+					Chunk chunk = chunkFactory.createChunk(contents, pos);
+					chunksA.add(chunk);
 
-				pos += chunk.getOnDiskSize();
-			} else {
-				System.err.println("Needed " + headerSize + " bytes to create the next chunk header, but only found " + (contents.length-pos) + " bytes, ignoring rest of data");
-				pos = contents.length;
+					pos += chunk.getOnDiskSize();
+				} else {
+					System.err.println("Needed " + headerSize + " bytes to create the next chunk header, but only found " + (contents.length-pos) + " bytes, ignoring rest of data");
+					pos = contents.length;
+				}
 			}
 		}
+		catch (Exception e)
+		{
+			System.err.println("Failed to create chunk at " + pos + ", ignoring rest of data." + e);
+		}
 
 		chunks = chunksA.toArray(new Chunk[chunksA.size()]);
 	}

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java Sun Aug  5 13:05:44 2012
@@ -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);
       }
    }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIStringAttribute.java Sun Aug  5 13:05:44 2012
@@ -37,13 +37,13 @@ public final class MAPIStringAttribute e
       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);

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java Sun Aug  5 13:05:44 2012
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hslf.blip;
 
+import org.apache.poi.util.PngUtils;
 import org.apache.poi.hslf.model.Picture;
 import org.apache.poi.hslf.exceptions.HSLFException;
 
@@ -35,22 +36,19 @@ public final class PNG extends Bitmap {
     /**
      * @return PNG data
      */
-    public byte[] getData(){
-         byte[] data = super.getData();
-          try {
-              //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
-              //Just cut it off!.
-              BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data));
-              if (bi == null){
-                  byte[] png = new byte[data.length-16];
-                  System.arraycopy(data, 16, png, 0, png.length);
-                  data = png;
-              }
-          } catch (IOException e){
-              throw new HSLFException(e);
-          }
-         return data;
-     }
+    public byte[] getData() {
+        byte[] data = super.getData();
+
+        //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
+        //Just cut it off!.
+        if (PngUtils.matchesPngHeader(data, 16)) {
+            byte[] png = new byte[data.length-16];
+            System.arraycopy(data, 16, png, 0, png.length);
+            data = png;
+        }
+
+        return data;
+    }
 
     /**
      * @return type of  this picture

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java Sun Aug  5 13:05:44 2012
@@ -218,6 +218,9 @@ public final class PPGraphics2D extends 
         p.setPath(path);
         p.getFill().setForegroundColor(null);
         applyStroke(p);
+        if (_paint instanceof Color) {
+            p.setLineColor((Color)_paint);
+        }
         _group.addShape(p);
     }
 

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java Sun Aug  5 13:05:44 2012
@@ -39,9 +39,9 @@ import org.apache.poi.hsmf.datatypes.Chu
 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 POIDocu
       
       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) {

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/AttachmentChunks.java Sun Aug  5 13:05:44 2012
@@ -31,10 +31,13 @@ import static org.apache.poi.hsmf.dataty
 import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_RENDERING;
 import static org.apache.poi.hsmf.datatypes.MAPIProperty.ATTACH_SIZE;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 
+import org.apache.poi.hsmf.MAPIMessage;
+
 /**
  * Collection of convenence chunks for standard parts of the MSG file attachment.
  */
@@ -68,6 +71,36 @@ public class AttachmentChunks implements
       this.poifsName = poifsName;
    }
    
+   
+   /**
+    * Is this Attachment an embedded MAPI message?
+    */
+   public boolean isEmbeddedMessage() {
+      return (attachmentDirectory != null);
+   }
+   /**
+    * Returns the embedded MAPI message, if the attachment
+    *  is an embedded message, or null otherwise
+    */
+   public MAPIMessage getEmbeddedMessage() throws IOException {
+      if (attachmentDirectory != null) {
+         return attachmentDirectory.getAsEmbededMessage();
+      }
+      return null;
+   }
+   
+   /**
+    * Returns the embedded object, if the attachment is an
+    *  object based embedding (image, document etc), or null
+    *  if it's an embedded message
+    */
+   public byte[] getEmbeddedAttachmentObject() {
+      if (attachData != null) {
+         return attachData.getValue();
+      }
+      return null;
+   }
+   
    public Chunk[] getAll() {
       return allChunks.toArray(new Chunk[allChunks.size()]);
    }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/ByteChunk.java Sun Aug  5 13:05:44 2012
@@ -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);
 	}
 

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java Sun Aug  5 13:05:44 2012
@@ -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;

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/DirectoryChunk.java Sun Aug  5 13:05:44 2012
@@ -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.D
 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;
     }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MAPIProperty.java Sun Aug  5 13:05:44 2012
@@ -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,20 +1023,22 @@ 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
+   // 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;
    
    /* ---------------------------------------------------------------------  */
    
    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 +1084,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);
       }
    }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/MessageSubmissionChunk.java Sun Aug  5 13:05:44 2012
@@ -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 exte
 	/**
 	 * 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 exte
 	 * Create a Byte Chunk, with the specified
 	 *  type.
 	 */
-	public MessageSubmissionChunk(int chunkId, int type) {
+	public MessageSubmissionChunk(int chunkId, MAPIType type) {
 	   super(chunkId, type);
 	}
 

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/NameIdChunks.java Sun Aug  5 13:05:44 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/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java Sun Aug  5 13:05:44 2012
@@ -22,7 +22,7 @@ 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;
 
@@ -38,7 +38,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 +46,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 +81,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 +97,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");
       }
 	}

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java Sun Aug  5 13:05:44 2012
@@ -17,56 +17,121 @@
 
 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>();
+   private static Map<Integer, MAPIType> customTypes = new HashMap<Integer, Types.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;
+         customTypes.put(id, this);
+      }
+      
+      /**
+       * 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 +140,36 @@ 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 asCustomName(typeId);
+   }
+   private static String asCustomName(int typeId) {
+      return "0x" + Integer.toHexString(typeId);
+   }
+   
+   public static MAPIType createCustom(int typeId) {
+      // 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 "0x" + Integer.toHexString(type);
+      
+      return type;
    }
 }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/HSMFDump.java Sun Aug  5 13:05:44 2012
@@ -23,7 +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.Types;
+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;
 
@@ -43,18 +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 + " - " + 
-                  Types.asName(chunk.getType())
-            );
-            System.out.println(
-                  "       " + chunk.toString()
-            );
          }
          System.out.println();
       }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/TypesLister.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/TypesLister.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/TypesLister.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/dev/TypesLister.java Sun Aug  5 13:05:44 2012
@@ -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);
       }
    }
    

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java Sun Aug  5 13:05:44 2012
@@ -27,11 +27,15 @@ 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;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
 import org.apache.poi.poifs.filesystem.DocumentNode;
@@ -65,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)) {
@@ -97,7 +101,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);
              }
          }
@@ -109,81 +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 type    = Integer.parseInt(ids.substring(4, 8), 16);
+         // 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
-            switch(type) {
-            case Types.BINARY:
-               chunk = new ByteChunk(namePrefix, chunkId, type);
-               break;
-            case 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);
+            }
+            
+            // 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);
+                  }
+               }
+               else if (type == Types.ASCII_STRING ||
+                        type == Types.UNICODE_STRING) {
+                  chunk = new StringChunk(namePrefix, chunkId, type);
+               } 
+               else {
+                  // Type of an unsupported type! Skipping... 
                }
-               break;
-            case Types.ASCII_STRING:
-            case Types.UNICODE_STRING:
-               chunk = new StringChunk(namePrefix, chunkId, type);
-               break;
             }
+         } 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);
+          }
       }
    }
 }

Modified: poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java Sun Aug  5 13:05:44 2012
@@ -34,6 +34,7 @@ import org.apache.poi.ddf.EscherProperty
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.hwpf.model.PICF;
 import org.apache.poi.hwpf.model.PICFAndOfficeArtData;
+import org.apache.poi.util.PngUtils;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.StringUtil;
@@ -191,6 +192,15 @@ public final class Picture
         {
             // Raw data is not compressed.
             content = rawContent;
+
+            //PNG created on MAC may have a 16-byte prefix which prevents successful reading.
+            //Just cut it off!.
+            if (PngUtils.matchesPngHeader(content, 16))
+            {
+                byte[] png = new byte[content.length-16];
+                System.arraycopy(content, 16, png, 0, png.length);
+                content = png;
+            }
         }
     }
 

Modified: poi/branches/gsoc2012/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java
URL: http://svn.apache.org/viewvc/poi/branches/gsoc2012/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java?rev=1369572&r1=1369571&r2=1369572&view=diff
==============================================================================
--- poi/branches/gsoc2012/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java (original)
+++ poi/branches/gsoc2012/src/scratchpad/testcases/org/apache/poi/hdgf/TestHDGFCore.java Sun Aug  5 13:05:44 2012
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hdgf;
 
+import org.apache.poi.hdgf.extractor.VisioTextExtractor;
 import org.apache.poi.hdgf.streams.PointerContainingStream;
 import org.apache.poi.hdgf.streams.TrailerStream;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@@ -88,4 +89,28 @@ public final class TestHDGFCore extends 
       HDGFDiagram hdgf = new HDGFDiagram(fs);
       assertNotNull(hdgf);
 	}
+
+    public void testV6NonUtf16LE() throws Exception {
+   		fs = new POIFSFileSystem(_dgTests.openResourceAsStream("v6-non-utf16le.vsd"));
+
+   		HDGFDiagram hdgf = new HDGFDiagram(fs);
+   		assertNotNull(hdgf);
+
+        VisioTextExtractor textExtractor = new VisioTextExtractor(hdgf);
+        String text = textExtractor.getText().replace("\u0000", "").trim();
+
+        assertEquals("Table\n\n\nPropertySheet\n\n\n\nPropertySheetField", text);
+   	}
+
+    public void testUtf16LE() throws Exception {
+   		fs = new POIFSFileSystem(_dgTests.openResourceAsStream("Test_Visio-Some_Random_Text.vsd"));
+
+   		HDGFDiagram hdgf = new HDGFDiagram(fs);
+   		assertNotNull(hdgf);
+
+        VisioTextExtractor textExtractor = new VisioTextExtractor(hdgf);
+        String text = textExtractor.getText().trim();
+
+        assertEquals("text\nView\nTest View\nI am a test view\nSome random text, on a page", text);
+   	}
 }



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