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.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
*/

View File

@ -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
*/

View File

@ -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 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},
* 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.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<? 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
*/
@ -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<? extends XSSFModel> 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<Drawing> drawings = new ArrayList<Drawing>();
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<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);
ArrayList<Drawing> drawings;
ArrayList<Control> 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<Drawing>)VML_DRAWINGS.findAll(part);
// Get the activeX controls for the sheet, if there are any
controls = (ArrayList<Control>)ACTIVEX_CONTROLS.findAll(part);
} catch(Exception e) {
throw new RuntimeException("Unable to construct child part",e);
}
// Now create the sheet

View File

@ -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);