import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
if (mainChunks.submissionChunk != null) {
return mainChunks.submissionChunk.getAcceptedAtTime();
}
- else if (mainChunks.messageProperties != null) {
+ else {
// Try a few likely suspects...
for (MAPIProperty prop : new MAPIProperty[] {
MAPIProperty.CLIENT_SUBMIT_TIME, MAPIProperty.LAST_MODIFICATION_TIME,
MAPIProperty.CREATION_TIME
}) {
- PropertyValue val = mainChunks.messageProperties.getValue(prop);
- if (val != null) {
- return ((TimePropertyValue)val).getValue();
+ List<PropertyValue> val = mainChunks.getProperties().get(prop);
+ if (val != null && val.size() > 0) {
+ return ((TimePropertyValue)val.get(0)).getValue();
}
}
}
--- /dev/null
+/* ====================================================================
+ 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.util.List;
+import java.util.Map;
+
+/**
+ * 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.
+ */
+ public Map<MAPIProperty,List<PropertyValue>> getProperties();
+}
package org.apache.poi.hsmf.datatypes;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
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.
*
* A partial list is available at:
* http://msdn.microsoft.com/en-us/library/ms526356%28v=exchg.10%29.aspx
+ *
+ * TODO Deprecate the public Chunks in favour of Property Lookups
*/
-public final class Chunks implements ChunkGroup {
- /** Holds all the chunks that were found, indexed by their MAPIProperty */
+public final class Chunks implements ChunkGroupWithProperties {
+ private static POILogger logger = POILogFactory.getLogger(Chunks.class);
+
+ /**
+ * Holds all the chunks that were found, indexed by their MAPIProperty.
+ * Normally a property will have zero chunks (fixed sized) or one chunk
+ * (variable size), but in some cases (eg Unknown) you may get more.
+ */
private Map<MAPIProperty,List<Chunk>> allChunks = new HashMap<MAPIProperty,List<Chunk>>();
/** Type of message that the MSG represents (ie. IPM.Note) */
/** The message ID */
public StringChunk messageId;
/** The message properties */
- public MessagePropertiesChunk messageProperties;
+ private MessagePropertiesChunk messageProperties;
+ public Map<MAPIProperty,List<PropertyValue>> getProperties() {
+ if (messageProperties != null) {
+ return messageProperties.getProperties();
+ }
+ else return Collections.emptyMap();
+ }
public Map<MAPIProperty,List<Chunk>> getAll() {
return allChunks;
}
}
public void chunksComplete() {
- // TODO Match variable sized properties to their chunks + index
+ if (messageProperties != null) {
+ messageProperties.matchVariableSizedPropertiesToChunks();
+ } else {
+ logger.log(POILogger.WARN, "Message didn't contain a root list of properties!");
+ }
}
-}
+}
\ No newline at end of file
/**
* The ChunkGroup that these properties apply to. Used when
* matching chunks to variable sized properties
- * TODO Make use of this
*/
private ChunkGroup parentGroup;
return NAME;
}
- /**
- * Returns all the properties in the chunk
- */
- public Map<MAPIProperty, List<PropertyValue>> getProperties() {
- return properties;
- }
-
- /**
- * Returns all values for the given property, of null if none exist
- */
- public List<PropertyValue> getValues(MAPIProperty property) {
- return properties.get(property);
- }
+ /**
+ * Returns all the properties in the chunk
+ */
+ public Map<MAPIProperty, List<PropertyValue>> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Returns all values for the given property, of null if none exist
+ */
+ public List<PropertyValue> getValues(MAPIProperty property) {
+ return properties.get(property);
+ }
+
+ /**
+ * Returns the (first/only) value for the given property, or
+ * null if none exist
+ */
+ public PropertyValue getValue(MAPIProperty property) {
+ List<PropertyValue> values = properties.get(property);
+ if (values != null && values.size() > 0) {
+ return values.get(0);
+ }
+ return null;
+ }
- /**
- * Returns the (first/only) value for the given property, or
- * null if none exist
- */
- public PropertyValue getValue(MAPIProperty property) {
- List<PropertyValue> values = properties.get(property);
- if (values != null && values.size() > 0) {
- return values.get(0);
- }
- return null;
- }
+ /**
+ * Called once the parent ChunkGroup has been populated, to match
+ * up the Chunks in it with our Variable Sized Properties.
+ */
+ protected void matchVariableSizedPropertiesToChunks() {
+ // TODO
+ }
protected void readProperties(InputStream value) throws IOException {
boolean going = true;
// Wrap and store
PropertyValue propVal = null;
if (isPointer) {
+ // We'll match up the chunk later
propVal = new ChunkBasedPropertyValue(prop, flags, data);
}
else if (type == Types.LONG_LONG) {
package org.apache.poi.hsmf.datatypes;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Map;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
* If a message has multiple recipients, there will be
* several of these.
*/
-public final class RecipientChunks implements ChunkGroup {
+public final class RecipientChunks implements ChunkGroupWithProperties {
private static POILogger logger = POILogFactory.getLogger(RecipientChunks.class);
public static final String PREFIX = "__recip_version1.0_#";
/** Holds all the chunks that were found. */
private List<Chunk> allChunks = new ArrayList<Chunk>();
+ public Map<MAPIProperty,List<PropertyValue>> getProperties() {
+ if (recipientProperties != null) {
+ return recipientProperties.getProperties();
+ }
+ else return Collections.emptyMap();
+ }
public Chunk[] getAll() {
return allChunks.toArray(new Chunk[allChunks.size()]);
}
}
public void chunksComplete() {
- // TODO Match variable sized properties to their chunks + index
+ if (recipientProperties != null) {
+ recipientProperties.matchVariableSizedPropertiesToChunks();
+ } else {
+ logger.log(POILogger.WARN, "Recipeints Chunk didn't contain a list of properties!");
+ }
}
/**
// All chunks are now processed, have the ChunkGroup
// match up variable-length properties and their chunks
for (ChunkGroup group : groups) {
- // TODO
+ group.chunksComplete();
}
// Finish