Initial HSMF (outlook) support from Travis
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@554774 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
af86158ea2
commit
ca73f5eb7e
@ -503,6 +503,7 @@ under the License.
|
||||
<sysproperty key="HDF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hdf/data"/>
|
||||
<sysproperty key="HWPF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hwpf/data"/>
|
||||
<sysproperty key="HSLF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hslf/data"/>
|
||||
<sysproperty key="HSMF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hsmf/data"/>
|
||||
<sysproperty key="HDGF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hdgf/data"/>
|
||||
<sysproperty key="java.awt.headless" value="true"/>
|
||||
<formatter type="plain"/>
|
||||
@ -536,6 +537,7 @@ under the License.
|
||||
<sysproperty key="HPSF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hpsf/data"/>
|
||||
<sysproperty key="HWPF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hwpf/data"/>
|
||||
<sysproperty key="HSLF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hslf/data"/>
|
||||
<sysproperty key="HSMF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hsmf/data"/>
|
||||
<sysproperty key="HDGF.testdata.path" file="${scratchpad.src.test}/org/apache/poi/hdgf/data"/>
|
||||
<sysproperty key="java.awt.headless" value="true"/>
|
||||
<sysproperty key="java.awt.headless" value="true"/>
|
||||
|
146
src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
Normal file
146
src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
Normal file
@ -0,0 +1,146 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.poi.hsmf.datatypes.Chunk;
|
||||
import org.apache.poi.hsmf.datatypes.Chunks;
|
||||
import org.apache.poi.hsmf.datatypes.StringChunk;
|
||||
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
|
||||
import org.apache.poi.hsmf.parsers.POIFSChunkParser;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
|
||||
/**
|
||||
* Reads an Outlook MSG File in and provides hooks into its data structure.
|
||||
*
|
||||
* @author Travis Ferguson
|
||||
*/
|
||||
public class MAPIMessage {
|
||||
private POIFSChunkParser chunkParser;
|
||||
private POIFSFileSystem fs;
|
||||
|
||||
/**
|
||||
* Constructor for creating new files.
|
||||
*
|
||||
*/
|
||||
public MAPIMessage() {
|
||||
//TODO make writing possible
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for reading MSG Files.
|
||||
* @param filename
|
||||
* @throws IOException
|
||||
*/
|
||||
public MAPIMessage(String filename) throws IOException {
|
||||
InputStream in = new FileInputStream(new File(filename));
|
||||
this.fs = new POIFSFileSystem(in);
|
||||
chunkParser = new POIFSChunkParser(this.fs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string value based on the passed chunk.
|
||||
* @param chunk
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getStringFromChunk(StringChunk chunk) throws ChunkNotFoundException {
|
||||
Chunk out = this.chunkParser.getDocumentNode(chunk);
|
||||
StringChunk strchunk = (StringChunk)out;
|
||||
return strchunk.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the plain text body of this Outlook Message
|
||||
* @return The string representation of the 'text' version of the body, if available.
|
||||
* @throws IOException
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getTextBody() throws IOException, ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().textBodyChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subject line of the Outlook Message
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getSubject() throws ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().subjectChunk);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the display value of the "TO" line of the outlook message
|
||||
* This is not the actual list of addresses/values that will be sent to if you click Reply in the email.
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getDisplayTo() throws ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().displayToChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display value of the "TO" line of the outlook message
|
||||
* This is not the actual list of addresses/values that will be sent to if you click Reply in the email.
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getDisplayCC() throws ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().displayCCChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display value of the "TO" line of the outlook message
|
||||
* This is not the actual list of addresses/values that will be sent to if you click Reply in the email.
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getDisplayBCC() throws ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().displayBCCChunk);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the conversation topic of the parsed Outlook Message.
|
||||
* This is the part of the subject line that is after the RE: and FWD:
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getConversationTopic() throws ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().conversationTopic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message class of the parsed Outlook Message.
|
||||
* (Yes, you can use this to determine if a message is a calendar item, note, or actual outlook Message)
|
||||
* For emails the class will be IPM.Note
|
||||
*
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public String getMessageClass() throws ChunkNotFoundException {
|
||||
return getStringFromChunk(Chunks.getInstance().messageClass);
|
||||
}
|
||||
}
|
68
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java
Normal file
68
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunk.java
Normal file
@ -0,0 +1,68 @@
|
||||
/* ====================================================================
|
||||
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.ByteArrayOutputStream;
|
||||
|
||||
abstract public class Chunk {
|
||||
protected int chunkId;
|
||||
protected int type;
|
||||
protected String namePrefix = "__substg1.0_";
|
||||
|
||||
/**
|
||||
* Gets the id of this chunk
|
||||
* @return
|
||||
*/
|
||||
public int getChunkId() {
|
||||
return this.chunkId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the numeric type of this chunk.
|
||||
* @return
|
||||
*/
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string to use to identify this chunk in the POI file system object.
|
||||
* @return
|
||||
*/
|
||||
public String getEntryName() {
|
||||
String type = Integer.toHexString(this.type);
|
||||
while(type.length() < 4) type = "0" + type;
|
||||
|
||||
String chunkId = Integer.toHexString(this.chunkId);
|
||||
while(chunkId.length() < 4) chunkId = "0" + chunkId;
|
||||
|
||||
return this.namePrefix + chunkId.toUpperCase() + type.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to a ByteArrayOutputStream that contains the value of this chunk.
|
||||
* @return
|
||||
*/
|
||||
public abstract ByteArrayOutputStream getValueByteArray();
|
||||
|
||||
/**
|
||||
* Sets the value of this chunk using a OutputStream
|
||||
* @param value
|
||||
*/
|
||||
public abstract void setValue(ByteArrayOutputStream value);
|
||||
}
|
40
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java
Normal file
40
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java
Normal file
@ -0,0 +1,40 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of convenence chunks for standard parts of the MSG file.
|
||||
*
|
||||
* @author Travis Ferguson
|
||||
*/
|
||||
public class Chunks {
|
||||
/* String parts of Outlook Messages that are currently known */
|
||||
public StringChunk messageClass = new StringChunk(0x001A); //Type of message that the MSG represents (ie. IPM.Note)
|
||||
public StringChunk textBodyChunk = new StringChunk(0x1000); //BODY Chunk, for plain/text messages
|
||||
public StringChunk subjectChunk = new StringChunk(0x0037); //Subject link chunk, in plain/text
|
||||
public StringChunk displayToChunk = new StringChunk(0x0E04); //Value that is in the TO field (not actually the addresses as they are stored in recip directory nodes
|
||||
public StringChunk displayCCChunk = new StringChunk(0x0E03); //value that shows in the CC field
|
||||
public StringChunk displayBCCChunk = new StringChunk(0x0E02); //Value that shows in the BCC field
|
||||
public StringChunk conversationTopic = new StringChunk(0x0070); //Sort of like the subject line, but without the RE: and FWD: parts.
|
||||
public StringChunk sentByServerType = new StringChunk(0x0075); //Type of server that the message originated from (SMTP, etc).
|
||||
|
||||
public static Chunks getInstance() {
|
||||
return new Chunks();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/* ====================================================================
|
||||
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.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* A Chunk made up of a single string.
|
||||
* @author Travis Ferguson
|
||||
*/
|
||||
public class StringChunk extends Chunk {
|
||||
|
||||
private String value;
|
||||
|
||||
public StringChunk(int chunkId) {
|
||||
this.chunkId = chunkId;
|
||||
this.type = Types.STRING;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.poi.hsmf.Chunk.Chunk#getValueByteArray()
|
||||
*/
|
||||
public ByteArrayOutputStream getValueByteArray() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.poi.hsmf.Chunk.Chunk#setValue(java.io.ByteArrayOutputStream)
|
||||
*/
|
||||
public void setValue(ByteArrayOutputStream value) {
|
||||
this.value = value.toString().replaceAll("\0", "");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
26
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
Normal file
26
src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
Normal file
@ -0,0 +1,26 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
public class Types {
|
||||
public static int BINARY = 0x0102;
|
||||
public static int STRING = 0x001E;
|
||||
public static int LONG = 0x0003;
|
||||
public static int TIME = 0x0040;
|
||||
public static int BOOLEAN = 0x000B;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/* ====================================================================
|
||||
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.exceptions;
|
||||
|
||||
public class ChunkNotFoundException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ChunkNotFoundException(String chunkName) {
|
||||
super(chunkName + " was named, but not found in POIFS object");
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/* ====================================================================
|
||||
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.exceptions;
|
||||
|
||||
/**
|
||||
* Exception for when a directory chunk is not found but is expected.
|
||||
* @author Travis Ferguson
|
||||
*/
|
||||
public class DirectoryChunkNotFoundException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DirectoryChunkNotFoundException(String directory) {
|
||||
super("Directory Chunk " + directory + " was not found!");
|
||||
}
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
/* ====================================================================
|
||||
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.parsers;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.poi.hsmf.datatypes.Chunk;
|
||||
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
|
||||
import org.apache.poi.hsmf.exceptions.DirectoryChunkNotFoundException;
|
||||
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||
import org.apache.poi.poifs.filesystem.DocumentNode;
|
||||
import org.apache.poi.poifs.filesystem.POIFSDocument;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.poifs.property.DirectoryProperty;
|
||||
import org.apache.poi.poifs.property.DocumentProperty;
|
||||
import org.apache.poi.poifs.storage.BlockWritable;
|
||||
|
||||
/**
|
||||
* Provides a HashMap with the ability to parse a PIOFS object and provide
|
||||
* an 'easy to access' hashmap structure for the document chunks inside it.
|
||||
*
|
||||
* @author Travis Ferguson
|
||||
*/
|
||||
public class POIFSChunkParser {
|
||||
/**
|
||||
* Constructor
|
||||
* @param fs
|
||||
* @throws IOException
|
||||
*/
|
||||
public POIFSChunkParser(POIFSFileSystem fs) throws IOException {
|
||||
this.setFileSystem(fs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the POIFileSystem object that this object is using.
|
||||
* @param fs
|
||||
* @throws IOException
|
||||
*/
|
||||
public void setFileSystem(POIFSFileSystem fs) throws IOException {
|
||||
this.fs = fs;
|
||||
this.reparseFileSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the FileSystem object that this object is currently using.
|
||||
* @return
|
||||
*/
|
||||
public POIFSFileSystem getFileSystem() {
|
||||
return this.fs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reparse the FileSystem object, resetting all the chunks stored in this object
|
||||
* @throws IOException
|
||||
*
|
||||
*/
|
||||
public void reparseFileSystem() throws IOException {
|
||||
// first clear this object of all chunks
|
||||
DirectoryEntry root = this.fs.getRoot();
|
||||
Iterator iter = root.getEntries();
|
||||
|
||||
this.directoryMap = this.processPOIIterator(iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the chunk data that's stored in this object's hashmap out and return it as a HashMap.
|
||||
* @param entryName
|
||||
* @return
|
||||
*/
|
||||
public Object getChunk(HashMap dirMap, String entryName) {
|
||||
if(dirMap == null) return null;
|
||||
else {
|
||||
return dirMap.get(entryName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull a directory/hashmap out of this hashmap and return it
|
||||
* @param directoryName
|
||||
* @return HashMap containing the chunks stored in the named directoryChunk
|
||||
* @throws DirectoryChunkNotFoundException This is thrown should the directoryMap HashMap on this object be null
|
||||
* or for some reason the directory is not found, is equal to null, or is for some reason not a HashMap/aka Directory Node.
|
||||
*/
|
||||
public HashMap getDirectoryChunk(String directoryName) throws DirectoryChunkNotFoundException {
|
||||
DirectoryChunkNotFoundException excep = new DirectoryChunkNotFoundException(directoryName);
|
||||
Object obj = getChunk(this.directoryMap, directoryName);
|
||||
if(obj == null || !(obj instanceof HashMap)) throw excep;
|
||||
|
||||
return (HashMap)obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls a ByteArrayOutputStream from this objects HashMap, this can be used to read a byte array of the contents of the given chunk.
|
||||
* @param directoryMap, chunk
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public Chunk getDocumentNode(HashMap dirNode, Chunk chunk) throws ChunkNotFoundException {
|
||||
String entryName = chunk.getEntryName();
|
||||
ChunkNotFoundException excep = new ChunkNotFoundException(entryName);
|
||||
Object obj = getChunk(dirNode, entryName);
|
||||
if(obj == null || !(obj instanceof ByteArrayOutputStream)) throw excep;
|
||||
|
||||
chunk.setValue((ByteArrayOutputStream)obj);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls a Chunk out of this objects root Node tree.
|
||||
* @param chunk
|
||||
* @return
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public Chunk getDocumentNode(Chunk chunk) throws ChunkNotFoundException {
|
||||
return getDocumentNode(this.directoryMap, chunk);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes an iterator returned by a POIFS call to getRoot().getEntries()
|
||||
* @param iter
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private HashMap processPOIIterator(Iterator iter) throws IOException {
|
||||
HashMap currentNode = new HashMap();
|
||||
|
||||
while(iter.hasNext()) {
|
||||
Object obj = iter.next();
|
||||
if(obj instanceof DocumentNode) {
|
||||
this.processDocumentNode((DocumentNode)obj, currentNode);
|
||||
} else if(obj instanceof DirectoryNode) {
|
||||
String blockName = ((DirectoryNode)obj).getName();
|
||||
Iterator viewIt = null;
|
||||
if( ((DirectoryNode)obj).preferArray()) {
|
||||
Object[] arr = ((DirectoryNode)obj).getViewableArray();
|
||||
ArrayList viewList = new ArrayList(arr.length);
|
||||
|
||||
for(int i = 0; i < arr.length; i++) {
|
||||
viewList.add(arr[i]);
|
||||
}
|
||||
viewIt = viewList.iterator();
|
||||
} else {
|
||||
viewIt = ((DirectoryNode)obj).getViewableIterator();
|
||||
}
|
||||
//store the next node on the hashmap
|
||||
currentNode.put(blockName, processPOIIterator(viewIt));
|
||||
} else if(obj instanceof DirectoryProperty) {
|
||||
//don't do anything with the directory property chunk...
|
||||
} else {
|
||||
System.err.println("Unknown node: " + obj.toString());
|
||||
}
|
||||
}
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a document node and adds it to the current directory HashMap
|
||||
* @param obj
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
private void processDocumentNode(DocumentNode obj, HashMap currentObj) throws IOException {
|
||||
String blockName = ((DocumentNode)obj).getName();
|
||||
|
||||
Iterator viewIt = null;
|
||||
if( ((DocumentNode)obj).preferArray()) {
|
||||
Object[] arr = ((DocumentNode)obj).getViewableArray();
|
||||
ArrayList viewList = new ArrayList(arr.length);
|
||||
|
||||
for(int i = 0; i < arr.length; i++) {
|
||||
viewList.add(arr[i]);
|
||||
}
|
||||
viewIt = viewList.iterator();
|
||||
} else {
|
||||
viewIt = ((DocumentNode)obj).getViewableIterator();
|
||||
}
|
||||
|
||||
while(viewIt.hasNext()) {
|
||||
Object view = viewIt.next();
|
||||
|
||||
if(view instanceof DocumentProperty) {
|
||||
//we don't care about the properties
|
||||
} else if(view instanceof POIFSDocument) {
|
||||
//check if our node has blocks or if it can just be read raw.
|
||||
int blockCount = ((POIFSDocument)view).countBlocks();
|
||||
//System.out.println("Block Name: " + blockName);
|
||||
if(blockCount <= 0) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
BlockWritable[] bws = ((POIFSDocument)view).getSmallBlocks();
|
||||
for(int i = 0; i < bws.length; i++) {
|
||||
bws[i].writeBlocks(out);
|
||||
}
|
||||
currentObj.put(blockName, out);
|
||||
} else {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
((POIFSDocument)view).writeBlocks(out);
|
||||
currentObj.put(blockName, out);
|
||||
}
|
||||
} else {
|
||||
System.err.println("Unknown View Type: " + view.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* private instance variables */
|
||||
private static final long serialVersionUID = 1L;
|
||||
private POIFSFileSystem fs;
|
||||
private HashMap directoryMap;
|
||||
}
|
40
src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java
Normal file
40
src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java
Normal file
@ -0,0 +1,40 @@
|
||||
/* ====================================================================
|
||||
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;
|
||||
|
||||
import junit.framework.*;
|
||||
|
||||
public class AllTests
|
||||
extends TestCase
|
||||
{
|
||||
|
||||
public AllTests(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite();
|
||||
suite.addTestSuite(org.apache.poi.hsmf.model.TestBlankFileRead.class);
|
||||
suite.addTestSuite(org.apache.poi.hsmf.model.TestSimpleFileRead.class);
|
||||
suite.addTestSuite(org.apache.poi.hsmf.model.TestChunkData.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
BIN
src/scratchpad/testcases/org/apache/poi/hsmf/data/blank.msg
Normal file
BIN
src/scratchpad/testcases/org/apache/poi/hsmf/data/blank.msg
Normal file
Binary file not shown.
Binary file not shown.
@ -0,0 +1,125 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.hsmf.MAPIMessage;
|
||||
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests to verify that the library can read blank msg files.
|
||||
*
|
||||
* @author Travis Ferguson
|
||||
*
|
||||
*/
|
||||
public class TestBlankFileRead extends TestCase {
|
||||
private MAPIMessage mapiMessage;
|
||||
|
||||
/**
|
||||
* Initialize this test, load up the blank.msg mapi message.
|
||||
* @throws IOException
|
||||
*/
|
||||
public TestBlankFileRead() throws IOException {
|
||||
String dirname = System.getProperty("HSMF.testdata.path");
|
||||
this.mapiMessage = new MAPIMessage(dirname + "/blank.msg");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can read the body of the blank message, we expect "".
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadBody() throws Exception {
|
||||
try {
|
||||
mapiMessage.getTextBody();
|
||||
} catch(ChunkNotFoundException exp) {
|
||||
return;
|
||||
}
|
||||
|
||||
TestCase.fail("Should have thrown a ChunkNotFoundException but didn't");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test to see if we can read the CC Chunk.
|
||||
* @throws ChunkNotFoundException
|
||||
*
|
||||
*/
|
||||
public void testReadDisplayCC() throws ChunkNotFoundException {
|
||||
String obtained = mapiMessage.getDisplayCC();
|
||||
String expected = "";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can read the CC Chunk.
|
||||
* @throws ChunkNotFoundException
|
||||
*
|
||||
*/
|
||||
public void testReadDisplayTo() throws ChunkNotFoundException {
|
||||
String obtained = mapiMessage.getDisplayTo();
|
||||
String expected = "";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can read the CC Chunk.
|
||||
* @throws ChunkNotFoundException
|
||||
*
|
||||
*/
|
||||
public void testReadDisplayBCC() throws ChunkNotFoundException {
|
||||
String obtained = mapiMessage.getDisplayBCC();
|
||||
String expected = "";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if we can read the subject line of the blank message, we expect ""
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadSubject() throws Exception {
|
||||
String obtained = mapiMessage.getSubject();
|
||||
TestCase.assertEquals("", obtained);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if we can read the subject line of the blank message, we expect ""
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadConversationTopic() throws Exception {
|
||||
try {
|
||||
mapiMessage.getConversationTopic();
|
||||
} catch(ChunkNotFoundException exp) {
|
||||
return;
|
||||
}
|
||||
TestCase.fail("We shouldn't have a ConversationTopic node on the blank.msg file.");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import org.apache.poi.hsmf.datatypes.Chunk;
|
||||
import org.apache.poi.hsmf.datatypes.Chunks;
|
||||
import org.apache.poi.hsmf.datatypes.StringChunk;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Verifies that the Chunks class is actually setup properly and hasn't been changed in ways
|
||||
* that will break the library.
|
||||
*
|
||||
* @author Travis Ferguson
|
||||
*
|
||||
*/
|
||||
public class TestChunkData extends TestCase {
|
||||
public void testChunkCreate() {
|
||||
StringChunk chunk = new StringChunk(0x0200);
|
||||
TestCase.assertEquals("__substg1.0_0200001E", chunk.getEntryName());
|
||||
|
||||
/* test the lower and upper limits of the chunk ids */
|
||||
chunk = new StringChunk(0x0000);
|
||||
TestCase.assertEquals("__substg1.0_0000001E", chunk.getEntryName());
|
||||
|
||||
chunk = new StringChunk(0xFFFF);
|
||||
TestCase.assertEquals("__substg1.0_FFFF001E", chunk.getEntryName());
|
||||
}
|
||||
|
||||
public void testTextBodyChunk() {
|
||||
StringChunk chunk = new StringChunk(0x1000);
|
||||
TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().textBodyChunk.getEntryName());
|
||||
}
|
||||
|
||||
public void testDisplayToChunk() {
|
||||
StringChunk chunk = new StringChunk(0x0E04);
|
||||
TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().displayToChunk.getEntryName());
|
||||
}
|
||||
|
||||
|
||||
public void testDisplayCCChunk() {
|
||||
StringChunk chunk = new StringChunk(0x0E03);
|
||||
TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().displayCCChunk.getEntryName());
|
||||
}
|
||||
|
||||
public void testDisplayBCCChunk() {
|
||||
StringChunk chunk = new StringChunk(0x0E02);
|
||||
TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().displayBCCChunk.getEntryName());
|
||||
}
|
||||
|
||||
public void testSubjectChunk() {
|
||||
Chunk chunk = new StringChunk(0x0037);
|
||||
TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().subjectChunk.getEntryName());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/* ====================================================================
|
||||
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.model;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.hsmf.MAPIMessage;
|
||||
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests to verify that we can read a simple msg file, that is in plain/text format with no attachments
|
||||
* or extra recipents.
|
||||
*
|
||||
* @author Travis Ferguson
|
||||
*/
|
||||
public class TestSimpleFileRead extends TestCase {
|
||||
private MAPIMessage mapiMessage;
|
||||
|
||||
/**
|
||||
* Initialize this test, load up the blank.msg mapi message.
|
||||
* @throws Exception
|
||||
*/
|
||||
public TestSimpleFileRead() throws IOException {
|
||||
String dirname = System.getProperty("HSMF.testdata.path");
|
||||
this.mapiMessage = new MAPIMessage(dirname + "/simple_test_msg.msg");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can read the CC Chunk.
|
||||
* @throws ChunkNotFoundException
|
||||
*
|
||||
*/
|
||||
public void testReadDisplayCC() throws ChunkNotFoundException {
|
||||
String obtained = mapiMessage.getDisplayCC();
|
||||
String expected = "";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can read the CC Chunk.
|
||||
* @throws ChunkNotFoundException
|
||||
*
|
||||
*/
|
||||
public void testReadDisplayTo() throws ChunkNotFoundException {
|
||||
String obtained = mapiMessage.getDisplayTo();
|
||||
String expected = "travis@overwrittenstack.com";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can read the CC Chunk.
|
||||
* @throws ChunkNotFoundException
|
||||
*
|
||||
*/
|
||||
public void testReadDisplayBCC() throws ChunkNotFoundException {
|
||||
String obtained = mapiMessage.getDisplayBCC();
|
||||
String expected = "";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if we can read the body of the blank message, we expect "".
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadBody() throws Exception {
|
||||
String obtained = mapiMessage.getTextBody();
|
||||
String expected = "This is a test message.";
|
||||
|
||||
TestCase.assertEquals(obtained, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can read the subject line of the blank message, we expect ""
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadSubject() throws Exception {
|
||||
String obtained = mapiMessage.getSubject();
|
||||
String expected = "test message";
|
||||
|
||||
TestCase.assertEquals(expected, obtained);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we can read the subject line of the blank message, we expect ""
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadConversationTopic() throws Exception {
|
||||
String obtained = mapiMessage.getConversationTopic();
|
||||
TestCase.assertEquals("test message", obtained);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if we can read the subject line of the blank message, we expect ""
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testReadMessageClass() throws Exception {
|
||||
String obtained = mapiMessage.getMessageClass();
|
||||
TestCase.assertEquals("IPM.Note", obtained);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user