From e5fe6f32bd2622ff2bf3ffa4104f73e6df3aec3b Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 30 Dec 2007 17:46:20 +0000 Subject: [PATCH] Make a start on OOXML pptx support git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@607564 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hslf/HSLFXML.java | 148 ++++++++++++++++++ .../poi/hslf/usermodel/HSLFXMLSlideShow.java | 39 +++++ .../org/apache/poi/hslf/TestHSLFXML.java | 123 +++++++++++++++ 3 files changed, 310 insertions(+) create mode 100644 src/scratchpad/ooxml-src/org/apache/poi/hslf/HSLFXML.java create mode 100644 src/scratchpad/ooxml-src/org/apache/poi/hslf/usermodel/HSLFXMLSlideShow.java create mode 100644 src/scratchpad/ooxml-testcases/org/apache/poi/hslf/TestHSLFXML.java diff --git a/src/scratchpad/ooxml-src/org/apache/poi/hslf/HSLFXML.java b/src/scratchpad/ooxml-src/org/apache/poi/hslf/HSLFXML.java new file mode 100644 index 000000000..568cb80aa --- /dev/null +++ b/src/scratchpad/ooxml-src/org/apache/poi/hslf/HSLFXML.java @@ -0,0 +1,148 @@ +/* ==================================================================== + 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.hslf; + +import java.io.IOException; + +import org.apache.poi.hxf.HXFDocument; +import org.apache.xmlbeans.XmlException; +import org.openxml4j.exceptions.InvalidFormatException; +import org.openxml4j.exceptions.OpenXML4JException; +import org.openxml4j.opc.Package; +import org.openxml4j.opc.PackagePart; +import org.openxml4j.opc.PackageRelationshipCollection; +import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide; +import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdList; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry; +import org.openxmlformats.schemas.presentationml.x2006.main.NotesDocument; +import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument; +import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument; +import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; + +/** + * Experimental class to do low level processing + * of pptx files. + * + * If you are using these low level classes, then you + * will almost certainly need to refer to the OOXML + * specifications from + * http://www.ecma-international.org/publications/standards/Ecma-376.htm + * + * WARNING - APIs expected to change rapidly + */ +public class HSLFXML extends HXFDocument { + public static final String MAIN_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"; + public static final String NOTES_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"; + public static final String SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml"; + public static final String SLIDE_LAYOUT_RELATION_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"; + public static final String NOTES_RELATION_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide"; + + private PresentationDocument presentationDoc; + + public HSLFXML(Package container) throws OpenXML4JException, IOException, XmlException { + super(container, MAIN_CONTENT_TYPE); + + presentationDoc = + PresentationDocument.Factory.parse(basePart.getInputStream()); + } + + /** + * Returns the low level presentation base object + */ + public CTPresentation getPresentation() { + return presentationDoc.getPresentation(); + } + + /** + * Returns the references from the presentation to its + * slides. + * You'll need these to figure out the slide ordering, + * and to get at the actual slides themselves + */ + public CTSlideIdList getSlideReferences() { + return getPresentation().getSldIdLst(); + } + /** + * Returns the references from the presentation to its + * slide masters. + * You'll need these to get at the actual slide + * masters themselves + */ + public CTSlideMasterIdList getSlideMasterReferences() { + return getPresentation().getSldMasterIdLst(); + } + + /** + * Returns the low level slide master object from + * the supplied slide master reference + */ + public CTSlideMaster getSlideMaster(CTSlideMasterIdListEntry master) throws IOException, XmlException { + PackagePart masterPart = + getRelatedPackagePart(master.getId2()); + SldMasterDocument masterDoc = + SldMasterDocument.Factory.parse(masterPart.getInputStream()); + return masterDoc.getSldMaster(); + } + + /** + * Returns the low level slide object from + * the supplied slide reference + */ + public CTSlide getSlide(CTSlideIdListEntry slide) throws IOException, XmlException { + PackagePart slidePart = + getRelatedPackagePart(slide.getId2()); + SldDocument slideDoc = + SldDocument.Factory.parse(slidePart.getInputStream()); + return slideDoc.getSld(); + } + + /** + * Returns the low level notes object for the given + * slide, as found from the supplied slide reference + */ + public CTNotesSlide getNotes(CTSlideIdListEntry slide) throws IOException, XmlException { + PackagePart slidePart = + getRelatedPackagePart(slide.getId2()); + + PackageRelationshipCollection notes; + try { + notes = slidePart.getRelationshipsByType(NOTES_RELATION_TYPE); + } catch(InvalidFormatException e) { + throw new IllegalStateException(e); + } + + if(notes.size() == 0) { + // No notes for this slide + return null; + } + if(notes.size() > 1) { + throw new IllegalStateException("Expecting 0 or 1 notes for a slide, but found " + notes.size()); + } + + PackagePart notesPart = + getPackagePart(notes.getRelationship(0)); + NotesDocument notesDoc = + NotesDocument.Factory.parse(notesPart.getInputStream()); + + return notesDoc.getNotes(); + } +} diff --git a/src/scratchpad/ooxml-src/org/apache/poi/hslf/usermodel/HSLFXMLSlideShow.java b/src/scratchpad/ooxml-src/org/apache/poi/hslf/usermodel/HSLFXMLSlideShow.java new file mode 100644 index 000000000..b8a5fcde3 --- /dev/null +++ b/src/scratchpad/ooxml-src/org/apache/poi/hslf/usermodel/HSLFXMLSlideShow.java @@ -0,0 +1,39 @@ +/* ==================================================================== + 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.hslf.usermodel; + +import org.apache.poi.POIXMLDocument; +import org.apache.poi.hslf.HSLFXML; + +/** + * High level representation of a ooxml slideshow. + * This is the first object most users will construct whether + * they are reading or writing a slideshow. It is also the + * top level object for creating new slides/etc. + */ +public class HSLFXMLSlideShow extends POIXMLDocument { + private org.apache.poi.hslf.HSLFXML hslfXML; + + public HSLFXMLSlideShow(HSLFXML xml) { + super(xml); + this.hslfXML = xml; + } + + public HSLFXML _getHSLFXML() { + return hslfXML; + } +} diff --git a/src/scratchpad/ooxml-testcases/org/apache/poi/hslf/TestHSLFXML.java b/src/scratchpad/ooxml-testcases/org/apache/poi/hslf/TestHSLFXML.java new file mode 100644 index 000000000..11e7efd28 --- /dev/null +++ b/src/scratchpad/ooxml-testcases/org/apache/poi/hslf/TestHSLFXML.java @@ -0,0 +1,123 @@ +/* ==================================================================== + 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.hslf; + +import java.io.File; + +import org.apache.poi.hxf.HXFDocument; +import org.openxml4j.opc.Package; +import org.openxml4j.opc.PackagePart; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdList; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry; +import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry; + +import junit.framework.TestCase; + +public class TestHSLFXML extends TestCase { + private File sampleFile; + + protected void setUp() throws Exception { + super.setUp(); + + sampleFile = new File( + System.getProperty("HSLF.testdata.path") + + File.separator + "sample.pptx" + ); + } + + public void testContainsMainContentType() throws Exception { + Package pack = HXFDocument.openPackage(sampleFile); + + boolean found = false; + for(PackagePart part : pack.getParts()) { + if(part.getContentType().equals(HSLFXML.MAIN_CONTENT_TYPE)) { + found = true; + } + System.out.println(part); + } + assertTrue(found); + } + + public void testOpen() throws Exception { + HXFDocument.openPackage(sampleFile); + + HSLFXML xml; + + // With the finalised uri, should be fine + xml = new HSLFXML( + HXFDocument.openPackage(sampleFile) + ); + + // Check the core + assertNotNull(xml.getPresentation()); + + // Check it has some slides + assertTrue( + xml.getSlideReferences().sizeOfSldIdArray() > 0 + ); + assertTrue( + xml.getSlideMasterReferences().sizeOfSldMasterIdArray() > 0 + ); + } + + public void testSlideBasics() throws Exception { + HSLFXML xml = new HSLFXML( + HXFDocument.openPackage(sampleFile) + ); + + // Should have 1 master + assertEquals(1, xml.getSlideMasterReferences().sizeOfSldMasterIdArray()); + assertEquals(1, xml.getSlideMasterReferences().getSldMasterIdArray().length); + + // Should have three sheets + assertEquals(2, xml.getSlideReferences().sizeOfSldIdArray()); + assertEquals(2, xml.getSlideReferences().getSldIdArray().length); + + // Check they're as expected + CTSlideIdListEntry[] slides = xml.getSlideReferences().getSldIdArray(); + assertEquals(256, slides[0].getId()); + assertEquals(257, slides[1].getId()); + assertEquals("rId2", slides[0].getId2()); + assertEquals("rId3", slides[1].getId2()); + + // Now get those objects + assertNotNull(xml.getSlide(slides[0])); + assertNotNull(xml.getSlide(slides[1])); + + // And check they have notes as expected + assertNotNull(xml.getNotes(slides[0])); + assertNotNull(xml.getNotes(slides[1])); + + // And again for the master + CTSlideMasterIdListEntry[] masters = + xml.getSlideMasterReferences().getSldMasterIdArray(); + assertEquals(2147483648l, masters[0].getId()); + assertEquals("rId1", masters[0].getId2()); + assertNotNull(xml.getSlideMaster(masters[0])); + } + + public void testMetadataBasics() throws Exception { + HSLFXML xml = new HSLFXML( + HXFDocument.openPackage(sampleFile) + ); + assertNotNull(xml.getDocumentProperties()); + + assertEquals("Microsoft Office PowerPoint", xml.getDocumentProperties().getApplication()); + assertEquals(0, xml.getDocumentProperties().getCharacters()); + assertEquals(0, xml.getDocumentProperties().getLines()); + } +}