Author: nick
Date: Wed Jan 16 04:46:43 2008
New Revision: 612438

URL: http://svn.apache.org/viewvc?rev=612438&view=rev
Log:
Add methods to check to see if a given InputStream has a OOXML file header, or 
a OLE2 file header, so that a future factory method could figure out which 
class to instantiate for a given InputStraeam

Added:
    poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/
    
poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/TestDetectAsOOXML.java
   (with props)
Modified:
    poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
    poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java
    poi/trunk/src/scratchpad/ooxml-src/org/apache/poi/hxf/HXFDocument.java
    
poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOffice2007XMLException.java

Modified: poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java?rev=612438&r1=612437&r2=612438&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/poifs/common/POIFSConstants.java Wed Jan 
16 04:46:43 2008
@@ -31,4 +31,7 @@
     public static final int END_OF_CHAIN   = -2;
     public static final int PROPERTY_SIZE  = 0x0080;
     public static final int UNUSED_BLOCK   = -1;
+    
+    public static final byte[] OOXML_FILE_HEADER = 
+       new byte[] { 0x50, 0x4b, 0x03, 0x04 };
 }   // end public interface POIFSConstants;

Modified: 
poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java?rev=612438&r1=612437&r2=612438&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSFileSystem.java Wed 
Jan 16 04:46:43 2008
@@ -34,6 +34,7 @@
 import org.apache.poi.poifs.storage.BlockAllocationTableWriter;
 import org.apache.poi.poifs.storage.BlockList;
 import org.apache.poi.poifs.storage.BlockWritable;
+import org.apache.poi.poifs.storage.HeaderBlockConstants;
 import org.apache.poi.poifs.storage.HeaderBlockReader;
 import org.apache.poi.poifs.storage.HeaderBlockWriter;
 import org.apache.poi.poifs.storage.RawDataBlock;
@@ -41,6 +42,9 @@
 import org.apache.poi.poifs.storage.SmallBlockTableReader;
 import org.apache.poi.poifs.storage.SmallBlockTableWriter;
 import org.apache.poi.poifs.storage.SmallDocumentBlock;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LongField;
