]> source.dussan.org Git - poi.git/commitdiff
Switch HMEF attributes to a factory scheme for creation, then add subtypes for cleane...
authorNick Burch <nick@apache.org>
Wed, 2 Mar 2011 17:52:12 +0000 (17:52 +0000)
committerNick Burch <nick@apache.org>
Wed, 2 Mar 2011 17:52:12 +0000 (17:52 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1076310 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hmef/Attachment.java
src/scratchpad/src/org/apache/poi/hmef/HMEFMessage.java
src/scratchpad/src/org/apache/poi/hmef/attribute/MAPIAttribute.java
src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFAttribute.java
src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFMAPIAttribute.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFStringAttribute.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hmef/dev/HMEFDumper.java
src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hmef/TestHMEFMessage.java
src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java [new file with mode: 0644]

index 1592941c5d2d6ae91804ddac360327d6a5062d3c..1d74ccc749d1ba61ec0b2ad7db5dfe3774ad4ce1 100644 (file)
@@ -20,8 +20,11 @@ package org.apache.poi.hmef;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.poi.hmef.attribute.TNEFAttribute;
 import org.apache.poi.hmef.attribute.MAPIAttribute;
+import org.apache.poi.hmef.attribute.TNEFAttribute;
+import org.apache.poi.hmef.attribute.TNEFMAPIAttribute;
+import org.apache.poi.hmef.attribute.TNEFProperty;
+import org.apache.poi.hsmf.datatypes.MAPIProperty;
 
 
 /**
@@ -33,21 +36,59 @@ public final class Attachment {
    private final List<TNEFAttribute> attributes = new ArrayList<TNEFAttribute>();
    private final List<MAPIAttribute> mapiAttributes = new ArrayList<MAPIAttribute>();
    
-   
-   
    protected void addAttribute(TNEFAttribute attr) {
       attributes.add(attr);
+      
+      if(attr instanceof TNEFMAPIAttribute) {
+         TNEFMAPIAttribute tnefMAPI = (TNEFMAPIAttribute)attr;
+         mapiAttributes.addAll( tnefMAPI.getMAPIAttributes() );
+      }
    }
    
-   protected void addAttribute(MAPIAttribute attr) {
-      mapiAttributes.add(attr);
+   /**
+    * Return the attachment attribute with the given ID,
+    *  or null if there isn't one. 
+    */
+   public TNEFAttribute getMessageAttribute(TNEFProperty id) {
+      for(TNEFAttribute attr : attributes) {
+         if(attr.getProperty() == id) {
+            return attr;
+         }
+      }
+      return null;
    }
    
+   /**
+    * Return the attachment MAPI Attribute with the given ID,
+    *  or null if there isn't one. 
+    */
+   public MAPIAttribute getMessageMAPIAttribute(MAPIProperty id) {
+      for(MAPIAttribute attr : mapiAttributes) {
+         if(attr.getProperty() == id) {
+            return attr;
+         }
+      }
+      return null;
+   }
+   
+   /**
+    * Returns all HMEF/TNEF attributes of the attachment, 
+    *  such as filename, icon and contents
+    */
    public List<TNEFAttribute> getAttributes() {
       return attributes;
    }
    
+   /**
+    * Returns all MAPI attributes of the attachment, 
+    *  such as extension, encoding, size and position
+    */
    public List<MAPIAttribute> getMAPIAttributes() {
       return mapiAttributes;
    }
+   
+   public String getFilename() {
+      TNEFAttribute attr = null;
+      return null;
+   }
 }
index 7b108b9df98affd5b2c56f87e9cfcbf902cf9c9a..c23718ee68f66c9cc6bc2608a778be6b7b8000ac 100644 (file)
@@ -23,7 +23,10 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.poi.hmef.attribute.MAPIAttribute;
+import org.apache.poi.hmef.attribute.MAPIRtfAttribute;
+import org.apache.poi.hmef.attribute.MAPIStringAttribute;
 import org.apache.poi.hmef.attribute.TNEFAttribute;
