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
This commit is contained in:
Nick Burch 2008-07-29 23:37:35 +00:00
parent 233d99fc4d
commit 613f361d61
5 changed files with 104 additions and 46 deletions

View File

@ -12,7 +12,6 @@ import org.apache.xmlbeans.XmlOptions;
import org.openxml4j.exceptions.InvalidFormatException; import org.openxml4j.exceptions.InvalidFormatException;
import org.openxml4j.opc.PackagePart; import org.openxml4j.opc.PackagePart;
import org.openxml4j.opc.PackagePartName; import org.openxml4j.opc.PackagePartName;
import org.openxml4j.opc.PackageRelationship;
import org.openxml4j.opc.PackagingURIHelper; import org.openxml4j.opc.PackagingURIHelper;
import org.openxml4j.opc.TargetMode; import org.openxml4j.opc.TargetMode;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTControl; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTControl;
@ -64,15 +63,22 @@ public class Control implements XSSFChildContainingModel {
} }
/** /**
* Finds our XSSFActiveXData children * We expect active x binary parts
*/ */
public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException { public String[] getChildrenRelationshipTypes() {
for(PackageRelationship rel : modelPart.getRelationshipsByType(XSSFWorkbook.ACTIVEX_BINS.getRelation())) { return new String[] {
PackagePart binPart = XSSFWorkbook.getTargetPart(modelPart.getPackage(), rel); XSSFWorkbook.ACTIVEX_BINS.getRelation()
XSSFActiveXData actX = new XSSFActiveXData(binPart, rel.getId()); };
activexBins.add(actX);
}
} }
/**
* Generates and adds XSSFActiveXData children
*/
public void generateChild(PackagePart childPart, String childRelId) {
XSSFActiveXData actX = new XSSFActiveXData(childPart, childRelId);
activexBins.add(actX);
}
/** /**
* Writes back out our XSSFPictureData children * Writes back out our XSSFPictureData children
*/ */

View File

@ -12,7 +12,6 @@ import org.apache.xmlbeans.XmlOptions;
import org.openxml4j.exceptions.InvalidFormatException; import org.openxml4j.exceptions.InvalidFormatException;
import org.openxml4j.opc.PackagePart; import org.openxml4j.opc.PackagePart;
import org.openxml4j.opc.PackagePartName; import org.openxml4j.opc.PackagePartName;
import org.openxml4j.opc.PackageRelationship;
import org.openxml4j.opc.PackagingURIHelper; import org.openxml4j.opc.PackagingURIHelper;
import org.openxml4j.opc.TargetMode; import org.openxml4j.opc.TargetMode;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing; 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 { public String[] getChildrenRelationshipTypes() {
for(PackageRelationship rel : modelPart.getRelationshipsByType(XSSFWorkbook.IMAGES.getRelation())) { return new String[] {
PackagePart imagePart = XSSFWorkbook.getTargetPart(modelPart.getPackage(), rel); XSSFWorkbook.IMAGES.getRelation()
XSSFPictureData pd = new XSSFPictureData(imagePart, rel.getId()); };
pictures.add(pd);
}
} }
/**
* 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 * Writes back out our XSSFPictureData children
*/ */

View File

