In preparation for reading the HSMF __properties stream, improve the Types support to be a class with ID+Name+Length, rather than simply an ID. Allows some tidying in HMEF. (Also stubs a few properties bits)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1358802 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2012-07-08 18:05:17 +00:00
parent 0057c05051
commit 4088217930
19 changed files with 359 additions and 222 deletions

View File

@ -34,6 +34,7 @@
<changes>
<release version="3.9-beta1" date="2012-??-??">
<action dev="poi-developers" type="add">Change HSMF Types to have full data on ID, Name and Length, rather than just being a simple ID</action>
<action dev="poi-developers" type="add">48469 - Updated case study</action>
<action dev="poi-developers" type="add">53476 - Support Complex Name in formulas </action>
<action dev="poi-developers" type="fix">53414 - properly update sheet dimensions when adding column </action>

View File

@ -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);
}
}

View File

@ -37,13 +37,13 @@ public final class MAPIStringAttribute extends MAPIAttribute {
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);

View File

@ -39,9 +39,9 @@ import org.apache.poi.hsmf.datatypes.Chunks;
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 POIDocument {
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) {

View File

@ -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);
}

View File

@ -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;

View File

@ -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.DirectoryNode;
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;
}

View File

@ -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,7 +1023,7 @@ 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
private static final int ID_FIRST_CUSTOM = 0x8000;
@ -1027,11 +1032,11 @@ public class MAPIProperty {
/* --------------------------------------------------------------------- */
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 +1082,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);
}
}

View File

@ -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 extends Chunk {
/**
* 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 extends Chunk {
* Create a Byte Chunk, with the specified
* type.
*/
public MessageSubmissionChunk(int chunkId, int type) {
public MessageSubmissionChunk(int chunkId, MAPIType type) {
super(chunkId, type);
}

View File

@ -0,0 +1,50 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hsmf.datatypes;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* A Chunk which holds fixed-length properties, and pointer
* to the variable length ones (which get their own chunk)
*/
public class PropertiesChunk extends Chunk {
public static final String PREFIX = "__properties_version1.0";
/**
* Creates a Properties Chunk.
*/
public PropertiesChunk() {
super(PREFIX, -1, Types.UNKNOWN);
}
@Override
public String getEntryName() {
return PREFIX;
}
public void readValue(InputStream value) throws IOException {
// TODO
}
public void writeValue(OutputStream out) throws IOException {
// TODO
}
}

View File

@ -0,0 +1,31 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.hsmf.datatypes;
/**
* An instance of a {@link MAPIProperty} inside a {@link PropertiesChunk}.
* Where the {@link Types} type is a fixed length one, this will contain the
* actual value.
* Where the {@link Types} type is a variable length one, this will contain
* the length of the property, and the value will be in the associated {@link Chunk}.
*/
public class PropertyValue {
private MAPIProperty property;
private long flags;
private byte[] data;
}

View File

@ -23,6 +23,7 @@ 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 +39,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 +47,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 +82,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 +98,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");
}
}

View File

