Index: CHANGES.txt
===================================================================
--- CHANGES.txt	(revision 1188802)
+++ CHANGES.txt	(working copy)
@@ -22,6 +22,9 @@
  * TIKA-724: Added option to PDFParser to enable (the default) or
    disable auto-space insertion.
 
+ * TIKA-736: OpenOffice Presentation: text from the master slide is
+   now extracted.
+
 Release 0.10 - 09/25/2011
 
 The most notable changes in Tika 0.10 over previous releases are:
Index: tika-parsers/src/test/java/org/apache/tika/parser/odf/ODFParserTest.java
===================================================================
--- tika-parsers/src/test/java/org/apache/tika/parser/odf/ODFParserTest.java	(revision 1188802)
+++ tika-parsers/src/test/java/org/apache/tika/parser/odf/ODFParserTest.java	(working copy)
@@ -18,16 +18,16 @@
 
 import java.io.InputStream;
 
-import junit.framework.TestCase;
-
+import org.apache.tika.TikaTest;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.opendocument.OpenOfficeParser;
 import org.apache.tika.sax.BodyContentHandler;
 import org.xml.sax.ContentHandler;
 
-public class ODFParserTest extends TestCase {
+public class ODFParserTest extends TikaTest {
     /**
      * For now, allow us to run some tests against both
      *  the old and the new parser
@@ -207,4 +207,19 @@
           input.close();
       }
    }
-}
\ No newline at end of file
+
+    public void testODPMasterFooter() throws Exception {
+        InputStream input = ODFParserTest.class.getResourceAsStream(
+            "/test-documents/testMasterFooter.odp");
+        try {
+            Metadata metadata = new Metadata();
+            ContentHandler handler = new BodyContentHandler();
+            new AutoDetectParser().parse(input, handler, metadata);
+  
+            String content = handler.toString();
+            assertContains("Master footer is here", content);
+        } finally {
+            input.close();
+        }
+    }  
+}
Index: tika-parsers/src/test/resources/test-documents/testMasterFooter.odp
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: tika-parsers/src/test/resources/test-documents/testMasterFooter.odp
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Index: tika-parsers/src/main/java/org/apache/tika/parser/pkg/ZipContainerDetector.java
===================================================================
--- tika-parsers/src/main/java/org/apache/tika/parser/pkg/ZipContainerDetector.java	(revision 1188802)
+++ tika-parsers/src/main/java/org/apache/tika/parser/pkg/ZipContainerDetector.java	(working copy)
@@ -82,6 +82,10 @@
                         return MediaType.application("java-archive");
                     }
                 } finally {
+                    // TODO: shouldn't we record the open
+                    // container so it can be later
+                    // reused...?
+                    // tis.setOpenContainer(zip);
                     zip.close();
                 }
             } catch (IOException ignore) {
Index: tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java
===================================================================
--- tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java	(revision 1188802)
+++ tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentContentParser.java	(working copy)
@@ -174,10 +174,18 @@
             InputStream stream, ContentHandler handler,
             Metadata metadata, ParseContext context)
             throws IOException, SAXException, TikaException {
-        final XHTMLContentHandler xhtml =
-            new XHTMLContentHandler(handler,metadata);
-        DefaultHandler dh = new ElementMappingContentHandler(xhtml, MAPPINGS) {
+        parseInternal(stream,
+                      new XHTMLContentHandler(handler,metadata),
+                      metadata, context);
+    }
 
+    void parseInternal(
+            InputStream stream, final ContentHandler handler,
+            Metadata metadata, ParseContext context)
+            throws IOException, SAXException, TikaException {
+
+        DefaultHandler dh = new ElementMappingContentHandler(handler, MAPPINGS) {
+
             private final BitSet textNodeStack = new BitSet();
 
             private int nodeDepth = 0;
@@ -231,7 +239,7 @@
              * Check if a node is a text node
              */
             private boolean isTextNode(String namespaceURI, String localName) {
-                if (TEXT_NS.equals(namespaceURI)) {
+                if (TEXT_NS.equals(namespaceURI) && !localName.equals("page-number")) {
                     return true;
                 }
                 if (SVG_NS.equals(namespaceURI)) {
@@ -263,10 +271,10 @@
                 // call next handler if no filtering
                 if (completelyFiltered == 0) {
                     // special handling of text:h, that are directly passed
-                    // to xhtml handler
+                    // to incoming handler
                     if (TEXT_NS.equals(namespaceURI) && "h".equals(localName)) {
-                        xhtml.startElement(headingStack.push(
-                                getXHTMLHeaderTagName(atts)));
+                        final String el = headingStack.push(getXHTMLHeaderTagName(atts));
+                        handler.startElement(namespaceURI, el, el, atts);
                     } else {
                         super.startElement(
                                 namespaceURI, localName, qName, atts);
@@ -281,9 +289,10 @@
                 // call next handler if no filtering
                 if (completelyFiltered == 0) {
                     // special handling of text:h, that are directly passed
-                    // to xhtml handler
+                    // to incoming handler
                     if (TEXT_NS.equals(namespaceURI) && "h".equals(localName)) {
-                        xhtml.endElement(headingStack.pop());
+                        final String el = headingStack.pop();
+                        handler.endElement(namespaceURI, el, el);
                     } else {
                         super.endElement(namespaceURI,localName,qName);
                     }
Index: tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java
===================================================================
--- tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java	(revision 1188802)
+++ tika-parsers/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java	(working copy)
@@ -25,6 +25,8 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
+//import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+//import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.apache.tika.exception.TikaException;
 import org.apache.tika.io.IOUtils;
 import org.apache.tika.metadata.Metadata;
@@ -33,6 +35,7 @@
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.sax.EndDocumentShieldingContentHandler;
+import org.apache.tika.sax.XHTMLContentHandler;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
@@ -106,12 +109,37 @@
             InputStream stream, ContentHandler baseHandler,
             Metadata metadata, ParseContext context)
             throws IOException, SAXException, TikaException {
-       
+
+        // TODO: reuse the already opened ZIPFile, if
+        // present
+
+        /*
+        ZipFile zipFile;
+        if (stream instanceof TikaInputStream) {
+            TikaInputStream tis = (TikaInputStream) stream;
+            Object container = ((TikaInputStream) stream).getOpenContainer();
+            if (container instanceof ZipFile) {
+                zipFile = (ZipFile) container;
+            } else if (tis.hasFile()) {
+                zipFile = new ZipFile(tis.getFile());                
+            }
+        }
+        */
+
+        // TODO: if incoming IS is a TIS with a file
+        // associated, we should open ZipFile so we can
+        // visit metadata, mimetype first; today we lose
+        // all the metadata if meta.xml is hit after
+        // content.xml in the stream.  Then we can still
+        // read-once for the content.xml.
+
+        XHTMLContentHandler xhtml = new XHTMLContentHandler(baseHandler, metadata);
+
         // As we don't know which of the metadata or the content
         //  we'll hit first, catch the endDocument call initially
         EndDocumentShieldingContentHandler handler = 
-          new EndDocumentShieldingContentHandler(baseHandler);
-       
+          new EndDocumentShieldingContentHandler(xhtml);
+
         // Process the file in turn
         ZipInputStream zip = new ZipInputStream(stream);
         ZipEntry entry = zip.getNextEntry();
@@ -122,7 +150,19 @@
             } else if (entry.getName().equals("meta.xml")) {
                 meta.parse(zip, new DefaultHandler(), metadata, context);
             } else if (entry.getName().endsWith("content.xml")) {
-                content.parse(zip, handler, metadata, context);
+                if (content instanceof OpenDocumentContentParser) {
+                    ((OpenDocumentContentParser) content).parseInternal(zip, handler, metadata, context);
+                } else {
+                    // Foreign content parser was set:
+                    content.parse(zip, handler, metadata, context);
+                }
+            } else if (entry.getName().endsWith("styles.xml")) {
+                if (content instanceof OpenDocumentContentParser) {
+                    ((OpenDocumentContentParser) content).parseInternal(zip, handler, metadata, context);
+                } else {
+                    // Foreign content parser was set:
+                    content.parse(zip, handler, metadata, context);
+                }
             }
             entry = zip.getNextEntry();
         }