@ -29,10 +29,19 @@ import org.openxml4j.opc.PackagePart;
*/ */
public interface XSSFChildContainingModel extends XSSFModel { public interface XSSFChildContainingModel extends XSSFModel {
/** /**
* Find any children associated with the {@link XSSFModel}. * Returns the relationship type of any children we
* @param modelPart The PackagePart of this model * expect
*/ */
public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException; 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 generateChild(PackagePart childPart, String childRelId);
/** /**
* Writes out any children associated with the {@link XSSFModel}, * Writes out any children associated with the {@link XSSFModel},
* along with the required relationship stuff. * along with the required relationship stuff.

View File

@ -51,6 +51,7 @@ import org.apache.poi.xssf.model.Control;
import org.apache.poi.xssf.model.Drawing; import org.apache.poi.xssf.model.Drawing;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.XSSFChildContainingModel;
import org.apache.poi.xssf.model.XSSFModel; import org.apache.poi.xssf.model.XSSFModel;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
@ -235,6 +236,20 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
return null; return null;
} }
} }
/**
* Finds all the XSSFModels of this type which are
* defined as relationships of the given parent part
*/
public ArrayList<? extends XSSFModel> findAll(PackagePart parentPart) throws Exception {
ArrayList<XSSFModel> found = new ArrayList<XSSFModel>();
for(PackageRelationship rel : parentPart.getRelationshipsByType(REL)) {
PackagePart part = getTargetPart(parentPart.getPackage(), rel);
found.add(load(part));
}
return found;
}
/** /**
* Load, off the specified core part * Load, off the specified core part
*/ */
@ -250,6 +265,19 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
inp.close(); 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; return model;
} }
@ -347,32 +375,24 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
continue; continue;
} }
// Get the comments for the sheet, if there are any // Load child streams of the sheet
ArrayList<? extends XSSFModel> childModels;
CommentsSource comments = null; CommentsSource comments = null;
PackageRelationshipCollection commentsRel = ArrayList<Drawing> drawings;
part.getRelationshipsByType(SHEET_COMMENTS.REL); ArrayList<Control> controls;
if(commentsRel != null && commentsRel.size() > 0) { try {
PackagePart commentsPart = // Get the comments for the sheet, if there are any
getTargetPart(commentsRel.getRelationship(0)); childModels = SHEET_COMMENTS.findAll(part);
comments = new CommentsTable(commentsPart.getInputStream()); if(childModels.size() > 0) {
} comments = (CommentsSource)childModels.get(0);
}
// Get the drawings for the sheet, if there are any // Get the drawings for the sheet, if there are any
ArrayList<Drawing> drawings = new ArrayList<Drawing>(); drawings = (ArrayList<Drawing>)VML_DRAWINGS.findAll(part);
for(PackageRelationship rel : part.getRelationshipsByType(VML_DRAWINGS.REL)) { // Get the activeX controls for the sheet, if there are any
PackagePart drawingPart = getTargetPart(rel); controls = (ArrayList<Control>)ACTIVEX_CONTROLS.findAll(part);
Drawing drawing = new Drawing(drawingPart.getInputStream(), rel.getId()); } catch(Exception e) {
drawing.findChildren(drawingPart); throw new RuntimeException("Unable to construct child part",e);
drawings.add(drawing);
}
// Get the activeX controls for the sheet, if there are any
ArrayList<Control> controls = new ArrayList<Control>();
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);
} }
// Now create the sheet // Now create the sheet

View File

@ -93,23 +93,40 @@ public class TestXSSFBugs extends TestCase {
PackagingURIHelper.createPartName("/xl/vbaProject.bin") PackagingURIHelper.createPartName("/xl/vbaProject.bin")
); );
assertNotNull(vba); 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); Package nPkg = saveAndOpen(wb);
XSSFWorkbook nwb = new XSSFWorkbook(nPkg); XSSFWorkbook nwb = new XSSFWorkbook(nPkg);
assertTrue(nwb.isMacroEnabled()); assertTrue(nwb.isMacroEnabled());
vba = nPkg.getPart( vba = nPkg.getPart(
PackagingURIHelper.createPartName("/xl/vbaProject.bin") PackagingURIHelper.createPartName("/xl/vbaProject.bin")
); );
assertNotNull(vba); assertNotNull(vba);
drw = nPkg.getPart(
PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
);
assertNotNull(drw);
// And again, just to be sure // And again, just to be sure
nPkg = saveAndOpen(nwb); nPkg = saveAndOpen(nwb);
nwb = new XSSFWorkbook(nPkg); nwb = new XSSFWorkbook(nPkg);
assertTrue(nwb.isMacroEnabled());
vba = nPkg.getPart( vba = nPkg.getPart(
PackagingURIHelper.createPartName("/xl/vbaProject.bin") PackagingURIHelper.createPartName("/xl/vbaProject.bin")
); );
assertNotNull(vba); assertNotNull(vba);
drw = nPkg.getPart(
PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing1.vml")
);
assertNotNull(drw);
FileOutputStream fout = new FileOutputStream("/tmp/foo.xlsm"); FileOutputStream fout = new FileOutputStream("/tmp/foo.xlsm");
nwb.write(fout); nwb.write(fout);