Refactor the TNEF Attributes to better match the MAPI ones, and move both into their own package
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1076251 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
03b0eabcf8
commit
20f6e280a5
@ -20,15 +20,22 @@ package org.apache.poi.hmef;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.poi.hmef.attribute.TNEFAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.MAPIAttribute;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An attachment within a {@link HMEFMessage}
|
* An attachment within a {@link HMEFMessage}. Provides both helper
|
||||||
|
* methods to get at common parts and attributes of the attachment,
|
||||||
|
* and list methods to get all of them.
|
||||||
*/
|
*/
|
||||||
public final class Attachment {
|
public final class Attachment {
|
||||||
private final List<Attribute> attributes = new ArrayList<Attribute>();
|
private final List<TNEFAttribute> attributes = new ArrayList<TNEFAttribute>();
|
||||||
private final List<MAPIAttribute> mapiAttributes = new ArrayList<MAPIAttribute>();
|
private final List<MAPIAttribute> mapiAttributes = new ArrayList<MAPIAttribute>();
|
||||||
|
|
||||||
protected void addAttribute(Attribute attr) {
|
|
||||||
|
|
||||||
|
protected void addAttribute(TNEFAttribute attr) {
|
||||||
attributes.add(attr);
|
attributes.add(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +43,7 @@ public final class Attachment {
|
|||||||
mapiAttributes.add(attr);
|
mapiAttributes.add(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Attribute> getAttributes() {
|
public List<TNEFAttribute> getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,262 +0,0 @@
|
|||||||
/* ====================================================================
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.poi.util.IOUtils;
|
|
||||||
import org.apache.poi.util.LittleEndian;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An attribute which applies to a {@link HMEFMessage}
|
|
||||||
* or one of its {@link Attachment}s.
|
|
||||||
* Note - the types and IDs differ from standard Outlook/MAPI
|
|
||||||
* ones, so we can't just re-use the HSMF ones.
|
|
||||||
*/
|
|
||||||
public final class Attribute {
|
|
||||||
// Types taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributetype%28v=EXCHG.140%29.aspx
|
|
||||||
public static final int TYPE_TRIPLES = 0x0000;
|
|
||||||
public static final int TYPE_STRING = 0x0001;
|
|
||||||
public static final int TYPE_TEXT = 0x0002;
|
|
||||||
public static final int TYPE_DATE = 0x0003;
|
|
||||||
public static final int TYPE_SHORT = 0x0004;
|
|
||||||
public static final int TYPE_LONG = 0x0005;
|
|
||||||
public static final int TYPE_BYTE = 0x0006;
|
|
||||||
public static final int TYPE_WORD = 0x0007;
|
|
||||||
public static final int TYPE_DWORD = 0x0008;
|
|
||||||
public static final int TYPE_MAX = 0x0009;
|
|
||||||
|
|
||||||
// Types taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertytype%28v=EXCHG.140%29.aspx
|
|
||||||
/** AppTime - application time value */
|
|
||||||
public static final int PTYPE_APPTIME = 0x0007;
|
|
||||||
/** Binary - counted byte array */
|
|
||||||
public static final int PTYPE_BINARY = 0x0102;
|
|
||||||
/** Boolean - 16-bit Boolean value. '0' is false. Non-zero is true */
|
|
||||||
public static final int PTYPE_BOOLEAN = 0x000B;
|
|
||||||
/** ClassId - OLE GUID */
|
|
||||||
public static final int PTYPE_CLASSID = 0x0048;
|
|
||||||
/** 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 PTYPE_CURRENCY = 0x0006;
|
|
||||||
/** Double - floating point double */
|
|
||||||
public static final int PTYPE_DOUBLE = 0x0005;
|
|
||||||
/** Error - 32-bit error value */
|
|
||||||
public static final int PTYPE_ERROR = 0x000A;
|
|
||||||
/** I2 - signed 16-bit value */
|
|
||||||
public static final int PTYPE_I2 = 0x0002;
|
|
||||||
/** I8 - 8-byte signed integer */
|
|
||||||
public static final int PTYPE_I8 = 0x0014;
|
|
||||||
/** Long - signed 32-bit value */
|
|
||||||
public static final int PTYPE_LONG = 0x0003;
|
|
||||||
/** MultiValued - Value part contains multiple values */
|
|
||||||
public static final int PTYPE_MULTIVALUED = 0x1000;
|
|
||||||
/** Null - NULL property value */
|
|
||||||
public static final int PTYPE_NULL = 0x0001;
|
|
||||||
/** Object - embedded object in a property */
|
|
||||||
public static final int PTYPE_OBJECT = 0x000D;
|
|
||||||
/** R4 - 4-byte floating point value */
|
|
||||||
public static final int PTYPE_R4 = 0x0004;
|
|
||||||
/** String8 - null-terminated 8-bit character string */
|
|
||||||
public static final int PTYPE_STRING8 = 0x001E;
|
|
||||||
/** SysTime - FILETIME 64-bit integer specifying the number of 100ns periods since Jan 1, 1601 */
|
|
||||||
public static final int PTYPE_SYSTIME = 0x0040;
|
|
||||||
/** Unicode - null-terminated Unicode string */
|
|
||||||
public static final int PTYPE_UNICODE = 0x001F;
|
|
||||||
/** Unspecified */
|
|
||||||
public static final int PTYPE_UNSPECIFIED = 0x0000;
|
|
||||||
|
|
||||||
|
|
||||||
// Levels taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributelevel%28v=EXCHG.140%29.aspx
|
|
||||||
public static final int LEVEL_MESSAGE = 0x01;
|
|
||||||
public static final int LEVEL_ATTACHMENT = 0x02;
|
|
||||||
public static final int LEVEL_END_OF_FILE = -0x01;
|
|
||||||
|
|
||||||
// ID information taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributetag%28v=EXCHG.140%29.aspx
|
|
||||||
public static final AttributeID ID_AIDOWNER =
|
|
||||||
new AttributeID(0x0008, TYPE_LONG, "AidOwner", "PR_OWNER_APPT_ID");
|
|
||||||
public static final AttributeID ID_ATTACHCREATEDATE =
|
|
||||||
new AttributeID(0x8012, TYPE_DATE, "AttachCreateDate", "PR_CREATION_TIME");
|
|
||||||
public static final AttributeID ID_ATTACHDATA =
|
|
||||||
new AttributeID(0x800F, TYPE_BYTE, "AttachData", "PR_ATTACH_DATA_BIN");
|
|
||||||
public static final AttributeID ID_ATTACHMENT =
|
|
||||||
new AttributeID(0x9005, TYPE_BYTE, "Attachment", null);
|
|
||||||
public static final AttributeID ID_ATTACHMETAFILE =
|
|
||||||
new AttributeID(0x8011, TYPE_BYTE, "AttachMetaFile", "PR_ATTACH_RENDERING");
|
|
||||||
public static final AttributeID ID_ATTACHMODIFYDATE =
|
|
||||||
new AttributeID(0x8013, TYPE_DATE, "AttachModifyDate", "PR_LAST_MODIFICATION_TIME");
|
|
||||||
public static final AttributeID ID_ATTACHRENDERDATA =
|
|
||||||
new AttributeID(0x9002, TYPE_BYTE, "AttachRenderData", "attAttachRenddata");
|
|
||||||
public static final AttributeID ID_ATTACHTITLE =
|
|
||||||
new AttributeID(0x8010, TYPE_STRING, "AttachTitle", "PR_ATTACH_FILENAME");
|
|
||||||
public static final AttributeID ID_ATTACHTRANSPORTFILENAME =
|
|
||||||
new AttributeID(0x9001, TYPE_BYTE, "AttachTransportFilename", "PR_ATTACH_TRANSPORT_NAME");
|
|
||||||
public static final AttributeID ID_BODY =
|
|
||||||
new AttributeID(0x800C, TYPE_TEXT, "Body", "PR_BODY");
|
|
||||||
public static final AttributeID ID_CONVERSATIONID =
|
|
||||||
new AttributeID(0x800B, TYPE_STRING, "ConversationId", "PR_CONVERSATION_KEY");
|
|
||||||
public static final AttributeID ID_DATEEND =
|
|
||||||
new AttributeID(0x0007, TYPE_DATE, "DateEnd", "PR_END_DATE");
|
|
||||||
public static final AttributeID ID_DATEMODIFIED =
|
|
||||||
new AttributeID(0x8020, TYPE_DATE, "DateModified", "PR_LAST_MODIFICATION_TIME ");
|
|
||||||
public static final AttributeID ID_DATERECEIVED =
|
|
||||||
new AttributeID(0x8006, TYPE_DATE, "DateReceived", "PR_MESSAGE_DELIVERY_TIME ");
|
|
||||||
public static final AttributeID ID_DATESENT =
|
|
||||||
new AttributeID(0x8005, TYPE_DATE, "DateSent", "PR_CLIENT_SUBMIT_TIME ");
|
|
||||||
public static final AttributeID ID_DATESTART =
|
|
||||||
new AttributeID(0x0006, TYPE_DATE, "DateStart", "PR_START_DATE ");
|
|
||||||
public static final AttributeID ID_DELEGATE =
|
|
||||||
new AttributeID(0x0002, TYPE_BYTE, "Delegate", "PR_RCVD_REPRESENTING_xxx ");
|
|
||||||
public static final AttributeID ID_FROM =
|
|
||||||
new AttributeID(0x8000, TYPE_STRING, "From", "PR_SENDER_ENTRYID");
|
|
||||||
public static final AttributeID ID_MAPIPROPERTIES =
|
|
||||||
new AttributeID(0x9003, TYPE_BYTE, "MapiProperties", null);
|
|
||||||
public static final AttributeID ID_MESSAGECLASS =
|
|
||||||
new AttributeID(0x8008, TYPE_WORD, "MessageClass", "PR_MESSAGE_CLASS ");
|
|
||||||
public static final AttributeID ID_MESSAGEID =
|
|
||||||
new AttributeID(0x8009, TYPE_STRING, "MessageId", "PR_SEARCH_KEY");
|
|
||||||
public static final AttributeID ID_MESSAGESTATUS =
|
|
||||||
new AttributeID(0x8007, TYPE_BYTE, "MessageStatus", "PR_MESSAGE_FLAGS");
|
|
||||||
public static final AttributeID ID_NULL =
|
|
||||||
new AttributeID(0x0000, -1, "Null", null);
|
|
||||||
public static final AttributeID ID_OEMCODEPAGE =
|
|
||||||
new AttributeID(0x9007, TYPE_BYTE, "OemCodepage", "AttOemCodepage");
|
|
||||||
public static final AttributeID ID_ORIGINALMESSAGECLASS =
|
|
||||||
new AttributeID(0x0006, TYPE_WORD, "OriginalMessageClass", "PR_ORIG_MESSAGE_CLASS");
|
|
||||||
public static final AttributeID ID_OWNER =
|
|
||||||
new AttributeID(0x0000, TYPE_BYTE, "Owner", "PR_RCVD_REPRESENTING_xxx");
|
|
||||||
public static final AttributeID ID_PARENTID =
|
|
||||||
new AttributeID(0x800A, TYPE_STRING, "ParentId", "PR_PARENT_KEY");
|
|
||||||
public static final AttributeID ID_PRIORITY =
|
|
||||||
new AttributeID(0x800D, TYPE_SHORT, "Priority", "PR_IMPORTANCE");
|
|
||||||
public static final AttributeID ID_RECIPIENTTABLE =
|
|
||||||
new AttributeID(0x9004, TYPE_BYTE, "RecipientTable", "PR_MESSAGE_RECIPIENTS");
|
|
||||||
public static final AttributeID ID_REQUESTRESPONSE =
|
|
||||||
new AttributeID(0x009, TYPE_SHORT, "RequestResponse", "PR_RESPONSE_REQUESTED");
|
|
||||||
public static final AttributeID ID_SENTFOR =
|
|
||||||
new AttributeID(0x0001, TYPE_BYTE, "SentFor", "PR_SENT_REPRESENTING_xxx");
|
|
||||||
public static final AttributeID ID_SUBJECT =
|
|
||||||
new AttributeID(0x8004, TYPE_STRING, "Subject", "PR_SUBJECT");
|
|
||||||
public static final AttributeID ID_TNEFVERSION =
|
|
||||||
new AttributeID(0x9006, TYPE_DWORD, "TnefVersion", "attTnefVersion");
|
|
||||||
public static final AttributeID ID_UNKNOWN =
|
|
||||||
new AttributeID(-1, -1, "Unknown", null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds information on one potential ID of an
|
|
||||||
* attribute, and provides handy lookups for it.
|
|
||||||
*/
|
|
||||||
public static class AttributeID {
|
|
||||||
private static Map<Integer, List<AttributeID>> attributes = new HashMap<Integer, List<AttributeID>>();
|
|
||||||
|
|
||||||
public final int id;
|
|
||||||
public final int usualType;
|
|
||||||
public final String name;
|
|
||||||
public final String mapiProperty;
|
|
||||||
|
|
||||||
private AttributeID(int id, int usualType, String name, String mapiProperty) {
|
|
||||||
this.id = id;
|
|
||||||
this.usualType = usualType;
|
|
||||||
this.name = name;
|
|
||||||
this.mapiProperty = mapiProperty;
|
|
||||||
|
|
||||||
// Store it for lookup
|
|
||||||
if(! attributes.containsKey(id)) {
|
|
||||||
attributes.put(id, new ArrayList<AttributeID>());
|
|
||||||
}
|
|
||||||
attributes.get(id).add(this);
|
|
||||||
}
|
|
||||||
public static AttributeID getBest(int id, int type) {
|
|
||||||
List<AttributeID> attrs = attributes.get(id);
|
|
||||||
if(attrs == null) {
|
|
||||||
return ID_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there's only one, it's easy
|
|
||||||
if(attrs.size() == 1) {
|
|
||||||
return attrs.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try by type
|
|
||||||
for(AttributeID attr : attrs) {
|
|
||||||
if(attr.usualType == type) return attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go for the first if we can't otherwise decide...
|
|
||||||
return attrs.get(0);
|
|
||||||
}
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer str = new StringBuffer();
|
|
||||||
str.append(name);
|
|
||||||
str.append(" [");
|
|
||||||
str.append(id);
|
|
||||||
str.append("]");
|
|
||||||
if(mapiProperty != null) {
|
|
||||||
str.append(" (");
|
|
||||||
str.append(mapiProperty);
|
|
||||||
str.append(")");
|
|
||||||
}
|
|
||||||
return str.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final AttributeID id;
|
|
||||||
private final int type;
|
|
||||||
private final byte[] data;
|
|
||||||
private final int checksum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a single new attribute from
|
|
||||||
* the contents of the stream
|
|
||||||
*/
|
|
||||||
public Attribute(InputStream inp) throws IOException {
|
|
||||||
int id = LittleEndian.readUShort(inp);
|
|
||||||
this.type = LittleEndian.readUShort(inp);
|
|
||||||
int length = LittleEndian.readInt(inp);
|
|
||||||
|
|
||||||
this.id = AttributeID.getBest(id, type);
|
|
||||||
data = new byte[length];
|
|
||||||
IOUtils.readFully(inp, data);
|
|
||||||
|
|
||||||
checksum = LittleEndian.readUShort(inp);
|
|
||||||
|
|
||||||
// TODO Handle the MapiProperties attribute in
|
|
||||||
// a different way, as we need to recurse into it
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttributeID getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "Attachment " + getId().toString() + ", type=" + type +
|
|
||||||
", data length=" + data.length;
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,7 +22,9 @@ import java.io.InputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.hmef.Attribute.AttributeID;
|
import org.apache.poi.hmef.attribute.MAPIAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.TNEFAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.TNEFProperty;
|
||||||
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ public final class HMEFMessage {
|
|||||||
public static final long HEADER_SIGNATURE = 0x223e9f78;
|
public static final long HEADER_SIGNATURE = 0x223e9f78;
|
||||||
|
|
||||||
private int fileId;
|
private int fileId;
|
||||||
private List<Attribute> messageAttributes = new ArrayList<Attribute>();
|
private List<TNEFAttribute> messageAttributes = new ArrayList<TNEFAttribute>();
|
||||||
private List<MAPIAttribute> mapiAttributes = new ArrayList<MAPIAttribute>();
|
private List<MAPIAttribute> mapiAttributes = new ArrayList<MAPIAttribute>();
|
||||||
private List<Attachment> attachments = new ArrayList<Attachment>();
|
private List<Attachment> attachments = new ArrayList<Attachment>();
|
||||||
|
|
||||||
@ -59,16 +61,16 @@ public final class HMEFMessage {
|
|||||||
process(inp, 0);
|
process(inp, 0);
|
||||||
|
|
||||||
// Finally expand out the MAPI Attributes
|
// Finally expand out the MAPI Attributes
|
||||||
for(Attribute attr : messageAttributes) {
|
for(TNEFAttribute attr : messageAttributes) {
|
||||||
if(attr.getId() == Attribute.ID_MAPIPROPERTIES) {
|
if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) {
|
||||||
mapiAttributes.addAll(
|
mapiAttributes.addAll(
|
||||||
MAPIAttribute.create(attr)
|
MAPIAttribute.create(attr)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(Attachment attachment : attachments) {
|
for(Attachment attachment : attachments) {
|
||||||
for(Attribute attr : attachment.getAttributes()) {
|
for(TNEFAttribute attr : attachment.getAttributes()) {
|
||||||
if(attr.getId() == Attribute.ID_MAPIPROPERTIES) {
|
if(attr.getProperty()== TNEFProperty.ID_MAPIPROPERTIES) {
|
||||||
attachment.getMAPIAttributes().addAll(
|
attachment.getMAPIAttributes().addAll(
|
||||||
MAPIAttribute.create(attr)
|
MAPIAttribute.create(attr)
|
||||||
);
|
);
|
||||||
@ -80,19 +82,19 @@ public final class HMEFMessage {
|
|||||||
private void process(InputStream inp, int lastLevel) throws IOException {
|
private void process(InputStream inp, int lastLevel) throws IOException {
|
||||||
// Fetch the level
|
// Fetch the level
|
||||||
int level = inp.read();
|
int level = inp.read();
|
||||||
if(level == Attribute.LEVEL_END_OF_FILE) {
|
if(level == TNEFProperty.LEVEL_END_OF_FILE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the attribute
|
// Build the attribute
|
||||||
Attribute attr = new Attribute(inp);
|
TNEFAttribute attr = new TNEFAttribute(inp);
|
||||||
|
|
||||||
// Decide what to attach it to, based on the levels and IDs
|
// Decide what to attach it to, based on the levels and IDs
|
||||||
if(level == Attribute.LEVEL_MESSAGE) {
|
if(level == TNEFProperty.LEVEL_MESSAGE) {
|
||||||
messageAttributes.add(attr);
|
messageAttributes.add(attr);
|
||||||
} else if(level == Attribute.LEVEL_ATTACHMENT) {
|
} else if(level == TNEFProperty.LEVEL_ATTACHMENT) {
|
||||||
// Previous attachment or a new one?
|
// Previous attachment or a new one?
|
||||||
if(attachments.size() == 0 || attr.getId() == Attribute.ID_ATTACHRENDERDATA) {
|
if(attachments.size() == 0 || attr.getProperty() == TNEFProperty.ID_ATTACHRENDERDATA) {
|
||||||
attachments.add(new Attachment());
|
attachments.add(new Attachment());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +113,7 @@ public final class HMEFMessage {
|
|||||||
* Note - In a typical message, most of the interesting properties
|
* Note - In a typical message, most of the interesting properties
|
||||||
* are stored as {@link MAPIAttribute}s - see {@link #getMessageMAPIAttributes()}
|
* are stored as {@link MAPIAttribute}s - see {@link #getMessageMAPIAttributes()}
|
||||||
*/
|
*/
|
||||||
public List<Attribute> getMessageAttributes() {
|
public List<TNEFAttribute> getMessageAttributes() {
|
||||||
return messageAttributes;
|
return messageAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,9 +137,9 @@ public final class HMEFMessage {
|
|||||||
* Return the message attribute with the given ID,
|
* Return the message attribute with the given ID,
|
||||||
* or null if there isn't one.
|
* or null if there isn't one.
|
||||||
*/
|
*/
|
||||||
public Attribute getMessageAttribute(AttributeID id) {
|
public TNEFAttribute getMessageAttribute(TNEFProperty id) {
|
||||||
for(Attribute attr : messageAttributes) {
|
for(TNEFAttribute attr : messageAttributes) {
|
||||||
if(attr.getId() == id) {
|
if(attr.getProperty() == id) {
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hmef;
|
package org.apache.poi.hmef.attribute;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -23,6 +23,8 @@ import java.io.InputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
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.MAPIProperty;
|
||||||
import org.apache.poi.hsmf.datatypes.Types;
|
import org.apache.poi.hsmf.datatypes.Types;
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.util.HexDump;
|
||||||
@ -79,11 +81,11 @@ public class MAPIAttribute {
|
|||||||
* Parses a MAPI Properties TNEF Attribute, and returns
|
* Parses a MAPI Properties TNEF Attribute, and returns
|
||||||
* the list of MAPI Attributes contained within it
|
* the list of MAPI Attributes contained within it
|
||||||
*/
|
*/
|
||||||
public static List<MAPIAttribute> create(Attribute parent) throws IOException {
|
public static List<MAPIAttribute> create(TNEFAttribute parent) throws IOException {
|
||||||
if(parent.getId() != Attribute.ID_MAPIPROPERTIES) {
|
if(parent.getProperty() != TNEFProperty.ID_MAPIPROPERTIES) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can only create from a MAPIProperty attribute, " +
|
"Can only create from a MAPIProperty attribute, " +
|
||||||
"instead received a " + parent.getId() + " one"
|
"instead received a " + parent.getProperty() + " one"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ByteArrayInputStream inp = new ByteArrayInputStream(parent.getData());
|
ByteArrayInputStream inp = new ByteArrayInputStream(parent.getData());
|
@ -15,11 +15,14 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hmef;
|
package org.apache.poi.hmef.attribute;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hmef.Attachment;
|
||||||
|
import org.apache.poi.hmef.CompressedRTF;
|
||||||
|
import org.apache.poi.hmef.HMEFMessage;
|
||||||
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
|
|
@ -15,24 +15,15 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
package org.apache.poi.hmef;
|
package org.apache.poi.hmef.attribute;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.hmef.Attachment;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.hmef.HMEFMessage;
|
||||||
import org.apache.poi.util.LittleEndian;
|
|
||||||
import org.apache.poi.util.StringUtil;
|
|
||||||
import org.apache.poi.hmef.Attribute.AttributeID;
|
|
||||||
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
||||||
import org.apache.poi.hsmf.datatypes.Types;
|
import org.apache.poi.hsmf.datatypes.Types;
|
||||||
|
import org.apache.poi.util.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pure-MAPI attribute holding a String, which applies
|
* A pure-MAPI attribute holding a String, which applies
|
@ -0,0 +1,76 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.IOUtils;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An attribute which applies to a {@link HMEFMessage}
|
||||||
|
* or one of its {@link Attachment}s.
|
||||||
|
* 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 {
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public TNEFAttribute(InputStream inp) throws IOException {
|
||||||
|
int id = LittleEndian.readUShort(inp);
|
||||||
|
this.type = LittleEndian.readUShort(inp);
|
||||||
|
int length = LittleEndian.readInt(inp);
|
||||||
|
|
||||||
|
property = TNEFProperty.getBest(id, type);
|
||||||
|
data = new byte[length];
|
||||||
|
IOUtils.readFully(inp, data);
|
||||||
|
|
||||||
|
checksum = LittleEndian.readUShort(inp);
|
||||||
|
|
||||||
|
// TODO Handle the MapiProperties attribute in
|
||||||
|
// a different way, as we need to recurse into it
|
||||||
|
}
|
||||||
|
|
||||||
|
public TNEFProperty getProperty() {
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Attachment " + property.toString() + ", type=" + type +
|
||||||
|
", data length=" + data.length;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,216 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the list of TNEF Attributes, and allows lookup
|
||||||
|
* by friendly name, ID and MAPI Property Name.
|
||||||
|
*
|
||||||
|
* Note - the types and IDs differ from standard Outlook/MAPI
|
||||||
|
* ones, so we can't just re-use the HSMF ones.
|
||||||
|
*/
|
||||||
|
public final class TNEFProperty {
|
||||||
|
private static Map<Integer, List<TNEFProperty>> properties = new HashMap<Integer, List<TNEFProperty>>();
|
||||||
|
|
||||||
|
// Types taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributetype%28v=EXCHG.140%29.aspx
|
||||||
|
public static final int TYPE_TRIPLES = 0x0000;
|
||||||
|
public static final int TYPE_STRING = 0x0001;
|
||||||
|
public static final int TYPE_TEXT = 0x0002;
|
||||||
|
public static final int TYPE_DATE = 0x0003;
|
||||||
|
public static final int TYPE_SHORT = 0x0004;
|
||||||
|
public static final int TYPE_LONG = 0x0005;
|
||||||
|
public static final int TYPE_BYTE = 0x0006;
|
||||||
|
public static final int TYPE_WORD = 0x0007;
|
||||||
|
public static final int TYPE_DWORD = 0x0008;
|
||||||
|
public static final int TYPE_MAX = 0x0009;
|
||||||
|
|
||||||
|
// Types taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertytype%28v=EXCHG.140%29.aspx
|
||||||
|
/** AppTime - application time value */
|
||||||
|
public static final int PTYPE_APPTIME = 0x0007;
|
||||||
|
/** Binary - counted byte array */
|
||||||
|
public static final int PTYPE_BINARY = 0x0102;
|
||||||
|
/** Boolean - 16-bit Boolean value. '0' is false. Non-zero is true */
|
||||||
|
public static final int PTYPE_BOOLEAN = 0x000B;
|
||||||
|
/** ClassId - OLE GUID */
|
||||||
|
public static final int PTYPE_CLASSID = 0x0048;
|
||||||
|
/** 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 PTYPE_CURRENCY = 0x0006;
|
||||||
|
/** Double - floating point double */
|
||||||
|
public static final int PTYPE_DOUBLE = 0x0005;
|
||||||
|
/** Error - 32-bit error value */
|
||||||
|
public static final int PTYPE_ERROR = 0x000A;
|
||||||
|
/** I2 - signed 16-bit value */
|
||||||
|
public static final int PTYPE_I2 = 0x0002;
|
||||||
|
/** I8 - 8-byte signed integer */
|
||||||
|
public static final int PTYPE_I8 = 0x0014;
|
||||||
|
/** Long - signed 32-bit value */
|
||||||
|
public static final int PTYPE_LONG = 0x0003;
|
||||||
|
/** MultiValued - Value part contains multiple values */
|
||||||
|
public static final int PTYPE_MULTIVALUED = 0x1000;
|
||||||
|
/** Null - NULL property value */
|
||||||
|
public static final int PTYPE_NULL = 0x0001;
|
||||||
|
/** Object - embedded object in a property */
|
||||||
|
public static final int PTYPE_OBJECT = 0x000D;
|
||||||
|
/** R4 - 4-byte floating point value */
|
||||||
|
public static final int PTYPE_R4 = 0x0004;
|
||||||
|
/** String8 - null-terminated 8-bit character string */
|
||||||
|
public static final int PTYPE_STRING8 = 0x001E;
|
||||||
|
/** SysTime - FILETIME 64-bit integer specifying the number of 100ns periods since Jan 1, 1601 */
|
||||||
|
public static final int PTYPE_SYSTIME = 0x0040;
|
||||||
|
/** Unicode - null-terminated Unicode string */
|
||||||
|
public static final int PTYPE_UNICODE = 0x001F;
|
||||||
|
/** Unspecified */
|
||||||
|
public static final int PTYPE_UNSPECIFIED = 0x0000;
|
||||||
|
|
||||||
|
|
||||||
|
// Levels taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributelevel%28v=EXCHG.140%29.aspx
|
||||||
|
public static final int LEVEL_MESSAGE = 0x01;
|
||||||
|
public static final int LEVEL_ATTACHMENT = 0x02;
|
||||||
|
public static final int LEVEL_END_OF_FILE = -0x01;
|
||||||
|
|
||||||
|
// ID information taken from http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefattributetag%28v=EXCHG.140%29.aspx
|
||||||
|
public static final TNEFProperty ID_AIDOWNER =
|
||||||
|
new TNEFProperty(0x0008, TYPE_LONG, "AidOwner", "PR_OWNER_APPT_ID");
|
||||||
|
public static final TNEFProperty ID_ATTACHCREATEDATE =
|
||||||
|
new TNEFProperty(0x8012, TYPE_DATE, "AttachCreateDate", "PR_CREATION_TIME");
|
||||||
|
public static final TNEFProperty ID_ATTACHDATA =
|
||||||
|
new TNEFProperty(0x800F, TYPE_BYTE, "AttachData", "PR_ATTACH_DATA_BIN");
|
||||||
|
public static final TNEFProperty ID_ATTACHMENT =
|
||||||
|
new TNEFProperty(0x9005, TYPE_BYTE, "Attachment", null);
|
||||||
|
public static final TNEFProperty ID_ATTACHMETAFILE =
|
||||||
|
new TNEFProperty(0x8011, TYPE_BYTE, "AttachMetaFile", "PR_ATTACH_RENDERING");
|
||||||
|
public static final TNEFProperty ID_ATTACHMODIFYDATE =
|
||||||
|
new TNEFProperty(0x8013, TYPE_DATE, "AttachModifyDate", "PR_LAST_MODIFICATION_TIME");
|
||||||
|
public static final TNEFProperty ID_ATTACHRENDERDATA =
|
||||||
|
new TNEFProperty(0x9002, TYPE_BYTE, "AttachRenderData", "attAttachRenddata");
|
||||||
|
public static final TNEFProperty ID_ATTACHTITLE =
|
||||||
|
new TNEFProperty(0x8010, TYPE_STRING, "AttachTitle", "PR_ATTACH_FILENAME");
|
||||||
|
public static final TNEFProperty ID_ATTACHTRANSPORTFILENAME =
|
||||||
|
new TNEFProperty(0x9001, TYPE_BYTE, "AttachTransportFilename", "PR_ATTACH_TRANSPORT_NAME");
|
||||||
|
public static final TNEFProperty ID_BODY =
|
||||||
|
new TNEFProperty(0x800C, TYPE_TEXT, "Body", "PR_BODY");
|
||||||
|
public static final TNEFProperty ID_CONVERSATIONID =
|
||||||
|
new TNEFProperty(0x800B, TYPE_STRING, "ConversationId", "PR_CONVERSATION_KEY");
|
||||||
|
public static final TNEFProperty ID_DATEEND =
|
||||||
|
new TNEFProperty(0x0007, TYPE_DATE, "DateEnd", "PR_END_DATE");
|
||||||
|
public static final TNEFProperty ID_DATEMODIFIED =
|
||||||
|
new TNEFProperty(0x8020, TYPE_DATE, "DateModified", "PR_LAST_MODIFICATION_TIME ");
|
||||||
|
public static final TNEFProperty ID_DATERECEIVED =
|
||||||
|
new TNEFProperty(0x8006, TYPE_DATE, "DateReceived", "PR_MESSAGE_DELIVERY_TIME ");
|
||||||
|
public static final TNEFProperty ID_DATESENT =
|
||||||
|
new TNEFProperty(0x8005, TYPE_DATE, "DateSent", "PR_CLIENT_SUBMIT_TIME ");
|
||||||
|
public static final TNEFProperty ID_DATESTART =
|
||||||
|
new TNEFProperty(0x0006, TYPE_DATE, "DateStart", "PR_START_DATE ");
|
||||||
|
public static final TNEFProperty ID_DELEGATE =
|
||||||
|
new TNEFProperty(0x0002, TYPE_BYTE, "Delegate", "PR_RCVD_REPRESENTING_xxx ");
|
||||||
|
public static final TNEFProperty ID_FROM =
|
||||||
|
new TNEFProperty(0x8000, TYPE_STRING, "From", "PR_SENDER_ENTRYID");
|
||||||
|
public static final TNEFProperty ID_MAPIPROPERTIES =
|
||||||
|
new TNEFProperty(0x9003, TYPE_BYTE, "MapiProperties", null);
|
||||||
|
public static final TNEFProperty ID_MESSAGECLASS =
|
||||||
|
new TNEFProperty(0x8008, TYPE_WORD, "MessageClass", "PR_MESSAGE_CLASS ");
|
||||||
|
public static final TNEFProperty ID_MESSAGEID =
|
||||||
|
new TNEFProperty(0x8009, TYPE_STRING, "MessageId", "PR_SEARCH_KEY");
|
||||||
|
public static final TNEFProperty ID_MESSAGESTATUS =
|
||||||
|
new TNEFProperty(0x8007, TYPE_BYTE, "MessageStatus", "PR_MESSAGE_FLAGS");
|
||||||
|
public static final TNEFProperty ID_NULL =
|
||||||
|
new TNEFProperty(0x0000, -1, "Null", null);
|
||||||
|
public static final TNEFProperty ID_OEMCODEPAGE =
|
||||||
|
new TNEFProperty(0x9007, TYPE_BYTE, "OemCodepage", "AttOemCodepage");
|
||||||
|
public static final TNEFProperty ID_ORIGINALMESSAGECLASS =
|
||||||
|
new TNEFProperty(0x0006, TYPE_WORD, "OriginalMessageClass", "PR_ORIG_MESSAGE_CLASS");
|
||||||
|
public static final TNEFProperty ID_OWNER =
|
||||||
|
new TNEFProperty(0x0000, TYPE_BYTE, "Owner", "PR_RCVD_REPRESENTING_xxx");
|
||||||
|
public static final TNEFProperty ID_PARENTID =
|
||||||
|
new TNEFProperty(0x800A, TYPE_STRING, "ParentId", "PR_PARENT_KEY");
|
||||||
|
public static final TNEFProperty ID_PRIORITY =
|
||||||
|
new TNEFProperty(0x800D, TYPE_SHORT, "Priority", "PR_IMPORTANCE");
|
||||||
|
public static final TNEFProperty ID_RECIPIENTTABLE =
|
||||||
|
new TNEFProperty(0x9004, TYPE_BYTE, "RecipientTable", "PR_MESSAGE_RECIPIENTS");
|
||||||
|
public static final TNEFProperty ID_REQUESTRESPONSE =
|
||||||
|
new TNEFProperty(0x009, TYPE_SHORT, "RequestResponse", "PR_RESPONSE_REQUESTED");
|
||||||
|
public static final TNEFProperty ID_SENTFOR =
|
||||||
|
new TNEFProperty(0x0001, TYPE_BYTE, "SentFor", "PR_SENT_REPRESENTING_xxx");
|
||||||
|
public static final TNEFProperty ID_SUBJECT =
|
||||||
|
new TNEFProperty(0x8004, TYPE_STRING, "Subject", "PR_SUBJECT");
|
||||||
|
public static final TNEFProperty ID_TNEFVERSION =
|
||||||
|
new TNEFProperty(0x9006, TYPE_DWORD, "TnefVersion", "attTnefVersion");
|
||||||
|
public static final TNEFProperty ID_UNKNOWN =
|
||||||
|
new TNEFProperty(-1, -1, "Unknown", null);
|
||||||
|
|
||||||
|
/** The TNEF Property ID */
|
||||||
|
public final int id;
|
||||||
|
/** Usual Type */
|
||||||
|
public final int usualType;
|
||||||
|
/** Property Name */
|
||||||
|
public final String name;
|
||||||
|
/** Equivalent MAPI Property */
|
||||||
|
public final String mapiProperty;
|
||||||
|
|
||||||
|
private TNEFProperty(int id, int usualType, String name, String mapiProperty) {
|
||||||
|
this.id = id;
|
||||||
|
this.usualType = usualType;
|
||||||
|
this.name = name;
|
||||||
|
this.mapiProperty = mapiProperty;
|
||||||
|
|
||||||
|
// Store it for lookup
|
||||||
|
if(! properties.containsKey(id)) {
|
||||||
|
properties.put(id, new ArrayList<TNEFProperty>());
|
||||||
|
}
|
||||||
|
properties.get(id).add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TNEFProperty getBest(int id, int type) {
|
||||||
|
List<TNEFProperty> attrs = properties.get(id);
|
||||||
|
if(attrs == null) {
|
||||||
|
return ID_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's only one, it's easy
|
||||||
|
if(attrs.size() == 1) {
|
||||||
|
return attrs.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try by type
|
||||||
|
for(TNEFProperty attr : attrs) {
|
||||||
|
if(attr.usualType == type) return attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go for the first if we can't otherwise decide...
|
||||||
|
return attrs.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer str = new StringBuffer();
|
||||||
|
str.append(name);
|
||||||
|
str.append(" [");
|
||||||
|
str.append(id);
|
||||||
|
str.append("]");
|
||||||
|
if(mapiProperty != null) {
|
||||||
|
str.append(" (");
|
||||||
|
str.append(mapiProperty);
|
||||||
|
str.append(")");
|
||||||
|
}
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -22,9 +22,10 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.hmef.Attribute;
|
|
||||||
import org.apache.poi.hmef.HMEFMessage;
|
import org.apache.poi.hmef.HMEFMessage;
|
||||||
import org.apache.poi.hmef.MAPIAttribute;
|
import org.apache.poi.hmef.attribute.TNEFAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.MAPIAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.TNEFProperty;
|
||||||
import org.apache.poi.util.HexDump;
|
import org.apache.poi.util.HexDump;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
@ -82,17 +83,17 @@ public final class HMEFDumper {
|
|||||||
while(true) {
|
while(true) {
|
||||||
// Fetch the level
|
// Fetch the level
|
||||||
level = inp.read();
|
level = inp.read();
|
||||||
if(level == Attribute.LEVEL_END_OF_FILE) {
|
if(level == TNEFProperty.LEVEL_END_OF_FILE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the attribute
|
// Build the attribute
|
||||||
Attribute attr = new Attribute(inp);
|
TNEFAttribute attr = new TNEFAttribute(inp);
|
||||||
|
|
||||||
// Print the attribute into
|
// Print the attribute into
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"Level " + level + " : Type " + attr.getType() +
|
"Level " + level + " : Type " + attr.getType() +
|
||||||
" : ID " + attr.getId().toString()
|
" : ID " + attr.getProperty().toString()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Print the contents
|
// Print the contents
|
||||||
@ -124,7 +125,7 @@ public final class HMEFDumper {
|
|||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
if(attr.getId() == Attribute.ID_MAPIPROPERTIES) {
|
if(attr.getProperty() == TNEFProperty.ID_MAPIPROPERTIES) {
|
||||||
List<MAPIAttribute> attrs = MAPIAttribute.create(attr);
|
List<MAPIAttribute> attrs = MAPIAttribute.create(attr);
|
||||||
for(MAPIAttribute ma : attrs) {
|
for(MAPIAttribute ma : attrs) {
|
||||||
System.out.println(indent + indent + ma);
|
System.out.println(indent + indent + ma);
|
||||||
|
@ -22,7 +22,8 @@ import java.io.ByteArrayInputStream;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
import org.apache.poi.hmef.Attribute.AttributeID;
|
import org.apache.poi.hmef.attribute.MAPIAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.MAPIRtfAttribute;
|
||||||
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
import org.apache.poi.hsmf.datatypes.MAPIProperty;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
|
@ -20,6 +20,8 @@ package org.apache.poi.hmef;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
|
import org.apache.poi.hmef.attribute.TNEFAttribute;
|
||||||
|
import org.apache.poi.hmef.attribute.TNEFProperty;
|
||||||
|
|
||||||
public final class TestHMEFMessage extends TestCase {
|
public final class TestHMEFMessage extends TestCase {
|
||||||
private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
|
private static final POIDataSamples _samples = POIDataSamples.getHMEFInstance();
|
||||||
@ -70,20 +72,20 @@ public final class TestHMEFMessage extends TestCase {
|
|||||||
|
|
||||||
// Should have version, codepage, class and MAPI
|
// Should have version, codepage, class and MAPI
|
||||||
assertEquals(4, msg.getMessageAttributes().size());
|
assertEquals(4, msg.getMessageAttributes().size());
|
||||||
assertNotNull(msg.getMessageAttribute(Attribute.ID_TNEFVERSION));
|
assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_TNEFVERSION));
|
||||||
assertNotNull(msg.getMessageAttribute(Attribute.ID_OEMCODEPAGE));
|
assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_OEMCODEPAGE));
|
||||||
assertNotNull(msg.getMessageAttribute(Attribute.ID_MESSAGECLASS));
|
assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_MESSAGECLASS));
|
||||||
assertNotNull(msg.getMessageAttribute(Attribute.ID_MAPIPROPERTIES));
|
assertNotNull(msg.getMessageAttribute(TNEFProperty.ID_MAPIPROPERTIES));
|
||||||
|
|
||||||
// Check the order
|
// Check the order
|
||||||
assertEquals(Attribute.ID_TNEFVERSION, msg.getMessageAttributes().get(0).getId());
|
assertEquals(TNEFProperty.ID_TNEFVERSION, msg.getMessageAttributes().get(0).getProperty());
|
||||||
assertEquals(Attribute.ID_OEMCODEPAGE, msg.getMessageAttributes().get(1).getId());
|
assertEquals(TNEFProperty.ID_OEMCODEPAGE, msg.getMessageAttributes().get(1).getProperty());
|
||||||
assertEquals(Attribute.ID_MESSAGECLASS, msg.getMessageAttributes().get(2).getId());
|
assertEquals(TNEFProperty.ID_MESSAGECLASS, msg.getMessageAttributes().get(2).getProperty());
|
||||||
assertEquals(Attribute.ID_MAPIPROPERTIES, msg.getMessageAttributes().get(3).getId());
|
assertEquals(TNEFProperty.ID_MAPIPROPERTIES, msg.getMessageAttributes().get(3).getProperty());
|
||||||
|
|
||||||
// Check some that aren't there
|
// Check some that aren't there
|
||||||
assertNull(msg.getMessageAttribute(Attribute.ID_AIDOWNER));
|
assertNull(msg.getMessageAttribute(TNEFProperty.ID_AIDOWNER));
|
||||||
assertNull(msg.getMessageAttribute(Attribute.ID_ATTACHDATA));
|
assertNull(msg.getMessageAttribute(TNEFProperty.ID_ATTACHDATA));
|
||||||
|
|
||||||
// Now check the details of one or two
|
// Now check the details of one or two
|
||||||
// TODO
|
// TODO
|
||||||
|
Loading…
Reference in New Issue
Block a user