diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index 806fd6381..90a7959ad 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -28,7 +28,7 @@ import org.openxml4j.exceptions.OpenXML4JException; import org.openxml4j.opc.*; import org.openxml4j.opc.Package; -public class POIXMLDocument extends POIXMLDocumentPart{ +public abstract class POIXMLDocument extends POIXMLDocumentPart{ public static final String CORE_PROPERTIES_REL_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; public static final String EXTENDED_PROPERTIES_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"; @@ -43,33 +43,26 @@ public class POIXMLDocument extends POIXMLDocumentPart{ /** The OPC Package */ private Package pkg; - /** The OPC core Package Part */ - private PackagePart corePart; - /** * The properties of the OPC package, opened as needed */ private POIXMLProperties properties; - /** - * The embedded OLE2 files in the OPC package - */ - protected List embedds; - protected POIXMLDocument() { super(null, null); - embedds = new LinkedList(); + try { + Package pkg = newPackage(); + initialize(pkg); + } catch (IOException e){ + throw new POIXMLException(e); + } } protected POIXMLDocument(Package pkg) throws IOException { - this(); + super(null, null); initialize(pkg); } - protected POIXMLDocument(String path) throws IOException { - this(openPackage(path)); - } - /** * Wrapper to open a package, returning an IOException * in the event of a problem. @@ -83,7 +76,7 @@ public class POIXMLDocument extends POIXMLDocumentPart{ } } - protected void initialize(Package pkg) throws IOException { + private void initialize(Package pkg) throws IOException { try { this.pkg = pkg; @@ -91,10 +84,11 @@ public class POIXMLDocument extends POIXMLDocumentPart{ PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0); // Get core part - this.corePart = super.packagePart = this.pkg.getPart(coreDocRelationship); + this.packagePart = this.pkg.getPart(coreDocRelationship); + this.packageRel = coreDocRelationship; // Verify it's there - if(corePart == null) { + if(this.packagePart == null) { throw new IllegalArgumentException("No core part found for this document! Nothing with " + coreDocRelationship.getRelationshipType() + " present as a relation."); } } catch (OpenXML4JException e) { @@ -102,12 +96,16 @@ public class POIXMLDocument extends POIXMLDocumentPart{ } } + protected Package newPackage() throws IOException { + throw new POIXMLException("Must be overridden"); + } + public Package getPackage() { return this.pkg; } protected PackagePart getCorePart() { - return this.corePart; + return this.packagePart; } /** @@ -128,7 +126,7 @@ public class POIXMLDocument extends POIXMLDocumentPart{ * @return The target part * @throws InvalidFormatException */ - public static PackagePart getTargetPart(Package pkg, PackageRelationship rel) throws InvalidFormatException { + protected static PackagePart getTargetPart(Package pkg, PackageRelationship rel) throws InvalidFormatException { PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI()); PackagePart part = pkg.getPart(relName); if (part == null) { @@ -137,26 +135,6 @@ public class POIXMLDocument extends POIXMLDocumentPart{ return part; } - /** - * Fetches the (single) PackagePart which is defined as - * the supplied relation content type of the base - * package/container, or null if none found. - * @param relationType The relation content type to search for - * @throws IllegalArgumentException If we find more than one part of that type - */ - protected PackagePart getSinglePartByRelationType(String relationType) throws IllegalArgumentException, OpenXML4JException { - PackageRelationshipCollection rels = - pkg.getRelationshipsByType(relationType); - if(rels.size() == 0) { - return null; - } - if(rels.size() > 1) { - throw new IllegalArgumentException("Found " + rels.size() + " relations for the type " + relationType + ", should only ever be one!"); - } - PackageRelationship rel = rels.getRelationship(0); - return getTargetPart(rel); - } - /** * Retrieves all the PackageParts which are defined as * relationships of the base document with the @@ -164,7 +142,7 @@ public class POIXMLDocument extends POIXMLDocumentPart{ */ protected PackagePart[] getRelatedByType(String contentType) throws InvalidFormatException { PackageRelationshipCollection partsC = - getCorePart().getRelationshipsByType(contentType); + getPackagePart().getRelationshipsByType(contentType); PackagePart[] parts = new PackagePart[partsC.size()]; int count = 0; @@ -224,8 +202,6 @@ public class POIXMLDocument extends POIXMLDocumentPart{ /** * Get the document's embedded files. */ - public List getAllEmbedds() throws OpenXML4JException - { - return embedds; - } + public abstract List getAllEmbedds() throws OpenXML4JException; + } diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index 342c9949e..660d0fc9e 100755 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -213,14 +213,14 @@ public class POIXMLDocumentPart { /** * Fired when a new package part is created */ - public void onDocumentCreate(){ + protected void onDocumentCreate(){ } /** * Fired when a package part is read */ - public void onDocumentRead(){ + protected void onDocumentRead(){ } } diff --git a/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java index c029490bb..53851177b 100644 --- a/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/XSLFSlideShow.java @@ -17,6 +17,8 @@ package org.apache.poi.xslf; import java.io.IOException; +import java.util.List; +import java.util.LinkedList; import org.apache.poi.POIXMLDocument; import org.apache.xmlbeans.XmlException; @@ -61,13 +63,18 @@ public class XSLFSlideShow extends POIXMLDocument { public static final String COMMENT_RELATION_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"; private PresentationDocument presentationDoc; - + /** + * The embedded OLE2 files in the OPC package + */ + private List embedds; + public XSLFSlideShow(Package container) throws OpenXML4JException, IOException, XmlException { super(container); presentationDoc = PresentationDocument.Factory.parse(getCorePart().getInputStream()); + embedds = new LinkedList(); for (CTSlideIdListEntry ctSlide : getSlideReferences().getSldIdArray()) { PackagePart slidePart = getTargetPart(getCorePart().getRelationship(ctSlide.getId2())); @@ -224,4 +231,12 @@ public class XSLFSlideShow extends POIXMLDocument { throw new IllegalStateException(e); } } + + /** + * Get the document's embedded files. + */ + public List getAllEmbedds() throws OpenXML4JException { + return embedds; + } + } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 3ac30559b..105eea28c 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -38,6 +38,7 @@ import org.apache.poi.POIXMLException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.openxml4j.exceptions.OpenXML4JException; +import org.openxml4j.exceptions.InvalidFormatException; import org.openxml4j.opc.*; import org.openxml4j.opc.Package; import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; @@ -98,16 +99,17 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable embedds; + /** * Create a new SpreadsheetML workbook. */ public XSSFWorkbook() { super(); - try { - newWorkbook(); - }catch (Exception e){ - throw new POIXMLException(e); - } + onDocumentCreate(); } /** @@ -126,37 +128,38 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, IterablePackage object. */ public XSSFWorkbook(Package pkg) throws IOException { - super(); + super(ensureWriteAccess(pkg)); + onDocumentRead(); + } + + /** + * YK: current implementation of OpenXML4J is funny. + * Packages opened by Package.open(InputStream is) are read-only, + * there is no way to change or even save such an instance in a OutputStream. + * The workaround is to create a copy via a temp file + */ + private static Package ensureWriteAccess(Package pkg) throws IOException { if(pkg.getPackageAccess() == PackageAccess.READ){ //YK: current implementation of OpenXML4J is funny. - //Packages opened by Package.open(InputStream is) are read-only, - //there is no way to change or even save such an instance in a OutputStream. - //The workaround is to create a copy via a temp file try { - Package tmp = PackageHelper.clone(pkg); - initialize(tmp); + return PackageHelper.clone(pkg); } catch (OpenXML4JException e){ throw new POIXMLException(e); } - } else { - initialize(pkg); } + return pkg; } /** * Initialize this workbook from the specified Package */ @Override - protected void initialize(Package pkg) throws IOException { - super.initialize(pkg); - + protected void onDocumentRead() { try { //build the POIXMLDocumentPart tree, this workbook is the root read(XSSFFactory.getInstance()); - PackagePart corePart = getCorePart(); - - WorkbookDocument doc = WorkbookDocument.Factory.parse(corePart.getInputStream()); + WorkbookDocument doc = WorkbookDocument.Factory.parse(getPackagePart().getInputStream()); this.workbook = doc.getWorkbook(); HashMap shIdMap = new HashMap(); @@ -167,8 +170,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable(); + embedds = new LinkedList(); for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) { String id = ctSheet.getId(); XSSFSheet sh = shIdMap.get(id); @@ -215,22 +220,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable(); sheets = new LinkedList(); + embedds = new LinkedList(); + } + + /** + * Create a new SpreadsheetML package and setup the default minimal content + */ + protected Package newPackage() throws IOException { + try { + Package pkg = Package.create(PackageHelper.createTempFile()); + // Main part + PackagePartName corePartName = PackagingURIHelper.createPartName(XSSFRelation.WORKBOOK.getDefaultFileName()); + // Create main part relationship + pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT); + // Create main document part + pkg.createPart(corePartName, XSSFRelation.WORKBOOK.getContentType()); + + pkg.getPackageProperties().setCreatorProperty("Apache POI"); + + return pkg; + } catch (InvalidFormatException e){ + throw new POIXMLException(e); + } } /** @@ -709,7 +722,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable getAllEmbedds() throws OpenXML4JException { + return embedds; + } } diff --git a/src/ooxml/java/org/apache/poi/xwpf/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/XWPFDocument.java index e5d5924df..8ef9ad884 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/XWPFDocument.java +++ b/src/ooxml/java/org/apache/poi/xwpf/XWPFDocument.java @@ -71,7 +71,11 @@ public class XWPFDocument extends POIXMLDocument { protected List hyperlinks; protected List paragraphs; protected List tables; - + /** + * The embedded OLE2 files in the OPC package + */ + private List embedds; + /** Handles the joy of different headers/footers for different pages */ private XWPFHeaderFooterPolicy headerFooterPolicy; @@ -239,5 +243,13 @@ public class XWPFDocument extends POIXMLDocument { { return getCorePart().getRelationshipsByType(COMMENT_RELATION_TYPE); } + + /** + * Get the document's embedded files. + */ + public List getAllEmbedds() throws OpenXML4JException { + return embedds; + } + }