+import org.apache.poi.hmef.attribute.TNEFMAPIAttribute;
 import org.apache.poi.hmef.attribute.TNEFProperty;
 import org.apache.poi.hsmf.datatypes.MAPIProperty;
 import org.apache.poi.util.LittleEndian;
@@ -59,24 +62,6 @@ public final class HMEFMessage {
       
       // Now begin processing the contents
       process(inp, 0);
-      
-      // Finally expand out the MAPI Attributes
-      for(TNEFAttribute attr : messageAttributes) {
-         if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) {
-            mapiAttributes.addAll( 
-                  MAPIAttribute.create(attr) 
-            );
-         }
-      }
-      for(Attachment attachment : attachments) {
-         for(TNEFAttribute attr : attachment.getAttributes()) {
-            if(attr.getProperty()== TNEFProperty.ID_MAPIPROPERTIES) {
-               attachment.getMAPIAttributes().addAll(
-                     MAPIAttribute.create(attr) 
-               );
-            }
-         }
-      }
    }
    
    private void process(InputStream inp, int lastLevel) throws IOException {
@@ -87,11 +72,16 @@ public final class HMEFMessage {
       }
     
       // Build the attribute
-      TNEFAttribute attr = new TNEFAttribute(inp);
+      TNEFAttribute attr = TNEFAttribute.create(inp);
       
       // Decide what to attach it to, based on the levels and IDs
       if(level == TNEFProperty.LEVEL_MESSAGE) {
          messageAttributes.add(attr);
+         
+         if(attr instanceof TNEFMAPIAttribute) {
+            TNEFMAPIAttribute tnefMAPI = (TNEFMAPIAttribute)attr;
+            mapiAttributes.addAll( tnefMAPI.getMAPIAttributes() );
+         }
       } else if(level == TNEFProperty.LEVEL_ATTACHMENT) {
          // Previous attachment or a new one?
          if(attachments.size() == 0 || attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
@@ -99,7 +89,8 @@ public final class HMEFMessage {
          }
          
          // Save the attribute for it
-         attachments.get(attachments.size()-1).addAttribute(attr);
+         Attachment attach = attachments.get(attachments.size()-1);
+         attach.addAttribute(attr);
       } else {
          throw new IllegalStateException("Unhandled level " + level);
       }
@@ -158,4 +149,40 @@ public final class HMEFMessage {
       }
       return null;
    }
+   
+   /**
+    * Return the string value of the mapi property, or null
+    *  if it isn't set
+    */
+   private String getString(MAPIProperty id) {
+      MAPIAttribute attr = getMessageMAPIAttribute(id);
+      if(id == null) {
+         return null;
+      }
+      if(attr instanceof MAPIStringAttribute) {
+         return ((MAPIStringAttribute)attr).getDataString();
+      }
+      if(attr instanceof MAPIRtfAttribute) {
+         return ((MAPIRtfAttribute)attr).getDataString();
+      }
+      
+      System.err.println("Warning, no string property found: " + attr.toString());
+      return null;
+   }
+   
+   /**
+    * Returns the Message Subject, or null if the mapi property
+    *  for this isn't set
+    */
+   public String getSubject() {
+      return getString(MAPIProperty.CONVERSATION_TOPIC);
+   }
+   
+   /**
+    * Returns the Message Body, as RTF, or null if the mapi property
+    *  for this isn't set
+    */
+   public String getBody() {
+      return getString(MAPIProperty.RTF_COMPRESSED);
+   }
 }
