reindent code - prepare for cleanups
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1773544 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f27507244c
commit
6a8cb7493c
@ -34,7 +34,8 @@ import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* Collection of convenience chunks for standard parts of the MSG file attachment.
|
||||
* Collection of convenience chunks for standard parts of the MSG file
|
||||
* attachment.
|
||||
*/
|
||||
public class AttachmentChunks implements ChunkGroup {
|
||||
private static POILogger logger = POILogFactory.getLogger(AttachmentChunks.class);
|
||||
@ -48,9 +49,8 @@ public class AttachmentChunks implements ChunkGroup {
|
||||
public DirectoryChunk attachmentDirectory;
|
||||
|
||||
/**
|
||||
* This is in WMF Format. You'll probably want to pass it
|
||||
* to Apache Batik to turn it into a SVG that you can
|
||||
* then display.
|
||||
* This is in WMF Format. You'll probably want to pass it to Apache Batik to
|
||||
* turn it into a SVG that you can then display.
|
||||
*/
|
||||
public ByteChunk attachRenderingWMF;
|
||||
|
||||
@ -62,21 +62,20 @@ public class AttachmentChunks implements ChunkGroup {
|
||||
/** Holds all the chunks that were found. */
|
||||
private List<Chunk> allChunks = new ArrayList<Chunk>();
|
||||
|
||||
|
||||
public AttachmentChunks(String poifsName) {
|
||||
this.poifsName = poifsName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is this Attachment an embedded MAPI message?
|
||||
*/
|
||||
public boolean isEmbeddedMessage() {
|
||||
return (attachmentDirectory != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the embedded MAPI message, if the attachment
|
||||
* is an embedded message, or null otherwise
|
||||
* Returns the embedded MAPI message, if the attachment is an embedded
|
||||
* message, or null otherwise
|
||||
*/
|
||||
public MAPIMessage getEmbeddedMessage() throws IOException {
|
||||
if (attachmentDirectory != null) {
|
||||
@ -86,9 +85,8 @@ public class AttachmentChunks implements ChunkGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the embedded object, if the attachment is an
|
||||
* object based embedding (image, document etc), or null
|
||||
* if it's an embedded message
|
||||
* Returns the embedded object, if the attachment is an object based
|
||||
* embedding (image, document etc), or null if it's an embedded message
|
||||
*/
|
||||
public byte[] getEmbeddedAttachmentObject() {
|
||||
if (attachData != null) {
|
||||
@ -100,6 +98,7 @@ public class AttachmentChunks implements ChunkGroup {
|
||||
public Chunk[] getAll() {
|
||||
return allChunks.toArray(new Chunk[allChunks.size()]);
|
||||
}
|
||||
|
||||
public Chunk[] getChunks() {
|
||||
return getAll();
|
||||
}
|
||||
@ -147,19 +146,18 @@ public class AttachmentChunks implements ChunkGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to flag that all the chunks of the attachment
|
||||
* have now been located.
|
||||
* Used to flag that all the chunks of the attachment have now been located.
|
||||
*/
|
||||
public void chunksComplete() {
|
||||
// Currently, we don't need to do anything special once
|
||||
// all the chunks have been located
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Orders by the attachment number.
|
||||
*/
|
||||
public static class AttachmentChunksSorter implements Comparator<AttachmentChunks>, Serializable {
|
||||
public static class AttachmentChunksSorter
|
||||
implements Comparator<AttachmentChunks>, Serializable {
|
||||
public int compare(AttachmentChunks a, AttachmentChunks b) {
|
||||
return a.poifsName.compareTo(b.poifsName);
|
||||
}
|
||||
|
@ -24,10 +24,9 @@ import org.apache.poi.hsmf.datatypes.Types.MAPIType;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
|
||||
/**
|
||||
* A Chunk that holds binary data, normally unparsed.
|
||||
* Generally as we know how to make sense of the
|
||||
* contents, we create a new Chunk class and add
|
||||
* a special case in the parser for them.
|
||||
* A Chunk that holds binary data, normally unparsed. Generally as we know how
|
||||
* to make sense of the contents, we create a new Chunk class and add a special
|
||||
* case in the parser for them.
|
||||
*/
|
||||
|
||||
public class ByteChunk extends Chunk {
|
||||
@ -39,9 +38,9 @@ public class ByteChunk extends Chunk {
|
||||
public ByteChunk(String namePrefix, int chunkId, MAPIType type) {
|
||||
super(namePrefix, chunkId, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Byte Chunk, with the specified
|
||||
* type.
|
||||
* Create a Byte Chunk, with the specified type.
|
||||
*/
|
||||
public ByteChunk(int chunkId, MAPIType type) {
|
||||
super(chunkId, type);
|
||||
@ -58,6 +57,7 @@ public class ByteChunk extends Chunk {
|
||||
public byte[] getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(byte[] value) {
|
||||
this.value = value;
|
||||
}
|
||||
@ -70,9 +70,8 @@ public class ByteChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the byte array in a debug-friendly way,
|
||||
* showing all of a short array, and the start of a
|
||||
* longer one.
|
||||
* Formats the byte array in a debug-friendly way, showing all of a short
|
||||
* array, and the start of a longer one.
|
||||
*/
|
||||
protected static String toDebugFriendlyString(byte[] value) {
|
||||
if (value == null)
|
||||
@ -99,11 +98,10 @@ public class ByteChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data, formatted as a string assuming it
|
||||
* was a non-unicode string.
|
||||
* If your data isn't in fact stored as basically
|
||||
* ASCII, don't expect this to return much of any
|
||||
* sense....
|
||||
* Returns the data, formatted as a string assuming it was a non-unicode
|
||||
* string. If your data isn't in fact stored as basically ASCII, don't
|
||||
* expect this to return much of any sense....
|
||||
*
|
||||
* @return the data formatted as a string
|
||||
*/
|
||||
public String getAs7bitString() {
|
||||
|
@ -36,6 +36,7 @@ public abstract class Chunk {
|
||||
this.chunkId = chunkId;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
protected Chunk(int chunkId, MAPIType type) {
|
||||
this(DEFAULT_NAME_PREFIX, chunkId, type);
|
||||
}
|
||||
@ -55,15 +56,18 @@ public abstract class Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string to use to identify this chunk in the POI file system object.
|
||||
* Creates a string to use to identify this chunk in the POI file system
|
||||
* object.
|
||||
*/
|
||||
public String getEntryName() {
|
||||
String type = this.type.asFileEnding();
|
||||
|
||||
String chunkId = Integer.toHexString(this.chunkId);
|
||||
while(chunkId.length() < 4) chunkId = "0" + chunkId;
|
||||
while (chunkId.length() < 4)
|
||||
chunkId = "0" + chunkId;
|
||||
|
||||
return this.namePrefix + chunkId.toUpperCase(Locale.ROOT)
|
||||
return this.namePrefix
|
||||
+ chunkId.toUpperCase(Locale.ROOT)
|
||||
+ type.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
package org.apache.poi.hsmf.datatypes;
|
||||
|
||||
|
||||
/**
|
||||
* A variable length {@link PropertyValue} that is
|
||||
* backed by a {@link Chunk}
|
||||
* A variable length {@link PropertyValue} that is backed by a {@link Chunk}
|
||||
* TODO Provide a way to link these up with the chunks
|
||||
*/
|
||||
public class ChunkBasedPropertyValue extends PropertyValue {
|
||||
|
@ -18,14 +18,12 @@
|
||||
package org.apache.poi.hsmf.datatypes;
|
||||
|
||||
/**
|
||||
* A group of chunks, that are at the same point in the
|
||||
* file structure.
|
||||
* A group of chunks, that are at the same point in the file structure.
|
||||
*/
|
||||
public interface ChunkGroup {
|
||||
/**
|
||||
* Returns the chunks that make up the group.
|
||||
* Should certainly contain all the interesting Chunks,
|
||||
* but needn't always contain all of the Chunks.
|
||||
* Returns the chunks that make up the group. Should certainly contain all
|
||||
* the interesting Chunks, but needn't always contain all of the Chunks.
|
||||
*/
|
||||
public Chunk[] getChunks();
|
||||
|
||||
|
@ -21,18 +21,15 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A group of chunks which is indexable by {@link MAPIProperty}
|
||||
* entries.
|
||||
* A group of chunks which is indexable by {@link MAPIProperty} entries.
|
||||
*/
|
||||
public interface ChunkGroupWithProperties extends ChunkGroup {
|
||||
/**
|
||||
* Returns all the Properties contained in the Chunk, along
|
||||
* with their Values.
|
||||
* Normally, each property will have one value, sometimes
|
||||
* none, and rarely multiple (normally for Unknown etc).
|
||||
* For fixed sized properties, the value can be fetched
|
||||
* straight from the {@link PropertyValue}. For variable
|
||||
* sized properties, you'll need to go via the chunk.
|
||||
* Returns all the Properties contained in the Chunk, along with their
|
||||
* Values. Normally, each property will have one value, sometimes none, and
|
||||
* rarely multiple (normally for Unknown etc). For fixed sized properties,
|
||||
* the value can be fetched straight from the {@link PropertyValue}. For
|
||||
* variable sized properties, you'll need to go via the chunk.
|
||||
*/
|
||||
public Map<MAPIProperty, List<PropertyValue>> getProperties();
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import java.util.Map;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of convenience chunks for standard parts of the MSG file.
|
||||
*
|
||||
@ -87,19 +86,21 @@ public final class Chunks implements ChunkGroupWithProperties {
|
||||
public Map<MAPIProperty, List<PropertyValue>> getProperties() {
|
||||
if (messageProperties != null) {
|
||||
return messageProperties.getProperties();
|
||||
} else
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
else return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public Map<MAPIProperty, PropertyValue> getRawProperties() {
|
||||
if (messageProperties != null) {
|
||||
return messageProperties.getRawProperties();
|
||||
}
|
||||
else return Collections.emptyMap();
|
||||
} else
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public Map<MAPIProperty, List<Chunk>> getAll() {
|
||||
return allChunks;
|
||||
}
|
||||
|
||||
public Chunk[] getChunks() {
|
||||
ArrayList<Chunk> chunks = new ArrayList<Chunk>(allChunks.size());
|
||||
for (List<Chunk> c : allChunks.values()) {
|
||||
@ -118,62 +119,49 @@ public final class Chunks implements ChunkGroupWithProperties {
|
||||
// Assign it for easy lookup, as best we can
|
||||
if (prop == MAPIProperty.MESSAGE_CLASS) {
|
||||
messageClass = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.INTERNET_MESSAGE_ID) {
|
||||
} else if (prop == MAPIProperty.INTERNET_MESSAGE_ID) {
|
||||
messageId = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.MESSAGE_SUBMISSION_ID) {
|
||||
} else if (prop == MAPIProperty.MESSAGE_SUBMISSION_ID) {
|
||||
// TODO - parse
|
||||
submissionChunk = (MessageSubmissionChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.RECEIVED_BY_ADDRTYPE) {
|
||||
} else if (prop == MAPIProperty.RECEIVED_BY_ADDRTYPE) {
|
||||
sentByServerType = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.TRANSPORT_MESSAGE_HEADERS) {
|
||||
} else if (prop == MAPIProperty.TRANSPORT_MESSAGE_HEADERS) {
|
||||
messageHeaders = (StringChunk) chunk;
|
||||
}
|
||||
|
||||
else if (prop == MAPIProperty.CONVERSATION_TOPIC) {
|
||||
conversationTopic = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.SUBJECT) {
|
||||
} else if (prop == MAPIProperty.SUBJECT) {
|
||||
subjectChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.ORIGINAL_SUBJECT) {
|
||||
} else if (prop == MAPIProperty.ORIGINAL_SUBJECT) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
else if (prop == MAPIProperty.DISPLAY_TO) {
|
||||
displayToChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.DISPLAY_CC) {
|
||||
} else if (prop == MAPIProperty.DISPLAY_CC) {
|
||||
displayCCChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.DISPLAY_BCC) {
|
||||
} else if (prop == MAPIProperty.DISPLAY_BCC) {
|
||||
displayBCCChunk = (StringChunk) chunk;
|
||||
}
|
||||
|
||||
else if (prop == MAPIProperty.SENDER_EMAIL_ADDRESS) {
|
||||
emailFromChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.SENDER_NAME) {
|
||||
} else if (prop == MAPIProperty.SENDER_NAME) {
|
||||
displayFromChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.BODY) {
|
||||
} else if (prop == MAPIProperty.BODY) {
|
||||
textBodyChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(prop == MAPIProperty.BODY_HTML) {
|
||||
} else if (prop == MAPIProperty.BODY_HTML) {
|
||||
if (chunk instanceof StringChunk) {
|
||||
htmlBodyChunkString = (StringChunk) chunk;
|
||||
}
|
||||
if (chunk instanceof ByteChunk) {
|
||||
htmlBodyChunkBinary = (ByteChunk) chunk;
|
||||
}
|
||||
}
|
||||
else if(prop == MAPIProperty.RTF_COMPRESSED) {
|
||||
} else if (prop == MAPIProperty.RTF_COMPRESSED) {
|
||||
rtfBodyChunk = (ByteChunk) chunk;
|
||||
}
|
||||
else if(chunk instanceof MessagePropertiesChunk) {
|
||||
} else if (chunk instanceof MessagePropertiesChunk) {
|
||||
messageProperties = (MessagePropertiesChunk) chunk;
|
||||
}
|
||||
|
||||
@ -188,7 +176,8 @@ public final class Chunks implements ChunkGroupWithProperties {
|
||||
if (messageProperties != null) {
|
||||
messageProperties.matchVariableSizedPropertiesToChunks();
|
||||
} else {
|
||||
logger.log(POILogger.WARN, "Message didn't contain a root list of properties!");
|
||||
logger.log(POILogger.WARN,
|
||||
"Message didn't contain a root list of properties!");
|
||||
}
|
||||
}
|
||||
}
|
@ -25,11 +25,8 @@ import org.apache.poi.hsmf.datatypes.Types.MAPIType;
|
||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||
|
||||
/**
|
||||
* A Chunk that is just a placeholder in the
|
||||
* MAPIMessage directory structure, which
|
||||
* contains children.
|
||||
* This is most commonly used with nested
|
||||
* MAPIMessages
|
||||
* A Chunk that is just a placeholder in the MAPIMessage directory structure,
|
||||
* which contains children. This is most commonly used with nested MAPIMessages
|
||||
*/
|
||||
public class DirectoryChunk extends Chunk {
|
||||
private DirectoryNode dir;
|
||||
@ -40,18 +37,16 @@ public class DirectoryChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory entry for this chunk.
|
||||
* You can then use standard POIFS methods to
|
||||
* enumerate the entries in it.
|
||||
* Returns the directory entry for this chunk. You can then use standard
|
||||
* POIFS methods to enumerate the entries in it.
|
||||
*/
|
||||
public DirectoryNode getDirectory() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Treats the directory as an embeded MAPIMessage
|
||||
* (it normally is one), and returns a MAPIMessage
|
||||
* object to process it with.
|
||||
* Treats the directory as an embeded MAPIMessage (it normally is one), and
|
||||
* returns a MAPIMessage object to process it with.
|
||||
*/
|
||||
public MAPIMessage getAsEmbededMessage() throws IOException {
|
||||
return new MAPIMessage(dir);
|
||||
|
@ -36,8 +36,8 @@ 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.
|
||||
* Holds the list of MAPI Attributes, and allows lookup by friendly name, ID and
|
||||
* MAPI Property Name.
|
||||
*
|
||||
* These are taken from the following MSDN resources:
|
||||
* https://msdn.microsoft.com/en-us/library/microsoft.exchange.data.contenttypes.tnef.tnefpropertyid(v=exchg.150).aspx
|
||||
@ -1027,7 +1027,8 @@ public class MAPIProperty {
|
||||
new MAPIProperty(-1, Types.UNKNOWN, "Unknown", null);
|
||||
|
||||
// 0x8??? ones are outlook specific, and not standard MAPI
|
||||
// TODO See http://msdn.microsoft.com/en-us/library/ee157150%28v=exchg.80%29 for some
|
||||
// TODO See http://msdn.microsoft.com/en-us/library/ee157150%28v=exchg.80%29
|
||||
// for some
|
||||
// info on how we might decode them properly in the future
|
||||
private static final int ID_FIRST_CUSTOM = 0x8000;
|
||||
private static final int ID_LAST_CUSTOM = 0xFFFE;
|
||||
@ -1039,22 +1040,24 @@ public class MAPIProperty {
|
||||
public final String name;
|
||||
public final String mapiProperty;
|
||||
|
||||
private MAPIProperty(int id, MAPIType usualType, String name, String mapiProperty) {
|
||||
private MAPIProperty(int id, MAPIType usualType, String name,
|
||||
String mapiProperty) {
|
||||
this.id = id;
|
||||
this.usualType = usualType;
|
||||
this.name = name;
|
||||
this.mapiProperty = mapiProperty;
|
||||
|
||||
// If it isn't unknown or custom, store it for lookup
|
||||
if(id == -1 || (id >= ID_FIRST_CUSTOM && id <= ID_LAST_CUSTOM)
|
||||
if (id == -1
|
||||
|| (id >= ID_FIRST_CUSTOM && id <= ID_LAST_CUSTOM)
|
||||
|| (this instanceof CustomMAPIProperty)) {
|
||||
// Custom/Unknown, skip
|
||||
} else {
|
||||
if (attributes.containsKey(id)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Duplicate MAPI Property with ID " + id + " : " +
|
||||
toString() + " vs " + attributes.get(id).toString()
|
||||
);
|
||||
"Duplicate MAPI Property with ID " + id + " : "
|
||||
+ toString() + " vs "
|
||||
+ attributes.get(id).toString());
|
||||
}
|
||||
attributes.put(id, this);
|
||||
}
|
||||
@ -1090,6 +1093,7 @@ public class MAPIProperty {
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection<MAPIProperty> getAll() {
|
||||
return Collections.unmodifiableCollection(attributes.values());
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ import java.io.OutputStream;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* A {@link PropertiesChunk} for a Message or Embedded-Message.
|
||||
* This has a 32 byte header
|
||||
* A {@link PropertiesChunk} for a Message or Embedded-Message. This has a 32
|
||||
* byte header
|
||||
*/
|
||||
public class MessagePropertiesChunk extends PropertiesChunk {
|
||||
private long nextRecipientId;
|
||||
@ -40,6 +40,7 @@ public class MessagePropertiesChunk extends PropertiesChunk {
|
||||
public long getNextRecipientId() {
|
||||
return nextRecipientId;
|
||||
}
|
||||
|
||||
public long getNextAttachmentId() {
|
||||
return nextAttachmentId;
|
||||
}
|
||||
@ -47,6 +48,7 @@ public class MessagePropertiesChunk extends PropertiesChunk {
|
||||
public long getRecipientCount() {
|
||||
return recipientCount;
|
||||
}
|
||||
|
||||
public long getAttachmentCount() {
|
||||
return attachmentCount;
|
||||
}
|
||||
|
@ -31,30 +31,29 @@ import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* A Chunk that holds the details given back by the
|
||||
* server at submission time.
|
||||
* This includes the date the message was given to the
|
||||
* server, and an ID that's used if you want to cancel
|
||||
* a message or similar
|
||||
* A Chunk that holds the details given back by the server at submission time.
|
||||
* This includes the date the message was given to the server, and an ID that's
|
||||
* used if you want to cancel a message or similar
|
||||
*/
|
||||
public class MessageSubmissionChunk extends Chunk {
|
||||
private static POILogger logger = POILogFactory.getLogger(MessageSubmissionChunk.class);
|
||||
private static POILogger logger = POILogFactory
|
||||
.getLogger(MessageSubmissionChunk.class);
|
||||
private String rawId;
|
||||
private Calendar date;
|
||||
|
||||
private static final Pattern datePatern =
|
||||
Pattern.compile("(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)Z?");
|
||||
private static final Pattern datePatern = Pattern
|
||||
.compile("(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)Z?");
|
||||
|
||||
/**
|
||||
* Creates a Byte Chunk.
|
||||
*/
|
||||
public MessageSubmissionChunk(String namePrefix, int chunkId, MAPIType type) {
|
||||
public MessageSubmissionChunk(String namePrefix, int chunkId,
|
||||
MAPIType type) {
|
||||
super(namePrefix, chunkId, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Byte Chunk, with the specified
|
||||
* type.
|
||||
* Create a Byte Chunk, with the specified type.
|
||||
*/
|
||||
public MessageSubmissionChunk(int chunkId, MAPIType type) {
|
||||
super(chunkId, type);
|
||||
@ -75,11 +74,14 @@ public class MessageSubmissionChunk extends Chunk {
|
||||
String dateS = null;
|
||||
final int numberPartBegin = part.lastIndexOf('-');
|
||||
if (numberPartBegin != -1) {
|
||||
final int datePartBegin = part.lastIndexOf('-', numberPartBegin-1);
|
||||
final int datePartBegin = part.lastIndexOf('-',
|
||||
numberPartBegin - 1);
|
||||
if (datePartBegin != -1 &&
|
||||
// cannot extract date if only one hyphen is in the string...
|
||||
// cannot extract date if only one hyphen is in the
|
||||
// string...
|
||||
numberPartBegin > datePartBegin) {
|
||||
dateS = part.substring(datePartBegin + 1, numberPartBegin);
|
||||
dateS = part.substring(datePartBegin + 1,
|
||||
numberPartBegin);
|
||||
}
|
||||
}
|
||||
if (dateS != null) {
|
||||
@ -92,14 +94,18 @@ public class MessageSubmissionChunk extends Chunk {
|
||||
int year = Integer.parseInt(m.group(1));
|
||||
date.set(Calendar.YEAR, year + (year > 80 ? 1900 : 2000));
|
||||
|
||||
date.set(Calendar.MONTH, Integer.parseInt(m.group(2)) - 1); // Java is 0 based
|
||||
// Java is 0 based
|
||||
date.set(Calendar.MONTH, Integer.parseInt(m.group(2)) - 1);
|
||||
date.set(Calendar.DATE, Integer.parseInt(m.group(3)));
|
||||
date.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4)));
|
||||
date.set(Calendar.HOUR_OF_DAY,
|
||||
Integer.parseInt(m.group(4)));
|
||||
date.set(Calendar.MINUTE, Integer.parseInt(m.group(5)));
|
||||
date.set(Calendar.SECOND, Integer.parseInt(m.group(6)));
|
||||
date.clear(Calendar.MILLISECOND);
|
||||
} else {
|
||||
logger.log(POILogger.WARN, "Warning - unable to make sense of date " + dateS);
|
||||
logger.log(POILogger.WARN,
|
||||
"Warning - unable to make sense of date "
|
||||
+ dateS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,8 +118,8 @@ public class MessageSubmissionChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the date that the server accepted the
|
||||
* message, as found from the message ID it generated.
|
||||
* @return the date that the server accepted the message, as found from the
|
||||
* message ID it generated.
|
||||
*
|
||||
*/
|
||||
public Calendar getAcceptedAtTime() {
|
||||
@ -121,8 +127,8 @@ public class MessageSubmissionChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full ID that the server generated when
|
||||
* it accepted the message.
|
||||
* @return the full ID that the server generated when it accepted the
|
||||
* message.
|
||||
*/
|
||||
public String getSubmissionId() {
|
||||
return rawId;
|
||||
|
@ -20,10 +20,8 @@ package org.apache.poi.hsmf.datatypes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of convenience chunks for the
|
||||
* NameID part of an outlook file
|
||||
* Collection of convenience chunks for the NameID part of an outlook file
|
||||
*/
|
||||
public final class NameIdChunks implements ChunkGroup {
|
||||
public static final String NAME = "__nameid_version1.0";
|
||||
@ -34,6 +32,7 @@ public final class NameIdChunks implements ChunkGroup {
|
||||
public Chunk[] getAll() {
|
||||
return allChunks.toArray(new Chunk[allChunks.size()]);
|
||||
}
|
||||
|
||||
public Chunk[] getChunks() {
|
||||
return getAll();
|
||||
}
|
||||
@ -46,8 +45,7 @@ public final class NameIdChunks implements ChunkGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to flag that all the chunks of the NameID
|
||||
* have now been located.
|
||||
* Used to flag that all the chunks of the NameID have now been located.
|
||||
*/
|
||||
public void chunksComplete() {
|
||||
// Currently, we don't need to do anything special once
|
||||
|
@ -42,11 +42,11 @@ import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* <p>A Chunk which holds (single) fixed-length properties, and pointer
|
||||
* to the variable length ones / multi-valued ones (which get their
|
||||
* own chunk).
|
||||
* <p>There are two kinds of PropertiesChunks, which differ only in
|
||||
* their headers.
|
||||
* <p>
|
||||
* A Chunk which holds (single) fixed-length properties, and pointer to the
|
||||
* variable length ones / multi-valued ones (which get their own chunk).
|
||||
* <p>
|
||||
* There are two kinds of PropertiesChunks, which differ only in their headers.
|
||||
*/
|
||||
public abstract class PropertiesChunk extends Chunk {
|
||||
public static final String NAME = "__properties_version1.0";
|
||||
@ -55,15 +55,14 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
private POILogger logger = POILogFactory.getLogger(PropertiesChunk.class);
|
||||
|
||||
/**
|
||||
* Holds properties, indexed by type. If a property is multi-valued,
|
||||
* or variable length, it will be held via a {@link ChunkBasedPropertyValue}.
|
||||
* Holds properties, indexed by type. If a property is multi-valued, or
|
||||
* variable length, it will be held via a {@link ChunkBasedPropertyValue}.
|
||||
*/
|
||||
private Map<MAPIProperty, PropertyValue> properties =
|
||||
new HashMap<MAPIProperty, PropertyValue>();
|
||||
private Map<MAPIProperty, PropertyValue> properties = new HashMap<MAPIProperty, PropertyValue>();
|
||||
|
||||
/**
|
||||
* The ChunkGroup that these properties apply to. Used when
|
||||
* matching chunks to variable sized and multi-valued properties
|
||||
* The ChunkGroup that these properties apply to. Used when matching chunks
|
||||
* to variable sized and multi-valued properties
|
||||
*/
|
||||
private ChunkGroup parentGroup;
|
||||
|
||||
@ -81,17 +80,18 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the properties in the chunk, without
|
||||
* looking up any chunk-based values
|
||||
* Returns all the properties in the chunk, without looking up any
|
||||
* chunk-based values
|
||||
*/
|
||||
public Map<MAPIProperty, PropertyValue> getRawProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns all the properties in the chunk, along with their
|
||||
* values.
|
||||
* <p>Any chunk-based values will be looked up and returned as such
|
||||
* <p>
|
||||
* Returns all the properties in the chunk, along with their values.
|
||||
* <p>
|
||||
* Any chunk-based values will be looked up and returned as such
|
||||
*/
|
||||
public Map<MAPIProperty, List<PropertyValue>> getProperties() {
|
||||
Map<MAPIProperty, List<PropertyValue>> props =
|
||||
@ -103,8 +103,8 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all values for the given property, looking up chunk based
|
||||
* ones as required, of null if none exist
|
||||
* Returns all values for the given property, looking up chunk based ones as
|
||||
* required, of null if none exist
|
||||
*/
|
||||
public List<PropertyValue> getValues(MAPIProperty property) {
|
||||
PropertyValue val = properties.get(property);
|
||||
@ -121,16 +121,16 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value / pointer to the value chunk of
|
||||
* the property, or null if none exists
|
||||
* Returns the value / pointer to the value chunk of the property, or null
|
||||
* if none exists
|
||||
*/
|
||||
public PropertyValue getRawValue(MAPIProperty property) {
|
||||
return properties.get(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called once the parent ChunkGroup has been populated, to match
|
||||
* up the Chunks in it with our Variable Sized Properties.
|
||||
* Called once the parent ChunkGroup has been populated, to match up the
|
||||
* Chunks in it with our Variable Sized Properties.
|
||||
*/
|
||||
protected void matchVariableSizedPropertiesToChunks() {
|
||||
// Index the Parent Group chunks for easy lookup
|
||||
@ -145,7 +145,8 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
if (val instanceof ChunkBasedPropertyValue) {
|
||||
ChunkBasedPropertyValue cVal = (ChunkBasedPropertyValue) val;
|
||||
Chunk chunk = chunks.get(cVal.getProperty().id);
|
||||
//System.err.println(cVal.getProperty() + " = " + cVal + " -> " + HexDump.toHex(cVal.data));
|
||||
// System.err.println(cVal.getProperty() + " = " + cVal + " -> "
|
||||
// + HexDump.toHex(cVal.data));
|
||||
|
||||
// TODO Make sense of the raw offset value
|
||||
|
||||
@ -176,8 +177,9 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
prop = MAPIProperty.createCustom(id, type, "Unknown " + id);
|
||||
}
|
||||
if (type == null) {
|
||||
logger.log(POILogger.WARN, "Invalid type found, expected ", prop.usualType,
|
||||
" but got ", typeID, " for property ", prop);
|
||||
logger.log(POILogger.WARN, "Invalid type found, expected ",
|
||||
prop.usualType, " but got ", typeID,
|
||||
" for property ", prop);
|
||||
going = false;
|
||||
break;
|
||||
}
|
||||
@ -185,18 +187,22 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
// Sanity check the property's type against the value's type
|
||||
if (prop.usualType != type) {
|
||||
// Is it an allowed substitution?
|
||||
if (type == Types.ASCII_STRING && prop.usualType == Types.UNICODE_STRING ||
|
||||
type == Types.UNICODE_STRING && prop.usualType == Types.ASCII_STRING) {
|
||||
// It's fine to go with the specified instead of the normal
|
||||
if (type == Types.ASCII_STRING
|
||||
&& prop.usualType == Types.UNICODE_STRING
|
||||
|| type == Types.UNICODE_STRING
|
||||
&& prop.usualType == Types.ASCII_STRING) {
|
||||
// It's fine to go with the specified instead of the
|
||||
// normal
|
||||
} else if (prop.usualType == Types.UNKNOWN) {
|
||||
// We don't know what this property normally is, but it has come
|
||||
// We don't know what this property normally is, but it
|
||||
// has come
|
||||
// through with a valid type, so use that
|
||||
logger.log(POILogger.INFO, "Property definition for ", prop,
|
||||
" is missing a type definition, found a value with type ", type);
|
||||
} else {
|
||||
// Oh dear, something has gone wrong...
|
||||
logger.log(POILogger.WARN, "Type mismatch, expected ", prop.usualType,
|
||||
" but got ", type, " for property ", prop);
|
||||
logger.log(POILogger.WARN, "Type mismatch, expected ",
|
||||
prop.usualType, " but got ", type, " for property ", prop);
|
||||
going = false;
|
||||
break;
|
||||
}
|
||||
@ -231,32 +237,23 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
if (isPointer) {
|
||||
// We'll match up the chunk later
|
||||
propVal = new ChunkBasedPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.NULL) {
|
||||
} else if (type == Types.NULL) {
|
||||
propVal = new NullPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.BOOLEAN) {
|
||||
} else if (type == Types.BOOLEAN) {
|
||||
propVal = new BooleanPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.SHORT) {
|
||||
} else if (type == Types.SHORT) {
|
||||
propVal = new ShortPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.LONG) {
|
||||
} else if (type == Types.LONG) {
|
||||
propVal = new LongPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.LONG_LONG) {
|
||||
} else if (type == Types.LONG_LONG) {
|
||||
propVal = new LongLongPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.FLOAT) {
|
||||
} else if (type == Types.FLOAT) {
|
||||
propVal = new FloatPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.DOUBLE) {
|
||||
} else if (type == Types.DOUBLE) {
|
||||
propVal = new DoublePropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.CURRENCY) {
|
||||
} else if (type == Types.CURRENCY) {
|
||||
propVal = new CurrencyPropertyValue(prop, flags, data);
|
||||
}
|
||||
else if (type == Types.TIME) {
|
||||
} else if (type == Types.TIME) {
|
||||
propVal = new TimePropertyValue(prop, flags, data);
|
||||
}
|
||||
// TODO Add in the rest of the types
|
||||
@ -265,7 +262,8 @@ public abstract class PropertiesChunk extends Chunk {
|
||||
}
|
||||
|
||||
if (properties.get(prop) != null) {
|
||||
logger.log(POILogger.WARN, "Duplicate values found for " + prop);
|
||||
logger.log(POILogger.WARN,
|
||||
"Duplicate values found for " + prop);
|
||||
}
|
||||
properties.put(prop, propVal);
|
||||
} catch (BufferUnderrunException e) {
|
||||
|
@ -24,11 +24,11 @@ import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.LocaleUtil;
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
* 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;
|
||||
@ -46,8 +46,7 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw value flags.
|
||||
* TODO Also provide getters for the flag meanings
|
||||
* Get the raw value flags. TODO Also provide getters for the flag meanings
|
||||
*/
|
||||
public long getFlags() {
|
||||
return flags;
|
||||
@ -56,6 +55,7 @@ public class PropertyValue {
|
||||
public Object getValue() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setRawValue(byte[] value) {
|
||||
this.data = value;
|
||||
}
|
||||
@ -74,7 +74,8 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
public static class NullPropertyValue extends PropertyValue {
|
||||
public NullPropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
public NullPropertyValue(MAPIProperty property, long flags,
|
||||
byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
|
||||
@ -84,7 +85,8 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
public static class BooleanPropertyValue extends PropertyValue {
|
||||
public BooleanPropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
public BooleanPropertyValue(MAPIProperty property, long flags,
|
||||
byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
|
||||
@ -92,6 +94,7 @@ public class PropertyValue {
|
||||
short val = LittleEndian.getShort(data);
|
||||
return val > 0;
|
||||
}
|
||||
|
||||
public void setValue(boolean value) {
|
||||
if (data.length != 2) {
|
||||
data = new byte[2];
|
||||
@ -103,13 +106,15 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
public static class ShortPropertyValue extends PropertyValue {
|
||||
public ShortPropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
public ShortPropertyValue(MAPIProperty property, long flags,
|
||||
byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
|
||||
public Short getValue() {
|
||||
return LittleEndian.getShort(data);
|
||||
}
|
||||
|
||||
public void setValue(short value) {
|
||||
if (data.length != 2) {
|
||||
data = new byte[2];
|
||||
@ -126,6 +131,7 @@ public class PropertyValue {
|
||||
public Integer getValue() {
|
||||
return LittleEndian.getInt(data);
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
if (data.length != 4) {
|
||||
data = new byte[4];
|
||||
@ -135,13 +141,15 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
public static class LongLongPropertyValue extends PropertyValue {
|
||||
public LongLongPropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
public LongLongPropertyValue(MAPIProperty property, long flags,
|
||||
byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
|
||||
public Long getValue() {
|
||||
return LittleEndian.getLong(data);
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
if (data.length != 8) {
|
||||
data = new byte[8];
|
||||
@ -151,13 +159,15 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
public static class FloatPropertyValue extends PropertyValue {
|
||||
public FloatPropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
public FloatPropertyValue(MAPIProperty property, long flags,
|
||||
byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
|
||||
public Float getValue() {
|
||||
return LittleEndian.getFloat(data);
|
||||
}
|
||||
|
||||
public void setValue(float value) {
|
||||
if (data.length != 4) {
|
||||
data = new byte[4];
|
||||
@ -174,6 +184,7 @@ public class PropertyValue {
|
||||
public Double getValue() {
|
||||
return LittleEndian.getDouble(data);
|
||||
}
|
||||
|
||||
public void setValue(double value) {
|
||||
if (data.length != 8) {
|
||||
data = new byte[8];
|
||||
@ -183,11 +194,12 @@ public class PropertyValue {
|
||||
}
|
||||
|
||||
/**
|
||||
* signed 64-bit integer that represents a base ten decimal,
|
||||
* with four digits to the right of the decimal point
|
||||
* signed 64-bit integer that represents a base ten decimal, with four
|
||||
* digits to the right of the decimal point
|
||||
*/
|
||||
public static class CurrencyPropertyValue extends PropertyValue {
|
||||
private static final BigInteger SHIFT = BigInteger.valueOf(10000);
|
||||
|
||||
public CurrencyPropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
@ -196,6 +208,7 @@ public class PropertyValue {
|
||||
long unshifted = LittleEndian.getLong(data);
|
||||
return BigInteger.valueOf(unshifted).divide(SHIFT);
|
||||
}
|
||||
|
||||
public void setValue(BigInteger value) {
|
||||
if (data.length != 8) {
|
||||
data = new byte[8];
|
||||
@ -209,7 +222,9 @@ public class PropertyValue {
|
||||
* 64-bit integer specifying the number of 100ns periods since Jan 1, 1601
|
||||
*/
|
||||
public static class TimePropertyValue extends PropertyValue {
|
||||
private static final long OFFSET = 1000L * 60L * 60L * 24L * (365L * 369L + 89L);
|
||||
private static final long OFFSET = 1000L * 60L * 60L * 24L
|
||||
* (365L * 369L + 89L);
|
||||
|
||||
public TimePropertyValue(MAPIProperty property, long flags, byte[] data) {
|
||||
super(property, flags, data);
|
||||
}
|
||||
@ -223,6 +238,7 @@ public class PropertyValue {
|
||||
|
||||
return timeC;
|
||||
}
|
||||
|
||||
public void setValue(Calendar value) {
|
||||
if (data.length != 8) {
|
||||
data = new byte[8];
|
||||
|
@ -27,13 +27,10 @@ import java.util.Map;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of convenience chunks for the
|
||||
* Recip(ient) part of an outlook file.
|
||||
* Collection of convenience chunks for the Recip(ient) part of an outlook file.
|
||||
*
|
||||
* If a message has multiple recipients, there will be
|
||||
* several of these.
|
||||
* If a message has multiple recipients, there will be several of these.
|
||||
*/
|
||||
public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
private static POILogger logger = POILogFactory.getLogger(RecipientChunks.class);
|
||||
@ -53,36 +50,33 @@ public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
/** TODO */
|
||||
public ByteChunk recipientSearchChunk;
|
||||
/**
|
||||
* The "name", which could be their name if an
|
||||
* internal person, or their email address
|
||||
* if an external person
|
||||
* The "name", which could be their name if an internal person, or their
|
||||
* email address if an external person
|
||||
*/
|
||||
public StringChunk recipientNameChunk;
|
||||
/**
|
||||
* The email address of the recipient, which
|
||||
* could be in SMTP or SEARCH format, but
|
||||
* isn't always present...
|
||||
* The email address of the recipient, which could be in SMTP or SEARCH
|
||||
* format, but isn't always present...
|
||||
*/
|
||||
public StringChunk recipientEmailChunk;
|
||||
/**
|
||||
* The smtp destination email address of
|
||||
* the recipient, but isn't always present...
|
||||
* The smtp destination email address of the recipient, but isn't always
|
||||
* present...
|
||||
*/
|
||||
public StringChunk recipientSMTPChunk;
|
||||
/**
|
||||
* Normally EX or SMTP. Will generally affect
|
||||
* where the email address ends up.
|
||||
* Normally EX or SMTP. Will generally affect where the email address ends
|
||||
* up.
|
||||
*/
|
||||
public StringChunk deliveryTypeChunk;
|
||||
/**
|
||||
* The display name of the recipient.
|
||||
* Normally seems to hold the same value
|
||||
* The display name of the recipient. Normally seems to hold the same value
|
||||
* as in recipientNameChunk
|
||||
*/
|
||||
public StringChunk recipientDisplayNameChunk;
|
||||
/**
|
||||
* Holds the fixed sized properties, and the
|
||||
* pointers to the data of variable sized ones
|
||||
* Holds the fixed sized properties, and the pointers to the data of
|
||||
* variable sized ones
|
||||
*/
|
||||
private PropertiesChunk recipientProperties;
|
||||
|
||||
@ -94,14 +88,14 @@ public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
try {
|
||||
recipientNumber = Integer.parseInt(number, 16);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.log(POILogger.ERROR, "Invalid recipient number in name " + name);
|
||||
logger.log(POILogger.ERROR,
|
||||
"Invalid recipient number in name " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find their name,
|
||||
* in whichever chunk holds it.
|
||||
* Tries to find their name, in whichever chunk holds it.
|
||||
*/
|
||||
public String getRecipientName() {
|
||||
if (recipientNameChunk != null) {
|
||||
@ -116,8 +110,7 @@ public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find their email address, in
|
||||
* whichever chunk holds it given the
|
||||
* Tries to find their email address, in whichever chunk holds it given the
|
||||
* delivery type.
|
||||
*/
|
||||
public String getRecipientEmailAddress() {
|
||||
@ -171,12 +164,14 @@ public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
public Map<MAPIProperty, List<PropertyValue>> getProperties() {
|
||||
if (recipientProperties != null) {
|
||||
return recipientProperties.getProperties();
|
||||
} else
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
else return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public Chunk[] getAll() {
|
||||
return allChunks.toArray(new Chunk[allChunks.size()]);
|
||||
}
|
||||
|
||||
public Chunk[] getChunks() {
|
||||
return getAll();
|
||||
}
|
||||
@ -188,23 +183,17 @@ public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
if (chunk.getChunkId() == RECIPIENT_SEARCH.id) {
|
||||
// TODO - parse
|
||||
recipientSearchChunk = (ByteChunk) chunk;
|
||||
}
|
||||
else if(chunk.getChunkId() == RECIPIENT_NAME.id) {
|
||||
} else if (chunk.getChunkId() == RECIPIENT_NAME.id) {
|
||||
recipientDisplayNameChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(chunk.getChunkId() == RECIPIENT_DISPLAY_NAME.id) {
|
||||
} else if (chunk.getChunkId() == RECIPIENT_DISPLAY_NAME.id) {
|
||||
recipientNameChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(chunk.getChunkId() == RECIPIENT_EMAIL_ADDRESS.id) {
|
||||
} else if (chunk.getChunkId() == RECIPIENT_EMAIL_ADDRESS.id) {
|
||||
recipientEmailChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(chunk.getChunkId() == RECIPIENT_SMTP_ADDRESS.id) {
|
||||
} else if (chunk.getChunkId() == RECIPIENT_SMTP_ADDRESS.id) {
|
||||
recipientSMTPChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(chunk.getChunkId() == DELIVERY_TYPE.id) {
|
||||
} else if (chunk.getChunkId() == DELIVERY_TYPE.id) {
|
||||
deliveryTypeChunk = (StringChunk) chunk;
|
||||
}
|
||||
else if(chunk instanceof PropertiesChunk) {
|
||||
} else if (chunk instanceof PropertiesChunk) {
|
||||
recipientProperties = (PropertiesChunk) chunk;
|
||||
}
|
||||
|
||||
@ -223,7 +212,8 @@ public final class RecipientChunks implements ChunkGroupWithProperties {
|
||||
/**
|
||||
* Orders by the recipient number.
|
||||
*/
|
||||
public static class RecipientChunksSorter implements Comparator<RecipientChunks>, Serializable {
|
||||
public static class RecipientChunksSorter
|
||||
implements Comparator<RecipientChunks>, Serializable {
|
||||
public int compare(RecipientChunks a, RecipientChunks b) {
|
||||
if (a.recipientNumber < b.recipientNumber)
|
||||
return -1;
|
||||
|
@ -24,9 +24,8 @@ import java.io.OutputStream;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* A {@link PropertiesChunk} for a Storage Properties, such as
|
||||
* Attachments and Recipients.
|
||||
* This only has a 8 byte header
|
||||
* A {@link PropertiesChunk} for a Storage Properties, such as Attachments and
|
||||
* Recipients. This only has a 8 byte header
|
||||
*/
|
||||
public class StoragePropertiesChunk extends PropertiesChunk {
|
||||
public StoragePropertiesChunk(ChunkGroup parentGroup) {
|
||||
|
@ -43,28 +43,24 @@ public class StringChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a String Chunk, with the specified
|
||||
* type.
|
||||
* Create a String Chunk, with the specified type.
|
||||
*/
|
||||
public StringChunk(int chunkId, MAPIType type) {
|
||||
super(chunkId, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Encoding that will be used to
|
||||
* decode any "7 bit" (non unicode) data.
|
||||
* Most files default to CP1252
|
||||
* Returns the Encoding that will be used to decode any "7 bit" (non
|
||||
* unicode) data. Most files default to CP1252
|
||||
*/
|
||||
public String get7BitEncoding() {
|
||||
return encoding7Bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Encoding that will be used to
|
||||
* decode any "7 bit" (non unicode) data.
|
||||
* This doesn't appear to be stored anywhere
|
||||
* specific in the file, so you may need
|
||||
* to guess by looking at headers etc
|
||||
* Sets the Encoding that will be used to decode any "7 bit" (non unicode)
|
||||
* data. This doesn't appear to be stored anywhere specific in the file, so
|
||||
* you may need to guess by looking at headers etc
|
||||
*/
|
||||
public void set7BitEncoding(String encoding) {
|
||||
this.encoding7Bit = encoding;
|
||||
@ -79,6 +75,7 @@ public class StringChunk extends Chunk {
|
||||
rawValue = IOUtils.toByteArray(value);
|
||||
parseString();
|
||||
}
|
||||
|
||||
private void parseString() {
|
||||
String tmpValue;
|
||||
if (type == Types.ASCII_STRING) {
|
||||
@ -96,6 +93,7 @@ public class StringChunk extends Chunk {
|
||||
public void writeValue(OutputStream out) throws IOException {
|
||||
out.write(rawValue);
|
||||
}
|
||||
|
||||
private void storeString() {
|
||||
if (type == Types.ASCII_STRING) {
|
||||
rawValue = value.getBytes(Charset.forName(encoding7Bit));
|
||||
@ -127,15 +125,16 @@ public class StringChunk extends Chunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses as non-unicode, supposedly 7 bit CP1252 data
|
||||
* and returns the string that that yields.
|
||||
* Parses as non-unicode, supposedly 7 bit CP1252 data and returns the
|
||||
* string that that yields.
|
||||
*/
|
||||
protected static String parseAs7BitData(byte[] data) {
|
||||
return parseAs7BitData(data, DEFAULT_ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses as non-unicode, supposedly 7 bit data
|
||||
* and returns the string that that yields.
|
||||
* Parses as non-unicode, supposedly 7 bit data and returns the string that
|
||||
* that yields.
|
||||
*/
|
||||
protected static String parseAs7BitData(byte[] data, String encoding) {
|
||||
// Handle any encoding aliases, where outlook describes it differently
|
||||
|
@ -30,7 +30,8 @@ public final class Types {
|
||||
private static Map<Integer, MAPIType> customTypes = new HashMap<Integer, Types.MAPIType>();
|
||||
|
||||
/** Unspecified */
|
||||
public static final MAPIType UNSPECIFIED = new MAPIType(0x0000, "Unspecified", -1);
|
||||
public static final MAPIType UNSPECIFIED = new MAPIType(0x0000,
|
||||
"Unspecified", -1);
|
||||
/** Unknown */
|
||||
public static final MAPIType UNKNOWN = new MAPIType(-1, "Unknown", -1);
|
||||
|
||||
@ -44,7 +45,10 @@ public final class Types {
|
||||
public static final MAPIType FLOAT = new MAPIType(0x0004, "Float", 4);
|
||||
/** Double - floating point double */
|
||||
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 */
|
||||
/**
|
||||
* Currency - signed 64-bit integer that represents a base ten decimal with
|
||||
* four digits to the right of the decimal point
|
||||
*/
|
||||
public static final MAPIType CURRENCY = new MAPIType(0x0006, "Currency", 8);
|
||||
/** AppTime - application time value */
|
||||
public static final MAPIType APP_TIME = new MAPIType(0x0007, "Application Time", 8);
|
||||
@ -56,7 +60,10 @@ public final class Types {
|
||||
public static final MAPIType DIRECTORY = new MAPIType(0x000D, "Directory", -1);
|
||||
/** I8 - 8-byte signed integer */
|
||||
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 */
|
||||
/**
|
||||
* SysTime - FILETIME 64-bit integer specifying the number of 100ns periods
|
||||
* since Jan 1, 1601
|
||||
*/
|
||||
public static final MAPIType TIME = new MAPIType(0x0040, "Time", 8);
|
||||
/** ClassId - OLE GUID */
|
||||
public static final MAPIType CLS_ID = new MAPIType(0x0048, "CLS ID GUID", 16);
|
||||
@ -65,9 +72,8 @@ public final class Types {
|
||||
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.
|
||||
* 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 MAPIType ASCII_STRING = new MAPIType(0x001E, "ASCII String", -1);
|
||||
/** A string, from Outlook 3.0 onwards. Normally unicode */
|
||||
@ -90,6 +96,7 @@ public final class Types {
|
||||
this.length = length;
|
||||
builtInTypes.put(id, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a custom type
|
||||
*/
|
||||
@ -101,12 +108,13 @@ public final class Types {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length, in bytes, of values of this type, or
|
||||
* -1 if it is a variable length type.
|
||||
* 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?
|
||||
*/
|
||||
@ -117,17 +125,18 @@ public final class Types {
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return id + " / 0x" + asFileEnding() + " - " + name + " @ " + length;
|
||||
return id + " / 0x" + asFileEnding() + " - " + name + " @ "
|
||||
+ length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 4 character hex encoded version,
|
||||
* as used in file endings
|
||||
* Return the 4 character hex encoded version, as used in file endings
|
||||
*/
|
||||
public String asFileEnding() {
|
||||
return Types.asFileEnding(id);
|
||||
@ -145,6 +154,7 @@ public final class Types {
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String asName(int typeId) {
|
||||
MAPIType type = builtInTypes.get(typeId);
|
||||
if (type != null) {
|
||||
@ -152,6 +162,7 @@ public final class Types {
|
||||
}
|
||||
return asCustomName(typeId);
|
||||
}
|
||||
|
||||
private static String asCustomName(int typeId) {
|
||||
return "0x" + Integer.toHexString(typeId);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user