+import org.apache.xmlbeans.impl.common.IOUtil;
 
 /**
  * This is the main class of the POIFS system; it manages the entire
@@ -105,6 +109,35 @@
                 .getRoot(), header_block_reader
                     .getSBATStart()), data_blocks, properties.getRoot()
                         .getChildren(), null);
+    }
+    
+    /**
+     * Checks that the supplied InputStream (which MUST
+     *  support mark and reset, or be a PushbackInputStream) 
+     *  has a POIFS (OLE2) header at the start of it.
+     * If your InputStream does not support mark / reset,
+     *  then wrap it in a PushBackInputStream, then be
+     *  sure to always use that, and not the original!
+     * @param inp An InputStream which supports either mark/reset, or is a 
PushbackInputStream 
+     */
+    public static boolean hasPOIFSHeader(InputStream inp) throws IOException {
+       // We want to peek at the first 8 bytes 
+       inp.mark(8);
+
+       byte[] header = new byte[8];
+       IOUtils.readFully(inp, header);
+        LongField signature = new 
LongField(HeaderBlockConstants._signature_offset, header);
+
+        // Wind back those 8 bytes
+        if(inp instanceof PushbackInputStream) {
+               PushbackInputStream pin = (PushbackInputStream)inp;
+               pin.unread(header);
+        } else {
+               inp.reset();
+        }
+       
+       // Did it match the signature?
+       return (signature.get() == HeaderBlockConstants._signature);
     }
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java?rev=612438&r1=612437&r2=612438&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/poifs/storage/HeaderBlockReader.java Wed 
Jan 16 04:46:43 2008
@@ -91,8 +91,11 @@
         if (signature.get() != _signature)
         {
                        // Is it one of the usual suspects?
-                       if(_data[0] == 0x50 && _data[1] == 0x4b && _data[2] == 
0x03 &&
-                                       _data[3] == 0x04) {
+               byte[] OOXML_FILE_HEADER = POIFSConstants.OOXML_FILE_HEADER;
+                       if(_data[0] == OOXML_FILE_HEADER[0] && 
+                                       _data[1] == OOXML_FILE_HEADER[1] && 
+                                       _data[2] == OOXML_FILE_HEADER[2] &&
+                                       _data[3] == OOXML_FILE_HEADER[3]) {
                                throw new OfficeXmlFileException("The supplied 
data appears to be in the Office 2007+ XML. POI only supports OLE2 Office 
documents");
                        }
 

Modified: poi/trunk/src/scratchpad/ooxml-src/org/apache/poi/hxf/HXFDocument.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/ooxml-src/org/apache/poi/hxf/HXFDocument.java?rev=612438&r1=612437&r2=612438&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/ooxml-src/org/apache/poi/hxf/HXFDocument.java 
(original)
+++ poi/trunk/src/scratchpad/ooxml-src/org/apache/poi/hxf/HXFDocument.java Wed 
Jan 16 04:46:43 2008
@@ -18,9 +18,15 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
 import java.util.ArrayList;
 
 import org.apache.poi.POIXMLDocument;
+import org.apache.poi.poifs.common.POIFSConstants;
+import org.apache.poi.poifs.storage.HeaderBlockConstants;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LongField;
 import org.apache.xmlbeans.XmlException;
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
@@ -87,6 +93,39 @@
                }
        }
        
+    /**
+     * Checks that the supplied InputStream (which MUST
+     *  support mark and reset, or be a PushbackInputStream) 
+     *  has a OOXML (zip) header at the start of it.
+     * If your InputStream does not support mark / reset,
+     *  then wrap it in a PushBackInputStream, then be
+     *  sure to always use that, and not the original!
+     * @param inp An InputStream which supports either mark/reset, or is a 
PushbackInputStream 
+     */
+    public static boolean hasOOXMLHeader(InputStream inp) throws IOException {
+       // We want to peek at the first 4 bytes 
+       inp.mark(4);
+
+       byte[] header = new byte[4];
+       IOUtils.readFully(inp, header);
+
+        // Wind back those 4 bytes
+        if(inp instanceof PushbackInputStream) {
+               PushbackInputStream pin = (PushbackInputStream)inp;
+               pin.unread(header);
+        } else {
+               inp.reset();
+        }
+       
+       // Did it match the ooxml zip signature?
+        return (
+               header[0] == POIFSConstants.OOXML_FILE_HEADER[0] && 
+               header[1] == POIFSConstants.OOXML_FILE_HEADER[1] && 
+               header[2] == POIFSConstants.OOXML_FILE_HEADER[2] && 
+               header[3] == POIFSConstants.OOXML_FILE_HEADER[3]
+        );                                                         
+    }
+    
        /**
         * Fetches the (single) PackagePart with the supplied
         *  content type.

Added: 
poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/TestDetectAsOOXML.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/TestDetectAsOOXML.java?rev=612438&view=auto
==============================================================================
--- 
poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/TestDetectAsOOXML.java
 (added)
+++ 
poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/TestDetectAsOOXML.java
 Wed Jan 16 04:46:43 2008
@@ -0,0 +1,65 @@
+
+/* ====================================================================
+   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.hxf;
+
+import junit.framework.TestCase;
+import java.io.*;
+
+/**
+ * Class to test that HXF correctly detects OOXML
+ *  documents
+ */
+public class TestDetectAsOOXML extends TestCase
+{
+       public String dirname;
+
+       public void setUp() {
+               dirname = System.getProperty("HSSF.testdata.path");
+       }
+
+       public void testOpensProperly() throws Exception
+       {
+               File f = new File(dirname + "/sample.xlsx");
+
+               HXFDocument.openPackage(f);
+       }
+       
+       public void testDetectAsPOIFS() throws Exception {
+               InputStream in;
+               
+               // ooxml file is
+               in = new PushbackInputStream(
+                               new FileInputStream(dirname + 
"/SampleSS.xlsx"), 10
+               );
+               assertTrue(HXFDocument.hasOOXMLHeader(in));
+               
+               // xls file isn't
+               in = new PushbackInputStream(
+                               new FileInputStream(dirname + "/SampleSS.xls"), 
10
+               );
+               assertFalse(HXFDocument.hasOOXMLHeader(in));
+               
+               // text file isn't
+               in = new PushbackInputStream(
+                               new FileInputStream(dirname + "/SampleSS.txt"), 
10
+               );
+               assertFalse(HXFDocument.hasOOXMLHeader(in));
+       }
+}

Propchange: 
poi/trunk/src/scratchpad/ooxml-testcases/org/apache/poi/hxf/TestDetectAsOOXML.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOffice2007XMLException.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOffice2007XMLException.java?rev=612438&r1=612437&r2=612438&view=diff
==============================================================================
--- 
poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOffice2007XMLException.java
 (original)
+++ 
poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestOffice2007XMLException.java
 Wed Jan 16 04:46:43 2008
@@ -47,4 +47,26 @@
                        // Good
                }
        }
+       
+       public void testDetectAsPOIFS() throws IOException {
+               InputStream in;
+               
+               // ooxml file isn't
+               in = new PushbackInputStream(
+                               new FileInputStream(dirname + 
"/SampleSS.xlsx"), 10
+               );
+               assertFalse(POIFSFileSystem.hasPOIFSHeader(in));
+               
+               // xls file is
+               in = new PushbackInputStream(
+                               new FileInputStream(dirname + "/SampleSS.xls"), 
10
+               );
+               assertTrue(POIFSFileSystem.hasPOIFSHeader(in));
+               
+               // text file isn't
+               in = new PushbackInputStream(
+                               new FileInputStream(dirname + "/SampleSS.txt"), 
10
+               );
+               assertFalse(POIFSFileSystem.hasPOIFSHeader(in));
+       }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to