index 4b1e3f732c784dbd4947b51a1c98e0afe75a91d4..1ebd1211443c761453c2f96d591e6aaa9499fe34 100644 (file)
@@ -82,7 +82,14 @@ public class MAPIAttribute {
     *  the list of MAPI Attributes contained within it
     */
    public static List<MAPIAttribute> create(TNEFAttribute parent) throws IOException {
-      if(parent.getProperty() != TNEFProperty.ID_MAPIPROPERTIES) {
+      if(parent.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) {
+         // Regular MAPI Properties, normally on the message
+      }
+      else if(parent.getProperty() == TNEFProperty.ID_ATTACHMENT) {
+         // MAPI Properties for an attachment
+      }
+      else {
+         // Something else, oh dear...
          throw new IllegalArgumentException(
                "Can only create from a MAPIProperty attribute, " +
                "instead received a " + parent.getProperty() + " one"
index 2ba783d2327f27e05aec40bd6aecf7ffada59258..b2152a5e346467859053581fcc2fa433ebc7419b 100644 (file)
@@ -32,19 +32,18 @@ import org.apache.poi.util.LittleEndian;
  * Note - the types and IDs differ from standard Outlook/MAPI
  *  ones, so we can't just re-use the HSMF ones.
  */
-public final class TNEFAttribute {
+public class TNEFAttribute {
    private final TNEFProperty property;
    private final int type;
    private final byte[] data;
    private final int checksum;
    
    /**
-    * Constructs a single new attribute from
-    *  the contents of the stream
+    * Constructs a single new attribute from the id, type,
+    *  and the contents of the stream
     */
-   public TNEFAttribute(InputStream inp) throws IOException {
-      int id     = LittleEndian.readUShort(inp);
-      this.type  = LittleEndian.readUShort(inp);
+   protected TNEFAttribute(int id, int type, InputStream inp) throws IOException {
+      this.type = type;
       int length = LittleEndian.readInt(inp);
       
       property = TNEFProperty.getBest(id, type);
@@ -52,9 +51,26 @@ public final class TNEFAttribute {
       IOUtils.readFully(inp, data);
       
       checksum = LittleEndian.readUShort(inp);
+   }
+   
+   /**
+    * Creates a new TNEF Attribute by reading data from
+    *  the stream within a {@link HMEFMessage}
+    */
+   public static TNEFAttribute create(InputStream inp) throws IOException {
+      int id   = LittleEndian.readUShort(inp);
+      int type = LittleEndian.readUShort(inp);
       
-      // TODO Handle the MapiProperties attribute in
-      //  a different way, as we need to recurse into it
+      // Create as appropriate
+      if(id == TNEFProperty.ID_MAPIPROPERTIES.id ||
+            id == TNEFProperty.ID_ATTACHMENT.id) {
+         return new TNEFMAPIAttribute(id, type, inp);
+      }
+      if(type == TNEFProperty.TYPE_STRING ||
+           type == TNEFProperty.TYPE_TEXT) {
+         return new TNEFStringAttribute(id, type, inp);
+      }
+      return new TNEFAttribute(id, type, inp); 
    }
 
    public TNEFProperty getProperty() {
@@ -70,7 +86,7 @@ public final class TNEFAttribute {
    }
    
    public String toString() {
-      return "Attachment " + property.toString() + ", type=" + type + 
+      return "Attribute " + property.toString() + ", type=" + type + 
              ", data length=" + data.length; 
    }
 }
diff --git a/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFMAPIAttribute.java b/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFMAPIAttribute.java
new file mode 100644 (file)
index 0000000..3144981
--- /dev/null
@@ -0,0 +1,52 @@
+/* ====================================================================
+   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.hmef.attribute;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.poi.hmef.Attachment;
+import org.apache.poi.hmef.HMEFMessage;
+
+/**
+ * A TNEF Attribute holding MAPI Attributes, which applies to a 
+ *  {@link HMEFMessage} or one of its {@link Attachment}s.
+ */
+public final class TNEFMAPIAttribute extends TNEFAttribute {
+   private final List<MAPIAttribute> attributes;
+   
+   /**
+    * Constructs a single new mapi containing attribute from the 
+    *  id, type, and the contents of the stream
+    */
+   protected TNEFMAPIAttribute(int id, int type, InputStream inp) throws IOException {
+      super(id, type, inp);
+      
+      attributes = MAPIAttribute.create(this);
+   }
+
+   public List<MAPIAttribute> getMAPIAttributes() {
+      return attributes;
+   }
+   
+   public String toString() {
+      return "Attribute " + getProperty().toString() + ", type=" + getType() + 
+             ", " + attributes.size() + " MAPI Attributes"; 
+   }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFStringAttribute.java b/src/scratchpad/src/org/apache/poi/hmef/attribute/TNEFStringAttribute.java
new file mode 100644 (file)
index 0000000..6063c5e
--- /dev/null
@@ -0,0 +1,55 @@
+/* ====================================================================
+   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.hmef.attribute;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.hmef.Attachment;
+import org.apache.poi.hmef.HMEFMessage;
+import org.apache.poi.util.StringUtil;
+
+/**
+ * An String attribute which applies to a {@link HMEFMessage}
+ *  or one of its {@link Attachment}s.
+ */
+public final class TNEFStringAttribute extends TNEFAttribute {
+   /**
+    * Constructs a single new string attribute from the id, type,
+    *  and the contents of the stream
+    */
+   protected TNEFStringAttribute(int id, int type, InputStream inp) throws IOException {
+      super(id, type, inp);
+   }
+
+   public String getString() {
+      byte[] data = getData();
+      // TODO Verify if these are the right way around
+      if(getType() == TNEFProperty.TYPE_TEXT) {
+         return StringUtil.getFromUnicodeLE(data);
+      }
+      return StringUtil.getFromCompressedUnicode(
+            data, 0, data.length
+      );
+   }
+   
+   public String toString() {
+      return "Attribute " + getProperty().toString() + ", type=" + getType() + 
+             ", data=" + getString(); 
+   }
+}
index 26ecbf52395120dc4438cca95c20e0b350836852..e1ad196ee8d515241abb925e533db8300fd79ad8 100644 (file)
@@ -79,6 +79,7 @@ public final class HMEFDumper {
    
    private void dump() throws IOException {
       int level;
+      int attachments = 0;
       
       while(true) {
          // Fetch the level
@@ -88,7 +89,16 @@ public final class HMEFDumper {
          }
        
          // Build the attribute
-         TNEFAttribute attr = new TNEFAttribute(inp);
+         TNEFAttribute attr = TNEFAttribute.create(inp);
+         
+         // Is it a new attachment?
+         if(level == TNEFProperty.LEVEL_ATTACHMENT && 
+               attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
+            attachments++;
+            System.out.println();
+            System.out.println("Attachment # " + attachments);
+            System.out.println();
+         }
          
          // Print the attribute into
          System.out.println(
@@ -125,7 +135,8 @@ public final class HMEFDumper {
          }
          System.out.println();
          
-         if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) {
+         if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES ||
+               attr.getProperty() == TNEFProperty.ID_ATTACHMENT) {
             List<MAPIAttribute> attrs = MAPIAttribute.create(attr);
             for(MAPIAttribute ma : attrs) {
                System.out.println(indent + indent + ma);
diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java b/src/scratchpad/testcases/org/apache/poi/hmef/TestAttachments.java
new file mode 100644 (file)
index 0000000..f5ddb8a
--- /dev/null
@@ -0,0 +1,60 @@
+/* ====================================================================
+   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.hmef;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+
+public final class TestAttachments extends TestCase {
+   private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
+
+   /**
+    * Check the file is as we expect
+    */
+       public void testCounts() throws Exception {
+      HMEFMessage msg = new HMEFMessage(
+            _samples.openResourceAsStream("quick-winmail.dat")
+      );
+      
+      // Should have 5 attachments
+      assertEquals(5, msg.getAttachments().size());
+       }
+   
+       /**
+        * Check some basic bits about the attachments 
+        */
+   public void testBasicAttachments() throws Exception {
+      // TODO
+   }
+   
+   /**
+    * Query the attachments in detail, and check we see
+    *  the right values for key things
+    */
+   public void testAttachmentDetails() throws Exception {
+      // TODO
+   }
+
+   /**
+    * Ensure the attachment contents come back as they should do 
+    */
+   public void testAttachmentContents() throws Exception {
+      // TODO
+   }
+}
index b4542d4316667bff1c43bc9c66b7f214f052bb19..449b2722e061c5e550c8186c35d9659781e3c76c 100644 (file)
@@ -20,8 +20,8 @@ package org.apache.poi.hmef;
 import junit.framework.TestCase;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hmef.attribute.TNEFAttribute;
 import org.apache.poi.hmef.attribute.TNEFProperty;
+import org.apache.poi.util.LittleEndian;
 
 public final class TestHMEFMessage extends TestCase {
     private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
@@ -56,13 +56,9 @@ public final class TestHMEFMessage extends TestCase {
          int mapiAttrCount = attach.getMAPIAttributes().size();
          
          assertEquals(6, attrCount);
-         // TODO
-//         assertTrue("Should be 3-4 attributes, found " + mapiAttrCount, mapiAttrCount >= 20);
-//         assertTrue("Should be 3-4 attributes, found " + mapiAttrCount, mapiAttrCount <= 25);
+         assertTrue("Should be 20-25 mapi attributes, found " + mapiAttrCount, mapiAttrCount >= 20);
+         assertTrue("Should be 20-25 mapi attributes, found " + mapiAttrCount, mapiAttrCount <= 25);
       }
-      
-      
-      // TODO
        }
        
        public void testBasicMessageAttributes() throws Exception {
@@ -88,18 +84,22 @@ public final class TestHMEFMessage extends TestCase {
       assertNull(msg.getMessageAttribute(TNEFProperty.ID_ATTACHDATA));
       
       // Now check the details of one or two
-      // TODO
+      assertEquals(
+            0x010000, 
+            LittleEndian.getInt( msg.getMessageAttribute(TNEFProperty.ID_TNEFVERSION).getData() )
+      );
+      assertEquals(
+            "IPM.Microsoft Mail.Note\0", 
+            new String(msg.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS).getData(), "ASCII")
+      );
        }
    
    public void testBasicMessageMAPIAttributes() throws Exception {
-      // TODO
-   }
-   
-   public void testBasicAttachments() throws Exception {
-      // TODO
-   }
-   
-   public void testMessageAttributeDetails() throws Exception {
-      // TODO
+      HMEFMessage msg = new HMEFMessage(
+            _samples.openResourceAsStream("quick-winmail.dat")
+      );
+      
+      assertEquals("This is a test message", msg.getSubject());
+      assertEquals("{\\rtf1", msg.getBody().substring(0, 6));
    }
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestMAPIAttributes.java
new file mode 100644 (file)
index 0000000..8ed7ba5
--- /dev/null
@@ -0,0 +1,42 @@
+/* ====================================================================
+   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.hmef.attribute;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hmef.HMEFMessage;
+
+public final class TestMAPIAttributes extends TestCase {
+    private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
+
+       public void testOpen() throws Exception {
+               HMEFMessage msg = new HMEFMessage(
+                _samples.openResourceAsStream("quick-winmail.dat")
+               );
+
+               assertNotNull(msg);
+       }
+
+       // Test basics
+       // Test counts
+       
+       // Check untyped
+       // Check typed
+       // Check common
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java b/src/scratchpad/testcases/org/apache/poi/hmef/attribute/TestTNEFAttributes.java
new file mode 100644 (file)
index 0000000..6096ba3
--- /dev/null
@@ -0,0 +1,43 @@
+/* ====================================================================
+   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.hmef.attribute;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hmef.HMEFMessage;
+
+public final class TestTNEFAttributes extends TestCase {
+    private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
+
+       public void testOpen() throws Exception {
+               HMEFMessage msg = new HMEFMessage(
+                _samples.openResourceAsStream("quick-winmail.dat")
+               );
+
+               assertNotNull(msg);
+       }
+       
+       // Test counts
+       
+       // Test basics
+       
+       // Test string
+       
+       // Test a bit of mapi
+}