From 11f59e96b8056298f846cdd322cb4bbec30dcdfa Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 29 Jul 2008 23:37:35 +0000 Subject: [PATCH] Tidying up of some xssfmodel stuff, by doing more work generically in XSSFRelation git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@680882 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/xssf/model/Control.java | 22 +++--- .../org/apache/poi/xssf/model/Drawing.java | 22 +++--- .../xssf/model/XSSFChildContainingModel.java | 17 +++-- .../poi/xssf/usermodel/XSSFWorkbook.java | 70 ++++++++++++------- .../poi/xssf/usermodel/TestXSSFBugs.java | 19 ++++- 5 files changed, 104 insertions(+), 46 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/model/Control.java b/src/ooxml/java/org/apache/poi/xssf/model/Control.java index 55f4872bec..0dc55a63fb 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/Control.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/Control.java @@ -12,7 +12,6 @@ import org.apache.xmlbeans.XmlOptions; import org.openxml4j.exceptions.InvalidFormatException; import org.openxml4j.opc.PackagePart; import org.openxml4j.opc.PackagePartName; -import org.openxml4j.opc.PackageRelationship; import org.openxml4j.opc.PackagingURIHelper; import org.openxml4j.opc.TargetMode; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTControl; @@ -62,17 +61,24 @@ public class Control implements XSSFChildContainingModel { options.setSavePrettyPrint(); control.save(out, options); } + + /** + * We expect active x binary parts + */ + public String[] getChildrenRelationshipTypes() { + return new String[] { + XSSFWorkbook.ACTIVEX_BINS.getRelation() + }; + } /** - * Finds our XSSFActiveXData children + * Generates and adds XSSFActiveXData children */ - public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException { - for(PackageRelationship rel : modelPart.getRelationshipsByType(XSSFWorkbook.ACTIVEX_BINS.getRelation())) { - PackagePart binPart = XSSFWorkbook.getTargetPart(modelPart.getPackage(), rel); - XSSFActiveXData actX = new XSSFActiveXData(binPart, rel.getId()); - activexBins.add(actX); - } + public void generateChild(PackagePart childPart, String childRelId) { + XSSFActiveXData actX = new XSSFActiveXData(childPart, childRelId); + activexBins.add(actX); } + /** * Writes back out our XSSFPictureData children */ diff --git a/src/ooxml/java/org/apache/poi/xssf/model/Drawing.java b/src/ooxml/java/org/apache/poi/xssf/model/Drawing.java index 41123e0005..df4ed853ee 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/Drawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/Drawing.java @@ -12,7 +12,6 @@ import org.apache.xmlbeans.XmlOptions; import org.openxml4j.exceptions.InvalidFormatException; import org.openxml4j.opc.PackagePart; import org.openxml4j.opc.PackagePartName; -import org.openxml4j.opc.PackageRelationship; import org.openxml4j.opc.PackagingURIHelper; import org.openxml4j.opc.TargetMode; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing; @@ -66,15 +65,22 @@ public class Drawing implements XSSFChildContainingModel { } /** - * Finds our XSSFPictureData children + * We expect image parts */ - public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException { - for(PackageRelationship rel : modelPart.getRelationshipsByType(XSSFWorkbook.IMAGES.getRelation())) { - PackagePart imagePart = XSSFWorkbook.getTargetPart(modelPart.getPackage(), rel); - XSSFPictureData pd = new XSSFPictureData(imagePart, rel.getId()); - pictures.add(pd); - } + public String[] getChildrenRelationshipTypes() { + return new String[] { + XSSFWorkbook.IMAGES.getRelation() + }; + } + + /** + * Generates and adds XSSFActiveXData children + */ + public void generateChild(PackagePart childPart, String childRelId) { + XSSFPictureData pd = new XSSFPictureData(childPart, childRelId); + pictures.add(pd); } + /** * Writes back out our XSSFPictureData children */ diff --git a/src/ooxml/java/org/apache/poi/xssf/model/XSSFChildContainingModel.java b/src/ooxml/java/org/apache/poi/xssf/model/XSSFChildContainingModel.java index eedfcc0869..d50a8eba05 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/XSSFChildContainingModel.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/XSSFChildContainingModel.java @@ -28,11 +28,20 @@ import org.openxml4j.opc.PackagePart; * raw images associated with it. */ public interface XSSFChildContainingModel extends XSSFModel { - /** - * Find any children associated with the {@link XSSFModel}. - * @param modelPart The PackagePart of this model + /** + * Returns the relationship type of any children we + * expect + */ + public String[] getChildrenRelationshipTypes(); + /** + * Called for each matching child, so that the + * appropriate model or usermodel thing can be + * created for it. + * @param childPart The PackagePart of the child + * @param childId the ID of the relationship the child comes from */ - public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException; + public void generateChild(PackagePart childPart, String childRelId); + /** * Writes out any children associated with the {@link XSSFModel}, * along with the required relationship stuff. 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 9aea48a0f3..cb953dfbe1 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -51,6 +51,7 @@ import org.apache.poi.xssf.model.Control; import org.apache.poi.xssf.model.Drawing; import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.StylesTable; +import org.apache.poi.xssf.model.XSSFChildContainingModel; import org.apache.poi.xssf.model.XSSFModel; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; @@ -235,6 +236,20 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { return null; } } + + /** + * Finds all the XSSFModels of this type which are + * defined as relationships of the given parent part + */ + public ArrayList findAll(PackagePart parentPart) throws Exception { + ArrayList found = new ArrayList(); + for(PackageRelationship rel : parentPart.getRelationshipsByType(REL)) { + PackagePart part = getTargetPart(parentPart.getPackage(), rel); + found.add(load(part)); + } + return found; + } + /** * Load, off the specified core part */ @@ -250,6 +265,19 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { inp.close(); } } + + // Do children, if required + if(model instanceof XSSFChildContainingModel) { + XSSFChildContainingModel ccm = + (XSSFChildContainingModel)model; + for(String relType : ccm.getChildrenRelationshipTypes()) { + for(PackageRelationship rel : corePart.getRelationshipsByType(relType)) { + PackagePart childPart = getTargetPart(corePart.getPackage(), rel); + ccm.generateChild(childPart, rel.getId()); + } + } + } + return model; } @@ -347,32 +375,24 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { continue; } - // Get the comments for the sheet, if there are any + // Load child streams of the sheet + ArrayList childModels; CommentsSource comments = null; - PackageRelationshipCollection commentsRel = - part.getRelationshipsByType(SHEET_COMMENTS.REL); - if(commentsRel != null && commentsRel.size() > 0) { - PackagePart commentsPart = - getTargetPart(commentsRel.getRelationship(0)); - comments = new CommentsTable(commentsPart.getInputStream()); - } - - // Get the drawings for the sheet, if there are any - ArrayList drawings = new ArrayList(); - for(PackageRelationship rel : part.getRelationshipsByType(VML_DRAWINGS.REL)) { - PackagePart drawingPart = getTargetPart(rel); - Drawing drawing = new Drawing(drawingPart.getInputStream(), rel.getId()); - drawing.findChildren(drawingPart); - drawings.add(drawing); - } - - // Get the activeX controls for the sheet, if there are any - ArrayList controls = new ArrayList(); - for(PackageRelationship rel : part.getRelationshipsByType(ACTIVEX_CONTROLS.REL)) { - PackagePart controlPart = getTargetPart(rel); - Control control = new Control(controlPart.getInputStream(), rel.getId()); - control.findChildren(controlPart); - controls.add(control); + ArrayList drawings; + ArrayList controls; + try { + // Get the comments for the sheet, if there are any + childModels = SHEET_COMMENTS.findAll(part); + if(childModels.size() > 0) { + comments = (CommentsSource)childModels.get(0); + } + + // Get the drawings for the sheet, if there are any + drawings = (ArrayList)VML_DRAWINGS.findAll(part); + // Get the activeX controls for the sheet, if there are any + controls = (ArrayList)ACTIVEX_CONTROLS.findAll(part); + } catch(Exception e) { + throw new RuntimeException("Unable to construct child part",e); } // Now create the sheet diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 703133f425..9eb0da6b4a 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -93,23 +93,40 @@ public class TestXSSFBugs extends TestCase { PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); assertNotNull(vba); + // And the drawing bit + PackagePart drw = pkg.getPart( + PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") + ); + assertNotNull(drw); + - // Save and re-open, is still there + // Save and re-open, both still there Package nPkg = saveAndOpen(wb); XSSFWorkbook nwb = new XSSFWorkbook(nPkg); assertTrue(nwb.isMacroEnabled()); + vba = nPkg.getPart( PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); assertNotNull(vba); + drw = nPkg.getPart( + PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") + ); + assertNotNull(drw); // And again, just to be sure nPkg = saveAndOpen(nwb); nwb = new XSSFWorkbook(nPkg); + assertTrue(nwb.isMacroEnabled()); + vba = nPkg.getPart( PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); assertNotNull(vba); + drw = nPkg.getPart( + PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml") + ); + assertNotNull(drw); FileOutputStream fout = new FileOutputStream("/tmp/foo.xlsm"); nwb.write(fout); -- 2.39.5