You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/09/15 23:57:21 UTC
svn commit: r695651 - in /poi/branches/ooxml: ./
src/documentation/content/xdocs/
src/java/org/apache/poi/hssf/record/formula/functions/
src/java/org/apache/poi/hssf/usermodel/
src/scratchpad/src/org/apache/poi/hsmf/
src/scratchpad/src/org/apache/poi/h...
Author: nick
Date: Mon Sep 15 14:57:21 2008
New Revision: 695651
URL: http://svn.apache.org/viewvc?rev=695651&view=rev
Log:
Merged revisions 695649 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk
........
r695649 | nick | 2008-09-15 22:51:14 +0100 (Mon, 15 Sep 2008) | 1 line
Fix inspired by bug #45804 - Update HSMF to handle Outlook 3.0 msg files, which have a different string chunk type
........
Added:
poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/data/outlook_30_msg.msg
- copied unchanged from r695649, poi/trunk/src/scratchpad/testcases/org/apache/poi/hsmf/data/outlook_30_msg.msg
poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestOutlook30FileRead.java
- copied unchanged from r695649, poi/trunk/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestOutlook30FileRead.java
Modified:
poi/branches/ooxml/ (props changed)
poi/branches/ooxml/src/documentation/content/xdocs/changes.xml
poi/branches/ooxml/src/documentation/content/xdocs/status.xml
poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/DateFunc.java (props changed)
poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java (props changed)
poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java (props changed)
poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java
poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java
poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java
poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java
poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestChunkData.java
Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 15 14:57:21 2008
@@ -1 +1 @@
-/poi/trunk:693591-694881,695264-695420,695621
+/poi/trunk:693591-694881,695264-695420,695621,695649
Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Sep 15 14:57:21 2008
@@ -1 +1 @@
-/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-695621
+/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-695649
Modified: poi/branches/ooxml/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/documentation/content/xdocs/changes.xml?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/documentation/content/xdocs/changes.xml (original)
+++ poi/branches/ooxml/src/documentation/content/xdocs/changes.xml Mon Sep 15 14:57:21 2008
@@ -66,7 +66,8 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
- <release version="3.1.1-alpha1" date="2008-??-??">
+ <release version="3.2-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45804 - Update HSMF to handle Outlook 3.0 msg files, which have a different string chunk type</action>
<action dev="POI-DEVELOPERS" type="add">Expose the name of Named Cell Styles via HSSFCellStyle (normally held on the parent style though)</action>
<action dev="POI-DEVELOPERS" type="fix">45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences</action>
<action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
Modified: poi/branches/ooxml/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/documentation/content/xdocs/status.xml?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/documentation/content/xdocs/status.xml (original)
+++ poi/branches/ooxml/src/documentation/content/xdocs/status.xml Mon Sep 15 14:57:21 2008
@@ -63,7 +63,8 @@
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling PowerPoint files, irrespective of if they are .ppt or .pptx</action>
<action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
</release>
- <release version="3.1.1-alpha1" date="2008-??-??">
+ <release version="3.2-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">45804 - Update HSMF to handle Outlook 3.0 msg files, which have a different string chunk type</action>
<action dev="POI-DEVELOPERS" type="add">Expose the name of Named Cell Styles via HSSFCellStyle (normally held on the parent style though)</action>
<action dev="POI-DEVELOPERS" type="fix">45978 - Fixed IOOBE in Ref3DPtg.toFormulaString() due eager initialisation of SheetReferences</action>
<action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/functions/DateFunc.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 15 14:57:21 2008
@@ -1 +1 @@
-/poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/DateFunc.java:695264-695420,695621
+/poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/DateFunc.java:695264-695420,695621,695649
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 15 14:57:21 2008
@@ -1 +1 @@
-/poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java:695264-695420,695621
+/poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyAreaEval.java:695264-695420,695621,695649
Propchange: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 15 14:57:21 2008
@@ -1 +1 @@
-/poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java:695264-695420,695621
+/poi/trunk/src/java/org/apache/poi/hssf/usermodel/LazyRefEval.java:695264-695420,695621,695649
Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/MAPIMessage.java Mon Sep 15 14:57:21 2008
@@ -37,6 +37,7 @@
public class MAPIMessage {
private POIFSChunkParser chunkParser;
private POIFSFileSystem fs;
+ private Chunks chunks;
/**
* Constructor for creating new files.
@@ -64,6 +65,10 @@
public MAPIMessage(InputStream in) throws IOException {
this.fs = new POIFSFileSystem(in);
chunkParser = new POIFSChunkParser(this.fs);
+
+ // Figure out the right string type, based on
+ // the chunks present
+ chunks = chunkParser.identifyChunks();
}
@@ -87,7 +92,7 @@
* @throws ChunkNotFoundException
*/
public String getTextBody() throws IOException, ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().textBodyChunk);
+ return getStringFromChunk(chunks.textBodyChunk);
}
/**
@@ -96,7 +101,7 @@
* @throws ChunkNotFoundException
*/
public String getSubject() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().subjectChunk);
+ return getStringFromChunk(chunks.subjectChunk);
}
@@ -107,7 +112,7 @@
* @throws ChunkNotFoundException
*/
public String getDisplayTo() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().displayToChunk);
+ return getStringFromChunk(chunks.displayToChunk);
}
/**
@@ -117,7 +122,7 @@
* @throws ChunkNotFoundException
*/
public String getDisplayFrom() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().displayFromChunk);
+ return getStringFromChunk(chunks.displayFromChunk);
}
/**
@@ -127,7 +132,7 @@
* @throws ChunkNotFoundException
*/
public String getDisplayCC() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().displayCCChunk);
+ return getStringFromChunk(chunks.displayCCChunk);
}
/**
@@ -137,7 +142,7 @@
* @throws ChunkNotFoundException
*/
public String getDisplayBCC() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().displayBCCChunk);
+ return getStringFromChunk(chunks.displayBCCChunk);
}
@@ -148,7 +153,7 @@
* @throws ChunkNotFoundException
*/
public String getConversationTopic() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().conversationTopic);
+ return getStringFromChunk(chunks.conversationTopic);
}
/**
@@ -160,6 +165,6 @@
* @throws ChunkNotFoundException
*/
public String getMessageClass() throws ChunkNotFoundException {
- return getStringFromChunk(Chunks.getInstance().messageClass);
+ return getStringFromChunk(chunks.messageClass);
}
}
Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Chunks.java Mon Sep 15 14:57:21 2008
@@ -25,17 +25,39 @@
*/
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 displayFromChunk = new StringChunk(0x0C1A); //Value that is in the FROM field
- 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).
+
+ /** Type of message that the MSG represents (ie. IPM.Note) */
+ public StringChunk messageClass;
+ /** BODY Chunk, for plain/text messages */
+ public StringChunk textBodyChunk;
+ /** Subject link chunk, in plain/text */
+ public StringChunk subjectChunk;
+ /** Value that is in the TO field (not actually the addresses as they are stored in recip directory nodes */
+ public StringChunk displayToChunk;
+ /** Value that is in the FROM field */
+ public StringChunk displayFromChunk;
+ /** value that shows in the CC field */
+ public StringChunk displayCCChunk;
+ /** Value that shows in the BCC field */
+ public StringChunk displayBCCChunk;
+ /** Sort of like the subject line, but without the RE: and FWD: parts. */
+ public StringChunk conversationTopic;
+ /** Type of server that the message originated from (SMTP, etc). */
+ public StringChunk sentByServerType;
- public static Chunks getInstance() {
- return new Chunks();
+ private Chunks(boolean newStringType) {
+ messageClass = new StringChunk(0x001A, newStringType);
+ textBodyChunk = new StringChunk(0x1000, newStringType);
+ subjectChunk = new StringChunk(0x0037, newStringType);
+ displayToChunk = new StringChunk(0x0E04, newStringType);
+ displayFromChunk = new StringChunk(0x0C1A, newStringType);
+ displayCCChunk = new StringChunk(0x0E03, newStringType);
+ displayBCCChunk = new StringChunk(0x0E02, newStringType);
+ conversationTopic = new StringChunk(0x0070, newStringType);
+ sentByServerType = new StringChunk(0x0075, newStringType);
+ }
+
+ public static Chunks getInstance(boolean newStringType) {
+ return new Chunks(newStringType);
}
}
Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/StringChunk.java Mon Sep 15 14:57:21 2008
@@ -27,9 +27,26 @@
private String value;
- public StringChunk(int chunkId) {
+ /**
+ * Creates a String Chunk, for either the old
+ * or new style of string chunk types.
+ */
+ public StringChunk(int chunkId, boolean newStyleString) {
+ this(chunkId, getStringType(newStyleString));
+ }
+ private static int getStringType(boolean newStyleString) {
+ if(newStyleString)
+ return Types.NEW_STRING;
+ return Types.OLD_STRING;
+ }
+
+ /**
+ * Create a String Chunk, with the specified
+ * type.
+ */
+ public StringChunk(int chunkId, int type) {
this.chunkId = chunkId;
- this.type = Types.STRING;
+ this.type = type;
}
/* (non-Javadoc)
Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/datatypes/Types.java Mon Sep 15 14:57:21 2008
@@ -19,8 +19,21 @@
public class Types {
public static int BINARY = 0x0102;
- public static int STRING = 0x001E;
+
+ /** A string, until Outlook 3.0 */
+ public static int OLD_STRING = 0x001E;
+ /** A string, from Outlook 3.0 onwards */
+ public static int NEW_STRING = 0x001F;
+
public static int LONG = 0x0003;
public static int TIME = 0x0040;
public static int BOOLEAN = 0x000B;
+
+ public static String asFileEnding(int type) {
+ String str = Integer.toHexString(type).toUpperCase();
+ while(str.length() < 4) {
+ str = "0" + str;
+ }
+ return str;
+ }
}
Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hsmf/parsers/POIFSChunkParser.java Mon Sep 15 14:57:21 2008
@@ -24,6 +24,8 @@
import java.util.Iterator;
import org.apache.poi.hsmf.datatypes.Chunk;
+import org.apache.poi.hsmf.datatypes.Chunks;
+import org.apache.poi.hsmf.datatypes.Types;
import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
import org.apache.poi.hsmf.exceptions.DirectoryChunkNotFoundException;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
@@ -82,7 +84,36 @@
this.directoryMap = this.processPOIIterator(iter);
}
-
+
+ /**
+ * Returns a list of the standard chunk types, as
+ * appropriate for the chunks we find in the file.
+ */
+ public Chunks identifyChunks() {
+ // Are they of the old or new type of strings?
+ boolean hasOldStrings = false;
+ boolean hasNewStrings = false;
+ String oldStringEnd = Types.asFileEnding(Types.OLD_STRING);
+ String newStringEnd = Types.asFileEnding(Types.NEW_STRING);
+
+ for(Iterator i = directoryMap.keySet().iterator(); i.hasNext();) {
+ String entry = (String)i.next();
+ if(entry.endsWith( oldStringEnd )) {
+ hasOldStrings = true;
+ }
+ if(entry.endsWith( newStringEnd )) {
+ hasNewStrings = true;
+ }
+ }
+
+ if(hasOldStrings && hasNewStrings) {
+ throw new IllegalStateException("Your file contains string chunks of both the old and new types. Giving up");
+ } else if(hasNewStrings) {
+ return Chunks.getInstance(true);
+ }
+ return Chunks.getInstance(false);
+ }
+
/**
* Pull the chunk data that's stored in this object's hashmap out and return it as a HashMap.
* @param entryName
Modified: poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java (original)
+++ poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/AllTests.java Mon Sep 15 14:57:21 2008
@@ -33,6 +33,7 @@
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.TestOutlook30FileRead.class);
suite.addTestSuite(org.apache.poi.hsmf.model.TestChunkData.class);
return suite;
Modified: poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestChunkData.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestChunkData.java?rev=695651&r1=695650&r2=695651&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestChunkData.java (original)
+++ poi/branches/ooxml/src/scratchpad/testcases/org/apache/poi/hsmf/model/TestChunkData.java Mon Sep 15 14:57:21 2008
@@ -31,42 +31,47 @@
*
*/
public class TestChunkData extends TestCase {
+ private Chunks chunks = Chunks.getInstance(false);
+
public void testChunkCreate() {
- StringChunk chunk = new StringChunk(0x0200);
+ StringChunk chunk = new StringChunk(0x0200, false);
TestCase.assertEquals("__substg1.0_0200001E", chunk.getEntryName());
/* test the lower and upper limits of the chunk ids */
- chunk = new StringChunk(0x0000);
+ chunk = new StringChunk(0x0000, false);
TestCase.assertEquals("__substg1.0_0000001E", chunk.getEntryName());
- chunk = new StringChunk(0xFFFF);
+ chunk = new StringChunk(0xFFFF, false);
TestCase.assertEquals("__substg1.0_FFFF001E", chunk.getEntryName());
+
+ chunk = new StringChunk(0xFFFF, true);
+ TestCase.assertEquals("__substg1.0_FFFF001F", chunk.getEntryName());
}
public void testTextBodyChunk() {
- StringChunk chunk = new StringChunk(0x1000);
- TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().textBodyChunk.getEntryName());
+ StringChunk chunk = new StringChunk(0x1000, false);
+ TestCase.assertEquals(chunk.getEntryName(), chunks.textBodyChunk.getEntryName());
}
public void testDisplayToChunk() {
- StringChunk chunk = new StringChunk(0x0E04);
- TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().displayToChunk.getEntryName());
+ StringChunk chunk = new StringChunk(0x0E04, false);
+ TestCase.assertEquals(chunk.getEntryName(), chunks.displayToChunk.getEntryName());
}
public void testDisplayCCChunk() {
- StringChunk chunk = new StringChunk(0x0E03);
- TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().displayCCChunk.getEntryName());
+ StringChunk chunk = new StringChunk(0x0E03, false);
+ TestCase.assertEquals(chunk.getEntryName(), chunks.displayCCChunk.getEntryName());
}
public void testDisplayBCCChunk() {
- StringChunk chunk = new StringChunk(0x0E02);
- TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().displayBCCChunk.getEntryName());
+ StringChunk chunk = new StringChunk(0x0E02, false);
+ TestCase.assertEquals(chunk.getEntryName(), chunks.displayBCCChunk.getEntryName());
}
public void testSubjectChunk() {
- Chunk chunk = new StringChunk(0x0037);
- TestCase.assertEquals(chunk.getEntryName(), Chunks.getInstance().subjectChunk.getEntryName());
+ Chunk chunk = new StringChunk(0x0037, false);
+ TestCase.assertEquals(chunk.getEntryName(), chunks.subjectChunk.getEntryName());
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org