@ -17,56 +17,119 @@
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>();
/** 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;
}
/**
* 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 +138,18 @@ 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 "0x" + Integer.toHexString(type);
return asCustomName(typeId);
}
private static String asCustomName(int typeId) {
return "0x" + Integer.toHexString(typeId);
}
public static MAPIType createCustom(int typeId) {
return new MAPIType(typeId, -1);
}
}

View File

@ -23,7 +23,6 @@ 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.parsers.POIFSChunkParser;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@ -49,8 +48,7 @@ public class HSMFDump {
}
System.out.println(
" " + idName + " - " +
Types.asName(chunk.getType())
" " + idName + " - " + chunk.getType().getName()
);
System.out.println(
" " + chunk.toString()

View File

@ -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);
}
}

View File

@ -32,6 +32,7 @@ import org.apache.poi.hsmf.datatypes.NameIdChunks;
import org.apache.poi.hsmf.datatypes.RecipientChunks;
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;
@ -97,7 +98,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);
}
}
@ -141,7 +142,12 @@ public final class POIFSChunkParser {
// 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);
int typeId = Integer.parseInt(ids.substring(4, 8), 16);
MAPIType type = Types.getById(typeId);
if (type == null) {
type = Types.createCustom(typeId);
}
Chunk chunk = null;
@ -152,19 +158,20 @@ public final class POIFSChunkParser {
else {
// Nothing special about this ID
// So, do the usual thing which is by type
switch(type) {
case Types.BINARY:
if (type == Types.BINARY) {
chunk = new ByteChunk(namePrefix, chunkId, type);
break;
case Types.DIRECTORY:
}
else if (type == Types.DIRECTORY) {
if(entry instanceof DirectoryNode) {
chunk = new DirectoryChunk((DirectoryNode)entry, namePrefix, chunkId, type);
}
break;
case Types.ASCII_STRING:
case Types.UNICODE_STRING:
}
else if (type == Types.ASCII_STRING ||
type == Types.UNICODE_STRING) {
chunk = new StringChunk(namePrefix, chunkId, type);
break;
}
else {
// Type of an unsupported type! Skipping...
}
}

View File

@ -30,24 +30,29 @@ public final class TestChunkData extends TestCase {
public void testChunkCreate() {
Chunk chunk;
chunk = new StringChunk(0x0200, 0x001E);
chunk = new StringChunk(0x0200, Types.createCustom(0x001E));
assertEquals("__substg1.0_0200001E", chunk.getEntryName());
assertEquals(0x0200, chunk.getChunkId());
assertEquals(0x001E, chunk.getType());
assertEquals(0x001E, chunk.getType().getId());
chunk = new StringChunk("__substg1.0_", 0x0200, 0x001E);
chunk = new StringChunk("__substg1.0_", 0x0200, Types.createCustom(0x001E));
assertEquals("__substg1.0_0200001E", chunk.getEntryName());
assertEquals(0x0200, chunk.getChunkId());
assertEquals(0x001E, chunk.getType());
assertEquals(0x001E, chunk.getType().getId());
chunk = new StringChunk("__substg1.0_", 0x0200, Types.getById(0x001E));
assertEquals("__substg1.0_0200001E", chunk.getEntryName());
assertEquals(0x0200, chunk.getChunkId());
assertEquals(0x001E, chunk.getType().getId());
/* test the lower and upper limits of the chunk ids */
chunk = new StringChunk(0x0000, 0x001E);
chunk = new StringChunk(0x0000, Types.createCustom(0x001E));
assertEquals("__substg1.0_0000001E", chunk.getEntryName());
chunk = new StringChunk(0xFFFF, 0x001E);
chunk = new StringChunk(0xFFFF, Types.createCustom(0x001E));
assertEquals("__substg1.0_FFFF001E", chunk.getEntryName());
chunk = new StringChunk(0xFFFF, 0x001F);
chunk = new StringChunk(0xFFFF, Types.createCustom(0x001F));
assertEquals("__substg1.0_FFFF001F", chunk.getEntryName());
}

View File

@ -37,16 +37,16 @@ public final class TestMAPIProperty extends TestCase {
assertEquals(true, all.contains(MAPIProperty.DISPLAY_CC));
// Won't contain custom
assertEquals(false, all.contains(MAPIProperty.createCustom(1, 1, "")));
assertEquals(false, all.contains(MAPIProperty.createCustom(1, Types.UNSPECIFIED, "")));
// Won't contain unknown
assertEquals(false, all.contains(MAPIProperty.UNKNOWN));
}
public void testCustom() throws Exception {
MAPIProperty c1 = MAPIProperty.createCustom(1, 1, "");
MAPIProperty c2a = MAPIProperty.createCustom(2, 1, "2");
MAPIProperty c2b = MAPIProperty.createCustom(2, 1, "2");
MAPIProperty c1 = MAPIProperty.createCustom(1, Types.UNSPECIFIED, "");
MAPIProperty c2a = MAPIProperty.createCustom(2, Types.UNSPECIFIED, "2");
MAPIProperty c2b = MAPIProperty.createCustom(2, Types.UNSPECIFIED, "2");
// New object each time
assertNotSame(c1, c2a);

View File

@ -28,13 +28,21 @@ import junit.framework.TestCase;
*/
public final class TestTypes extends TestCase {
public void testTypeIds() {
assertEquals(0x1e, Types.ASCII_STRING);
assertEquals(0x1f, Types.UNICODE_STRING);
assertEquals(0x1e, Types.ASCII_STRING.getId());
assertEquals(0x1f, Types.UNICODE_STRING.getId());
assertEquals(0x0102, Types.BINARY);
assertEquals(0x000B, Types.BOOLEAN);
assertEquals(0x0003, Types.LONG);
assertEquals(0x0040, Types.TIME);
assertEquals(0x0102, Types.BINARY.getId());
assertEquals(0x000B, Types.BOOLEAN.getId());
assertEquals(0x0003, Types.LONG.getId());
assertEquals(0x0040, Types.TIME.getId());
assertEquals(Types.ASCII_STRING, Types.getById(0x1e));
assertEquals(Types.UNICODE_STRING, Types.getById(0x1f));
assertEquals(Types.BINARY, Types.getById(0x0102));
assertEquals(Types.BOOLEAN, Types.getById(0x000B));
assertEquals(Types.LONG, Types.getById(0x0003));
assertEquals(Types.TIME, Types.getById(0x0040));
}
public void testTypeFormatting() {
@ -45,7 +53,7 @@ public final class TestTypes extends TestCase {
}
public void testName() {
assertEquals("ASCII String", Types.asName(Types.ASCII_STRING));
assertEquals("Boolean", Types.asName(Types.BOOLEAN));
assertEquals("ASCII String", Types.ASCII_STRING.getName());
assertEquals("Boolean", Types.BOOLEAN.getName());
}
}