Continue with support for property lookups of chunks

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1441427 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2013-02-01 12:43:58 +00:00
parent 8edde11bbc
commit 1fe52e8cfc
6 changed files with 118 additions and 37 deletions

View File

@ -25,6 +25,7 @@ import java.io.OutputStream;
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;
@ -516,15 +517,15 @@ public class MAPIMessage extends POIDocument {
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();
}
}
}

View File

@ -0,0 +1,38 @@
/* ====================================================================
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();
}

View File

@ -18,10 +18,14 @@
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.
@ -30,9 +34,17 @@ import java.util.Map;
*
* 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) */
@ -70,8 +82,14 @@ public final class Chunks implements ChunkGroup {
/** 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;
}
@ -160,6 +178,10 @@ public final class Chunks implements ChunkGroup {
}
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!");
}
}
}
}

View File

@ -56,7 +56,6 @@ public abstract class PropertiesChunk extends Chunk {
/**
* The ChunkGroup that these properties apply to. Used when
* matching chunks to variable sized properties
* TODO Make use of this
*/
private ChunkGroup parentGroup;
@ -73,31 +72,39 @@ public abstract class PropertiesChunk extends Chunk {
return NAME;
}
/**
* Returns all the properties in the chunk
*/
public Map<MAPIProperty, List<PropertyValue>> getProperties() {
return properties;
}
/**
* 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 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;
}
/**
* 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;
@ -141,6 +148,7 @@ public abstract class PropertiesChunk extends Chunk {
// 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) {

View File

@ -18,8 +18,10 @@
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;
@ -32,7 +34,7 @@ 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_#";
@ -165,6 +167,12 @@ public final class RecipientChunks implements ChunkGroup {
/** 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()]);
}
@ -204,7 +212,11 @@ public final class RecipientChunks implements ChunkGroup {
}
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!");
}
}
/**

View File

@ -95,7 +95,7 @@ public final class POIFSChunkParser {
// All chunks are now processed, have the ChunkGroup
// match up variable-length properties and their chunks
for (ChunkGroup group : groups) {
// TODO
group.chunksComplete();
}
// Finish