first commit

This commit is contained in:
MaddoScientisto 2026-03-14 20:04:39 +01:00
commit 4d332ef662
27586 changed files with 3281783 additions and 0 deletions

View file

@ -0,0 +1,324 @@
package org.docx4j;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import net.engio.mbassy.bus.MBassador;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.HTMLSettings;
import org.docx4j.convert.out.common.Exporter;
import org.docx4j.convert.out.common.preprocess.PartialDeepCopy;
import org.docx4j.convert.out.fo.FOExporterVisitor;
import org.docx4j.convert.out.fo.FOExporterXslt;
import org.docx4j.convert.out.html.HTMLExporterVisitor;
import org.docx4j.convert.out.html.HTMLExporterXslt;
import org.docx4j.events.Docx4jEvent;
import org.docx4j.events.EventFinished;
import org.docx4j.events.PackageIdentifier;
import org.docx4j.events.StartEvent;
import org.docx4j.events.WellKnownJobTypes;
import org.docx4j.events.WellKnownProcessSteps;
import org.docx4j.model.datastorage.BindingHandler;
import org.docx4j.model.datastorage.CustomXmlDataStoragePartSelector;
import org.docx4j.model.datastorage.OpenDoPEHandler;
import org.docx4j.model.datastorage.RemovalHandler;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.utils.TraversalUtilVisitor;
import org.docx4j.wml.SdtElement;
import org.docx4j.wml.SdtPr;
import org.w3c.dom.Document;
public class Docx4J {
public static final String MIME_PDF = "application/pdf";
public static final String MIME_FO = "application/xml-fo";
public static final int FLAG_NONE = 0;
public static final int FLAG_EXPORT_PREFER_XSL = 1;
public static final int FLAG_EXPORT_PREFER_NONXSL = 2;
public static final int FLAG_SAVE_ZIP_FILE = 1;
public static final int FLAG_SAVE_FLAT_XML = 2;
public static final int FLAG_BIND_INSERT_XML = 1;
public static final int FLAG_BIND_BIND_XML = 2;
public static final int FLAG_BIND_REMOVE_SDT = 4;
public static final int FLAG_BIND_REMOVE_XML = 8;
private static MBassador<Docx4jEvent> bus;
protected static final String NS_CONDITIONS = "http://opendope.org/conditions";
protected static final String NS_XPATHS = "http://opendope.org/xpaths";
protected static final String NS_QUESTIONS = "http://opendope.org/questions";
protected static final String NS_COMPONENTS = "http://opendope.org/components";
public static void setEventNotifier(MBassador<Docx4jEvent> eventbus) {
bus = eventbus;
}
protected static class FindContentControlsVisitor extends TraversalUtilVisitor<SdtElement> {
public static class BreakException extends RuntimeException {}
protected Set<String> definedStoreItemIds = null;
protected String storeItemId = null;
public FindContentControlsVisitor(Set<String> definedStoreItemIds) {
this.definedStoreItemIds = definedStoreItemIds;
}
public void apply(SdtElement element) {
SdtPr sdtPr = element.getSdtPr();
if (sdtPr.getDataBinding() != null && sdtPr.getDataBinding().getStoreItemID() != null) {
String tmp = sdtPr.getDataBinding().getStoreItemID().toLowerCase();
if (this.definedStoreItemIds.contains(tmp)) {
this.storeItemId = tmp;
throw new BreakException();
}
}
}
public String getdefinedStoreItemId() {
return this.storeItemId;
}
}
protected static final Set<String> PART_TO_REMOVE_SCHEMA_TYPES = new TreeSet<String>();
static {
PART_TO_REMOVE_SCHEMA_TYPES.add("http://opendope.org/conditions");
PART_TO_REMOVE_SCHEMA_TYPES.add("http://opendope.org/xpaths");
PART_TO_REMOVE_SCHEMA_TYPES.add("http://opendope.org/questions");
PART_TO_REMOVE_SCHEMA_TYPES.add("http://opendope.org/components");
}
public static WordprocessingMLPackage load(File inFile) throws Docx4JException {
return WordprocessingMLPackage.load(inFile);
}
public static WordprocessingMLPackage load(PackageIdentifier pkgIdentifier, File inFile) throws Docx4JException {
return (WordprocessingMLPackage)OpcPackage.load(pkgIdentifier, inFile);
}
public static WordprocessingMLPackage load(InputStream inStream) throws Docx4JException {
return WordprocessingMLPackage.load(inStream);
}
public static WordprocessingMLPackage load(PackageIdentifier pkgIdentifier, InputStream inStream) throws Docx4JException {
return (WordprocessingMLPackage)OpcPackage.load(pkgIdentifier, inStream);
}
public static void save(WordprocessingMLPackage wmlPackage, File outFile, int flags) throws Docx4JException {
wmlPackage.save(outFile, flags);
}
public static void save(WordprocessingMLPackage wmlPackage, OutputStream outStream, int flags) throws Docx4JException {
wmlPackage.save(outStream, flags);
}
public static void bind(WordprocessingMLPackage wmlPackage, String xmlDocument, int flags) throws Docx4JException {
ByteArrayInputStream xmlStream = null;
if (flags == 0)
flags = 15;
if ((flags & 0x1) == 1)
try {
xmlStream = new ByteArrayInputStream(xmlDocument.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e1) {
xmlStream = new ByteArrayInputStream(xmlDocument.getBytes());
}
bind(wmlPackage, xmlStream, flags);
}
public static void bind(WordprocessingMLPackage wmlPackage, InputStream xmlDocument, int flags) throws Docx4JException {
StartEvent bindJobStartEvent = new StartEvent(WellKnownJobTypes.BIND, wmlPackage);
bindJobStartEvent.publish();
if (flags == 0)
flags = 15;
Document xmlDoc = null;
if ((flags & 0x1) == 1)
try {
xmlDoc = XmlUtils.getNewDocumentBuilder().parse(xmlDocument);
} catch (Exception e) {
throw new Docx4JException("Problems creating a org.w3c.dom.Document for the passed input stream.", e);
}
bind(wmlPackage, xmlDoc, flags);
new EventFinished(bindJobStartEvent).publish();
}
public static void bind(WordprocessingMLPackage wmlPackage, Document xmlDocument, int flags) throws Docx4JException {
OpenDoPEHandler openDoPEHandler = null;
CustomXmlDataStoragePart customXmlDataStoragePart = null;
RemovalHandler removalHandler = null;
AtomicInteger bookmarkId = null;
if (flags == 0)
flags = 15;
customXmlDataStoragePart = CustomXmlDataStoragePartSelector.getCustomXmlDataStoragePart(wmlPackage);
if (customXmlDataStoragePart == null)
throw new Docx4JException("Couldn't find CustomXmlDataStoragePart! exiting..");
if ((flags & 0x1) == 1) {
StartEvent startEvent = new StartEvent(WellKnownJobTypes.BIND, wmlPackage, WellKnownProcessSteps.BIND_INSERT_XML);
startEvent.publish();
insertXMLData(customXmlDataStoragePart, xmlDocument);
new EventFinished(startEvent).publish();
}
if ((flags & 0x2) == 2) {
StartEvent startEvent = new StartEvent(WellKnownJobTypes.BIND, wmlPackage, WellKnownProcessSteps.BIND_BIND_XML);
startEvent.publish();
if (wmlPackage.getMainDocumentPart().getXPathsPart() != null) {
openDoPEHandler = new OpenDoPEHandler(wmlPackage);
openDoPEHandler.preprocess();
bookmarkId = openDoPEHandler.getNextBookmarkId();
}
BindingHandler bh = new BindingHandler(wmlPackage);
bh.setStartingIdForNewBookmarks(bookmarkId);
bh.applyBindings();
new EventFinished(startEvent).publish();
}
if ((flags & 0x4) == 4) {
StartEvent startEvent = new StartEvent(WellKnownJobTypes.BIND, wmlPackage, WellKnownProcessSteps.BIND_REMOVE_SDT);
startEvent.publish();
removeSDTs(wmlPackage);
new EventFinished(startEvent).publish();
}
if ((flags & 0x8) == 8) {
StartEvent startEvent = new StartEvent(WellKnownJobTypes.BIND, wmlPackage, WellKnownProcessSteps.BIND_REMOVE_XML);
startEvent.publish();
removeDefinedCustomXmlParts(wmlPackage, customXmlDataStoragePart);
new EventFinished(startEvent).publish();
}
}
protected static void insertXMLData(CustomXmlDataStoragePart customXmlDataStoragePart, Document xmlDocument) throws Docx4JException {
customXmlDataStoragePart.getData().setDocument(xmlDocument);
}
protected static String findXPathStorageItemIdInContentControls(WordprocessingMLPackage wmlPackage) {
FindContentControlsVisitor visitor = null;
if (wmlPackage.getCustomXmlDataStorageParts() != null && !wmlPackage.getCustomXmlDataStorageParts().isEmpty())
try {
visitor = new FindContentControlsVisitor(wmlPackage.getCustomXmlDataStorageParts().keySet());
TraversalUtil.visit(wmlPackage, false, visitor);
} catch (FindContentControlsVisitor.BreakException be) {}
return (visitor != null) ? visitor.getdefinedStoreItemId() : null;
}
protected static void removeSDTs(WordprocessingMLPackage wmlPackage) throws Docx4JException {
RemovalHandler removalHandler = new RemovalHandler();
removalHandler.removeSDTs(wmlPackage.getMainDocumentPart(), RemovalHandler.Quantifier.ALL, (String[])null);
for (Part part : wmlPackage.getParts().getParts().values()) {
if (part instanceof HeaderPart) {
removalHandler.removeSDTs((HeaderPart)part, RemovalHandler.Quantifier.ALL, (String[])null);
continue;
}
if (part instanceof FooterPart)
removalHandler.removeSDTs((FooterPart)part, RemovalHandler.Quantifier.ALL, (String[])null);
}
}
protected static void removeDefinedCustomXmlParts(WordprocessingMLPackage wmlPackage, CustomXmlDataStoragePart customXmlDataStoragePart) {
List<PartName> partsToRemove = new ArrayList<PartName>();
RelationshipsPart relationshipsPart = wmlPackage.getMainDocumentPart().getRelationshipsPart();
List<Relationship> relationshipsList = (relationshipsPart != null && relationshipsPart.getRelationships() != null) ? relationshipsPart.getRelationships().getRelationship() : null;
Part part = null;
if (relationshipsList != null)
for (Relationship relationship : relationshipsList) {
if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml".equals(relationship.getType())) {
part = relationshipsPart.getPart(relationship);
if (part == customXmlDataStoragePart)
partsToRemove.add(part.getPartName());
}
}
if (!partsToRemove.isEmpty())
for (int i = 0; i < partsToRemove.size(); i++)
relationshipsPart.removePart(partsToRemove.get(i));
}
public static WordprocessingMLPackage clone(WordprocessingMLPackage wmlPackage) throws Docx4JException {
return (WordprocessingMLPackage)PartialDeepCopy.process(wmlPackage, null);
}
public static FOSettings createFOSettings() {
return new FOSettings();
}
public static void toFO(FOSettings settings, OutputStream outputStream, int flags) throws Docx4JException {
Exporter<FOSettings> exporter = getFOExporter(flags);
exporter.export(settings, outputStream);
}
public static void toPDF(WordprocessingMLPackage wmlPackage, OutputStream outputStream) throws Docx4JException {
StartEvent startEvent = new StartEvent(wmlPackage, WellKnownProcessSteps.PDF);
startEvent.publish();
FOSettings settings = createFOSettings();
settings.setWmlPackage(wmlPackage);
settings.setApacheFopMime("application/pdf");
toFO(settings, outputStream, 0);
new EventFinished(startEvent).publish();
}
protected static Exporter<FOSettings> getFOExporter(int flags) {
switch (flags) {
case 2:
return FOExporterVisitor.getInstance();
}
return FOExporterXslt.getInstance();
}
public static HTMLSettings createHTMLSettings() {
return new HTMLSettings();
}
public static void toHTML(HTMLSettings settings, OutputStream outputStream, int flags) throws Docx4JException {
StartEvent startEvent = new StartEvent(settings.getWmlPackage(), WellKnownProcessSteps.HTML_OUT);
startEvent.publish();
Exporter<HTMLSettings> exporter = getHTMLExporter(flags);
exporter.export(settings, outputStream);
new EventFinished(startEvent).publish();
}
public static void toHTML(WordprocessingMLPackage wmlPackage, String imageDirPath, String imageTargetUri, OutputStream outputStream) throws Docx4JException {
StartEvent startEvent = new StartEvent(wmlPackage, WellKnownProcessSteps.HTML_OUT);
startEvent.publish();
HTMLSettings settings = createHTMLSettings();
settings.setWmlPackage(wmlPackage);
if (imageDirPath != null)
settings.setImageDirPath(imageDirPath);
if (imageTargetUri != null)
settings.setImageTargetUri(imageTargetUri);
toHTML(settings, outputStream, 0);
new EventFinished(startEvent).publish();
}
protected static Exporter<HTMLSettings> getHTMLExporter(int flags) {
switch (flags) {
case 2:
return HTMLExporterVisitor.getInstance();
}
return HTMLExporterXslt.getInstance();
}
}

View file

@ -0,0 +1,58 @@
package org.docx4j;
import java.util.Properties;
import org.docx4j.utils.ResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Docx4jProperties {
protected static Logger log = LoggerFactory.getLogger(Docx4jProperties.class);
private static Properties properties;
private static void init() {
properties = new Properties();
try {
properties.load(ResourceUtils.getResource("docx4j.properties"));
} catch (Exception e) {
log.warn("Couldn't find/read docx4j.properties; " + e.getMessage());
}
}
public static String getProperty(String key) {
if (properties == null)
init();
return properties.getProperty(key);
}
public static String getProperty(String key, String defaultValue) {
if (properties == null)
init();
return properties.getProperty(key, defaultValue);
}
public static boolean getProperty(String key, boolean defaultValue) {
if (properties == null)
init();
String result = properties.getProperty(key, Boolean.toString(defaultValue));
return Boolean.parseBoolean(result);
}
public static Properties getProperties() {
if (properties == null)
init();
return properties;
}
public static void setProperty(String key, Boolean value) {
if (properties == null)
init();
properties.setProperty(key, value.toString());
}
public static void setProperty(String key, String value) {
if (properties == null)
init();
properties.setProperty(key, value);
}
}

View file

@ -0,0 +1,65 @@
package org.docx4j;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import org.docx4j.jaxb.Context;
import org.docx4j.jaxb.NamespacePrefixMapperUtils;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class TextUtils {
private static Logger log = LoggerFactory.getLogger(TextUtils.class);
public static void extractText(Object o, Writer w) throws Exception {
extractText(o, w, Context.jc);
}
public static void extractText(Object o, Writer w, JAXBContext jc) throws Exception {
Marshaller marshaller = jc.createMarshaller();
NamespacePrefixMapperUtils.setProperty(marshaller, NamespacePrefixMapperUtils.getPrefixMapper());
marshaller.marshal(o, new TextExtractor(w));
}
public static void extractText(Object o, Writer w, JAXBContext jc, String uri, String local, Class declaredType) throws Exception {
Marshaller marshaller = jc.createMarshaller();
NamespacePrefixMapperUtils.setProperty(marshaller, NamespacePrefixMapperUtils.getPrefixMapper());
marshaller.marshal(new JAXBElement(new QName(uri, local), declaredType, o), new TextExtractor(w));
}
static class TextExtractor extends DefaultHandler {
private Writer out;
public TextExtractor(Writer out) {
this.out = out;
}
public void characters(char[] text, int start, int length) throws SAXException {
try {
this.out.write(text, start, length);
} catch (IOException e) {
throw new SAXException(e);
}
}
}
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/sample-docs/Table.docx";
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputfilepath));
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
Document wmlDocumentEl = documentPart.getJaxbElement();
Writer out = new OutputStreamWriter(System.out);
extractText(wmlDocumentEl, out);
out.close();
}
}

View file

@ -0,0 +1,380 @@
package org.docx4j;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.docx4j.dml.CTGvmlGroupShape;
import org.docx4j.dml.CTGvmlPicture;
import org.docx4j.dml.CTHyperlink;
import org.docx4j.dml.CTNonVisualDrawingProps;
import org.docx4j.dml.Graphic;
import org.docx4j.dml.GraphicData;
import org.docx4j.dml.diagram.CTDataModel;
import org.docx4j.dml.diagram2008.CTDrawing;
import org.docx4j.dml.picture.Pic;
import org.docx4j.dml.wordprocessingDrawing.Anchor;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.CommentsPart;
import org.docx4j.openpackaging.parts.WordprocessingML.EndnotesPart;
import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart;
import org.docx4j.openpackaging.parts.WordprocessingML.FootnotesPart;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.utils.CompoundTraversalUtilVisitorCallback;
import org.docx4j.utils.SingleTraversalUtilVisitorCallback;
import org.docx4j.utils.TraversalUtilVisitor;
import org.docx4j.vml.CTShape;
import org.docx4j.vml.CTTextbox;
import org.docx4j.wml.Body;
import org.docx4j.wml.CTObject;
import org.docx4j.wml.CTTxbxContent;
import org.docx4j.wml.Comments;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Document;
import org.docx4j.wml.FldChar;
import org.docx4j.wml.Pict;
import org.docx4j.wml.SdtBlock;
import org.docx4j.wml.SdtElement;
import org.docx4j.wml.Text;
import org.jvnet.jaxb2_commons.ppp.Child;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
public class TraversalUtil {
private static Logger log = LoggerFactory.getLogger(TraversalUtil.class);
Callback cb;
public static abstract class CallbackImpl implements Callback {
public void walkJAXBElements(Object parent) {
List<Object> children = getChildren(parent);
if (children != null)
for (Object o : children) {
o = XmlUtils.unwrap(o);
if (o instanceof Child)
if (parent instanceof SdtBlock) {
((Child)o).setParent(((SdtBlock)parent).getSdtContent());
} else {
((Child)o).setParent(parent);
}
apply(o);
if (shouldTraverse(o))
walkJAXBElements(o);
}
}
public List<Object> getChildren(Object o) {
return TraversalUtil.getChildrenImpl(o);
}
public abstract List<Object> apply(Object param1Object);
public boolean shouldTraverse(Object o) {
return true;
}
}
public TraversalUtil(Object parent, Callback cb) {
this.cb = cb;
cb.walkJAXBElements(parent);
}
static void visitChildrenImpl(Object o) {}
private static List<Object> handleGraphicData(GraphicData graphicData) {
List<Object> tmpArtificialList = new ArrayList();
if (graphicData.getPic() != null) {
CTNonVisualDrawingProps picNonVisual = graphicData.getPic().getNvPicPr().getCNvPr();
if (picNonVisual != null)
handleCTNonVisualDrawingProps(picNonVisual, tmpArtificialList);
}
if (graphicData.getPic() != null && graphicData.getPic().getBlipFill() != null && graphicData.getPic().getBlipFill().getBlip() != null) {
log.debug("found CTBlip");
List<Object> artificialList = new ArrayList();
if (!tmpArtificialList.isEmpty())
artificialList.addAll(tmpArtificialList);
artificialList.add(graphicData.getPic().getBlipFill().getBlip());
return artificialList;
}
return graphicData.getAny();
}
private static void handleCTNonVisualDrawingProps(CTNonVisualDrawingProps drawingProps, List<Object> artificialList) {
if (drawingProps != null) {
CTHyperlink docPrHyperLink = drawingProps.getHlinkClick();
if (docPrHyperLink != null)
artificialList.add(docPrHyperLink);
}
}
public static List<Object> getChildrenImpl(Object o) {
if (o == null) {
log.warn("null passed to getChildrenImpl");
return null;
}
log.debug("getting children of " + o.getClass().getName());
if (o instanceof Text)
return null;
if (o instanceof List)
return (List<Object>)o;
if (o instanceof ContentAccessor)
return ((ContentAccessor)o).getContent();
if (o instanceof SdtElement)
return ((SdtElement)o).getSdtContent().getContent();
if (o instanceof Anchor) {
Anchor anchor = (Anchor)o;
List<Object> artificialList = new ArrayList();
CTNonVisualDrawingProps drawingProps = anchor.getDocPr();
if (drawingProps != null)
handleCTNonVisualDrawingProps(drawingProps, artificialList);
if (anchor.getGraphic() != null) {
log.debug("found a:graphic");
Graphic graphic = anchor.getGraphic();
if (graphic.getGraphicData() != null)
artificialList.addAll(handleGraphicData(graphic.getGraphicData()));
}
if (!artificialList.isEmpty())
return artificialList;
} else if (o instanceof Inline) {
Inline inline = (Inline)o;
List<Object> artificialList = new ArrayList();
CTNonVisualDrawingProps drawingProps = inline.getDocPr();
if (drawingProps != null)
handleCTNonVisualDrawingProps(drawingProps, artificialList);
if (inline.getGraphic() != null) {
log.debug("found a:graphic");
Graphic graphic = inline.getGraphic();
if (graphic.getGraphicData() != null)
artificialList.addAll(handleGraphicData(graphic.getGraphicData()));
return artificialList;
}
if (!artificialList.isEmpty())
return artificialList;
} else {
if (o instanceof Pict)
return ((Pict)o).getAnyAndAny();
if (o instanceof Pic) {
Pic dmlPic = (Pic)o;
if (dmlPic.getBlipFill() != null && dmlPic.getBlipFill().getBlip() != null) {
log.debug("found DML Blip");
List<Object> artificialList = new ArrayList();
artificialList.add(dmlPic.getBlipFill().getBlip());
return artificialList;
}
return null;
}
if (o instanceof CTGvmlPicture) {
CTGvmlPicture dmlPic = (CTGvmlPicture)o;
if (dmlPic.getBlipFill() != null && dmlPic.getBlipFill().getBlip() != null) {
log.debug("found DML Blip");
List<Object> artificialList = new ArrayList();
artificialList.add(dmlPic.getBlipFill().getBlip());
return artificialList;
}
return null;
}
if (o instanceof CTShape) {
List<Object> artificialList = new ArrayList();
for (JAXBElement<?> j : ((CTShape)o).getPathOrFormulasOrHandles())
artificialList.add(j);
return artificialList;
}
if (o instanceof CTDataModel) {
CTDataModel dataModel = (CTDataModel)o;
List<Object> artificialList = new ArrayList();
artificialList.addAll(dataModel.getPtLst().getPt());
artificialList.addAll(dataModel.getCxnLst().getCxn());
return artificialList;
}
if (o instanceof CTDrawing)
return ((CTDrawing)o).getSpTree().getSpOrGrpSp();
if (o instanceof CTTextbox) {
CTTextbox textBox = (CTTextbox)o;
if (textBox.getTxbxContent() == null)
return null;
return textBox.getTxbxContent().getEGBlockLevelElts();
}
if (o instanceof CTObject) {
CTObject ctObject = (CTObject)o;
List<Object> artificialList = new ArrayList();
artificialList.addAll(ctObject.getAnyAndAny());
if (ctObject.getControl() != null)
artificialList.add(ctObject.getControl());
return artificialList;
}
if (o instanceof CTGvmlGroupShape)
return ((CTGvmlGroupShape)o).getTxSpOrSpOrCxnSp();
if (o instanceof FldChar) {
FldChar fldChar = (FldChar)o;
List<Object> artificialList = new ArrayList();
artificialList.add(fldChar.getFldCharType());
if (fldChar.getFfData() != null)
artificialList.add(fldChar.getFfData());
if (fldChar.getFldData() != null)
artificialList.add(fldChar.getFldData());
if (fldChar.getNumberingChange() != null)
artificialList.add(fldChar.getNumberingChange());
return artificialList;
}
}
log.debug(".. looking for method which returns list ");
try {
Method[] methods = o.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getReturnType().getName().equals("java.util.List"))
return (List<Object>)m.invoke(o);
}
} catch (Exception e) {
e.printStackTrace();
}
log.debug(".. no list member");
return null;
}
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/sample-docs/sample-docx.xml";
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputfilepath));
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
Document wmlDocumentEl = documentPart.getJaxbElement();
Body body = wmlDocumentEl.getBody();
new TraversalUtil(body, new Callback() {
String indent = "";
public List<Object> apply(Object o) {
String text = "";
if (o instanceof Text)
text = ((Text)o).getValue();
System.out.println(this.indent + o.getClass().getName() + " \"" + text + "\"");
return null;
}
public boolean shouldTraverse(Object o) {
return true;
}
public void walkJAXBElements(Object parent) {
this.indent += " ";
List<Object> children = getChildren(parent);
if (children != null)
for (Object o : children) {
o = XmlUtils.unwrap(o);
apply(o);
if (shouldTraverse(o))
walkJAXBElements(o);
}
this.indent = this.indent.substring(0, this.indent.length() - 4);
}
public List<Object> getChildren(Object o) {
return TraversalUtil.getChildrenImpl(o);
}
});
}
public static interface Callback {
void walkJAXBElements(Object param1Object);
List<Object> getChildren(Object param1Object);
List<Object> apply(Object param1Object);
boolean shouldTraverse(Object param1Object);
}
public static void replaceChildren(Object o, List<Object> newChildren) {
log.debug("Clearing " + o.getClass().getName());
if (o instanceof ContentAccessor) {
((ContentAccessor)o).getContent().clear();
((ContentAccessor)o).getContent().addAll(newChildren);
} else if (o instanceof SdtElement) {
((SdtElement)o).getSdtContent().getContent().clear();
((SdtElement)o).getSdtContent().getContent().addAll(newChildren);
} else if (o instanceof CTTxbxContent) {
((CTTxbxContent)o).getEGBlockLevelElts().clear();
((CTTxbxContent)o).getEGBlockLevelElts().addAll(newChildren);
} else {
log.warn("Don't know how to replaceChildren in " + o.getClass().getName());
if (o instanceof Node)
log.warn(" IGNORED " + ((Node)o).getNodeName());
}
}
public static void visit(WordprocessingMLPackage wmlPackage, boolean bodyOnly, TraversalUtilVisitor visitor) {
if (visitor != null)
visit(wmlPackage, bodyOnly, new SingleTraversalUtilVisitorCallback(visitor));
}
public static void visit(Object parent, TraversalUtilVisitor visitor) {
if (visitor != null)
visit(parent, new SingleTraversalUtilVisitorCallback(visitor));
}
public static void visit(WordprocessingMLPackage wmlPackage, boolean bodyOnly, List<TraversalUtilVisitor> visitorList) {
CompoundTraversalUtilVisitorCallback callback = null;
if (visitorList != null && !visitorList.isEmpty())
if (visitorList.size() > 1) {
visit(wmlPackage, bodyOnly, new CompoundTraversalUtilVisitorCallback(visitorList));
} else {
visit(wmlPackage, bodyOnly, visitorList.get(0));
}
}
public static void visit(Object parent, List<TraversalUtilVisitor> visitorList) {
CompoundTraversalUtilVisitorCallback callback = null;
if (visitorList != null && !visitorList.isEmpty())
if (visitorList.size() > 1) {
visit(parent, new CompoundTraversalUtilVisitorCallback(visitorList));
} else {
visit(parent, visitorList.get(0));
}
}
public static void visit(Object parent, Callback callback) {
if (parent != null && callback != null)
callback.walkJAXBElements(parent);
}
public static void visit(WordprocessingMLPackage wmlPackage, boolean bodyOnly, Callback callback) {
MainDocumentPart mainDocument = null;
RelationshipsPart relPart = null;
List<Relationship> relList = null;
List<Object> elementList = null;
if (wmlPackage != null && callback != null) {
mainDocument = wmlPackage.getMainDocumentPart();
callback.walkJAXBElements(mainDocument.getJaxbElement().getBody());
if (!bodyOnly) {
relPart = mainDocument.getRelationshipsPart();
relList = relPart.getRelationships().getRelationship();
for (Relationship rs : relList) {
elementList = null;
if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header".equals(rs.getType())) {
elementList = ((HeaderPart)relPart.getPart(rs)).getJaxbElement().getContent();
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer".equals(rs.getType())) {
elementList = ((FooterPart)relPart.getPart(rs)).getJaxbElement().getContent();
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes".equals(rs.getType())) {
elementList = new ArrayList();
elementList.addAll(((EndnotesPart)relPart.getPart(rs)).getJaxbElement().getEndnote());
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes".equals(rs.getType())) {
elementList = new ArrayList();
elementList.addAll(((FootnotesPart)relPart.getPart(rs)).getJaxbElement().getFootnote());
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments".equals(rs.getType())) {
elementList = new ArrayList();
for (Comments.Comment comment : ((CommentsPart)relPart.getPart(rs)).getJaxbElement().getComment())
elementList.addAll(comment.getEGBlockLevelElts());
}
if (elementList != null && !elementList.isEmpty()) {
log.debug("Processing target: " + rs.getTarget() + ", type: " + rs.getType());
callback.walkJAXBElements(elementList);
}
}
}
}
}
}

View file

@ -0,0 +1,98 @@
package org.docx4j;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UnitsOfMeasurement {
private static final Logger log = LoggerFactory.getLogger(UnitsOfMeasurement.class);
public static final DecimalFormat format2DP = new DecimalFormat("##.##", new DecimalFormatSymbols(Locale.ENGLISH));
public static final int DPI = Integer.parseInt(Docx4jProperties.getProperty("docx4j.DPI", "96"));
public static long twipToEMU(double twips) {
return Math.round(635.0D * twips);
}
public static int inchToTwip(float inch) {
return Math.round(inch * 1440.0F);
}
public static float twipToInch(int twip) {
return (float)twip / 1440.0F;
}
public static float twipToMm(int twip) {
return (float)twip / 56.6928F;
}
public static int mmToTwip(float mm) {
float inch = mm * 0.0394F;
return inchToTwip(inch);
}
public static float twipToPoint(int twip) {
return (float)twip / 20.0F;
}
public static int pointToTwip(float point) {
return Math.round(20.0F * point);
}
public static int pxToTwip(float px) {
float inch = px / (float)DPI;
return inchToTwip(inch);
}
public static String twipToBest(int leftL) {
float inch4f = 80.0F * twipToInch(leftL);
float inch4fabit = inch4f + 0.49F;
int inch4 = Math.round(inch4f);
int inch4next = Math.round(inch4fabit);
float inches = twipToInch(leftL);
if (inch4 == inch4next) {
log.debug(leftL + " twips -> " + inches + "inches");
return format2DP.format((double)inches) + "in";
}
float mm = inches / 0.0394F;
log.debug(leftL + " twips -> " + mm + "mm (" + format2DP.format((double)inches) + "inches)");
return Math.round(mm) + "mm";
}
public static String rgbTripleToHex(float red, float green, float blue) {
return getHex(red) + getHex(green) + getHex(blue);
}
private static String getHex(float f) {
int i = Math.round(f);
if (i <= 16)
return "0" + Integer.toHexString(i);
return Integer.toHexString(i);
}
public static String toHexColor(int color) {
String ret = Integer.toHexString(color).toUpperCase();
return (ret.length() < 6) ? ("000000".substring(0, 6 - ret.length()) + ret) : ret;
}
public static int combineColors(int fgColor, int bgColor, int pctFg) {
int resColor = 0;
if (pctFg < 1) {
resColor = bgColor;
} else if (pctFg == 100) {
resColor = fgColor;
} else {
int pctBg = 100 - pctFg;
resColor = ((fgColor >> 16 & 0xFF) * pctFg + (bgColor >> 16 & 0xFF) * pctBg) / 100 << 16 | ((fgColor >> 8 & 0xFF) * pctFg + (bgColor >> 8 & 0xFF) * pctBg) / 100 << 8 | ((fgColor & 0xFF) * pctFg + (bgColor & 0xFF) * pctBg) / 100;
}
return resColor;
}
private String calcHexColor(int value) {
String ret = Integer.toHexString(value).toUpperCase();
return (ret.length() < 6) ? ("000000".substring(0, 6 - ret.length()) + ret) : ret;
}
}

View file

@ -0,0 +1,624 @@
package org.docx4j;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.util.JAXBResult;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import org.docx4j.jaxb.Context;
import org.docx4j.jaxb.JAXBAssociation;
import org.docx4j.jaxb.JaxbValidationEventHandler;
import org.docx4j.jaxb.NamespacePrefixMapperUtils;
import org.docx4j.jaxb.NamespacePrefixMappings;
import org.docx4j.jaxb.XPathBinderAssociationIsPartialException;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.utils.XPathFactoryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class XmlUtils {
private static Logger log = LoggerFactory.getLogger(XmlUtils.class);
public static String TRANSFORMER_FACTORY_PROCESSOR_XALAN = "org.apache.xalan.processor.TransformerFactoryImpl";
private static TransformerFactory transformerFactory;
public static TransformerFactory getTransformerFactory() {
return transformerFactory;
}
@Deprecated
public static DocumentBuilderFactory getDocumentBuilderFactory() {
return documentBuilderFactory;
}
public static DocumentBuilder getNewDocumentBuilder() {
synchronized (documentBuilderFactory) {
return documentBuilderFactory.newDocumentBuilder();
}
}
static {
instantiateTransformerFactory();
log.debug(System.getProperty("java.vendor"));
log.debug(System.getProperty("java.version"));
String sp = Docx4jProperties.getProperty("javax.xml.parsers.SAXParserFactory");
if (sp != null) {
System.setProperty("javax.xml.parsers.SAXParserFactory", sp);
log.info("Using " + sp + " (from docx4j.properties)");
} else if (Docx4jProperties.getProperty("docx4j.javax.xml.parsers.SAXParserFactory.donotset", false)) {
log.info("Not setting docx4j.javax.xml.parsers.SAXParserFactory");
} else if ((System.getProperty("java.version").startsWith("1.6") && System.getProperty("java.vendor").startsWith("Sun")) || (System.getProperty("java.version").startsWith("1.7") && System.getProperty("java.vendor").startsWith("Oracle")) || (System.getProperty("java.version").startsWith("1.8") && System.getProperty("java.vendor").startsWith("Oracle")) || (System.getProperty("java.version").startsWith("1.7") && System.getProperty("java.vendor").startsWith("Jeroen"))) {
System.setProperty("javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
log.info("Using com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
} else {
log.warn("default SAXParserFactory property : " + System.getProperty("javax.xml.parsers.SAXParserFactory") + "\n Please consider using Xerces.");
}
String dbf = Docx4jProperties.getProperty("javax.xml.parsers.DocumentBuilderFactory");
if (dbf != null) {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", dbf);
log.info("Using " + dbf + " (from docx4j.properties)");
} else if (Docx4jProperties.getProperty("docx4j.javax.xml.parsers.DocumentBuilderFactory.donotset", false)) {
log.info("Not setting docx4j.javax.xml.parsers.DocumentBuilderFactory");
} else if ((System.getProperty("java.version").startsWith("1.6") && System.getProperty("java.vendor").startsWith("Sun")) || (System.getProperty("java.version").startsWith("1.7") && System.getProperty("java.vendor").startsWith("Oracle")) || (System.getProperty("java.version").startsWith("1.8") && System.getProperty("java.vendor").startsWith("Oracle")) || (System.getProperty("java.version").startsWith("1.7") && System.getProperty("java.vendor").startsWith("Jeroen"))) {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
log.info("Using com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
} else {
log.warn("default DocumentBuilderFactory property: " + System.getProperty("javax.xml.parsers.DocumentBuilderFactory") + "\n Please consider using Xerces.");
}
}
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
static {
documentBuilderFactory.setNamespaceAware(true);
try {
documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
} catch (ParserConfigurationException e) {
log.error(e.getMessage(), (Throwable)e);
}
documentBuilderFactory.setXIncludeAware(false);
documentBuilderFactory.setExpandEntityReferences(false);
try {
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
} catch (ParserConfigurationException e) {
log.error(e.getMessage(), (Throwable)e);
}
try {
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
} catch (ParserConfigurationException e) {
log.error(e.getMessage(), (Throwable)e);
}
}
private static void instantiateTransformerFactory() {
String originalSystemProperty = System.getProperty("javax.xml.transform.TransformerFactory");
try {
System.setProperty("javax.xml.transform.TransformerFactory", TRANSFORMER_FACTORY_PROCESSOR_XALAN);
transformerFactory = TransformerFactory.newInstance();
if (originalSystemProperty == null) {
System.clearProperty("javax.xml.transform.TransformerFactory");
} else {
System.setProperty("javax.xml.transform.TransformerFactory", originalSystemProperty);
}
} catch (TransformerFactoryConfigurationError e) {
log.error("Warning: Xalan jar missing from classpath; xslt not supported", (Throwable)e);
if (originalSystemProperty == null) {
System.clearProperty("javax.xml.transform.TransformerFactory");
} else {
System.setProperty("javax.xml.transform.TransformerFactory", originalSystemProperty);
}
transformerFactory = TransformerFactory.newInstance();
}
LoggingErrorListener errorListener = new LoggingErrorListener(false);
transformerFactory.setErrorListener(errorListener);
}
public static Object unwrap(Object o) {
if (o == null)
return null;
if (o instanceof JAXBElement) {
log.debug("Unwrapped " + ((JAXBElement)o).getDeclaredType().getName());
log.debug("name: " + ((JAXBElement)o).getName());
return ((JAXBElement)o).getValue();
}
return o;
}
public static String JAXBElementDebug(JAXBElement o) {
String prefix = null;
if (o.getName().getNamespaceURI() != null)
try {
prefix = NamespacePrefixMapperUtils.getPreferredPrefix(o.getName().getNamespaceURI(), null, false);
} catch (JAXBException e) {
e.printStackTrace();
}
if (prefix != null)
return prefix + ':' + o.getName().getLocalPart() + " is a javax.xml.bind.JAXBElement; it has declared type " + o.getDeclaredType().getName();
return o.getName() + " is a javax.xml.bind.JAXBElement; it has declared type " + o.getDeclaredType().getName();
}
public static JAXBElement<?> getListItemByQName(List<JAXBElement<?>> list, QName name) {
for (JAXBElement<?> el : list) {
if (el.getName().equals(name))
return el;
}
return null;
}
public static Object unmarshal(InputStream is) throws JAXBException {
return unmarshal(is, Context.jc);
}
public static Object unmarshal(InputStream is, JAXBContext jc) throws JAXBException {
Object o = null;
Unmarshaller u = jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
o = u.unmarshal(is);
return o;
}
public static Object unmarshalString(String str) throws JAXBException {
return unmarshalString(str, Context.jc);
}
public static Object unmarshalString(String str, JAXBContext jc, Class declaredType) throws JAXBException {
Unmarshaller u = jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Object o = u.unmarshal(new StreamSource(new StringReader(str)), declaredType);
if (o instanceof JAXBElement)
return ((JAXBElement)o).getValue();
return o;
}
public static Object unmarshalString(String str, JAXBContext jc) throws JAXBException {
log.debug("Unmarshalling '" + str + "'");
Unmarshaller u = jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
return u.unmarshal(new StreamSource(new StringReader(str)));
}
public static Object unmarshal(Node n) throws JAXBException {
Unmarshaller u = Context.jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
return u.unmarshal(n);
}
public static Object unmarshal(Node n, JAXBContext jc, Class declaredType) throws JAXBException {
Unmarshaller u = jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Object o = u.unmarshal(n, declaredType);
if (o instanceof JAXBElement)
return ((JAXBElement)o).getValue();
return o;
}
public static Object unmarshallFromTemplate(String wmlTemplateString, HashMap<String, String> mappings) throws JAXBException {
return unmarshallFromTemplate(wmlTemplateString, mappings, Context.jc);
}
public static Object unmarshallFromTemplate(String wmlTemplateString, HashMap<String, String> mappings, JAXBContext jc) throws JAXBException {
String wmlString = replace(wmlTemplateString, 0, new StringBuilder(), mappings).toString();
log.debug("Results of substitution: " + wmlString);
return unmarshalString(wmlString, jc);
}
public static Object unmarshallFromTemplate(String wmlTemplateString, HashMap<String, String> mappings, JAXBContext jc, Class<?> declaredType) throws JAXBException {
String wmlString = replace(wmlTemplateString, 0, new StringBuilder(), mappings).toString();
return unmarshalString(wmlString, jc, declaredType);
}
private static StringBuilder replace(String wmlTemplateString, int offset, StringBuilder strB, HashMap<String, String> mappings) {
int startKey = wmlTemplateString.indexOf("${", offset);
if (startKey == -1)
return strB.append(wmlTemplateString.substring(offset));
strB.append(wmlTemplateString.substring(offset, startKey));
int keyEnd = wmlTemplateString.indexOf('}', startKey);
String key = wmlTemplateString.substring(startKey + 2, keyEnd);
String val = mappings.get(key);
if (val == null) {
log.warn("Invalid key '" + key + "' or key not mapped to a value");
strB.append(key);
} else {
strB.append(val);
}
return replace(wmlTemplateString, keyEnd + 1, strB, mappings);
}
public static String marshaltoString(Object o) {
JAXBContext jc = Context.jc;
return marshaltoString(o, true, true, jc);
}
public static String marshaltoString(Object o, JAXBContext jc) {
return marshaltoString(o, true, true, jc);
}
@Deprecated
public static String marshaltoString(Object o, boolean suppressDeclaration) {
JAXBContext jc = Context.jc;
return marshaltoString(o, suppressDeclaration, false, jc);
}
@Deprecated
public static String marshaltoString(Object o, boolean suppressDeclaration, JAXBContext jc) {
return marshaltoString(o, suppressDeclaration, false, jc);
}
public static String marshaltoString(Object o, boolean suppressDeclaration, boolean prettyprint) {
JAXBContext jc = Context.jc;
return marshaltoString(o, suppressDeclaration, prettyprint, jc);
}
public static String marshaltoString(Object o, boolean suppressDeclaration, boolean prettyprint, JAXBContext jc) {
if (o == null)
return null;
try {
Marshaller m = jc.createMarshaller();
NamespacePrefixMapperUtils.setProperty(m, NamespacePrefixMapperUtils.getPrefixMapper());
if (prettyprint)
m.setProperty("jaxb.formatted.output", Boolean.valueOf(true));
if (suppressDeclaration)
m.setProperty("jaxb.fragment", Boolean.valueOf(true));
StringWriter sWriter = new StringWriter();
m.marshal(o, sWriter);
return sWriter.toString();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static String marshaltoString(Object o, boolean suppressDeclaration, boolean prettyprint, JAXBContext jc, String uri, String local, Class declaredType) {
try {
Marshaller m = jc.createMarshaller();
NamespacePrefixMapperUtils.setProperty(m, NamespacePrefixMapperUtils.getPrefixMapper());
if (prettyprint)
m.setProperty("jaxb.formatted.output", Boolean.valueOf(true));
if (suppressDeclaration)
m.setProperty("jaxb.fragment", Boolean.valueOf(true));
StringWriter sWriter = new StringWriter();
m.marshal(new JAXBElement(new QName(uri, local), declaredType, o), sWriter);
return sWriter.toString();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static InputStream marshaltoInputStream(Object o, boolean suppressDeclaration, JAXBContext jc) {
try {
Marshaller m = jc.createMarshaller();
NamespacePrefixMapperUtils.setProperty(m, NamespacePrefixMapperUtils.getPrefixMapper());
if (suppressDeclaration)
m.setProperty("jaxb.fragment", Boolean.valueOf(true));
ByteArrayOutputStream os = new ByteArrayOutputStream();
m.marshal(o, os);
return new ByteArrayInputStream(os.toByteArray());
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static Document marshaltoW3CDomDocument(Object o) {
return marshaltoW3CDomDocument(o, Context.jc);
}
public static Document marshaltoW3CDomDocument(Object o, JAXBContext jc) {
try {
Marshaller marshaller = jc.createMarshaller();
Document doc = getNewDocumentBuilder().newDocument();
NamespacePrefixMapperUtils.setProperty(marshaller, NamespacePrefixMapperUtils.getPrefixMapper());
marshaller.marshal(o, doc);
return doc;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static Document marshaltoW3CDomDocument(Object o, JAXBContext jc, String uri, String local, Class declaredType) {
try {
Marshaller marshaller = jc.createMarshaller();
Document doc = getNewDocumentBuilder().newDocument();
NamespacePrefixMapperUtils.setProperty(marshaller, NamespacePrefixMapperUtils.getPrefixMapper());
marshaller.marshal(new JAXBElement(new QName(uri, local), declaredType, o), doc);
return doc;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static <T> T deepCopy(T value) {
return XmlUtils.<T>deepCopy(value, Context.jc);
}
public static <T> T deepCopy(T value, JAXBContext jc) {
if (value == null)
throw new IllegalArgumentException("Can't clone a null argument");
try {
Class<?> valueClass;
T res;
if (value instanceof JAXBElement) {
log.debug("deep copy of JAXBElement..");
elem = (JAXBElement)value;
valueClass = elem.getDeclaredType();
} else {
log.debug("deep copy of " + value.getClass().getName());
Class<T> classT = (Class<T>)value.getClass();
elem = new JAXBElement(new QName("temp"), classT, value);
valueClass = classT;
}
Marshaller mar = jc.createMarshaller();
ByteArrayOutputStream bout = new ByteArrayOutputStream(256);
mar.marshal(elem, bout);
Unmarshaller unmar = jc.createUnmarshaller();
if (log.isDebugEnabled())
unmar.setEventHandler(new JaxbValidationEventHandler());
JAXBElement<?> elem = unmar.unmarshal(new StreamSource(new ByteArrayInputStream(bout.toByteArray())), valueClass);
if (value instanceof JAXBElement) {
JAXBElement<?> jAXBElement2 = elem;
JAXBElement<?> jAXBElement1 = jAXBElement2;
} else {
T resT = (T)elem.getValue();
res = resT;
}
return res;
} catch (JAXBException ex) {
throw new IllegalArgumentException(ex);
}
}
public static String w3CDomNodeToString(Node n) {
StringWriter sw = new StringWriter();
try {
Transformer serializer = transformerFactory.newTransformer();
serializer.setOutputProperty("omit-xml-declaration", "yes");
serializer.setOutputProperty("method", "xml");
serializer.transform(new DOMSource(n), new StreamResult(sw));
return sw.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Document neww3cDomDocument() {
return getNewDocumentBuilder().newDocument();
}
public static void appendXmlFragment(Document document, Node parent, String fragment) throws IOException, SAXException, ParserConfigurationException {
Node fragmentNode = getNewDocumentBuilder().parse(new InputSource(new StringReader(fragment))).getDocumentElement();
fragmentNode = document.importNode(fragmentNode, true);
parent.appendChild(fragmentNode);
}
public static JAXBResult prepareJAXBResult(JAXBContext context) throws Docx4JException {
JAXBResult result;
try {
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setEventHandler(new JaxbValidationEventHandler());
result = new JAXBResult(unmarshaller);
} catch (JAXBException e) {
throw new Docx4JException("Error preparing empty JAXB result", e);
}
return result;
}
public static void transform(Document doc, Templates template, Map<String, Object> transformParameters, Result result) throws Docx4JException {
if (doc == null) {
Throwable t = new Throwable();
throw new Docx4JException("Null DOM Doc", t);
}
DOMSource domSource = new DOMSource(doc);
transform(domSource, template, transformParameters, result);
}
public static Templates getTransformerTemplate(Source xsltSource) throws TransformerConfigurationException {
return transformerFactory.newTemplates(xsltSource);
}
public static void transform(Source source, Templates template, Map<String, Object> transformParameters, Result result) throws Docx4JException {
Transformer xformer;
if (source == null) {
Throwable t = new Throwable();
throw new Docx4JException("Null Source doc", t);
}
try {
xformer = template.newTransformer();
} catch (TransformerConfigurationException e) {
throw new Docx4JException("The Transformer is ill-configured", e);
}
if (!xformer.getClass().getName().equals("org.apache.xalan.transformer.TransformerImpl"))
log.error("Detected " + xformer.getClass().getName() + ", but require org.apache.xalan.transformer.TransformerImpl. " + "Ensure Xalan 2.7.0 is on your classpath!");
LoggingErrorListener errorListener = new LoggingErrorListener(false);
xformer.setErrorListener(errorListener);
if (transformParameters != null) {
Iterator<Map.Entry> parameterIterator = transformParameters.entrySet().iterator();
while (parameterIterator.hasNext()) {
Map.Entry pairs = parameterIterator.next();
if (pairs.getKey() == null) {
log.info("Skipped null key");
continue;
}
if (pairs.getKey().equals("customXsltTemplates"))
continue;
if (pairs.getValue() == null) {
log.warn("parameter '" + pairs.getKey() + "' was null.");
continue;
}
xformer.setParameter((String)pairs.getKey(), pairs.getValue());
}
}
try {
xformer.transform(source, result);
} catch (TransformerException e) {
throw new Docx4JException("Cannot perform the transformation", e);
} finally {}
}
public static List<Object> getJAXBNodesViaXPath(Binder<Node> binder, Object jaxbElement, String xpathExpr, boolean refreshXmlFirst) throws JAXBException, XPathBinderAssociationIsPartialException {
List<JAXBAssociation> associations = getJAXBAssociationsForXPath(binder, jaxbElement, xpathExpr, refreshXmlFirst);
List<Object> resultList = new ArrayList();
for (JAXBAssociation association : associations) {
if (association.getJaxbObject() == null)
throw new XPathBinderAssociationIsPartialException("no object association for xpath result: " + association.getDomNode().getNodeName());
resultList.add(association.getJaxbObject());
}
return resultList;
}
public static List<JAXBAssociation> getJAXBAssociationsForXPath(Binder<Node> binder, Object jaxbElement, String xpathExpr, boolean refreshXmlFirst) throws JAXBException, XPathBinderAssociationIsPartialException {
if (refreshXmlFirst)
Node node1 = (Node)binder.updateXML(jaxbElement);
Node node = (Node)binder.getXMLNode(jaxbElement);
List<JAXBAssociation> resultList = new ArrayList<JAXBAssociation>();
for (Node n : xpath(node, xpathExpr))
resultList.add(new JAXBAssociation(n, binder.getJAXBNode(n)));
return resultList;
}
public static List<Node> xpath(Node node, String xpathExpression) {
NamespaceContext nsContext = new NamespacePrefixMappings();
return xpath(node, xpathExpression, nsContext);
}
public static List<Node> xpath(Node node, String xpathExpression, NamespaceContext nsContext) {
log.debug(w3CDomNodeToString(node));
XPath xpath = XPathFactoryUtil.newXPath();
try {
List<Node> result = new ArrayList<Node>();
xpath.setNamespaceContext(nsContext);
NodeList nl = (NodeList)xpath.evaluate(xpathExpression, node, XPathConstants.NODESET);
log.info("evaluate returned " + nl.getLength());
for (int i = 0; i < nl.getLength(); i++)
result.add(nl.item(i));
return result;
} catch (XPathExpressionException e) {
log.error("Problem with '" + xpathExpression + "'", (Throwable)e);
throw new RuntimeException(e);
}
}
static class LoggingErrorListener implements ErrorListener {
boolean strict;
public LoggingErrorListener(boolean strict) {}
public void warning(TransformerException exception) {
XmlUtils.log.warn(exception.getMessage(), (Throwable)exception);
}
public void error(TransformerException exception) throws TransformerException {
XmlUtils.log.error(exception.getMessage(), (Throwable)exception);
if (this.strict)
throw exception;
}
public void fatalError(TransformerException exception) throws TransformerException {
XmlUtils.log.error(exception.getMessage(), (Throwable)exception);
throw exception;
}
}
public static void treeCopy(NodeList sourceNodes, Node destParent) {
for (int i = 0; i < sourceNodes.getLength(); i++)
treeCopy(sourceNodes.item(i), destParent);
}
public static void treeCopy(Node sourceNode, Node destParent) {
NodeList nodes;
Node newChild;
NamedNodeMap atts;
int i;
NodeList children;
log.debug("node type" + sourceNode.getNodeType());
switch (sourceNode.getNodeType()) {
case 9:
case 11:
nodes = sourceNode.getChildNodes();
if (nodes != null)
for (int j = 0; j < nodes.getLength(); j++) {
log.debug("child " + j + "of DOCUMENT_NODE");
treeCopy(nodes.item(j), destParent);
}
break;
case 1:
log.debug("copying: " + sourceNode.getNodeName());
if (destParent instanceof Document) {
newChild = ((Document)destParent).createElementNS(sourceNode.getNamespaceURI(), sourceNode.getLocalName());
} else if (sourceNode.getNamespaceURI() != null) {
newChild = destParent.getOwnerDocument().createElementNS(sourceNode.getNamespaceURI(), sourceNode.getLocalName());
} else {
newChild = destParent.getOwnerDocument().createElement(sourceNode.getNodeName());
}
destParent.appendChild(newChild);
atts = sourceNode.getAttributes();
for (i = 0; i < atts.getLength(); i++) {
Attr attr = (Attr)atts.item(i);
if (!attr.getNodeName().startsWith("xmlns:"))
if (attr.getNamespaceURI() == null) {
((Element)newChild).setAttribute(attr.getName(), attr.getValue());
} else if (!attr.getNamespaceURI().equals("http://www.w3.org/2000/xmlns/")) {
if (attr.getNodeName() != null) {
((Element)newChild).setAttributeNS(attr.getNamespaceURI(), attr.getNodeName(), attr.getValue());
} else {
((Element)newChild).setAttributeNS(attr.getNamespaceURI(), attr.getLocalName(), attr.getValue());
}
}
}
children = sourceNode.getChildNodes();
if (children != null)
for (int j = 0; j < children.getLength(); j++)
treeCopy(children.item(j), newChild);
break;
case 3:
if (destParent.getOwnerDocument() == null && destParent.getNodeName().equals("#document")) {
Node textNode = ((Document)destParent).createTextNode(sourceNode.getNodeValue());
destParent.appendChild(textNode);
} else {
Node textNode = destParent.getOwnerDocument().createTextNode(sourceNode.getNodeValue());
Node appended = destParent.appendChild(textNode);
}
break;
}
}
}

View file

@ -0,0 +1,23 @@
package org.docx4j.bibliography;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CT_AuthorType", propOrder = {"artistOrAuthorOrBookAuthor"})
public class CTAuthorType {
@XmlElementRefs({@XmlElementRef(name = "Counsel", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Director", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Composer", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Performer", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Conductor", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "BookAuthor", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Interviewer", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Editor", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "ProducerName", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Translator", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Author", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Artist", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Interviewee", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Compiler", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Writer", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class), @XmlElementRef(name = "Inventor", namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", type = JAXBElement.class)})
protected List<JAXBElement<?>> artistOrAuthorOrBookAuthor;
public List<JAXBElement<?>> getArtistOrAuthorOrBookAuthor() {
if (this.artistOrAuthorOrBookAuthor == null)
this.artistOrAuthorOrBookAuthor = new ArrayList<JAXBElement<?>>();
return this.artistOrAuthorOrBookAuthor;
}
}

View file

@ -0,0 +1,21 @@
package org.docx4j.bibliography;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CT_NameListType", propOrder = {"person"})
public class CTNameListType {
@XmlElement(name = "Person", required = true)
protected List<CTPersonType> person;
public List<CTPersonType> getPerson() {
if (this.person == null)
this.person = new ArrayList<CTPersonType>();
return this.person;
}
}

View file

@ -0,0 +1,32 @@
package org.docx4j.bibliography;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CT_NameOrCorporateType", propOrder = {"nameList", "corporate"})
public class CTNameOrCorporateType {
@XmlElement(name = "NameList")
protected CTNameListType nameList;
@XmlElement(name = "Corporate")
protected String corporate;
public CTNameListType getNameList() {
return this.nameList;
}
public void setNameList(CTNameListType value) {
this.nameList = value;
}
public String getCorporate() {
return this.corporate;
}
public void setCorporate(String value) {
this.corporate = value;
}
}

View file

@ -0,0 +1,21 @@
package org.docx4j.bibliography;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CT_NameType", propOrder = {"nameList"})
public class CTNameType {
@XmlElement(name = "NameList", required = true)
protected CTNameListType nameList;
public CTNameListType getNameList() {
return this.nameList;
}
public void setNameList(CTNameListType value) {
this.nameList = value;
}
}

View file

@ -0,0 +1,39 @@
package org.docx4j.bibliography;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CT_PersonType", propOrder = {"last", "first", "middle"})
public class CTPersonType {
@XmlElement(name = "Last")
protected List<String> last;
@XmlElement(name = "First")
protected List<String> first;
@XmlElement(name = "Middle")
protected List<String> middle;
public List<String> getLast() {
if (this.last == null)
this.last = new ArrayList<String>();
return this.last;
}
public List<String> getFirst() {
if (this.first == null)
this.first = new ArrayList<String>();
return this.first;
}
public List<String> getMiddle() {
if (this.middle == null)
this.middle = new ArrayList<String>();
return this.middle;
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,55 @@
package org.docx4j.bibliography;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CT_Sources", propOrder = {"source"})
public class CTSources {
@XmlElement(name = "Source")
protected List<CTSourceType> source;
@XmlAttribute(name = "SelectedStyle")
protected String selectedStyle;
@XmlAttribute(name = "StyleName")
protected String styleName;
@XmlAttribute(name = "URI")
protected String uri;
public List<CTSourceType> getSource() {
if (this.source == null)
this.source = new ArrayList<CTSourceType>();
return this.source;
}
public String getSelectedStyle() {
return this.selectedStyle;
}
public void setSelectedStyle(String value) {
this.selectedStyle = value;
}
public String getStyleName() {
return this.styleName;
}
public void setStyleName(String value) {
this.styleName = value;
}
public String getURI() {
return this.uri;
}
public void setURI(String value) {
this.uri = value;
}
}

View file

@ -0,0 +1,518 @@
package org.docx4j.bibliography;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {
private static final QName _Sources_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Sources");
private static final QName _CTAuthorTypeEditor_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Editor");
private static final QName _CTAuthorTypeInventor_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Inventor");
private static final QName _CTAuthorTypeInterviewee_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Interviewee");
private static final QName _CTAuthorTypeBookAuthor_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "BookAuthor");
private static final QName _CTAuthorTypeProducerName_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "ProducerName");
private static final QName _CTAuthorTypeInterviewer_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Interviewer");
private static final QName _CTAuthorTypeAuthor_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Author");
private static final QName _CTAuthorTypePerformer_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Performer");
private static final QName _CTAuthorTypeCompiler_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Compiler");
private static final QName _CTAuthorTypeCounsel_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Counsel");
private static final QName _CTAuthorTypeWriter_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Writer");
private static final QName _CTAuthorTypeConductor_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Conductor");
private static final QName _CTAuthorTypeComposer_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Composer");
private static final QName _CTAuthorTypeArtist_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Artist");
private static final QName _CTAuthorTypeDirector_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Director");
private static final QName _CTAuthorTypeTranslator_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Translator");
private static final QName _CTSourceTypeComments_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Comments");
private static final QName _CTSourceTypeInternetSiteTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "InternetSiteTitle");
private static final QName _CTSourceTypePages_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Pages");
private static final QName _CTSourceTypeProductionCompany_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "ProductionCompany");
private static final QName _CTSourceTypeDistributor_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Distributor");
private static final QName _CTSourceTypePublisher_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Publisher");
private static final QName _CTSourceTypePatentNumber_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "PatentNumber");
private static final QName _CTSourceTypeTheater_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Theater");
private static final QName _CTSourceTypeThesisType_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "ThesisType");
private static final QName _CTSourceTypeAlbumTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "AlbumTitle");
private static final QName _CTSourceTypeMonth_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Month");
private static final QName _CTSourceTypeYearAccessed_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "YearAccessed");
private static final QName _CTSourceTypeConferenceName_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "ConferenceName");
private static final QName _CTSourceTypeRecordingNumber_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "RecordingNumber");
private static final QName _CTSourceTypeBookTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "BookTitle");
private static final QName _CTSourceTypeGuid_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Guid");
private static final QName _CTSourceTypeIssue_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Issue");
private static final QName _CTSourceTypeTag_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Tag");
private static final QName _CTSourceTypeCaseNumber_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "CaseNumber");
private static final QName _CTSourceTypeVersion_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Version");
private static final QName _CTSourceTypeReporter_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Reporter");
private static final QName _CTSourceTypeMedium_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Medium");
private static final QName _CTSourceTypeBroadcaster_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Broadcaster");
private static final QName _CTSourceTypeLCID_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "LCID");
private static final QName _CTSourceTypeBroadcastTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "BroadcastTitle");
private static final QName _CTSourceTypeSourceType_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "SourceType");
private static final QName _CTSourceTypeVolume_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Volume");
private static final QName _CTSourceTypeMonthAccessed_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "MonthAccessed");
private static final QName _CTSourceTypeJournalName_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "JournalName");
private static final QName _CTSourceTypeInstitution_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Institution");
private static final QName _CTSourceTypeTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Title");
private static final QName _CTSourceTypeCity_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "City");
private static final QName _CTSourceTypeEdition_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Edition");
private static final QName _CTSourceTypeStandardNumber_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "StandardNumber");
private static final QName _CTSourceTypeRefOrder_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "RefOrder");
private static final QName _CTSourceTypeShortTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "ShortTitle");
private static final QName _CTSourceTypeAbbreviatedCaseNumber_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "AbbreviatedCaseNumber");
private static final QName _CTSourceTypeType_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Type");
private static final QName _CTSourceTypeCountryRegion_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "CountryRegion");
private static final QName _CTSourceTypeChapterNumber_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "ChapterNumber");
private static final QName _CTSourceTypePublicationTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "PublicationTitle");
private static final QName _CTSourceTypePeriodicalTitle_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "PeriodicalTitle");
private static final QName _CTSourceTypeDay_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Day");
private static final QName _CTSourceTypeDayAccessed_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "DayAccessed");
private static final QName _CTSourceTypeYear_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Year");
private static final QName _CTSourceTypeStation_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Station");
private static final QName _CTSourceTypeNumberVolumes_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "NumberVolumes");
private static final QName _CTSourceTypeStateProvince_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "StateProvince");
private static final QName _CTSourceTypeURL_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "URL");
private static final QName _CTSourceTypeCourt_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Court");
private static final QName _CTSourceTypeDepartment_QNAME = new QName("http://schemas.openxmlformats.org/officeDocument/2006/bibliography", "Department");
public CTAuthorType createCTAuthorType() {
return new CTAuthorType();
}
public CTNameListType createCTNameListType() {
return new CTNameListType();
}
public CTSources createCTSources() {
return new CTSources();
}
public CTPersonType createCTPersonType() {
return new CTPersonType();
}
public CTNameOrCorporateType createCTNameOrCorporateType() {
return new CTNameOrCorporateType();
}
public CTNameType createCTNameType() {
return new CTNameType();
}
public CTSourceType createCTSourceType() {
return new CTSourceType();
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Sources")
public JAXBElement<CTSources> createSources(CTSources value) {
return new JAXBElement(_Sources_QNAME, CTSources.class, null, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Editor", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeEditor(CTNameType value) {
return new JAXBElement(_CTAuthorTypeEditor_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Inventor", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeInventor(CTNameType value) {
return new JAXBElement(_CTAuthorTypeInventor_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Interviewee", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeInterviewee(CTNameType value) {
return new JAXBElement(_CTAuthorTypeInterviewee_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "BookAuthor", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeBookAuthor(CTNameType value) {
return new JAXBElement(_CTAuthorTypeBookAuthor_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "ProducerName", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeProducerName(CTNameType value) {
return new JAXBElement(_CTAuthorTypeProducerName_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Interviewer", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeInterviewer(CTNameType value) {
return new JAXBElement(_CTAuthorTypeInterviewer_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Author", scope = CTAuthorType.class)
public JAXBElement<CTNameOrCorporateType> createCTAuthorTypeAuthor(CTNameOrCorporateType value) {
return new JAXBElement(_CTAuthorTypeAuthor_QNAME, CTNameOrCorporateType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Performer", scope = CTAuthorType.class)
public JAXBElement<CTNameOrCorporateType> createCTAuthorTypePerformer(CTNameOrCorporateType value) {
return new JAXBElement(_CTAuthorTypePerformer_QNAME, CTNameOrCorporateType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Compiler", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeCompiler(CTNameType value) {
return new JAXBElement(_CTAuthorTypeCompiler_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Counsel", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeCounsel(CTNameType value) {
return new JAXBElement(_CTAuthorTypeCounsel_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Writer", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeWriter(CTNameType value) {
return new JAXBElement(_CTAuthorTypeWriter_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Conductor", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeConductor(CTNameType value) {
return new JAXBElement(_CTAuthorTypeConductor_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Composer", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeComposer(CTNameType value) {
return new JAXBElement(_CTAuthorTypeComposer_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Artist", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeArtist(CTNameType value) {
return new JAXBElement(_CTAuthorTypeArtist_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Director", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeDirector(CTNameType value) {
return new JAXBElement(_CTAuthorTypeDirector_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Translator", scope = CTAuthorType.class)
public JAXBElement<CTNameType> createCTAuthorTypeTranslator(CTNameType value) {
return new JAXBElement(_CTAuthorTypeTranslator_QNAME, CTNameType.class, CTAuthorType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Comments", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeComments(String value) {
return new JAXBElement(_CTSourceTypeComments_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "InternetSiteTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeInternetSiteTitle(String value) {
return new JAXBElement(_CTSourceTypeInternetSiteTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Pages", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypePages(String value) {
return new JAXBElement(_CTSourceTypePages_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "ProductionCompany", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeProductionCompany(String value) {
return new JAXBElement(_CTSourceTypeProductionCompany_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Distributor", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeDistributor(String value) {
return new JAXBElement(_CTSourceTypeDistributor_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Publisher", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypePublisher(String value) {
return new JAXBElement(_CTSourceTypePublisher_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "PatentNumber", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypePatentNumber(String value) {
return new JAXBElement(_CTSourceTypePatentNumber_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Theater", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeTheater(String value) {
return new JAXBElement(_CTSourceTypeTheater_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "ThesisType", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeThesisType(String value) {
return new JAXBElement(_CTSourceTypeThesisType_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "AlbumTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeAlbumTitle(String value) {
return new JAXBElement(_CTSourceTypeAlbumTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Month", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeMonth(String value) {
return new JAXBElement(_CTSourceTypeMonth_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "YearAccessed", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeYearAccessed(String value) {
return new JAXBElement(_CTSourceTypeYearAccessed_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "ConferenceName", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeConferenceName(String value) {
return new JAXBElement(_CTSourceTypeConferenceName_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "RecordingNumber", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeRecordingNumber(String value) {
return new JAXBElement(_CTSourceTypeRecordingNumber_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "BookTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeBookTitle(String value) {
return new JAXBElement(_CTSourceTypeBookTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Guid", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeGuid(String value) {
return new JAXBElement(_CTSourceTypeGuid_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Issue", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeIssue(String value) {
return new JAXBElement(_CTSourceTypeIssue_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Tag", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeTag(String value) {
return new JAXBElement(_CTSourceTypeTag_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "CaseNumber", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeCaseNumber(String value) {
return new JAXBElement(_CTSourceTypeCaseNumber_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Version", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeVersion(String value) {
return new JAXBElement(_CTSourceTypeVersion_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Reporter", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeReporter(String value) {
return new JAXBElement(_CTSourceTypeReporter_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Medium", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeMedium(String value) {
return new JAXBElement(_CTSourceTypeMedium_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Broadcaster", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeBroadcaster(String value) {
return new JAXBElement(_CTSourceTypeBroadcaster_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "LCID", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeLCID(String value) {
return new JAXBElement(_CTSourceTypeLCID_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "BroadcastTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeBroadcastTitle(String value) {
return new JAXBElement(_CTSourceTypeBroadcastTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "SourceType", scope = CTSourceType.class)
public JAXBElement<STSourceType> createCTSourceTypeSourceType(STSourceType value) {
return new JAXBElement(_CTSourceTypeSourceType_QNAME, STSourceType.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Volume", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeVolume(String value) {
return new JAXBElement(_CTSourceTypeVolume_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "MonthAccessed", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeMonthAccessed(String value) {
return new JAXBElement(_CTSourceTypeMonthAccessed_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "JournalName", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeJournalName(String value) {
return new JAXBElement(_CTSourceTypeJournalName_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Institution", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeInstitution(String value) {
return new JAXBElement(_CTSourceTypeInstitution_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Title", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeTitle(String value) {
return new JAXBElement(_CTSourceTypeTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "City", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeCity(String value) {
return new JAXBElement(_CTSourceTypeCity_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Edition", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeEdition(String value) {
return new JAXBElement(_CTSourceTypeEdition_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "StandardNumber", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeStandardNumber(String value) {
return new JAXBElement(_CTSourceTypeStandardNumber_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "RefOrder", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeRefOrder(String value) {
return new JAXBElement(_CTSourceTypeRefOrder_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "ShortTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeShortTitle(String value) {
return new JAXBElement(_CTSourceTypeShortTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "AbbreviatedCaseNumber", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeAbbreviatedCaseNumber(String value) {
return new JAXBElement(_CTSourceTypeAbbreviatedCaseNumber_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Type", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeType(String value) {
return new JAXBElement(_CTSourceTypeType_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "CountryRegion", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeCountryRegion(String value) {
return new JAXBElement(_CTSourceTypeCountryRegion_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "ChapterNumber", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeChapterNumber(String value) {
return new JAXBElement(_CTSourceTypeChapterNumber_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Author", scope = CTSourceType.class)
public JAXBElement<CTAuthorType> createCTSourceTypeAuthor(CTAuthorType value) {
return new JAXBElement(_CTAuthorTypeAuthor_QNAME, CTAuthorType.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "PublicationTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypePublicationTitle(String value) {
return new JAXBElement(_CTSourceTypePublicationTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "PeriodicalTitle", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypePeriodicalTitle(String value) {
return new JAXBElement(_CTSourceTypePeriodicalTitle_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Day", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeDay(String value) {
return new JAXBElement(_CTSourceTypeDay_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "DayAccessed", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeDayAccessed(String value) {
return new JAXBElement(_CTSourceTypeDayAccessed_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Year", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeYear(String value) {
return new JAXBElement(_CTSourceTypeYear_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Station", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeStation(String value) {
return new JAXBElement(_CTSourceTypeStation_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "NumberVolumes", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeNumberVolumes(String value) {
return new JAXBElement(_CTSourceTypeNumberVolumes_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "StateProvince", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeStateProvince(String value) {
return new JAXBElement(_CTSourceTypeStateProvince_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "URL", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeURL(String value) {
return new JAXBElement(_CTSourceTypeURL_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Court", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeCourt(String value) {
return new JAXBElement(_CTSourceTypeCourt_QNAME, String.class, CTSourceType.class, value);
}
@XmlElementDecl(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", name = "Department", scope = CTSourceType.class)
public JAXBElement<String> createCTSourceTypeDepartment(String value) {
return new JAXBElement(_CTSourceTypeDepartment_QNAME, String.class, CTSourceType.class, value);
}
}

View file

@ -0,0 +1,45 @@
package org.docx4j.bibliography;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;
@XmlType(name = "ST_SourceType")
@XmlEnum
public enum STSourceType {
ARTICLE_IN_A_PERIODICAL("ArticleInAPeriodical"),
BOOK("Book"),
BOOK_SECTION("BookSection"),
JOURNAL_ARTICLE("JournalArticle"),
CONFERENCE_PROCEEDINGS("ConferenceProceedings"),
REPORT("Report"),
SOUND_RECORDING("SoundRecording"),
PERFORMANCE("Performance"),
ART("Art"),
DOCUMENT_FROM_INTERNET_SITE("DocumentFromInternetSite"),
INTERNET_SITE("InternetSite"),
FILM("Film"),
INTERVIEW("Interview"),
PATENT("Patent"),
ELECTRONIC_SOURCE("ElectronicSource"),
CASE("Case"),
MISC("Misc");
private final String value;
STSourceType(String v) {
this.value = v;
}
public String value() {
return this.value;
}
public static STSourceType fromValue(String v) {
for (STSourceType c : values()) {
if (c.value.equals(v))
return c;
}
throw new IllegalArgumentException(v);
}
}

View file

@ -0,0 +1,7 @@
package org.docx4j.bibliography;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
@XmlSchema(namespace = "http://schemas.openxmlformats.org/officeDocument/2006/bibliography", elementFormDefault = XmlNsForm.QUALIFIED)
interface package-info {}

View file

@ -0,0 +1,201 @@
package org.docx4j.convert.in;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.DocumentProperties;
import org.apache.poi.hwpf.model.ListTables;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.Section;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.docx4j.UnitsOfMeasurement;
import org.docx4j.XmlUtils;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.Drawing;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.TblGrid;
import org.docx4j.wml.TblPr;
import org.docx4j.wml.Tc;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Doc {
private static Logger log = LoggerFactory.getLogger(Doc.class);
public static WordprocessingMLPackage convert(InputStream in) throws Exception {
HWPFDocument doc = new HWPFDocument(in);
WordprocessingMLPackage out = WordprocessingMLPackage.createPackage();
convert(doc, out);
return out;
}
private static void convert(HWPFDocument doc, WordprocessingMLPackage wordMLPackage) throws Exception {
StyleSheet stylesheet = doc.getStyleSheet();
ListTables listTables = doc.getListTables();
DocumentProperties docProps = doc.getDocProperties();
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
ObjectFactory factory = new ObjectFactory();
Range r = doc.getRange();
for (int x = 0; x < r.numSections(); x++) {
Section s = r.getSection(x);
for (int y = 0; y < s.numParagraphs(); y++) {
Paragraph p = s.getParagraph(y);
if (p.isInTable()) {
Table t = s.getTable(p);
int cl = numCol(t);
log.info("Found " + t.numRows() + "x" + cl + " table - TODO - convert");
handleTable(wordMLPackage, doc, t, stylesheet, documentPart, factory);
y += t.numParagraphs() - 1;
} else {
P paraToAdd = handleP(wordMLPackage, doc, p, stylesheet, documentPart, factory);
documentPart.addObject(paraToAdd);
}
}
}
}
private static int ID1 = 1;
private static int ID2 = 2;
private static P handleP(WordprocessingMLPackage wordMLPackage, HWPFDocument doc, Paragraph p, StyleSheet stylesheet, MainDocumentPart documentPart, ObjectFactory factory) {
P wmlP = null;
if (p.getStyleIndex() > 0) {
log.debug("Styled paragraph, with index: " + p.getStyleIndex());
String styleName = stylesheet.getStyleDescription(p.getStyleIndex()).getName();
log.debug(styleName);
wmlP = documentPart.createStyledParagraphOfText(stripSpace(styleName), null);
} else {
wmlP = documentPart.createParagraphOfText(null);
}
for (int z = 0; z < p.numCharacterRuns(); z++) {
CharacterRun run = p.getCharacterRun(z);
RPr rPr = null;
if (run.isBold()) {
if (rPr == null)
rPr = factory.createRPr();
BooleanDefaultTrue boldOn = factory.createBooleanDefaultTrue();
boldOn.setVal(Boolean.TRUE);
rPr.setB(boldOn);
}
if (doc instanceof HWPFDocument && doc.getPicturesTable().hasPicture(run)) {
Picture picture = doc.getPicturesTable().extractPicture(run, true);
try {
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, picture.getContent());
long cx = UnitsOfMeasurement.twipToEMU((double)Math.round((double)imagePart.getImageInfo().getSize().getWidthMpt() * (double)picture.getHorizontalScalingFactor() * 1.0E-5D)) * 2L;
long cy = UnitsOfMeasurement.twipToEMU((double)Math.round((double)imagePart.getImageInfo().getSize().getHeightMpt() * (double)picture.getVerticalScalingFactor() * 1.0E-5D)) * 2L;
Inline inline = imagePart.createImageInline(null, "", ID1++, ID2++, cx, cy, false);
R imgrun = factory.createR();
Drawing drawing = factory.createDrawing();
imgrun.getContent().add(drawing);
drawing.getAnchorOrInline().add(inline);
wmlP.getContent().add(imgrun);
} catch (Exception e1) {
e1.printStackTrace();
}
} else {
String text = run.text();
log.debug("Processing: " + text);
String cleansed = stripNonValidXMLCharacters(text);
if (!text.equals(cleansed))
log.warn("Cleansed..");
Text t = factory.createText();
t.setValue(cleansed);
R wmlRun = factory.createR();
if (rPr != null)
wmlRun.setRPr(rPr);
wmlRun.getRunContent().add(t);
wmlP.getParagraphContent().add(wmlRun);
}
}
System.out.println(XmlUtils.marshaltoString(wmlP, true, true));
return wmlP;
}
private static String stripSpace(String in) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < in.length(); i++) {
if (in.charAt(i) != ' ')
sb.append(in.charAt(i));
}
return sb.toString();
}
private static void addTODO(ObjectFactory factory, P wmlP, String message) {
Text t = factory.createText();
t.setValue(message);
R wmlRun = factory.createR();
wmlRun.getRunContent().add(t);
wmlP.getParagraphContent().add(wmlRun);
}
public static String stripNonValidXMLCharacters(String in) {
StringBuffer out = new StringBuffer();
if (in == null || "".equals(in))
return "";
for (int i = 0; i < in.length(); i++) {
char current = in.charAt(i);
if (current == '\t' || current == '\n' || current == '\r' || (current >= ' ' && current <= '퟿') || (current >= '' && current <= '<27>') || (current >= 65536 && current <= 1114111)) {
out.append(current);
} else {
out.append("[#?]");
}
}
return out.toString();
}
private static int numCol(Table t) {
int col = 0;
for (int i = 0; i < t.numRows(); i++) {
if (t.getRow(i).numCells() > col)
col = t.getRow(i).numCells();
}
return col;
}
private static void handleTable(WordprocessingMLPackage wordMLPackage, HWPFDocument doc, Table t, StyleSheet stylesheet, MainDocumentPart documentPart, ObjectFactory factory) {
Tbl tbl = factory.createTbl();
documentPart.addObject(tbl);
TblPr tblPr = factory.createTblPr();
tbl.setTblPr(tblPr);
TblGrid tblGrid = factory.createTblGrid();
tbl.setTblGrid(tblGrid);
for (int i = 0; i < t.numRows(); i++) {
TableRow tr = t.getRow(i);
Tr trOut = factory.createTr();
tbl.getEGContentRowContent().add(trOut);
for (int j = 0; j < tr.numCells(); j++) {
TableCell tc = tr.getCell(j);
Tc tcOut = factory.createTc();
trOut.getEGContentCellContent().add(tcOut);
for (int y = 0; y < tc.numParagraphs(); y++) {
Paragraph p = tc.getParagraph(y);
P paraToAdd = handleP(wordMLPackage, doc, p, stylesheet, documentPart, factory);
tcOut.getEGBlockLevelElts().add(paraToAdd);
log.debug("Added p to tc");
}
}
}
}
public static void main(String[] args) throws Exception {
String localPath = System.getProperty("user.dir") + "/LineSpacing.doc";
WordprocessingMLPackage out = convert(new FileInputStream(localPath));
}
}

View file

@ -0,0 +1,328 @@
package org.docx4j.convert.in;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.docx4j.XmlUtils;
import org.docx4j.bibliography.CTSources;
import org.docx4j.convert.out.flatOpcXml.FlatOpcXmlCreator;
import org.docx4j.docProps.coverPageProps.CoverPageProperties;
import org.docx4j.jaxb.Context;
import org.docx4j.jaxb.JaxbValidationEventHandler;
import org.docx4j.model.datastorage.CustomXmlDataStorage;
import org.docx4j.openpackaging.Base;
import org.docx4j.openpackaging.URIHelper;
import org.docx4j.openpackaging.contenttype.ContentType;
import org.docx4j.openpackaging.contenttype.ContentTypeManager;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.exceptions.PartUnrecognisedException;
import org.docx4j.openpackaging.io.Load;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.PresentationMLPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart;
import org.docx4j.openpackaging.parts.DocPropsCoverPagePart;
import org.docx4j.openpackaging.parts.JaxbXmlPart;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.BibliographyPart;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart;
import org.docx4j.openpackaging.parts.XmlPart;
import org.docx4j.openpackaging.parts.opendope.ComponentsPart;
import org.docx4j.openpackaging.parts.opendope.ConditionsPart;
import org.docx4j.openpackaging.parts.opendope.QuestionsPart;
import org.docx4j.openpackaging.parts.opendope.StandardisedAnswersPart;
import org.docx4j.openpackaging.parts.opendope.XPathsPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.xmlPackage.Package;
import org.docx4j.xmlPackage.Part;
import org.opendope.answers.Answers;
import org.opendope.components.Components;
import org.opendope.conditions.Conditions;
import org.opendope.questions.Questionnaire;
import org.opendope.xpaths.Xpaths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class FlatOpcXmlImporter {
private static Logger log = LoggerFactory.getLogger(FlatOpcXmlImporter.class);
private HashMap<String, Part> parts;
private ContentTypeManager ctm;
public FlatOpcXmlImporter(InputStream is) throws JAXBException {
JAXBContext jc = Context.jcXmlPackage;
Unmarshaller u = jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Package flatOpcXml = null;
try {
flatOpcXml = (Package)XmlUtils.unwrap(u.unmarshal(new StreamSource(is)));
} catch (UnmarshalException e) {
if (e.getMessage().contains("http://schemas.microsoft.com/office/word/2003/wordml"))
throw new IllegalArgumentException("Word 2003 XML is not supported. Use a docx or Flat OPC XML instead, or look at the Word2003XmlConverter proof of concept.");
throw e;
}
init(flatOpcXml);
}
public FlatOpcXmlImporter(Package flatOpcXml) {
init(flatOpcXml);
}
private void init(Package flatOpcXml) {
this.parts = new HashMap<String, Part>();
for (Part p : flatOpcXml.getPart())
this.parts.put(p.getName(), p);
}
protected HashMap<String, String> handled = new HashMap<String, String>();
private OpcPackage packageResult;
public OpcPackage get() throws Docx4JException {
this.ctm = new ContentTypeManager();
this.ctm.addDefaultContentType("rels", "application/vnd.openxmlformats-package.relationships+xml");
this.ctm.addDefaultContentType("xml", "application/xml");
if (this.parts.get("/word/document.xml") != null) {
this.packageResult = new WordprocessingMLPackage(this.ctm);
} else if (this.parts.get("/ppt/presentation.xml") != null) {
this.packageResult = new PresentationMLPackage(this.ctm);
} else {
throw new Docx4JException("Unrecognised package");
}
log.info("Creating " + this.packageResult.getClass().getName());
String partName = "/_rels/.rels";
RelationshipsPart rp = getRelationshipsPartFromXmlPackage(this.packageResult, partName);
this.packageResult.setRelationships(rp);
log.info("Object created for: " + partName);
addPartsFromRelationships(this.packageResult, rp);
Load.registerCustomXmlDataStorageParts(this.packageResult);
return this.packageResult;
}
private RelationshipsPart getRelationshipsPartFromXmlPackage(Base p, String partName) throws Docx4JException {
RelationshipsPart rp = null;
try {
Part part = this.parts.get(partName);
if (part == null)
return null;
rp = p.getRelationshipsPart(true);
populateRelationshipsPart(rp, part.getXmlData().getAny());
} catch (Exception e) {
e.printStackTrace();
throw new Docx4JException("Error getting document from XmlPackage:" + partName, e);
}
return rp;
}
public static RelationshipsPart populateRelationshipsPart(RelationshipsPart rp, Element el) throws InvalidFormatException, JAXBException {
rp.setRelationships(rp.unmarshal(el));
return rp;
}
private void addPartsFromRelationships(Base source, RelationshipsPart rp) throws Docx4JException {
OpcPackage pkg = source.getPackage();
for (Relationship r : rp.getRelationships().getRelationship()) {
log.debug("For Relationship Id=" + r.getId() + " Source is " + rp.getSourceP().getPartName() + ", Target is " + r.getTarget());
try {
getPart(pkg, rp, r);
} catch (Exception e) {
throw new Docx4JException("Failed to add parts from relationships", e);
}
}
}
private void getPart(OpcPackage pkg, RelationshipsPart rp, Relationship r) throws Docx4JException, InvalidFormatException, URISyntaxException {
Base source = null;
String resolvedPartUri = null;
if (r.getTargetMode() == null || !r.getTargetMode().equals("External")) {
source = rp.getSourceP();
resolvedPartUri = URIHelper.resolvePartUri(rp.getSourceURI(), new URI(r.getTarget())).toString();
} else {
log.info("Encountered external resource " + r.getTarget() + " of type " + r.getType());
return;
}
if (this.handled.get(resolvedPartUri) != null)
return;
String relationshipType = r.getType();
org.docx4j.openpackaging.parts.Part part = getRawPart(this.ctm, resolvedPartUri, r);
rp.loadPart(part, r);
this.handled.put(resolvedPartUri, resolvedPartUri);
if (source.setPartShortcut(part, relationshipType))
log.debug("Convenience method established from " + source.getPartName() + " to " + part.getPartName());
RelationshipsPart rrp = getRelationshipsPart(part);
if (rrp != null)
addPartsFromRelationships(part, rrp);
}
public RelationshipsPart getRelationshipsPart(org.docx4j.openpackaging.parts.Part part) throws Docx4JException, InvalidFormatException {
String relPart = PartName.getRelationshipsPartName(part.getPartName().getName());
RelationshipsPart rrp = getRelationshipsPartFromXmlPackage(part, relPart);
if (rrp != null) {
part.setRelationships(rrp);
} else {
log.debug("No relationships " + relPart);
return null;
}
return rrp;
}
public org.docx4j.openpackaging.parts.Part getRawPart(ContentTypeManager ctm, String resolvedPartUri, Relationship rel) throws Docx4JException {
Part pkgPart = this.parts.get(resolvedPartUri);
if (pkgPart == null) {
log.error("Missing part: " + resolvedPartUri);
return null;
}
return getRawPart(ctm, pkgPart, rel);
}
public static org.docx4j.openpackaging.parts.Part getRawPart(ContentTypeManager ctm, Part pkgPart, Relationship rel) throws Docx4JException {
org.docx4j.openpackaging.parts.Part part = null;
try {
Element el = null;
try {
String contentType = pkgPart.getContentType();
log.debug("contentType: " + contentType);
if (pkgPart.getXmlData() != null)
el = pkgPart.getXmlData().getAny();
part = ctm.newPartForContentType(contentType, pkgPart.getName(), rel);
part.setContentType(new ContentType(contentType));
ctm.addOverrideContentType(new URI(pkgPart.getName()), contentType);
if (part instanceof org.docx4j.openpackaging.parts.ThemePart) {
((JaxbXmlPart)part).setJAXBContext(Context.jcThemePart);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof org.docx4j.openpackaging.parts.DocPropsCorePart) {
((JaxbXmlPart)part).setJAXBContext(Context.jcDocPropsCore);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof org.docx4j.openpackaging.parts.DocPropsCustomPart) {
((JaxbXmlPart)part).setJAXBContext(Context.jcDocPropsCustom);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof org.docx4j.openpackaging.parts.DocPropsExtendedPart) {
((JaxbXmlPart)part).setJAXBContext(Context.jcDocPropsExtended);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart) {
((JaxbXmlPart)part).setJAXBContext(Context.jcCustomXmlProperties);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof org.docx4j.openpackaging.parts.digitalsignature.XmlSignaturePart) {
((JaxbXmlPart)part).setJAXBContext(Context.jcXmlDSig);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof org.docx4j.openpackaging.parts.PresentationML.JaxbPmlPart) {
((JaxbXmlPart)part).setJAXBContext(org.pptx4j.jaxb.Context.jcPML);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof JaxbXmlPart) {
((JaxbXmlPart)part).setJAXBContext(Context.jc);
((JaxbXmlPart)part).unmarshal(el);
} else if (part instanceof BinaryPart) {
log.debug("Detected BinaryPart " + part.getClass().getName());
((BinaryPart)part).setBinaryData(pkgPart.getBinaryData());
} else if (part instanceof CustomXmlDataStoragePart) {
try {
Unmarshaller u = Context.jc.createUnmarshaller();
Object o = u.unmarshal(el);
log.debug(o.getClass().getName());
PartName name = part.getPartName();
if (o instanceof CoverPageProperties) {
part = new DocPropsCoverPagePart(name);
((DocPropsCoverPagePart)part).setJaxbElement((CoverPageProperties)o);
} else if (o instanceof Conditions) {
part = new ConditionsPart(name);
((ConditionsPart)part).setJaxbElement((Conditions)o);
} else if (o instanceof Xpaths) {
part = new XPathsPart(name);
((XPathsPart)part).setJaxbElement((Xpaths)o);
} else if (o instanceof Questionnaire) {
part = new QuestionsPart(name);
((QuestionsPart)part).setJaxbElement((Questionnaire)o);
} else if (o instanceof Answers) {
part = new StandardisedAnswersPart(name);
((StandardisedAnswersPart)part).setJaxbElement((Answers)o);
} else if (o instanceof Components) {
part = new ComponentsPart(name);
((ComponentsPart)part).setJaxbElement((Components)o);
} else if (o instanceof JAXBElement && XmlUtils.unwrap(o) instanceof CTSources) {
part = new BibliographyPart(name);
((BibliographyPart)part).setJaxbElement((JAXBElement<CTSources>)o);
} else {
log.warn("No known part after all for CustomXmlPart " + o.getClass().getName());
CustomXmlDataStorage data = Load.getCustomXmlDataStorageClass().factory();
Document doc = XmlUtils.getNewDocumentBuilder().newDocument();
Node copy = doc.importNode(el, true);
try {
copy.getAttributes().removeNamedItemNS("http://www.w3.org/2000/xmlns/", "xml");
} catch (DOMException e) {}
doc.appendChild(copy);
data.setDocument(doc);
((CustomXmlDataStoragePart)part).setData(data);
}
} catch (UnmarshalException ue) {
CustomXmlDataStorage data = Load.getCustomXmlDataStorageClass().factory();
Document doc = XmlUtils.getNewDocumentBuilder().newDocument();
Node copy = doc.importNode(el, true);
try {
copy.getAttributes().removeNamedItemNS("http://www.w3.org/2000/xmlns/", "xml");
} catch (DOMException e) {}
doc.appendChild(copy);
data.setDocument(doc);
((CustomXmlDataStoragePart)part).setData(data);
}
} else if (part instanceof XmlPart) {
Document doc = XmlUtils.getNewDocumentBuilder().newDocument();
Node copy = doc.importNode(el, true);
try {
copy.getAttributes().removeNamedItemNS("http://www.w3.org/2000/xmlns/", "xml");
} catch (DOMException e) {}
doc.appendChild(copy);
((XmlPart)part).setDocument(doc);
} else {
log.error("No suitable part found for: " + pkgPart.getName());
part = null;
}
} catch (IllegalArgumentException e) {
if (el != null) {
log.error(e.getMessage());
log.error(XmlUtils.w3CDomNodeToString(el));
}
throw e;
} catch (PartUnrecognisedException e) {
log.error("Part unrecognised: " + pkgPart.getName());
part = new BinaryPart(new PartName(pkgPart.getName()));
((BinaryPart)part).setBinaryData(pkgPart.getBinaryData());
}
} catch (Exception ex) {
ex.printStackTrace();
throw new Docx4JException("Failed to getPart", ex);
}
return part;
}
public static void main(String[] args) throws Exception {
String inputfilepath = "/home/dev/workspace/docx4j/sample-docs/pkg.pkg";
FileInputStream fin = new FileInputStream(inputfilepath);
JAXBContext jc = Context.jcXmlPackage;
Unmarshaller u = jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Object o = u.unmarshal(new StreamSource(fin));
Package xmlPackage = (Package)((JAXBElement)o).getValue();
FlatOpcXmlImporter inWorker = new FlatOpcXmlImporter(xmlPackage);
WordprocessingMLPackage wordMLPackage = (WordprocessingMLPackage)inWorker.get();
FlatOpcXmlCreator outWorker = new FlatOpcXmlCreator(wordMLPackage);
Package result = outWorker.get();
boolean suppressDeclaration = true;
boolean prettyprint = true;
log.debug(XmlUtils.marshaltoString(result, suppressDeclaration, prettyprint, Context.jcXmlPackage));
}
}

View file

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:transit="http://www.docx4java.org/word2003xml/to/wordprocessingml/2006"
xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
xmlns:w03="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2"
xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<!-- This stylesheet is the first phase of a proof of concept of converting Word 2003 XML,
to ECMA 376.
It produces output matching:
<xsd:element name="transition03to06">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="w:fonts" />
<xsd:element ref="w:numbering" />
<xsd:element ref="w:styles" />
<xsd:element ref="w:body" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
where wordDocument is in namespace http://www.docx4java.org/word2003xml/to/wordprocessingml/2006
and its children are real http://schemas.openxmlformats.org/wordprocessingml/2006/main content.
-->
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="w03:wordDocument">
<!-- Put this in the transit namespace and drop its attributes eg: w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve" -->
<xsl:element namespace="http://www.docx4java.org/word2003xml/to/wordprocessingml/2006" name="transition03to06">
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>
<!-- move descendents to modern namespace-->
<xsl:template match="w03:*">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ ignoreSubtree ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:ignoreSubtree" />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ o:DocumentProperties +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- TODO convert these-->
<xsl:template match="o:DocumentProperties" />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ fonts ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:fonts">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="fonts">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="w03:panose-1">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="panose">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@w03:usb-0" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="usb0">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@w03:usb-1" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="usb1">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@w03:usb-2" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="usb2">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@w03:usb-3" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="usb3">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@w03:csb-0" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="csb0">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@w03:csb-1" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="csb1">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ lists ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:lists">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="numbering">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="w03:defaultFonts" /> <!-- drop for now -->
<!-- listDef becomes abstractNum-->
<xsl:template match="w03:listDef">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="abstractNum">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@w03:listDefId" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="abstractNumId">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="w03:lsid">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="nsid">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="w03:plt">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="multiLevelType">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@w03:tplc" />
<xsl:template match="@w03:tentative" />
<xsl:template match="@w03:hint" />
<!-- list becomes num-->
<xsl:template match="w03:list">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="num">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@w03:ilfo" >
<xsl:attribute namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="numId">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="w03:ilst">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="abstractNumId">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ styles +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:styles">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="w03:versionOfBuiltInStylenames" />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ shapeDefaults ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:shapeDefaults" />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ docPr ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:docPr" />
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- +++ body +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<xsl:template match="w03:body">
<xsl:element namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main" name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<!-- drop wx-->
<xsl:template match="wx:*">
<xsl:apply-templates select="node()"/>
</xsl:template>
<!-- drop aml for now. TODO convert to WordML -->
<xsl:template match="aml:*">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="w03:delText" />
<!-- drop image data for now. TODO come back and get this later.. -->
<xsl:template match="w03:pict" />
<xsl:template match="w03:binData" />
</xsl:stylesheet>

View file

@ -0,0 +1,10 @@
package org.docx4j.convert.in.word2003xml;
import javax.xml.bind.annotation.XmlRegistry;
@XmlRegistry
public class ObjectFactory {
public Transition03To06 createTransition03To06() {
return new Transition03To06();
}
}

View file

@ -0,0 +1,60 @@
package org.docx4j.convert.in.word2003xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.docx4j.wml.Body;
import org.docx4j.wml.Fonts;
import org.docx4j.wml.Numbering;
import org.docx4j.wml.Styles;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"fonts", "numbering", "styles", "body"})
@XmlRootElement(name = "transition03to06")
public class Transition03To06 {
@XmlElement(namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", required = true)
protected Fonts fonts;
@XmlElement(namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", required = true)
protected Numbering numbering;
@XmlElement(namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", required = true)
protected Styles styles;
@XmlElement(namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main", required = true)
protected Body body;
public Fonts getFonts() {
return this.fonts;
}
public void setFonts(Fonts value) {
this.fonts = value;
}
public Numbering getNumbering() {
return this.numbering;
}
public void setNumbering(Numbering value) {
this.numbering = value;
}
public Styles getStyles() {
return this.styles;
}
public void setStyles(Styles value) {
this.styles = value;
}
public Body getBody() {
return this.body;
}
public void setBody(Body value) {
this.body = value;
}
}

View file

@ -0,0 +1,98 @@
package org.docx4j.convert.in.word2003xml;
import java.io.File;
import java.io.IOException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.util.JAXBResult;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.FileUtils;
import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.FontTablePart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.utils.ResourceUtils;
import org.docx4j.wml.Numbering;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Word2003XmlConverter {
private static Logger log = LoggerFactory.getLogger(Word2003XmlConverter.class);
static Templates xslt;
private Transition03To06 transitionContainer;
static {
try {
Source xsltSource = new StreamSource(ResourceUtils.getResource("org/docx4j/convert/in/word2003xml/2003-import.xslt"));
xslt = XmlUtils.getTransformerTemplate(xsltSource);
} catch (IOException e) {
e.printStackTrace();
log.error("Couldn't setup 2003-import.xslt", (Throwable)e);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
log.error("Couldn't setup 2003-import.xslt", (Throwable)e);
}
}
public Word2003XmlConverter(Source source) throws JAXBException, Docx4JException {
JAXBResult result = new JAXBResult(JAXBContext.newInstance("org.docx4j.convert.in.word2003xml"));
XmlUtils.transform(source, xslt, null, (Result)result);
this.transitionContainer = (Transition03To06)result.getResult();
}
private WordprocessingMLPackage getWordprocessingMLPackage() {
return getWordprocessingMLPackage(false);
}
private WordprocessingMLPackage getWordprocessingMLPackage(boolean mainDocOnly) {
WordprocessingMLPackage wordMLPackage = null;
try {
wordMLPackage = WordprocessingMLPackage.createPackage();
} catch (InvalidFormatException e) {}
MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
mdp.getJaxbElement().setBody(this.transitionContainer.getBody());
if (!mainDocOnly) {
mdp.getStyleDefinitionsPart(true).setJaxbElement(this.transitionContainer.getStyles());
try {
NumberingDefinitionsPart ndp = new NumberingDefinitionsPart();
ndp.setJaxbElement(this.transitionContainer.getNumbering());
mdp.addTargetPart(ndp);
for (Numbering.AbstractNum anum : ndp.getJaxbElement().getAbstractNum()) {
if (anum.getMultiLevelType() == null)
continue;
String multiLevelType = anum.getMultiLevelType().getVal();
multiLevelType = multiLevelType.substring(0, 1).toLowerCase() + multiLevelType.substring(1);
anum.getMultiLevelType().setVal(multiLevelType);
}
} catch (InvalidFormatException e) {}
try {
FontTablePart fontsPart = new FontTablePart();
fontsPart.setJaxbElement(this.transitionContainer.getFonts());
mdp.addTargetPart(fontsPart);
} catch (InvalidFormatException e) {}
}
return wordMLPackage;
}
public static void main(String[] args) throws IOException, JAXBException, Docx4JException {
boolean save = true;
File file = new File(System.getProperty("user.dir") + "/sample-docs/word/2003/word2003xml.xml");
Source source = new StreamSource(FileUtils.openInputStream(file));
Word2003XmlConverter conv = new Word2003XmlConverter(source);
WordprocessingMLPackage wordMLPackage = conv.getWordprocessingMLPackage();
if (save) {
String filename = System.getProperty("user.dir") + "/OUT_FromWord2003XML.docx";
wordMLPackage.save(new File(filename));
System.out.println("Saved " + filename);
}
}
}

View file

@ -0,0 +1,7 @@
package org.docx4j.convert.in.word2003xml;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
@XmlSchema(namespace = "http://www.docx4java.org/word2003xml/to/wordprocessingml/2006", elementFormDefault = XmlNsForm.QUALIFIED)
interface package-info {}

View file

@ -0,0 +1,5 @@
package org.docx4j.convert.in.xhtml;
public enum FormattingOption {
CLASS_TO_STYLE_ONLY, CLASS_PLUS_OTHER, IGNORE_CLASS;
}

View file

@ -0,0 +1,45 @@
package org.docx4j.convert.in.xhtml;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.transform.Source;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
public interface XHTMLImporter {
void setHyperlinkStyle(String paramString);
void setRunFormatting(FormattingOption paramFormattingOption);
void setParagraphFormatting(FormattingOption paramFormattingOption);
void setTableFormatting(FormattingOption paramFormattingOption);
List<Object> convert(File paramFile, String paramString) throws Docx4JException;
List<Object> convert(InputSource paramInputSource, String paramString) throws Docx4JException;
List<Object> convert(InputStream paramInputStream, String paramString) throws Docx4JException;
List<Object> convert(Node paramNode, String paramString) throws Docx4JException;
List<Object> convert(Reader paramReader, String paramString) throws Docx4JException;
List<Object> convert(Source paramSource, String paramString) throws Docx4JException;
List<Object> convert(URL paramURL) throws Docx4JException;
List<Object> convert(String paramString1, String paramString2) throws Docx4JException;
Map<String, Integer> getSequenceCounters();
void setSequenceCounters(Map<String, Integer> paramMap);
AtomicInteger getBookmarkIdLast();
}

View file

@ -0,0 +1,88 @@
package org.docx4j.convert.out;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.docx4j.model.images.ConversionImageHandler;
import org.docx4j.openpackaging.packages.OpcPackage;
public abstract class AbstractConversionSettings {
public static final String IMAGE_INCLUDE_UUID = "imageIncludeUUID";
public static final String IMAGE_DIR_PATH = "imageDirPath";
public static final String IMAGE_HANDLER = "imageHandler";
public static final String HYPERLINK_HANDLER = "hyperlinkHandler";
public static final String WML_PACKAGE = "wmlPackage";
public static final String CUSTOM_XSLT_TEMPLATES = "customXsltTemplates";
protected Map<String, Object> settings = new TreeMap<String, Object>();
protected Set<String> features = new TreeSet<String>();
public Map<String, Object> getSettings() {
return this.settings;
}
public Set<String> getFeatures() {
return this.features;
}
public void addFeatures(String[] featuresArray) {
if (featuresArray != null && featuresArray.length > 0)
for (int i = 0; i < featuresArray.length; i++)
getFeatures().add(featuresArray[i]);
}
public void setImageDirPath(String imageDirPath) {
this.settings.put("imageDirPath", imageDirPath);
}
public String getImageDirPath() {
return (String)this.settings.get("imageDirPath");
}
public void setImageIncludeUUID(boolean imageIncludeUUID) {
this.settings.put("imageIncludeUUID", Boolean.valueOf(imageIncludeUUID));
}
public boolean isImageIncludeUUID() {
return this.settings.containsKey("imageIncludeUUID") ? (Boolean)this.settings.get("imageIncludeUUID") : true;
}
public void setImageHandler(ConversionImageHandler imageHandler) {
this.settings.put("imageHandler", imageHandler);
}
public ConversionImageHandler getImageHandler() {
return (ConversionImageHandler)this.settings.get("imageHandler");
}
public void setHyperlinkHandler(ConversionHyperlinkHandler hyperlinkHandler) {
this.settings.put("hyperlinkHandler", hyperlinkHandler);
}
public ConversionHyperlinkHandler getHyperlinkHandler() {
return (ConversionHyperlinkHandler)this.settings.get("hyperlinkHandler");
}
public void setWmlPackage(OpcPackage wmlPackage) {
this.settings.put("wmlPackage", wmlPackage);
}
public OpcPackage getWmlPackage() {
return (OpcPackage)this.settings.get("wmlPackage");
}
public void setCustomXsltTemplates(Object templates) {
this.settings.put("customXsltTemplates", templates);
}
public Object getCustomXsltTemplates() {
return this.settings.get("customXsltTemplates");
}
}

View file

@ -0,0 +1,49 @@
package org.docx4j.convert.out;
import java.util.Set;
import org.docx4j.openpackaging.packages.OpcPackage;
public abstract class ConversionFeatures {
public static final String PP_COMMON_DEEP_COPY = "pp.common.deepcopy";
public static final String PP_COMMON_MOVE_BOOKMARKS = "pp.common.movebookmarks";
public static final String PP_COMMON_MOVE_PAGEBREAK = "pp.common.movepagebreak";
public static final String PP_COMMON_CONTAINERIZATION = "pp.common.containerization";
public static final String PP_COMMON_COMBINE_FIELDS = "pp.common.combinefields";
public static final String PP_COMMON_PAGE_NUMBERING = "pp.common.pagenumbering";
public static final String PP_COMMON_DUMMY_PAGE_NUMBERING = "pp.common.dummypagenumbering";
public static final String PP_COMMON_CREATE_SECTIONS = "pp.common.createsections";
public static final String PP_COMMON_DUMMY_CREATE_SECTIONS = "pp.common.dummycreatesections";
public static final String PP_PDF_APACHEFOP_DISABLE_PAGEBREAK_FIRST_PARAGRAPH = "pp.apachefop.disablepagebreakfirstparagraph";
public static final String PP_PDF_APACHEFOP_DISABLE_PAGEBREAK_LIST_ITEM = "pp.apachefop.disablepagebreaklistitem";
public static final String PP_PDF_COVERPAGE_MOVE_SECTPR = "pp.common.coverpagemovesectpr";
public static final String PP_COMMON_TABLE_PARAGRAPH_STYLE_FIX = "pp.common.tbl-p-style-fix";
public static final String[] DEFAULT_PDF_FEATURES = new String[] { "pp.common.deepcopy", "pp.common.movebookmarks", "pp.common.movepagebreak", "pp.common.coverpagemovesectpr", "pp.common.containerization", "pp.common.combinefields", "pp.common.pagenumbering", "pp.common.createsections", "pp.apachefop.disablepagebreakfirstparagraph", "pp.common.tbl-p-style-fix" };
public static final String[] DEFAULT_HTML_FEATURES = new String[] { "pp.common.deepcopy", "pp.common.movebookmarks", "pp.common.movepagebreak", "pp.common.containerization", "pp.common.combinefields", "pp.common.dummypagenumbering", "pp.common.dummycreatesections", "pp.common.tbl-p-style-fix" };
protected static void checkParams(OpcPackage opcPackage, Set<String> features) {
if (opcPackage == null)
throw new IllegalArgumentException("The passed opcPackage is null.");
if (features == null)
throw new IllegalArgumentException("The set of the features is null.");
if (features.contains("pp.common.pagenumbering"))
features.add("pp.common.combinefields");
if (!features.contains("pp.common.pagenumbering"))
features.add("pp.common.dummypagenumbering");
if (!features.contains("pp.common.createsections"))
features.add("pp.common.dummycreatesections");
}
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public interface ConversionHTMLScriptElementHandler {
Element createScriptElement(OpcPackage paramOpcPackage, Document paramDocument, String paramString);
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public interface ConversionHTMLStyleElementHandler {
Element createStyleElement(OpcPackage paramOpcPackage, Document paramDocument, String paramString);
}

View file

@ -0,0 +1,42 @@
package org.docx4j.convert.out;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.parts.Part;
import org.w3c.dom.Node;
public interface ConversionHyperlinkHandler {
void handleHyperlink(Model paramModel, OpcPackage paramOpcPackage, Part paramPart) throws Docx4JException;
public static interface Model {
String getTarget();
void setTarget(String param1String);
boolean isExternal();
void setExternal(boolean param1Boolean);
String getAnchor();
void setAnchor(String param1String);
String getDocLocation();
void setDocLocation(String param1String);
String getRId();
void setRId(String param1String);
String getTgtFrame();
void setTgtFrame(String param1String);
String getTooltip();
void setTooltip(String param1String);
Node getContent();
}
}

View file

@ -0,0 +1,23 @@
package org.docx4j.convert.out;
import java.io.OutputStream;
import java.util.List;
import org.docx4j.openpackaging.exceptions.Docx4JException;
public interface FORenderer {
public static final String PLACEHOLDER_PREFIX = "${";
public static final String PLACEHOLDER_SUFFIX = "}";
void render(String paramString, FOSettings paramFOSettings, boolean paramBoolean, List<SectionPageInformation> paramList, OutputStream paramOutputStream) throws Docx4JException;
public static interface SectionPageInformation {
String getDocumentPageCountID();
String getDocumentPageCountFoFormat();
String getSectionPageCountID();
String getSectionPageCountFoFormat();
}
}

View file

@ -0,0 +1,63 @@
package org.docx4j.convert.out;
import java.io.File;
public class FOSettings extends AbstractConversionSettings {
public static final String INTERNAL_FO_MIME = "application/xml-fo";
public static final String MIME_PDF = "application/pdf";
public static final String APACHEFOP_CONFIGURATION = "apacheFopConfiguration";
public static final String APACHEFOP_MIME = "apacheFopMime";
public static final String CUSTOM_FO_RENDERER = "customFoRenderer";
public static final String FO_DUMP_FILE = "foDumpFile";
public FOSettings() {
addFeatures(ConversionFeatures.DEFAULT_PDF_FEATURES);
}
public String getApacheFopConfiguration() {
return (String)this.settings.get("apacheFopConfiguration");
}
public void setApacheFopConfiguration(String apacheFopConfiguration) {
this.settings.put("apacheFopConfiguration", apacheFopConfiguration);
}
public String getApacheFopMime() {
return (String)this.settings.get("apacheFopMime");
}
public void setApacheFopMime(String apacheFopMime) {
this.settings.put("apacheFopMime", apacheFopMime);
}
public FORenderer getCustomFoRenderer() {
return (FORenderer)this.settings.get("customFoRenderer");
}
public void setCustomFoRenderer(FORenderer customFoRenderer) {
this.settings.put("customFoRenderer", customFoRenderer);
}
public File getFoDumpFile() {
return (File)this.settings.get("foDumpFile");
}
public void setFoDumpFile(File foFile) {
this.settings.put("foDumpFile", foFile);
}
private boolean layoutMasterSetCalculationInProgress = false;
public boolean lsLayoutMasterSetCalculationInProgress() {
return this.layoutMasterSetCalculationInProgress;
}
public void setLayoutMasterSetCalculationInProgress(boolean layoutMasterSetCalculationInProgress) {
this.layoutMasterSetCalculationInProgress = layoutMasterSetCalculationInProgress;
}
}

View file

@ -0,0 +1,109 @@
package org.docx4j.convert.out;
import org.docx4j.fonts.Mapper;
public class HTMLSettings extends AbstractConversionSettings {
public static final String IMAGE_TARGET_URI = "imageTargetUri";
public static final String CONDITIONAL_COMMENTS = "conditionalComments";
public static final String FONT_FAMILY_STACK = "fontFamilyStack";
public static final String STYLE_ELEMENT_HANDLER = "styleElementHandler";
public static final String SCRIPT_ELEMENT_HANDLER = "scriptElementHandler";
public static final String USER_CSS = "userCSS";
public static final String USER_SCRIPT = "userScript";
public static final String USER_BODY_TOP = "userBodyTop";
public static final String USER_BODY_TAIL = "userBodyTail";
public HTMLSettings() {
this.settings.put("conditionalComments", Boolean.FALSE);
this.settings.put("fontFamilyStack", Boolean.FALSE);
this.settings.put("userCSS", "");
this.settings.put("userScript", "");
this.settings.put("userBodyTop", "<!-- userBodyTop goes here -->");
this.settings.put("userBodyTail", "<!-- userBodyTail goes here -->");
addFeatures(ConversionFeatures.DEFAULT_HTML_FEATURES);
}
public void setConditionalComments(Boolean conditionalComments) {
this.settings.put("conditionalComments", conditionalComments);
}
public void setFontFamilyStack(boolean val) {
this.settings.put("fontFamilyStack", new Boolean(val));
}
public void setFontMapper(Mapper fontMapper) {
this.settings.put("fontMapper", fontMapper);
}
public Mapper getFontMapper() {
return (Mapper)this.settings.get("fontMapper");
}
@Deprecated
public String getUserCSS() {
return (String)this.settings.get("userCSS");
}
@Deprecated
public void setUserCSS(String val) {
this.settings.put("userCSS", val);
}
@Deprecated
public String getUserScript() {
return (String)this.settings.get("userScript");
}
@Deprecated
public void setUserScript(String val) {
this.settings.put("userScript", val);
}
public String getUserBodyTop() {
return (String)this.settings.get("userBodyTop");
}
public void setUserBodyTop(String val) {
this.settings.put("userBodyTop", val);
}
public String getUserBodyTail() {
return (String)this.settings.get("userBodyTail");
}
public void setUserBodyTail(String val) {
this.settings.put("userBodyTail", val);
}
public void setImageTargetUri(String imageTargetUri) {
this.settings.put("imageTargetUri", imageTargetUri);
}
public String getImageTargetUri() {
return (String)this.settings.get("imageTargetUri");
}
public void setStyleElementHandler(ConversionHTMLStyleElementHandler styleElementHandler) {
this.settings.put("styleElementHandler", styleElementHandler);
}
public ConversionHTMLStyleElementHandler getStyleElementHandler() {
return (ConversionHTMLStyleElementHandler)this.settings.get("styleElementHandler");
}
public void setScriptElementHandler(ConversionHTMLScriptElementHandler scriptElementHandler) {
this.settings.put("scriptElementHandler", scriptElementHandler);
}
public ConversionHTMLScriptElementHandler getScriptElementHandler() {
return (ConversionHTMLScriptElementHandler)this.settings.get("scriptElementHandler");
}
}

View file

@ -0,0 +1,8 @@
package org.docx4j.convert.out;
import javax.xml.transform.Result;
import org.docx4j.openpackaging.exceptions.Docx4JException;
public interface Output {
void output(Result paramResult) throws Docx4JException;
}

View file

@ -0,0 +1,74 @@
package org.docx4j.convert.out.XSLFO;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.avalon.framework.configuration.Configuration;
import org.docx4j.Docx4J;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FORenderer;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.fo.renderers.FORendererApacheFOP;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class XSLFOExporterNonXSLT {
private static Logger log = LoggerFactory.getLogger(XSLFOExporterNonXSLT.class);
protected static final int DEFAULT_OUTPUT_SIZE = 102400;
FOSettings foSettings = null;
public XSLFOExporterNonXSLT(WordprocessingMLPackage wmlPackage, FOSettings pdfSettings) {
this.foSettings = pdfSettings;
if (this.foSettings.getWmlPackage() == null && wmlPackage != null)
this.foSettings.setWmlPackage(wmlPackage);
}
public Document export() throws Docx4JException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(102400);
Document ret = null;
this.foSettings.setApacheFopMime("application/xml-fo");
try {
Docx4J.toFO(this.foSettings, outStream, 2);
ret = XmlUtils.getNewDocumentBuilder().parse(new ByteArrayInputStream(outStream.toByteArray()));
} catch (Docx4JException e) {
log.error("Exception exporting document: " + e.getMessage(), (Throwable)e);
} catch (SAXException e) {
log.error("Exception parsing document: " + e.getMessage(), (Throwable)e);
} catch (IOException e) {
log.error("Exception parsing document: " + e.getMessage(), (Throwable)e);
}
return ret;
}
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/sample-docs/word/sample-docxv2.docx";
WordprocessingMLPackage wmlPackage = WordprocessingMLPackage.load(new File(inputfilepath));
FOSettings pdfSettings = new FOSettings();
pdfSettings.setWmlPackage(wmlPackage);
XSLFOExporterNonXSLT withoutXSLT = new XSLFOExporterNonXSLT(wmlPackage, pdfSettings);
long startTime = System.currentTimeMillis();
Document xslfo = withoutXSLT.export();
long endTime = System.currentTimeMillis();
log.info("done. elapsed time: " + Math.round((float)((endTime - startTime) / 1000L)));
log.info(XmlUtils.w3CDomNodeToString(xslfo));
String outputfilepath = inputfilepath + "K.pdf";
OutputStream os = new FileOutputStream(outputfilepath);
withoutXSLT.output(xslfo, os, null);
System.out.println("Saved " + outputfilepath);
}
public void output(Document xslfo, OutputStream os, Configuration fopConfigZZZ) throws Docx4JException {
FORenderer renderer = FORendererApacheFOP.getInstance();
String foDocument = XmlUtils.w3CDomNodeToString(xslfo);
renderer.render(foDocument, this.foSettings, false, null, os);
}
}

View file

@ -0,0 +1,133 @@
package org.docx4j.convert.out.common;
import java.util.HashMap;
import java.util.Map;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.convert.out.ConversionHyperlinkHandler;
import org.docx4j.convert.out.common.writer.AbstractMessageWriter;
import org.docx4j.model.images.ConversionImageHandler;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.parts.Part;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.traversal.NodeIterator;
public abstract class AbstractConversionContext {
private static final Logger log = LoggerFactory.getLogger(AbstractConversionContext.class);
public static final String CONVERSION_CONTEXT_ID = "conversionContext";
protected static final AbstractMessageWriter DUMMY_WRITER = new AbstractMessageWriter() {
public DocumentFragment notImplemented(AbstractConversionContext context, NodeIterator nodes, String message) {
return null;
}
public DocumentFragment message(AbstractConversionContext context, String message) {
return null;
}
protected String getOutputSuffix() {
return null;
}
protected String getOutputPrefix() {
return null;
}
};
protected static final ConversionHyperlinkHandler DUMMY_HYPERLINK_HANDLER = new ConversionHyperlinkHandler() {
public void handleHyperlink(ConversionHyperlinkHandler.Model hyperlinkModel, OpcPackage opcPackage, Part currentPart) throws Docx4JException {}
};
private Map<String, Object> xsltParameters = null;
private OpcPackage opcPackage = null;
private ConversionImageHandler imageHandler = null;
private ConversionHyperlinkHandler hyperlinkHandler = null;
private AbstractMessageWriter messageWriter = null;
private AbstractConversionSettings settings = null;
public AbstractConversionSettings getConversionSettings() {
return this.settings;
}
protected AbstractConversionContext(AbstractMessageWriter messageWriter, AbstractConversionSettings conversionSettings, OpcPackage localOpcPackage) {
initializeSettings(conversionSettings, localOpcPackage);
this.messageWriter = initializeMessageWriter(messageWriter);
}
protected void initializeSettings(AbstractConversionSettings settings, OpcPackage localOpcPackage) {
if (settings != null) {
this.settings = settings;
if (localOpcPackage == null && settings.getWmlPackage() == null)
throw new IllegalArgumentException("The OpcPackage is missing in the settings.");
this.imageHandler = initializeImageHandler(settings, settings.getImageHandler());
this.hyperlinkHandler = initializeHyperlinkHandler(settings, settings.getHyperlinkHandler());
this.opcPackage = initializeOpcPackage(settings, (localOpcPackage != null) ? localOpcPackage : settings.getWmlPackage());
this.xsltParameters = initializeXsltParameters(settings, settings.getSettings());
}
}
protected ConversionImageHandler initializeImageHandler(AbstractConversionSettings settings, ConversionImageHandler handler) {
return handler;
}
protected ConversionHyperlinkHandler initializeHyperlinkHandler(AbstractConversionSettings settings, ConversionHyperlinkHandler handler) {
return (handler != null) ? handler : DUMMY_HYPERLINK_HANDLER;
}
protected OpcPackage initializeOpcPackage(AbstractConversionSettings settings, OpcPackage opcPackage) {
return opcPackage;
}
protected Map<String, Object> initializeXsltParameters(AbstractConversionSettings settings, Map<String, Object> settingParameters) {
Map<String, Object> ret = new HashMap<String, Object>();
if (settingParameters != null) {
ret.putAll(settingParameters);
ret.remove("imageHandler");
ret.remove("wmlPackage");
ret.remove("imageIncludeUUID");
ret.remove("imageDirPath");
}
ret.put("conversionContext", this);
return ret;
}
protected AbstractMessageWriter initializeMessageWriter(AbstractMessageWriter writer) {
return (writer != null) ? writer : DUMMY_WRITER;
}
protected OpcPackage getOpcPackage() {
return this.opcPackage;
}
public ConversionImageHandler getImageHandler() {
return this.imageHandler;
}
protected ConversionHyperlinkHandler getHyperlinkHandler() {
return this.hyperlinkHandler;
}
public void handleHyperlink(ConversionHyperlinkHandler.Model model) throws Docx4JException {
getHyperlinkHandler().handleHyperlink(model, getOpcPackage(), null);
}
public AbstractMessageWriter getMessageWriter() {
return this.messageWriter;
}
public Map<String, Object> getXsltParameters() {
return this.xsltParameters;
}
public Logger getLog() {
return log;
}
}

View file

@ -0,0 +1,77 @@
package org.docx4j.convert.out.common;
import java.io.IOException;
import java.io.OutputStream;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractExporter<CS extends AbstractConversionSettings, CC extends AbstractConversionContext, PK extends OpcPackage> implements Exporter<CS> {
protected static Logger LocalLog = LoggerFactory.getLogger(AbstractExporter.class);
public void export(CS conversionSettings, OutputStream outputStream) throws Docx4JException {
PK preprocessedPackage = null;
ConversionSectionWrappers sectionWrappers = null;
CC conversionContext = null;
OutputStream intermediateOutputStream = null;
long startTime = System.currentTimeMillis();
long currentTime = startTime;
Logger log = LocalLog;
try {
log.debug("Start conversion");
preprocessedPackage = preprocess(conversionSettings);
if (preprocessedPackage instanceof WordprocessingMLPackage)
log.debug("Results of preprocess: " + ((WordprocessingMLPackage)preprocessedPackage).getMainDocumentPart().getXML());
currentTime = logDebugStep(log, "Preprocessing", currentTime);
sectionWrappers = createWrappers(conversionSettings, preprocessedPackage);
currentTime = logDebugStep(log, "Create section wrappers", currentTime);
conversionContext = createContext(conversionSettings, preprocessedPackage, sectionWrappers);
currentTime = logDebugStep(log, "Create conversion context", currentTime);
intermediateOutputStream = createIntermediateOutputStream(outputStream);
process(conversionSettings, conversionContext, intermediateOutputStream);
currentTime = logDebugStep(log, "Processing", currentTime);
postprocess(conversionSettings, conversionContext, intermediateOutputStream, outputStream);
currentTime = logDebugStep(log, "Postprocessing", currentTime);
logDebugStep(log, "Conversion done", startTime);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Only non-null Positions with an index can be checked"))
throw new Docx4JException("Exception exporting package; FOP https://issues.apache.org/bugzilla/show_bug.cgi?id=54094 .. try PP_APACHEFOP_DISABLE_PAGEBREAK_LIST_ITEM", e);
throw new Docx4JException("Exception exporting package", e);
} catch (Exception e) {
log.error("Exception exporting package", (Throwable)e);
throw new Docx4JException("Exception exporting package", e);
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
protected long logDebugStep(Logger log, String stepLabel, long startTime) {
long currentTime = 0L;
if (log.isDebugEnabled()) {
currentTime = System.currentTimeMillis();
log.debug(stepLabel + ", " + Long.toString(currentTime - startTime) + "ms");
}
return currentTime;
}
protected abstract PK preprocess(CS paramCS) throws Docx4JException;
protected abstract ConversionSectionWrappers createWrappers(CS paramCS, PK paramPK) throws Docx4JException;
protected abstract CC createContext(CS paramCS, PK paramPK, ConversionSectionWrappers paramConversionSectionWrappers);
protected OutputStream createIntermediateOutputStream(OutputStream outputStream) throws Docx4JException {
return outputStream;
}
protected abstract void process(CS paramCS, CC paramCC, OutputStream paramOutputStream) throws Docx4JException;
protected void postprocess(CS conversionSettings, AbstractConversionContext conversionContext, OutputStream intermediateOutputStream, OutputStream outputStream) throws Docx4JException {}
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out.common;
import java.io.OutputStream;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.openpackaging.exceptions.Docx4JException;
public abstract class AbstractExporterDelegate<CS extends AbstractConversionSettings, CC extends AbstractWmlConversionContext> {
public abstract void process(CS paramCS, CC paramCC, OutputStream paramOutputStream) throws Docx4JException;
}

View file

@ -0,0 +1,128 @@
package org.docx4j.convert.out.common;
import java.io.OutputStream;
import java.util.List;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.events.EventFinished;
import org.docx4j.events.StartEvent;
import org.docx4j.events.WellKnownProcessSteps;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.parts.Part;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public abstract class AbstractVisitorExporterDelegate<CS extends AbstractConversionSettings, CC extends AbstractWmlConversionContext> extends AbstractExporterDelegate<CS, CC> {
protected AbstractVisitorExporterGeneratorFactory<CC> generatorFactory = null;
protected AbstractVisitorExporterDelegate(AbstractVisitorExporterGeneratorFactory<CC> generatorFactory) {
this.generatorFactory = generatorFactory;
}
public void process(CS conversionSettings, CC conversionContext, OutputStream outputStream) throws Docx4JException {
StartEvent startEvent = new StartEvent(conversionSettings.getWmlPackage(), WellKnownProcessSteps.OUT_AbstractVisitorExporterDelegate);
startEvent.publish();
Document document = null;
Element documentRoot = null;
Element documentRootBody = null;
Element sectionRoot = null;
Element sectionRootBody = null;
Element currentParent = null;
Element flow = null;
conversionContext.setCurrentPartMainDocument();
document = XmlUtils.neww3cDomDocument();
currentParent = documentRoot = createDocumentRoot(conversionContext, document);
document.appendChild(documentRoot);
appendDocumentHeader(conversionContext, document, documentRoot);
documentRootBody = createDocumentBody(conversionContext, document, documentRoot);
if (documentRootBody != null) {
currentParent.appendChild(documentRootBody);
currentParent = documentRootBody;
}
List<ConversionSectionWrapper> sectionWrappers = conversionContext.getSections().getList();
for (int secindex = 0; secindex < sectionWrappers.size(); secindex++) {
ConversionSectionWrapper sectionWrapper = sectionWrappers.get(secindex);
conversionContext.getSections().next();
sectionRoot = createSectionRoot(conversionContext, document, sectionWrapper, currentParent);
if (sectionRoot != null) {
currentParent.appendChild(sectionRoot);
currentParent = sectionRoot;
}
appendSectionHeader(conversionContext, document, sectionWrapper, currentParent);
sectionRootBody = createSectionBody(conversionContext, document, sectionWrapper, currentParent);
if (sectionRootBody != null) {
currentParent.appendChild(sectionRootBody);
currentParent = sectionRootBody;
}
generateBodyContent(conversionContext, document, sectionWrapper.getContent(), currentParent);
currentParent = sectionRoot;
if (currentParent == null) {
currentParent = documentRootBody;
if (currentParent == null)
currentParent = documentRoot;
}
appendSectionFooter(conversionContext, document, sectionWrapper, currentParent);
currentParent = documentRootBody;
if (currentParent == null)
currentParent = documentRoot;
}
appendDocumentFooter(conversionContext, document, documentRoot);
writeDocument(conversionContext, document, outputStream);
new EventFinished(startEvent).publish();
}
protected abstract Element createDocumentRoot(CC paramCC, Document paramDocument) throws Docx4JException;
protected void appendDocumentHeader(CC conversionContext, Document document, Element documentRoot) throws Docx4JException {}
protected Element createDocumentBody(CC conversionContext, Document document, Element documentRoot) {
return null;
}
protected Element createSectionRoot(CC conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {
return null;
}
protected void appendSectionHeader(CC conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {}
protected Element createSectionBody(CC conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {
return null;
}
protected void appendPartContent(CC conversionContext, Document document, Part part, List<Object> content, Element currentParent) throws Docx4JException {
Part previousPart = conversionContext.getCurrentPart();
conversionContext.setCurrentPart(part);
generateBodyContent(conversionContext, document, content, currentParent);
conversionContext.setCurrentPart(previousPart);
}
protected void generateBodyContent(CC conversionContext, Document document, List<Object> content, Element currentParent) throws Docx4JException {
AbstractVisitorExporterGenerator<CC> generator = this.generatorFactory.createInstance(conversionContext, document, currentParent);
new TraversalUtil(content, generator);
}
protected void appendSectionFooter(CC conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {}
protected void appendDocumentFooter(CC conversionContext, Document document, Element documentRoot) throws Docx4JException {}
protected void writeDocument(CC conversionContext, Document document, OutputStream outputStream) throws Docx4JException {
Transformer serializer = null;
try {
serializer = XmlUtils.getTransformerFactory().newTransformer();
serializer.setOutputProperty("omit-xml-declaration", "yes");
serializer.setOutputProperty("method", "xml");
serializer.transform(new DOMSource(document), new StreamResult(outputStream));
} catch (Exception e) {
throw new Docx4JException("Exception writing Document to OutputStream: " + e.getMessage(), e);
}
}
public static interface AbstractVisitorExporterGeneratorFactory<CC extends AbstractWmlConversionContext> {
AbstractVisitorExporterGenerator<CC> createInstance(CC param1CC, Document param1Document, Node param1Node);
}
}

View file

@ -0,0 +1,259 @@
package org.docx4j.convert.out.common;
import java.util.LinkedList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.vml.CTShape;
import org.docx4j.vml.CTTextbox;
import org.docx4j.vml.wordprocessingDrawing.CTWrap;
import org.docx4j.wml.Br;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.FldChar;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.Pict;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.docx4j.wml.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public abstract class AbstractVisitorExporterGenerator<CC extends AbstractWmlConversionContext> extends TraversalUtil.CallbackImpl {
private static Logger log = LoggerFactory.getLogger(AbstractVisitorExporterGenerator.class);
protected static final String TAB_DUMMY = "   ";
protected static final int NODE_BLOCK = 1;
protected static final int NODE_INLINE = 2;
protected static final int IMAGE_E10 = 1;
protected static final int IMAGE_E20 = 2;
protected CC conversionContext = null;
protected Document document = null;
protected Node parentNode = null;
protected Element currentP = null;
protected Element currentSpan = null;
protected LinkedList<Element> tr = new LinkedList<Element>();
protected LinkedList<Element> tc = new LinkedList<Element>();
protected PPr pPr = null;
protected RPr rPr = null;
protected Object anchorOrInline;
protected AbstractVisitorExporterGenerator(CC conversionContext, Document document, Node parentNode) {
this.conversionContext = conversionContext;
this.document = document;
this.parentNode = parentNode;
}
public boolean shouldTraverse(Object o) {
if (o instanceof org.docx4j.wml.Tbl || o instanceof P.Hyperlink || o instanceof org.docx4j.wml.CTSimpleField || o instanceof CTTextbox || o instanceof FldChar)
return false;
return true;
}
protected Node getCurrentParent() {
return (this.currentSpan != null) ? this.currentSpan : ((this.currentP != null) ? this.currentP : this.parentNode);
}
protected void convertToNode(CC conversionContext, Object unmarshalledNode, String modelId, Document document, Node parentNode) throws DOMException {
log.debug(modelId);
DocumentFragment childResults = null;
if (unmarshalledNode instanceof ContentAccessor) {
childResults = document.createDocumentFragment();
AbstractVisitorExporterGenerator<CC> generator = getFactory().createInstance(conversionContext, document, childResults);
new TraversalUtil(((ContentAccessor)unmarshalledNode).getContent(), generator);
} else if (unmarshalledNode instanceof Pict) {
CTTextbox textBox = getTextBox((Pict)unmarshalledNode);
if (textBox != null) {
childResults = document.createDocumentFragment();
AbstractVisitorExporterGenerator<CC> generator = getFactory().createInstance(conversionContext, document, childResults);
new TraversalUtil(textBox.getTxbxContent().getContent(), generator);
}
}
Node resultNode = conversionContext.getWriterRegistry().toNode(conversionContext, unmarshalledNode, modelId, childResults, document);
if (resultNode != null) {
log.debug("Appending " + XmlUtils.w3CDomNodeToString(resultNode));
parentNode.appendChild(resultNode);
}
}
protected void rtlAwareAppendChildToCurrentP(Element child) {
this.parentNode.appendChild(child);
}
public void walkJAXBElements(Object o) {
Node existingParentNode = this.parentNode;
if (o instanceof org.docx4j.wml.Tr) {
this.tr.push(this.document.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "tr"));
this.parentNode.appendChild(this.tr.peek());
} else if (o instanceof org.docx4j.wml.Tc) {
this.tc.push(this.document.createElementNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "tc"));
this.tr.peek().appendChild(this.tc.peek());
this.parentNode = this.tc.peek();
}
super.walkJAXBElements(o);
if (o instanceof org.docx4j.wml.Tr) {
this.tr.pop();
} else if (o instanceof org.docx4j.wml.Tc) {
this.tc.pop();
this.parentNode = existingParentNode;
}
}
public List<Object> apply(Object o) {
if (o instanceof P) {
this.currentP = createNode(this.document, 1);
this.currentSpan = null;
if (this.tc.peek() != null) {
this.tc.peek().appendChild(this.currentP);
} else {
this.parentNode.appendChild(this.currentP);
}
this.pPr = ((P)o).getPPr();
this.currentP = handlePPr(this.conversionContext, this.pPr, false, this.currentP);
} else if (o instanceof R) {
if (!this.conversionContext.isInComplexFieldDefinition()) {
Element spanEl = createNode(this.document, 2);
this.currentSpan = spanEl;
this.rPr = ((R)o).getRPr();
if (this.rPr != null)
handleRPr(this.conversionContext, this.pPr, this.rPr, this.currentSpan);
if (this.currentP == null) {
this.parentNode.appendChild(spanEl);
} else {
rtlAwareAppendChildToCurrentP(spanEl);
}
}
} else if (o instanceof FldChar) {
this.conversionContext.updateComplexFieldDefinition(((FldChar)o).getFldCharType());
} else if (o instanceof Text) {
if (!this.conversionContext.isInComplexFieldDefinition()) {
if (this.currentSpan == null) {
log.error("null currentSpan! " + ((Text)o).getValue());
Element spanEl = createNode(this.document, 2);
if (this.currentP == null) {
this.parentNode.appendChild(spanEl);
} else {
this.currentP.appendChild(spanEl);
}
this.currentSpan = spanEl;
}
log.debug(((Text)o).getValue());
DocumentFragment df = (DocumentFragment)this.conversionContext.getRunFontSelector().fontSelector(this.pPr, this.rPr, (Text)o);
XmlUtils.treeCopy(df, this.currentSpan);
}
} else if (o instanceof R.Tab) {
convertTabToNode(this.conversionContext, this.document);
} else if (o instanceof org.docx4j.wml.CTSimpleField) {
convertToNode(this.conversionContext, o, "w:fldSimple", this.document, getCurrentParent());
} else if (o instanceof P.Hyperlink) {
convertToNode(this.conversionContext, o, "w:hyperlink", this.document, getCurrentParent());
} else if (o instanceof org.docx4j.wml.CTBookmark) {
convertToNode(this.conversionContext, o, "w:bookmarkStart", this.document, getCurrentParent());
} else if (o instanceof org.docx4j.wml.Tbl) {
convertToNode(this.conversionContext, o, "w:tbl", this.document, (this.currentP != null) ? this.currentP : this.parentNode);
this.currentP = null;
this.currentSpan = null;
} else if (!(o instanceof org.docx4j.wml.Tr)) {
if (!(o instanceof org.docx4j.wml.Tc))
if (o instanceof org.docx4j.dml.wordprocessingDrawing.Inline || o instanceof org.docx4j.dml.wordprocessingDrawing.Anchor) {
this.anchorOrInline = o;
} else if (o instanceof org.docx4j.dml.CTBlip) {
DocumentFragment foreignFragment = createImage(2, this.conversionContext, this.anchorOrInline);
this.anchorOrInline = null;
this.currentP.appendChild(this.document.importNode(foreignFragment, true));
} else if (o instanceof Pict) {
CTTextbox textBox = getTextBox((Pict)o);
if (textBox == null) {
DocumentFragment foreignFragment = createImage(1, this.conversionContext, o);
this.currentP.appendChild(this.document.importNode(foreignFragment, true));
} else {
convertToNode(this.conversionContext, o, "w:pict", this.document, getCurrentParent());
}
} else if (o instanceof Br) {
handleBr((Br)o);
} else if (o instanceof R.Sym) {
convertToNode(this.conversionContext, o, "w:sym", this.document, getCurrentParent());
} else if (!(o instanceof org.docx4j.wml.ProofErr) && !(o instanceof R.LastRenderedPageBreak) && !(o instanceof org.docx4j.wml.CTMarkupRange)) {
log.warn("Need to handle " + o.getClass().getName());
log.debug(XmlUtils.marshaltoString(o));
}
}
return null;
}
protected abstract void handleBr(Br paramBr);
protected int getPos(List list, Object wanted) {
int index = 0;
for (Object o : (Iterable<Object>)list) {
if (o == wanted)
return index;
index++;
}
return -1;
}
protected void convertTabToNode(CC conversionContext, Document document) throws DOMException {
if (!conversionContext.isInComplexFieldDefinition())
getCurrentParent().appendChild(document.createTextNode("   "));
}
private CTTextbox getTextBox(Pict pict) {
CTShape shape = null;
for (Object o2 : (Iterable<Object>)pict.getAnyAndAny()) {
o2 = XmlUtils.unwrap(o2);
if (o2 instanceof CTShape) {
shape = (CTShape)o2;
break;
}
}
if (shape == null) {
log.warn("no shape in pict ");
return null;
}
CTTextbox textBox = null;
CTWrap w10Wrap = null;
for (JAXBElement<?> o2 : shape.getPathOrFormulasOrHandles()) {
o2 = (JAXBElement<?>)XmlUtils.unwrap(o2);
if (o2 instanceof CTTextbox)
textBox = (CTTextbox)o2;
if (o2 instanceof CTWrap)
w10Wrap = (CTWrap)o2;
}
return textBox;
}
protected abstract Element handlePPr(CC paramCC, PPr paramPPr, boolean paramBoolean, Element paramElement);
protected abstract void handleRPr(CC paramCC, PPr paramPPr, RPr paramRPr, Element paramElement);
protected abstract AbstractVisitorExporterDelegate.AbstractVisitorExporterGeneratorFactory<CC> getFactory();
protected abstract DocumentFragment createImage(int paramInt, CC paramCC, Object paramObject);
protected abstract Element createNode(Document paramDocument, int paramInt);
protected Logger getLog() {
return log;
}
}

View file

@ -0,0 +1,140 @@
package org.docx4j.convert.out.common;
import java.util.Map;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.convert.out.ConversionHyperlinkHandler;
import org.docx4j.convert.out.common.writer.AbstractMessageWriter;
import org.docx4j.fonts.RunFontSelector;
import org.docx4j.model.PropertyResolver;
import org.docx4j.model.styles.StyleTree;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.wml.STFldCharType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractWmlConversionContext extends AbstractConversionContext {
private static Logger log = LoggerFactory.getLogger(AbstractWmlConversionContext.class);
private Map<String, Writer.TransformState> transformStates = null;
private AbstractWriterRegistry writerRegistry = null;
protected Part currentPart = null;
protected int complexFieldDefinitionLevel = 0;
protected int footnoteNumberCounter = 0;
protected int endnoteNumberCounter = 0;
protected ConversionSectionWrappers conversionSectionWrappers = null;
protected StyleTree styleTree = null;
private RunFontSelector runFontSelector = null;
protected AbstractWmlConversionContext(AbstractWriterRegistry writerRegistry, AbstractMessageWriter messageWriter, AbstractConversionSettings conversionSettings, WordprocessingMLPackage wmlPackage, ConversionSectionWrappers conversionSectionWrappers, RunFontSelector runFontSelector) {
super(messageWriter, conversionSettings, wmlPackage);
this.writerRegistry = initializeWriterRegistry(writerRegistry);
this.transformStates = initializeTransformStates();
this.conversionSectionWrappers = conversionSectionWrappers;
this.styleTree = initializeStyleTree();
this.runFontSelector = runFontSelector;
}
protected OpcPackage initializeOpcPackage(AbstractConversionSettings conversionSettings, OpcPackage opcPackage) {
OpcPackage ret = super.initializeOpcPackage(conversionSettings, opcPackage);
if (!(ret instanceof WordprocessingMLPackage))
throw new IllegalArgumentException("The opcPackage isn't a WordprocessingMLPackage, it is a " + ret.getClass().getName());
resolveLinkedAbstractNum((WordprocessingMLPackage)ret);
return ret;
}
protected AbstractWriterRegistry initializeWriterRegistry(AbstractWriterRegistry registry) {
return registry;
}
protected Map<String, Writer.TransformState> initializeTransformStates() {
return getWriterRegistry().createTransformStates();
}
protected void resolveLinkedAbstractNum(WordprocessingMLPackage wmlPkg) {
if (wmlPkg.getMainDocumentPart().getStyleDefinitionsPart(false) != null && wmlPkg.getMainDocumentPart().getNumberingDefinitionsPart() != null)
wmlPkg.getMainDocumentPart().getNumberingDefinitionsPart().resolveLinkedAbstractNum(wmlPkg.getMainDocumentPart().getStyleDefinitionsPart(false));
}
protected StyleTree initializeStyleTree() {
return getWmlPackage().getMainDocumentPart().getStyleTree();
}
public Writer.TransformState getTransformState(String name) {
return (this.transformStates != null) ? this.transformStates.get(name) : null;
}
public WordprocessingMLPackage getWmlPackage() {
return (WordprocessingMLPackage)getOpcPackage();
}
public AbstractWriterRegistry getWriterRegistry() {
return this.writerRegistry;
}
public PropertyResolver getPropertyResolver() {
return getWmlPackage().getMainDocumentPart().getPropertyResolver();
}
public int getNextEndnoteNumber() {
return this.endnoteNumberCounter++;
}
public int getNextFootnoteNumber() {
return this.footnoteNumberCounter++;
}
public void setCurrentPart(Part currentPart) {
this.currentPart = currentPart;
}
public Part getCurrentPart() {
return this.currentPart;
}
public void setCurrentPartMainDocument() {
setCurrentPart(getWmlPackage().getMainDocumentPart());
}
public ConversionSectionWrappers getSections() {
return this.conversionSectionWrappers;
}
public StyleTree getStyleTree() {
return this.styleTree;
}
public RunFontSelector getRunFontSelector() {
return this.runFontSelector;
}
public void handleHyperlink(ConversionHyperlinkHandler.Model model) throws Docx4JException {
getHyperlinkHandler().handleHyperlink(model, getOpcPackage(), getCurrentPart());
}
public void updateComplexFieldDefinition(STFldCharType fieldCharType) {
if (fieldCharType == STFldCharType.BEGIN) {
this.complexFieldDefinitionLevel++;
} else if (fieldCharType == STFldCharType.SEPARATE) {
if (this.complexFieldDefinitionLevel == 1)
this.complexFieldDefinitionLevel--;
} else if (fieldCharType == STFldCharType.END &&
this.complexFieldDefinitionLevel > 0) {
this.complexFieldDefinitionLevel--;
}
}
public boolean isInComplexFieldDefinition() {
return (this.complexFieldDefinitionLevel > 0);
}
}

View file

@ -0,0 +1,37 @@
package org.docx4j.convert.out.common;
import java.io.OutputStream;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
public abstract class AbstractWmlExporter<CS extends AbstractConversionSettings, CC extends AbstractWmlConversionContext> extends AbstractExporter<CS, CC, WordprocessingMLPackage> {
protected AbstractExporterDelegate<CS, CC> exporterDelegate = null;
protected AbstractWmlExporter(AbstractExporterDelegate<CS, CC> exporterDelegate) {
this.exporterDelegate = exporterDelegate;
}
protected WordprocessingMLPackage preprocess(CS conversionSettings) throws Docx4JException {
WordprocessingMLPackage wmlPackage = null;
try {
wmlPackage = (WordprocessingMLPackage)conversionSettings.getWmlPackage();
} catch (ClassCastException cce) {
throw new Docx4JException("Invalid document package in the settings, it isn't a WordprocessingMLPackage");
}
if (wmlPackage == null)
throw new Docx4JException("Missing WordprocessingMLPackage in the conversion settings");
return Preprocess.process(wmlPackage, conversionSettings.getFeatures());
}
protected ConversionSectionWrappers createWrappers(CS conversionSettings, WordprocessingMLPackage preprocessedPackage) throws Docx4JException {
ConversionSectionWrappers ret = null;
ret = CreateWrappers.process(preprocessedPackage, conversionSettings.getFeatures());
return ret;
}
protected void process(CS conversionSettings, CC conversionContext, OutputStream outputStream) throws Docx4JException {
this.exporterDelegate.process(conversionSettings, conversionContext, outputStream);
}
}

View file

@ -0,0 +1,74 @@
package org.docx4j.convert.out.common;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBException;
import org.docx4j.XmlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public abstract class AbstractWriterRegistry {
private static final Logger log = LoggerFactory.getLogger(AbstractWriterRegistry.class);
private Map<String, Writer> writerInstances = new HashMap<String, Writer>();
public AbstractWriterRegistry() {
registerDefaultWriterInstances();
}
protected abstract void registerDefaultWriterInstances();
public void registerWriter(Writer converter) {
this.writerInstances.put(converter.getID(), converter);
}
public Map<String, Writer.TransformState> createTransformStates() {
Map<String, Writer.TransformState> ret = new HashMap<String, Writer.TransformState>();
Writer.TransformState state = null;
for (Map.Entry<String, Writer> item : this.writerInstances.entrySet()) {
state = item.getValue().createTransformState();
if (state != null)
ret.put(item.getKey(), state);
}
return ret;
}
public Node toNode(AbstractWmlConversionContext context, Node node, NodeList childResults) {
Object unmarshalledNode = null;
Document doc = XmlUtils.neww3cDomDocument();
Node content = (childResults != null && childResults.getLength() > 0) ? childResults.item(0) : null;
Node ret = null;
try {
unmarshalledNode = XmlUtils.unmarshal(node);
} catch (JAXBException e) {
log.error("Cannot unmarshall " + node.getNodeName(), (Throwable)e);
}
if (unmarshalledNode != null)
ret = toNode(context, unmarshalledNode, node.getNodeName(), content, doc);
return ret;
}
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, String modelID, Node content, Document doc) {
Node ret = null;
try {
Writer converter = this.writerInstances.get(modelID);
if (converter == null) {
log.warn("No writer registered for " + modelID);
log.info("Generating wml from model.");
Document docMarshalled = XmlUtils.marshaltoW3CDomDocument(unmarshalledNode);
DocumentFragment docfrag = docMarshalled.createDocumentFragment();
docfrag.appendChild(docMarshalled.getDocumentElement());
ret = docfrag;
} else {
ret = converter.toNode(context, unmarshalledNode, content, context.getTransformState(modelID), doc);
}
} catch (Exception e) {
log.error("Cannot convert " + unmarshalledNode, (Throwable)e);
}
return ret;
}
}

View file

@ -0,0 +1,68 @@
package org.docx4j.convert.out.common;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.events.EventFinished;
import org.docx4j.events.StartEvent;
import org.docx4j.events.WellKnownProcessSteps;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.utils.ResourceUtils;
import org.w3c.dom.Document;
public abstract class AbstractXsltExporterDelegate<CS extends AbstractConversionSettings, CC extends AbstractWmlConversionContext> extends AbstractExporterDelegate<CS, CC> {
protected String defaultTemplatesResource = null;
protected Templates defaultTemplates = null;
protected AbstractXsltExporterDelegate(String defaultTemplatesResource) {
this.defaultTemplatesResource = defaultTemplatesResource;
}
public void process(CS conversionSettings, CC conversionContext, OutputStream outputStream) throws Docx4JException {
StartEvent startEvent = new StartEvent(conversionSettings.getWmlPackage(), WellKnownProcessSteps.OUT_XsltExporterDelegate);
startEvent.publish();
Document domDoc = getSourceDocument(conversionSettings, conversionContext);
Templates templates = getTemplates(conversionSettings, conversionContext);
Result intermediateResult = new StreamResult(outputStream);
XmlUtils.transform(domDoc, templates, conversionContext.getXsltParameters(), intermediateResult);
new EventFinished(startEvent).publish();
}
protected abstract Document getSourceDocument(CS paramCS, CC paramCC) throws Docx4JException;
protected Templates getTemplates(CS conversionSettings, CC conversionContext) throws Docx4JException {
Templates ret = (Templates)conversionSettings.getCustomXsltTemplates();
return (ret == null) ? getDefaultTemplate() : ret;
}
protected Templates getDefaultTemplate() throws Docx4JException {
if (this.defaultTemplates == null)
synchronized (XmlUtils.getTransformerFactory()) {
if (this.defaultTemplates == null)
this.defaultTemplates = loadDefaultTemplates();
}
return this.defaultTemplates;
}
protected Templates loadDefaultTemplates() throws Docx4JException {
Templates ret = null;
Source xsltSource = null;
try {
xsltSource = new StreamSource(ResourceUtils.getResource(this.defaultTemplatesResource));
ret = XmlUtils.getTransformerTemplate(xsltSource);
} catch (IOException e) {
throw new Docx4JException("Exception loading default template \"" + this.defaultTemplatesResource + "\", " + e.getMessage(), e);
} catch (TransformerConfigurationException e) {
throw new Docx4JException("Exception loading default template \"" + this.defaultTemplatesResource + "\", " + e.getMessage(), e);
}
return ret;
}
}

View file

@ -0,0 +1,39 @@
package org.docx4j.convert.out.common;
import java.util.List;
import org.docx4j.convert.out.common.preprocess.PageNumberInformation;
import org.docx4j.model.structure.HeaderFooterPolicy;
import org.docx4j.model.structure.SectionWrapper;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.SectPr;
public class ConversionSectionWrapper extends SectionWrapper {
protected List<Object> content = null;
protected String id = null;
protected PageNumberInformation pageNumberInformation = null;
public ConversionSectionWrapper(SectPr sectPr, HeaderFooterPolicy previousHF, RelationshipsPart rels, BooleanDefaultTrue evenAndOddHeaders, String id, List<Object> content) {
super(sectPr, previousHF, rels, evenAndOddHeaders);
this.id = id;
this.content = content;
}
public String getId() {
return this.id;
}
public List<Object> getContent() {
return this.content;
}
public void setPageNumberInformation(PageNumberInformation pageNumberInformation) {
this.pageNumberInformation = pageNumberInformation;
}
public PageNumberInformation getPageNumberInformation() {
return this.pageNumberInformation;
}
}

View file

@ -0,0 +1,71 @@
package org.docx4j.convert.out.common;
import java.util.List;
import org.docx4j.XmlUtils;
import org.docx4j.model.structure.jaxb.ObjectFactory;
import org.docx4j.model.structure.jaxb.Sections;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class ConversionSectionWrappers {
protected List<ConversionSectionWrapper> conversionSections = null;
protected int currentSectionIndex = -1;
protected ConversionSectionWrapper currentSection = null;
public ConversionSectionWrappers(List<ConversionSectionWrapper> conversionSections) {
this.conversionSections = conversionSections;
}
public Sections createSections() {
ObjectFactory factory = new ObjectFactory();
Sections ret = factory.createSections();
for (int i = 0; i < this.conversionSections.size(); i++)
ret.getSection().add(createSection(factory, this.conversionSections.get(i)));
return ret;
}
private Sections.Section createSection(ObjectFactory factory, ConversionSectionWrapper conversionSectionWrapper) {
Sections.Section ret = factory.createSectionsSection();
ret.setName(conversionSectionWrapper.getId());
for (int i = 0; i < conversionSectionWrapper.getContent().size(); i++)
ret.getAny().add(marshall(conversionSectionWrapper.getContent().get(i)));
return ret;
}
private static Element marshall(Object o) {
try {
Document w3cDoc = XmlUtils.marshaltoW3CDomDocument(o);
return w3cDoc.getDocumentElement();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public List<ConversionSectionWrapper> getList() {
return this.conversionSections;
}
public void start() {
this.currentSectionIndex = -1;
}
public void next() {
this.currentSectionIndex++;
this.currentSection = null;
if (this.currentSectionIndex >= 0 && this.currentSectionIndex < this.conversionSections.size())
this.currentSection = this.conversionSections.get(this.currentSectionIndex);
}
public ConversionSectionWrapper getCurrentSection() {
if (this.currentSection != null)
return this.currentSection;
if (this.currentSectionIndex < 0)
throw new IllegalArgumentException("Trying to access a section, but moveNext wasn't called");
if (this.currentSectionIndex >= this.conversionSections.size())
throw new IllegalArgumentException("Trying to access more sections than avaiable");
throw new IllegalArgumentException("There is no current section");
}
}

View file

@ -0,0 +1,24 @@
package org.docx4j.convert.out.common;
import java.util.Set;
import org.docx4j.convert.out.ConversionFeatures;
import org.docx4j.convert.out.common.wrappers.ConversionSectionWrapperFactory;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CreateWrappers extends ConversionFeatures {
private static Logger log = LoggerFactory.getLogger(CreateWrappers.class);
public static ConversionSectionWrappers process(WordprocessingMLPackage wmlPackage, Set<String> features) throws Docx4JException {
ConversionSectionWrappers ret = null;
boolean dummySections = false;
boolean dummyPageNumbering = false;
checkParams(wmlPackage, features);
dummySections = !features.contains("pp.common.createsections");
dummyPageNumbering = !features.contains("pp.common.pagenumbering");
ret = ConversionSectionWrapperFactory.process(wmlPackage, dummySections, dummyPageNumbering);
return ret;
}
}

View file

@ -0,0 +1,8 @@
package org.docx4j.convert.out.common;
import java.io.OutputStream;
import org.docx4j.openpackaging.exceptions.Docx4JException;
public interface Exporter<T extends org.docx4j.convert.out.AbstractConversionSettings> {
void export(T paramT, OutputStream paramOutputStream) throws Docx4JException;
}

View file

@ -0,0 +1,95 @@
package org.docx4j.convert.out.common;
import java.util.Set;
import java.util.TreeSet;
import org.docx4j.convert.out.ConversionFeatures;
import org.docx4j.convert.out.common.preprocess.BookmarkMover;
import org.docx4j.convert.out.common.preprocess.Containerization;
import org.docx4j.convert.out.common.preprocess.CoverPageSectPrMover;
import org.docx4j.convert.out.common.preprocess.FieldsCombiner;
import org.docx4j.convert.out.common.preprocess.FopWorkaroundDisablePageBreakOnFirstParagraph;
import org.docx4j.convert.out.common.preprocess.FopWorkaroundReplacePageBreakInEachList;
import org.docx4j.convert.out.common.preprocess.PageBreak;
import org.docx4j.convert.out.common.preprocess.ParagraphStylesInTableFix;
import org.docx4j.convert.out.common.preprocess.PartialDeepCopy;
import org.docx4j.events.EventFinished;
import org.docx4j.events.StartEvent;
import org.docx4j.events.WellKnownProcessSteps;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Preprocess extends ConversionFeatures {
private static Logger log = LoggerFactory.getLogger(Preprocess.class);
public static OpcPackage process(OpcPackage opcPackage, Set<String> features) throws Docx4JException {
OpcPackage ret = opcPackage;
Set<String> relationshipTypes = null;
checkParams(opcPackage, features);
relationshipTypes = createRelationshipTypes(features);
if (features.contains("pp.common.deepcopy")) {
ret = PartialDeepCopy.process(opcPackage, relationshipTypes);
if (ret instanceof WordprocessingMLPackage)
log.debug("Results of PP_COMMON_DEEP_COPY: " + ((WordprocessingMLPackage)ret).getMainDocumentPart().getXML());
}
return ret;
}
protected static Set<String> createRelationshipTypes(Set<String> features) {
Set<String> relationshipTypes = new TreeSet<String>();
if (features.contains("pp.common.movebookmarks") || features.contains("pp.common.containerization") || features.contains("pp.common.combinefields")) {
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments");
}
if (features.contains("pp.common.movepagebreak"))
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
return relationshipTypes;
}
public static WordprocessingMLPackage process(WordprocessingMLPackage wmlPackage, Set<String> features) throws Docx4JException {
WordprocessingMLPackage ret = (WordprocessingMLPackage)process((OpcPackage)wmlPackage, features);
StartEvent startEvent = new StartEvent(ret, WellKnownProcessSteps.CONVERT_PREPROCESS);
startEvent.publish();
if (features.contains("pp.common.combinefields")) {
log.debug("PP_COMMON_COMBINE_FIELDS");
FieldsCombiner.process(ret);
}
if (features.contains("pp.common.movebookmarks")) {
log.debug("PP_COMMON_MOVE_BOOKMARKS");
BookmarkMover.process(ret);
}
if (features.contains("pp.common.movepagebreak")) {
log.debug("PP_COMMON_MOVE_PAGEBREAK");
PageBreak.process(ret);
}
if (features.contains("pp.common.coverpagemovesectpr")) {
log.debug("PP_COMMON_COVERPAGE_MOVE_SECTPR");
CoverPageSectPrMover.process(ret);
}
if (features.contains("pp.common.containerization")) {
log.debug("PP_COMMON_CONTAINERIZATION");
Containerization.process(ret);
}
if (features.contains("pp.apachefop.disablepagebreakfirstparagraph")) {
log.debug("PP_APACHEFOP_DISABLE_PAGEBREAK_FIRST_PARAGRAPH");
FopWorkaroundDisablePageBreakOnFirstParagraph.process(ret);
}
if (features.contains("pp.apachefop.disablepagebreaklistitem")) {
log.debug("PP_APACHEFOP_DISABLE_PAGEBREAK_LIST_ITEM");
FopWorkaroundReplacePageBreakInEachList.process(ret);
}
if (features.contains("pp.common.tbl-p-style-fix")) {
log.debug("PP_COMMON_TABLE_PARAGRAPH_STYLE_FIX");
ParagraphStylesInTableFix.process(ret);
}
log.debug("Results of preprocessing: " + ret.getMainDocumentPart().getXML());
new EventFinished(startEvent).publish();
return ret;
}
}

View file

@ -0,0 +1,19 @@
package org.docx4j.convert.out.common;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.w3c.dom.Document;
public class WmlXsltExporterDelegate<CS extends AbstractConversionSettings, CC extends AbstractWmlConversionContext> extends AbstractXsltExporterDelegate<CS, CC> {
public WmlXsltExporterDelegate(String defaultTemplatesResource) {
super(defaultTemplatesResource);
}
protected Document getSourceDocument(CS conversionSettings, CC conversionContext) throws Docx4JException {
ConversionSectionWrappers conversionSectionWrappers = conversionContext.getSections();
Document ret = XmlUtils.marshaltoW3CDomDocument(conversionSectionWrappers.createSections(), Context.jcSectionModel);
return ret;
}
}

View file

@ -0,0 +1,15 @@
package org.docx4j.convert.out.common;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public interface Writer {
String getID();
Node toNode(AbstractWmlConversionContext paramAbstractWmlConversionContext, Object paramObject, Node paramNode, TransformState paramTransformState, Document paramDocument) throws TransformerException;
TransformState createTransformState();
public static interface TransformState {}
}

View file

@ -0,0 +1,290 @@
package org.docx4j.convert.out.common;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.jaxb.JaxbValidationEventHandler;
import org.docx4j.model.styles.StyleUtil;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.wml.CTFootnotes;
import org.docx4j.wml.CTFtnEdn;
import org.docx4j.wml.FldChar;
import org.docx4j.wml.Ftr;
import org.docx4j.wml.Hdr;
import org.docx4j.wml.PPr;
import org.docx4j.wml.ParaRPr;
import org.docx4j.wml.RPr;
import org.docx4j.wml.STFldCharType;
import org.docx4j.wml.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.NodeIterator;
public class XsltCommonFunctions {
private static Logger log = LoggerFactory.getLogger(XsltCommonFunctions.class);
public static DocumentFragment fontSelector(AbstractWmlConversionContext conversionContext, NodeIterator pPrNodeIt, NodeIterator rPrNodeIt, NodeIterator textNodeIt) {
PPr pPr = null;
RPr rPr = null;
Text text = null;
Node n = pPrNodeIt.nextNode();
if (n != null)
try {
Unmarshaller u = Context.jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Object jaxb = u.unmarshal(n);
pPr = (PPr)jaxb;
} catch (ClassCastException e) {
log.error("Couldn't cast to RPr!");
} catch (JAXBException e) {
log.error(e.getMessage(), (Throwable)e);
}
n = rPrNodeIt.nextNode();
if (n != null)
try {
Unmarshaller u = Context.jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Object jaxb = u.unmarshal(n);
if (jaxb instanceof RPr) {
rPr = (RPr)jaxb;
} else if (jaxb instanceof ParaRPr) {
rPr = conversionContext.getPropertyResolver().getEffectiveRPr(null, pPr);
StyleUtil.apply((ParaRPr)jaxb, rPr);
}
} catch (ClassCastException e) {
log.error("Couldn't cast to RPr!");
} catch (JAXBException e) {
log.error(e.getMessage(), (Throwable)e);
}
n = textNodeIt.nextNode();
if (n != null)
try {
Unmarshaller u = Context.jc.createUnmarshaller();
u.setEventHandler(new JaxbValidationEventHandler());
Object jaxb = u.unmarshal(n);
text = (Text)jaxb;
} catch (ClassCastException e) {
log.error("Couldn't cast to Text!");
} catch (JAXBException e) {
log.error(e.getMessage(), (Throwable)e);
}
return (DocumentFragment)conversionContext.getRunFontSelector().fontSelector(pPr, rPr, text);
}
public static Node toNode(AbstractWmlConversionContext context, Node node, NodeList childResults) {
return context.getWriterRegistry().toNode(context, node, childResults);
}
public static int getNextFootnoteNumber(AbstractWmlConversionContext context) {
return context.getNextFootnoteNumber();
}
public static Node getFootnote(AbstractWmlConversionContext context, String id) {
WordprocessingMLPackage wmlPackage = context.getWmlPackage();
CTFootnotes footnotes = wmlPackage.getMainDocumentPart().getFootnotesPart().getJaxbElement();
int pos = Integer.parseInt(id);
CTFtnEdn ftn = footnotes.getFootnote().get(pos);
Document d = XmlUtils.marshaltoW3CDomDocument(ftn, Context.jc, "http://schemas.openxmlformats.org/wordprocessingml/2006/main", "footnote", CTFtnEdn.class);
if (log.isDebugEnabled())
log.debug("Footnote " + id + ": " + XmlUtils.w3CDomNodeToString(d));
return d;
}
public static int getNextEndnoteNumber(AbstractWmlConversionContext context) {
return context.getNextEndnoteNumber();
}
public static void setCurrentPart(AbstractWmlConversionContext context, Part currentPart) {
context.setCurrentPart(currentPart);
}
public static Part getCurrentPart(AbstractWmlConversionContext context) {
return context.getCurrentPart();
}
public static void setCurrentPartMainDocument(AbstractWmlConversionContext context) {
context.setCurrentPartMainDocument();
}
public static void setCurrentPartDefaultHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
context.setCurrentPart(currentSection.getHeaderFooterPolicy().getDefaultHeader());
}
public static void setCurrentPartDefaultFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
context.setCurrentPart(currentSection.getHeaderFooterPolicy().getDefaultFooter());
}
public static void moveNextSection(AbstractWmlConversionContext context) {
context.getSections().next();
}
public static boolean hasDefaultHeaderOrFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getDefaultHeader() != null || currentSection.getHeaderFooterPolicy().getDefaultFooter() != null);
}
public static boolean hasFirstHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getFirstHeader() != null);
}
public static boolean hasEvenHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getEvenHeader() != null);
}
public static boolean hasDefaultHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getDefaultHeader() != null);
}
public static boolean hasFirstFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getFirstFooter() != null);
}
public static boolean hasEvenFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getEvenFooter() != null);
}
public static boolean hasDefaultFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
return (currentSection.getHeaderFooterPolicy().getDefaultFooter() != null);
}
public static Node getFirstHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
Hdr hdr = currentSection.getHeaderFooterPolicy().getFirstHeader().getJaxbElement();
return XmlUtils.marshaltoW3CDomDocument(hdr);
}
public static Node getFirstFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
Ftr ftr = currentSection.getHeaderFooterPolicy().getFirstFooter().getJaxbElement();
return XmlUtils.marshaltoW3CDomDocument(ftr);
}
public static Node getEvenHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
Hdr hdr = currentSection.getHeaderFooterPolicy().getEvenHeader().getJaxbElement();
return XmlUtils.marshaltoW3CDomDocument(hdr);
}
public static Node getEvenFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
Ftr ftr = currentSection.getHeaderFooterPolicy().getEvenFooter().getJaxbElement();
return XmlUtils.marshaltoW3CDomDocument(ftr);
}
public static Node getDefaultHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
Hdr hdr = currentSection.getHeaderFooterPolicy().getDefaultHeader().getJaxbElement();
return XmlUtils.marshaltoW3CDomDocument(hdr);
}
public static Node getDefaultFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
Ftr ftr = currentSection.getHeaderFooterPolicy().getDefaultFooter().getJaxbElement();
return XmlUtils.marshaltoW3CDomDocument(ftr);
}
public static void inFirstHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
setCurrentPart(context, currentSection.getHeaderFooterPolicy().getFirstHeader());
}
public static void inEvenHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
setCurrentPart(context, currentSection.getHeaderFooterPolicy().getEvenHeader());
}
public static void inDefaultHeader(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
setCurrentPart(context, currentSection.getHeaderFooterPolicy().getDefaultHeader());
}
public static void inFirstFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
setCurrentPart(context, currentSection.getHeaderFooterPolicy().getFirstFooter());
}
public static void inEvenFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
setCurrentPart(context, currentSection.getHeaderFooterPolicy().getEvenFooter());
}
public static void inDefaultFooter(AbstractWmlConversionContext context) {
ConversionSectionWrapper currentSection = context.getSections().getCurrentSection();
setCurrentPart(context, currentSection.getHeaderFooterPolicy().getDefaultFooter());
}
public static boolean hasEndnotesPart(AbstractWmlConversionContext context) {
return context.getWmlPackage().getMainDocumentPart().hasEndnotesPart();
}
public static Node getEndnotes(AbstractWmlConversionContext context) {
return XmlUtils.marshaltoW3CDomDocument(context.getWmlPackage().getMainDocumentPart().getEndNotesPart().getJaxbElement());
}
public static boolean hasFootnotesPart(AbstractWmlConversionContext context) {
return context.getWmlPackage().getMainDocumentPart().hasFootnotesPart();
}
public static Node getFootnotes(AbstractWmlConversionContext context) {
return XmlUtils.marshaltoW3CDomDocument(context.getWmlPackage().getMainDocumentPart().getFootnotesPart().getJaxbElement());
}
public static void updateComplexFieldDefinition(AbstractWmlConversionContext context, NodeIterator fldCharNodeIt) {
FldChar field = null;
Node node = fldCharNodeIt.nextNode();
try {
field = (FldChar)XmlUtils.unmarshal(node, Context.jc, FldChar.class);
} catch (JAXBException e1) {
e1.printStackTrace();
}
STFldCharType fieldCharType = field.getFldCharType();
if (fieldCharType == null) {
if (log.isDebugEnabled())
log.debug("Ignoring unrecognised: " + XmlUtils.w3CDomNodeToString(node));
} else {
context.updateComplexFieldDefinition(fieldCharType);
}
}
public static boolean isInComplexFieldDefinition(AbstractWmlConversionContext context) {
return context.isInComplexFieldDefinition();
}
public static DocumentFragment notImplemented(AbstractConversionContext context, NodeIterator nodes, String message) {
return context.getMessageWriter().notImplemented(context, nodes, message);
}
public static DocumentFragment message(AbstractConversionContext context, String message) {
return context.getMessageWriter().message(context, message);
}
public static boolean isLoggingEnabled(AbstractConversionContext context) {
return context.getLog().isDebugEnabled();
}
public static void logDebug(AbstractConversionContext context, String message) {
context.getLog().debug(message);
}
public static void logInfo(AbstractConversionContext context, String message) {
context.getLog().info(message);
}
public static void logWarn(AbstractConversionContext context, String message) {
context.getLog().warn(message);
}
}

View file

@ -0,0 +1,125 @@
package org.docx4j.convert.out.common.preprocess;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.utils.AbstractTraversalUtilVisitorCallback;
import org.docx4j.wml.CTBookmark;
import org.docx4j.wml.CTMarkupRange;
import org.docx4j.wml.P;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BookmarkMover {
protected static Logger log = LoggerFactory.getLogger(BookmarkMover.class);
public static void process(WordprocessingMLPackage wmlPackage) {
TraversalUtil.visit(wmlPackage, false, new BookmarkMoverVisitor());
}
protected static class BookmarkMoverVisitor extends AbstractTraversalUtilVisitorCallback {
protected static final QName QNAME_BOOKMARK_START = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "bookmarkStart");
protected static final QName QNAME_BOOKMARK_END = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "bookmarkEnd");
protected List<Object> bookmarksStartToMove = new ArrayList();
protected Set<BigInteger> bookmarksEndToRemove = new TreeSet<BigInteger>();
protected P currentParagraph = null;
public void walkJAXBElements(Object parent) {
List<Object> srcChildren = getChildren(XmlUtils.unwrap(parent));
List<Object> destChildren = null;
Object child = null;
if (srcChildren != null && !srcChildren.isEmpty()) {
destChildren = new ArrayList(srcChildren.size());
for (int c = 0; c < srcChildren.size(); c++) {
child = srcChildren.get(c);
if (isBookmarkStart(child)) {
if (this.currentParagraph == null) {
appendBookmarksToMove(child);
} else {
destChildren.add(child);
}
} else if (isBookmarkEnd(child)) {
if (!removeBookmarkEnd(child))
destChildren.add(child);
} else {
destChildren.add(child);
if (isParagraph(child)) {
try {
this.currentParagraph = (P)child;
walkJAXBElements(child);
moveBookmarks(child);
this.currentParagraph = null;
} finally {
this.currentParagraph = null;
}
} else {
walkJAXBElements(child);
}
}
}
if (destChildren.size() != srcChildren.size()) {
srcChildren.clear();
srcChildren.addAll(destChildren);
}
}
}
private boolean isBookmarkStart(Object child) {
return (child instanceof JAXBElement && ((JAXBElement)child).getName().equals(QNAME_BOOKMARK_START));
}
private void appendBookmarksToMove(Object child) {
CTBookmark bm = (CTBookmark)XmlUtils.unwrap(child);
JAXBElement<CTMarkupRange> jaxbBmEnd = null;
CTMarkupRange bmEnd = null;
this.bookmarksStartToMove.add(child);
bmEnd = Context.getWmlObjectFactory().createCTMarkupRange();
bmEnd.setId(bm.getId());
jaxbBmEnd = Context.getWmlObjectFactory().createPBookmarkEnd(bmEnd);
this.bookmarksStartToMove.add(jaxbBmEnd);
this.bookmarksEndToRemove.add(bm.getId());
}
private boolean isBookmarkEnd(Object child) {
return (child instanceof JAXBElement && ((JAXBElement)child).getName().equals(QNAME_BOOKMARK_END));
}
private boolean removeBookmarkEnd(Object child) {
CTMarkupRange bmEnd = (CTMarkupRange)XmlUtils.unwrap(child);
if (bmEnd.getId() == null)
return true;
return this.bookmarksEndToRemove.remove(bmEnd.getId());
}
private boolean isParagraph(Object child) {
return child instanceof P;
}
private void moveBookmarks(Object child) {
P p = null;
List<Object> content = null;
if (!this.bookmarksStartToMove.isEmpty()) {
p = (P)XmlUtils.unwrap(child);
content = p.getContent();
content.addAll(0, this.bookmarksStartToMove);
this.bookmarksStartToMove.clear();
}
}
protected List<Object> apply(Object child, Object parent, List children) {
return null;
}
}
}

View file

@ -0,0 +1,280 @@
package org.docx4j.convert.out.common.preprocess;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.CommentsPart;
import org.docx4j.openpackaging.parts.WordprocessingML.EndnotesPart;
import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart;
import org.docx4j.openpackaging.parts.WordprocessingML.FootnotesPart;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.CTBorder;
import org.docx4j.wml.CTShd;
import org.docx4j.wml.Comments;
import org.docx4j.wml.P;
import org.docx4j.wml.PPrBase;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.docx4j.wml.SdtBlock;
import org.docx4j.wml.SdtContentBlock;
import org.docx4j.wml.SdtPr;
import org.docx4j.wml.Tag;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Tc;
import org.docx4j.wml.Tr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Containerization {
private static Logger log = LoggerFactory.getLogger(Containerization.class);
public static final String TAG_SHADING = "XSLT_Shd";
public static final String TAG_BORDERS = "XSLT_PBdr";
public static final String TAG_RPR = "XSLT_RPr";
public static void process(WordprocessingMLPackage wmlPackage) {
MainDocumentPart mainDocument = null;
RelationshipsPart relPart = null;
List<Relationship> relList = null;
List<Object> elementList = null;
mainDocument = wmlPackage.getMainDocumentPart();
groupAdjacentBorders(mainDocument.getJaxbElement().getBody().getContent());
relPart = mainDocument.getRelationshipsPart();
relList = relPart.getRelationships().getRelationship();
for (Relationship rs : relList) {
elementList = null;
if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header".equals(rs.getType())) {
elementList = ((HeaderPart)relPart.getPart(rs)).getJaxbElement().getContent();
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer".equals(rs.getType())) {
elementList = ((FooterPart)relPart.getPart(rs)).getJaxbElement().getContent();
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes".equals(rs.getType())) {
elementList = new ArrayList();
elementList.addAll(((EndnotesPart)relPart.getPart(rs)).getJaxbElement().getEndnote());
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes".equals(rs.getType())) {
elementList = new ArrayList();
elementList.addAll(((FootnotesPart)relPart.getPart(rs)).getJaxbElement().getFootnote());
} else if ("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments".equals(rs.getType())) {
elementList = new ArrayList();
for (Comments.Comment comment : ((CommentsPart)relPart.getPart(rs)).getJaxbElement().getComment())
elementList.addAll(comment.getEGBlockLevelElts());
}
if (elementList != null && !elementList.isEmpty())
groupAdjacentBorders(elementList);
}
}
protected static void groupAdjacentBorders(List<Object> content) {
List<Object> groupedContent = null;
groupedContent = groupBodyContent(content);
if (groupedContent != null) {
content.clear();
content.addAll(groupedContent);
}
}
private static void groupTable(Tbl table) {
List<Object> cellElts = null;
Tr tr = null;
Tc tc = null;
for (Object elemTr : table.getContent()) {
if (elemTr instanceof JAXBElement)
elemTr = ((JAXBElement)elemTr).getValue();
if (elemTr instanceof Tr) {
tr = (Tr)elemTr;
if (tr.getContent() != null)
for (Object elemCe : tr.getContent()) {
if (elemCe instanceof JAXBElement)
elemCe = ((JAXBElement)elemCe).getValue();
if (elemCe instanceof Tc) {
tc = (Tc)elemCe;
if (tc.getContent() != null) {
cellElts = groupBodyContent(tc.getContent());
if (cellElts != null) {
tc.getContent().clear();
tc.getContent().addAll(cellElts);
}
}
}
}
}
}
}
private static List<Object> groupBodyContent(List<Object> bodyElts) {
List<Object> resultElts = new ArrayList();
List<Object> paragraphElts = null;
SdtBlock sdtBorders = null;
SdtBlock sdtShading = null;
PPrBase.PBdr lastBorders = null;
PPrBase.PBdr currentBorders = null;
CTShd lastShading = null;
CTShd currentShading = null;
P paragraph = null;
for (Object o : bodyElts) {
if (o instanceof JAXBElement)
o = ((JAXBElement)o).getValue();
if (o instanceof P) {
paragraph = (P)o;
paragraphElts = groupRuns(paragraph.getContent());
paragraph.getContent().clear();
if (paragraphElts != null)
paragraph.getContent().addAll(paragraphElts);
currentBorders = null;
currentShading = null;
if (paragraph.getPPr() != null) {
currentBorders = paragraph.getPPr().getPBdr();
currentShading = paragraph.getPPr().getShd();
}
if (bordersChanged(currentBorders, lastBorders))
if (currentBorders == null) {
sdtBorders = null;
} else {
sdtBorders = createSdt("XSLT_PBdr");
resultElts.add(sdtBorders);
}
if (shadingChanged(currentShading, lastShading))
if (currentShading == null) {
sdtShading = null;
} else {
sdtShading = createSdt("XSLT_Shd");
if (sdtBorders != null) {
sdtBorders.getSdtContent().getContent().add(sdtShading);
} else {
resultElts.add(sdtShading);
}
}
} else if (o instanceof Tbl) {
groupTable((Tbl)o);
}
if (sdtShading != null) {
sdtShading.getSdtContent().getContent().add(o);
} else if (sdtBorders != null) {
sdtBorders.getSdtContent().getContent().add(o);
} else {
resultElts.add(o);
}
lastBorders = currentBorders;
lastShading = currentShading;
}
return resultElts;
}
private static List<Object> groupRuns(List<Object> paragraphElts) {
List<Object> resultElts = new ArrayList();
SdtBlock currentBlock = null;
CTBorder lastBorder = null;
CTBorder currentBorder = null;
R run = null;
for (Object o : paragraphElts) {
if (o instanceof R) {
run = (R)o;
currentBorder = null;
if (run.getRPr() != null)
currentBorder = run.getRPr().getBdr();
if (borderChanged(currentBorder, lastBorder)) {
appendRun(currentBlock, resultElts);
currentBlock = null;
if (currentBorder != null)
currentBlock = createSdt("XSLT_RPr", run.getRPr());
}
}
if (currentBlock != null) {
currentBlock.getSdtContent().getContent().add(o);
} else {
resultElts.add(o);
}
lastBorder = currentBorder;
}
appendRun(currentBlock, resultElts);
return resultElts;
}
private static void appendRun(SdtBlock currentBlock, List<Object> resultElts) {
List<Object> blkElements = null;
R run = null;
RPr blockRPr = null;
if (currentBlock != null) {
blkElements = currentBlock.getSdtContent().getContent();
if (blkElements.size() == 1) {
resultElts.add(blkElements.get(0));
} else {
resultElts.add(currentBlock);
blockRPr = findBlockRPr(currentBlock);
for (Object elem : blkElements) {
if (elem instanceof R) {
run = (R)elem;
if (run.getRPr() != null) {
run.getRPr().setBdr(null);
if (!shadingChanged(blockRPr.getShd(), run.getRPr().getShd()))
run.getRPr().setShd(null);
}
}
}
}
}
}
private static RPr findBlockRPr(SdtBlock currentBlock) {
for (Object obj : currentBlock.getSdtPr().getRPrOrAliasOrLock()) {
if (obj instanceof RPr)
return (RPr)obj;
}
return null;
}
private static SdtBlock createSdt(String tagVal) {
return createSdt(tagVal, null);
}
private static SdtBlock createSdt(String tagVal, RPr rPr) {
SdtBlock sdtBlock = Context.getWmlObjectFactory().createSdtBlock();
SdtPr sdtPr = Context.getWmlObjectFactory().createSdtPr();
sdtBlock.setSdtPr(sdtPr);
SdtContentBlock sdtContent = Context.getWmlObjectFactory().createSdtContentBlock();
sdtBlock.setSdtContent(sdtContent);
Tag tag = Context.getWmlObjectFactory().createTag();
tag.setVal(tagVal);
sdtPr.setTag(tag);
if (rPr != null)
sdtPr.getRPrOrAliasOrLock().add(XmlUtils.<RPr>deepCopy(rPr));
return sdtBlock;
}
private static boolean bordersChanged(PPrBase.PBdr currentBorders, PPrBase.PBdr lastBorders) {
if (currentBorders != lastBorders) {
if (currentBorders != null && lastBorders != null)
return (borderChanged(currentBorders.getTop(), lastBorders.getTop()) || borderChanged(currentBorders.getBottom(), lastBorders.getBottom()));
return true;
}
return false;
}
private static boolean borderChanged(CTBorder currentBorder, CTBorder lastBorder) {
if (currentBorder != lastBorder) {
if (currentBorder != null && lastBorder != null)
return !currentBorder.getVal().equals(lastBorder.getVal());
return true;
}
return false;
}
private static boolean shadingChanged(CTShd currentShading, CTShd lastShading) {
if (currentShading == null && lastShading == null)
return false;
if (currentShading == null && lastShading != null)
return true;
if (currentShading != null && lastShading == null)
return true;
if (currentShading.getFill() == null || lastShading.getFill() == null)
return true;
return !currentShading.getFill().equals(lastShading.getFill());
}
}

View file

@ -0,0 +1,65 @@
package org.docx4j.convert.out.common.preprocess;
import java.util.List;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.Body;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.SdtElement;
import org.docx4j.wml.SectPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CoverPageSectPrMover {
private static Logger log = LoggerFactory.getLogger(CoverPageSectPrMover.class);
public static void process(WordprocessingMLPackage wmlPackage) {
Body body = wmlPackage.getMainDocumentPart().getJaxbElement().getBody();
moveSectPr(body);
}
private static void moveSectPr(Body body) {
if (body == null || body.getContent().size() == 0) {
log.warn("w:document/w:body null or empty");
return;
}
Object o = body.getContent().get(0);
if (o instanceof P) {
SectPr sectPr = cutSectPr((P)o);
if (sectPr != null) {
pasteSectPr(body.getContent(), sectPr);
log.info("Moved sectPr to new P");
return;
}
} else if (o instanceof SdtElement) {
Object o2 = ((SdtElement)o).getSdtContent().getContent().get(0);
if (o2 != null && o2 instanceof P) {
SectPr sectPr = cutSectPr((P)o2);
if (sectPr != null) {
pasteSectPr(((SdtElement)o).getSdtContent().getContent(), sectPr);
log.info("Moved sectPr to new P inside content control");
return;
}
}
}
log.info("No need to move sectPr ");
}
private static SectPr cutSectPr(P p) {
if (p.getPPr() != null && p.getPPr().getSectPr() != null) {
SectPr sectPr = p.getPPr().getSectPr();
p.getPPr().setSectPr(null);
return sectPr;
}
return null;
}
private static void pasteSectPr(List<Object> contentList, SectPr sectPr) {
P p = new P();
PPr ppr = Context.getWmlObjectFactory().createPPr();
p.setPPr(ppr);
ppr.setSectPr(sectPr);
contentList.add(1, p);
}
}

View file

@ -0,0 +1,165 @@
package org.docx4j.convert.out.common.preprocess;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.utils.TraversalUtilVisitor;
import org.docx4j.wml.CTSimpleField;
import org.docx4j.wml.FldChar;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.STFldCharType;
import org.docx4j.wml.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FieldsCombiner {
private static Logger log = LoggerFactory.getLogger(FieldsCombiner.class);
protected static final CombineVisitor COMBINE_VISITOR = new CombineVisitor();
public static void process(WordprocessingMLPackage wmlPackage) {
log.info("starting");
TraversalUtil.visit(wmlPackage, false, COMBINE_VISITOR);
if (log.isDebugEnabled())
log.debug(XmlUtils.marshaltoString(wmlPackage.getMainDocumentPart().getJaxbElement(), true, true));
}
protected static class CombineVisitor extends TraversalUtilVisitor<P> {
private static final QName _RInstrText_QNAME = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "instrText");
private static final int STATE_NONE = 0;
private static final int STATE_EXPECT_BEGIN = 1;
private static final int STATE_EXPECT_INSTR = 2;
private static final int STATE_EXPECT_RESULT = 4;
public void apply(P element) {
processContent(element.getContent());
}
protected void processContent(List<Object> pContent) {
List<Object> pResult = null;
boolean haveChanges = false;
boolean inField = false;
Object item = null;
STFldCharType fldCharType = null;
int level = 0;
int state = 1;
int markIdx = 0;
List<Object> resultList = new ArrayList(2);
StringBuilder instrTextBuffer = new StringBuilder(128);
String tmpInstrText = null;
if (pContent != null && !pContent.isEmpty()) {
pResult = new ArrayList(pContent.size());
for (int i = 0; i < pContent.size(); i++) {
item = pContent.get(i);
if (item instanceof R) {
fldCharType = getFldCharType((R)item);
if (fldCharType != null) {
if (STFldCharType.BEGIN.equals(fldCharType)) {
level++;
state = 2;
if (markIdx < i) {
copyItems(pContent, markIdx, i, pResult);
instrTextBuffer.setLength(0);
resultList.clear();
}
markIdx = i;
} else if (STFldCharType.SEPARATE.equals(fldCharType)) {
state = 4;
} else if (STFldCharType.END.equals(fldCharType) &&
level > 0) {
state = 1;
if (!resultList.isEmpty() && instrTextBuffer.length() > 0) {
pResult.add(createFldSimple(instrTextBuffer.toString(), resultList));
haveChanges = true;
markIdx = i + 1;
}
instrTextBuffer.setLength(0);
resultList.clear();
level--;
}
} else {
switch (state) {
case 2:
tmpInstrText = getInstrText((R)item);
if (tmpInstrText != null)
instrTextBuffer.append(tmpInstrText);
break;
case 4:
resultList.add(item);
break;
}
}
} else if (item instanceof JAXBElement && ((JAXBElement)item).getValue() instanceof CTSimpleField) {
if (markIdx < i)
copyItems(pContent, markIdx, i, pResult);
pResult.add(item);
instrTextBuffer.setLength(0);
resultList.clear();
markIdx = i + 1;
state = 1;
} else if (item instanceof JAXBElement && ((JAXBElement)item).getValue() instanceof P.Hyperlink) {
processContent(((P.Hyperlink)((JAXBElement)item).getValue()).getContent());
}
}
if (haveChanges) {
if (markIdx < pContent.size())
copyItems(pContent, markIdx, pContent.size(), pResult);
pContent.clear();
pContent.addAll(pResult);
}
}
}
private String getInstrText(R run) {
List<Object> rContent = run.getContent();
Object item = null;
Text text = null;
for (int i = 0; i < rContent.size(); i++) {
item = rContent.get(i);
if (item instanceof JAXBElement && ((JAXBElement)item).getName().equals(_RInstrText_QNAME)) {
text = (Text)((JAXBElement)item).getValue();
break;
}
}
return (text != null) ? text.getValue() : null;
}
private Object createFldSimple(String instrText, List<Object> resultList) {
CTSimpleField fldSimple = Context.getWmlObjectFactory().createCTSimpleField();
fldSimple.setInstr(instrText);
if (resultList != null && !resultList.isEmpty())
fldSimple.getContent().addAll(resultList);
return fldSimple;
}
private void copyItems(List<Object> source, int startIdx, int endIdx, List<Object> destination) {
for (int i = startIdx; i < endIdx; i++)
destination.add(source.get(i));
}
private STFldCharType getFldCharType(R r) {
STFldCharType ret = null;
List<Object> rContent = r.getContent();
Object item = null;
if (rContent != null && !rContent.isEmpty())
for (int i = 0; i < rContent.size(); i++) {
item = XmlUtils.unwrap(rContent.get(i));
if (item instanceof FldChar) {
ret = ((FldChar)item).getFldCharType();
break;
}
}
return ret;
}
}
}

View file

@ -0,0 +1,28 @@
package org.docx4j.convert.out.common.preprocess;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.Body;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FopWorkaroundDisablePageBreakOnFirstParagraph {
private static Logger log = LoggerFactory.getLogger(FopWorkaroundDisablePageBreakOnFirstParagraph.class);
public static void process(WordprocessingMLPackage wmlPackage) {
Body body = wmlPackage.getMainDocumentPart().getJaxbElement().getBody();
if (body == null || body.getContent().size() == 0) {
log.warn("w:document/w:body null or empty");
return;
}
Object o = body.getContent().get(0);
if (o instanceof P && ((P)o).getPPr() != null) {
PPr pPr = ((P)o).getPPr();
BooleanDefaultTrue val = new BooleanDefaultTrue();
val.setVal(Boolean.FALSE);
pPr.setPageBreakBefore(val);
}
}
}

View file

@ -0,0 +1,86 @@
package org.docx4j.convert.out.common.preprocess;
import java.util.ArrayList;
import java.util.List;
import org.docx4j.jaxb.Context;
import org.docx4j.model.PropertyResolver;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.SdtElement;
public class FopWorkaroundReplacePageBreakInEachList {
private WordprocessingMLPackage wmlPackage;
public static void process(WordprocessingMLPackage wmlPackage) {
FopWorkaroundReplacePageBreakInEachList worker = new FopWorkaroundReplacePageBreakInEachList(wmlPackage);
worker.process();
}
private FopWorkaroundReplacePageBreakInEachList(WordprocessingMLPackage wmlPackage) {
this.wmlPackage = wmlPackage;
}
private PropertyResolver propertyResolver = null;
private void process() {
this.propertyResolver = this.wmlPackage.getMainDocumentPart().getPropertyResolver();
List<Object> newContent = process(this.wmlPackage.getMainDocumentPart().getContent());
this.wmlPackage.getMainDocumentPart().getJaxbElement().getBody().getContent().clear();
this.wmlPackage.getMainDocumentPart().getJaxbElement().getBody().getContent().addAll(newContent);
}
private List process(List contentIn) {
List<Object> newContent = new ArrayList();
boolean inList = false;
for (Object o : (Iterable<Object>)contentIn) {
if (o instanceof P) {
P p = (P)o;
PPr effPPr = getEffectivePPr(p);
if (isListItem(effPPr)) {
inList = true;
if (hasBreakBefore(effPPr)) {
P newP = new P();
newP.setPPr(new PPr());
newP.getPPr().setPageBreakBefore(new BooleanDefaultTrue());
newContent.add(newP);
PPr pPr = p.getPPr();
if (pPr == null) {
pPr = Context.getWmlObjectFactory().createPPr();
p.setPPr(pPr);
}
BooleanDefaultTrue val = new BooleanDefaultTrue();
val.setVal(Boolean.FALSE);
pPr.setPageBreakBefore(val);
}
}
newContent.add(o);
continue;
}
if (o instanceof SdtElement) {
newContent.add(o);
SdtElement sdt = (SdtElement)o;
List<Object> recursiveL = process(sdt.getSdtContent().getContent());
sdt.getSdtContent().getContent().clear();
sdt.getSdtContent().getContent().addAll(recursiveL);
continue;
}
newContent.add(o);
}
return newContent;
}
private PPr getEffectivePPr(P p) {
PPr pPrDirect = p.getPPr();
return this.propertyResolver.getEffectivePPr(pPrDirect);
}
private boolean isListItem(PPr pPr) {
return (pPr != null && pPr.getNumPr() != null);
}
private static boolean hasBreakBefore(PPr pPr) {
return (pPr != null && pPr.getPageBreakBefore() != null && pPr.getPageBreakBefore().isVal());
}
}

View file

@ -0,0 +1,63 @@
package org.docx4j.convert.out.common.preprocess;
import java.util.List;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.Body;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.Br;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.R;
import org.docx4j.wml.STBrType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PageBreak {
private static Logger log = LoggerFactory.getLogger(PageBreak.class);
public static void process(WordprocessingMLPackage wmlPackage) {
Body body = wmlPackage.getMainDocumentPart().getJaxbElement().getBody();
movePageBreaks(body);
}
private static void movePageBreaks(Body body) {
List<Object> elts = body.getContent();
for (Object o : elts) {
if (o instanceof P)
updateParagraph((P)o);
}
}
private static void updateParagraph(P paragraph) {
boolean containsPageBreak = checkPageBreak(paragraph.getContent());
if (containsPageBreak) {
if (paragraph.getPPr() == null)
paragraph.setPPr(new PPr());
paragraph.getPPr().setPageBreakBefore(new BooleanDefaultTrue());
}
}
private static boolean checkPageBreak(List<Object> content) {
int foundIdx = -1;
Object ce = null;
if (content != null && !content.isEmpty()) {
for (int i = 0; foundIdx == -1 && i < content.size(); i++) {
ce = content.get(i);
if (ce instanceof R) {
if (checkPageBreak(((R)ce).getContent()))
if (((R)ce).getContent() == null || ((R)ce).getContent().isEmpty()) {
foundIdx = i;
} else {
return true;
}
} else if (ce instanceof Br &&
STBrType.PAGE.equals(((Br)ce).getType())) {
foundIdx = i;
}
}
if (foundIdx > -1)
content.remove(foundIdx);
}
return (foundIdx > -1);
}
}

View file

@ -0,0 +1,117 @@
package org.docx4j.convert.out.common.preprocess;
import org.docx4j.wml.CTPageNumber;
import org.docx4j.wml.NumberFormat;
import org.docx4j.wml.SectPr;
public class PageNumberInformation {
protected String defaultNumberFormat = null;
protected boolean pagePresent = false;
protected String pageFormat = null;
protected int pageStart = -1;
protected boolean numpagesPresent = false;
protected String numpagesFormat = null;
protected boolean sectionpagesPresent = false;
protected String sectionpagesFormat = null;
public PageNumberInformation(SectPr sectPr) {
CTPageNumber pageNumber = (sectPr != null) ? sectPr.getPgNumType() : null;
NumberFormat numberFormat = null;
if (pageNumber != null) {
if (pageNumber.getFmt() != null)
this.defaultNumberFormat = pageNumber.getFmt().value();
if (pageNumber.getStart() != null)
this.pageStart = pageNumber.getStart().intValue();
}
}
public boolean isPagePresent() {
return this.pagePresent;
}
public void setPagePresent(boolean pagePresent) {
this.pagePresent = pagePresent;
}
public boolean hasPageFormat() {
return (this.pageFormat != null);
}
public String getPageFormat() {
return hasPageFormat() ? this.pageFormat : this.defaultNumberFormat;
}
public void setPageFormat(String pageFormat) {
this.pageFormat = pageFormat;
}
public boolean hasPageStart() {
return (this.pageStart != -1);
}
public int getPageStart() {
return this.pageStart;
}
public void setPageStart(int pageStart) {
this.pageStart = pageStart;
}
public boolean isNumpagesPresent() {
return this.numpagesPresent;
}
public void setNumpagesPresent(boolean numpagesPresent) {
this.numpagesPresent = numpagesPresent;
}
public boolean hasNumpagesFormat() {
return (this.numpagesFormat != null);
}
public String getNumpagesFormat() {
return hasNumpagesFormat() ? this.numpagesFormat : this.defaultNumberFormat;
}
public void setNumpagesFormat(String numpagesFormat) {
this.numpagesFormat = numpagesFormat;
}
public boolean isSectionpagesPresent() {
return this.sectionpagesPresent;
}
public void setSectionpagesPresent(boolean sectionpagesPresent) {
this.sectionpagesPresent = sectionpagesPresent;
}
public boolean hasSectionpagesFormat() {
return (this.sectionpagesFormat != null);
}
public String getSectionpagesFormat() {
return hasSectionpagesFormat() ? this.sectionpagesFormat : this.defaultNumberFormat;
}
public void setSectionpagesFormat(String sectionpagesFormat) {
this.sectionpagesFormat = sectionpagesFormat;
}
public void reset() {
this.defaultNumberFormat = null;
this.pagePresent = false;
this.pageFormat = null;
this.pageStart = -1;
this.numpagesPresent = false;
this.numpagesFormat = null;
this.sectionpagesPresent = false;
this.sectionpagesFormat = null;
}
}

View file

@ -0,0 +1,83 @@
package org.docx4j.convert.out.common.preprocess;
import javax.xml.transform.TransformerException;
import org.docx4j.TraversalUtil;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.docx4j.model.structure.HeaderFooterPolicy;
import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart;
import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart;
import org.docx4j.utils.TraversalUtilVisitor;
import org.docx4j.wml.CTSimpleField;
public class PageNumberInformationCollector {
public static PageNumberInformation process(ConversionSectionWrapper sectionWrapper, boolean dummyPageNumbering) {
PageNumberInformation ret = new PageNumberInformation(sectionWrapper.getSectPr());
FieldVisitor fldVisitor = null;
HeaderFooterPolicy headerFooterPolicy = sectionWrapper.getHeaderFooterPolicy();
if (!dummyPageNumbering) {
fldVisitor = new FieldVisitor(ret);
TraversalUtil.visit(sectionWrapper.getContent(), fldVisitor);
process(headerFooterPolicy.getFirstHeader(), fldVisitor);
process(headerFooterPolicy.getFirstFooter(), fldVisitor);
process(headerFooterPolicy.getDefaultHeader(), fldVisitor);
process(headerFooterPolicy.getDefaultFooter(), fldVisitor);
process(headerFooterPolicy.getEvenHeader(), fldVisitor);
process(headerFooterPolicy.getEvenFooter(), fldVisitor);
}
return ret;
}
protected static void process(FooterPart footer, FieldVisitor fldVisitor) {
if (footer != null && !footer.getContent().isEmpty())
TraversalUtil.visit(footer.getContent(), fldVisitor);
}
protected static void process(HeaderPart header, FieldVisitor fldVisitor) {
if (header != null && !header.getContent().isEmpty())
TraversalUtil.visit(header.getContent(), fldVisitor);
}
protected static class FieldVisitor extends TraversalUtilVisitor<CTSimpleField> {
private static final Object PAGE_FIELD_TYPE = "PAGE";
private static final Object NUMPAGES_FIELD_TYPE = "NUMPAGES";
private static final Object SECTIONPAGES_FIELD_TYPE = "SECTIONPAGES";
protected PageNumberInformation results = null;
protected FldSimpleModel fldSimpleModel = new FldSimpleModel();
public FieldVisitor(PageNumberInformation results) {
this.results = results;
}
public void apply(CTSimpleField element) {
String instr = element.getInstr();
String fieldType = FormattingSwitchHelper.getFldSimpleName(instr);
if (PAGE_FIELD_TYPE.equals(fieldType)) {
this.results.setPagePresent(true);
this.results.setPageFormat(extractFormat(instr));
} else if (NUMPAGES_FIELD_TYPE.equals(fieldType)) {
this.results.setNumpagesPresent(true);
this.results.setNumpagesFormat(extractFormat(instr));
} else if (SECTIONPAGES_FIELD_TYPE.equals(fieldType)) {
this.results.setSectionpagesPresent(true);
this.results.setSectionpagesFormat(extractFormat(instr));
}
}
protected String extractFormat(String instr) {
String ret = null;
try {
this.fldSimpleModel.build(instr);
return FormattingSwitchHelper.findFirstSwitchValue("\\*", this.fldSimpleModel.getFldParameters(), true);
} catch (TransformerException e) {
ret = null;
return ret;
}
}
}
}

View file

@ -0,0 +1,294 @@
package org.docx4j.convert.out.common.preprocess;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.model.PropertyResolver;
import org.docx4j.model.styles.StyleUtil;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart;
import org.docx4j.wml.CTCompatSetting;
import org.docx4j.wml.HpsMeasure;
import org.docx4j.wml.Jc;
import org.docx4j.wml.JcEnumeration;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.PPrBase;
import org.docx4j.wml.RPr;
import org.docx4j.wml.SdtBlock;
import org.docx4j.wml.Style;
import org.docx4j.wml.Styles;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.TblPr;
import org.jvnet.jaxb2_commons.ppp.Child;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ParagraphStylesInTableFix {
protected static Logger log = LoggerFactory.getLogger(ParagraphStylesInTableFix.class);
private static final CTCompatSetting defaultSetting = Context.getWmlObjectFactory().createCTCompatSetting();
static {
defaultSetting.setVal("0");
}
public static void process(WordprocessingMLPackage wmlPackage) {
Throwable t = new Throwable();
StackTraceElement[] trace = t.getStackTrace();
for (int i = 0; i < trace.length; i++) {
if (trace[i].getClassName().contains("FOPAreaTreeHelper"))
return;
}
StyleRenamer styleRenamer = new StyleRenamer();
try {
DocumentSettingsPart dsp = wmlPackage.getMainDocumentPart().getDocumentSettingsPart();
if (dsp == null) {
dsp = new DocumentSettingsPart();
wmlPackage.getMainDocumentPart().addTargetPart(dsp);
dsp.setContents(Context.getWmlObjectFactory().createCTSettings());
} else {
styleRenamer.overrideTableStyleFontSizeAndJustification = dsp.getWordCompatSetting("overrideTableStyleFontSizeAndJustification");
if (styleRenamer.overrideTableStyleFontSizeAndJustification == null)
styleRenamer.overrideTableStyleFontSizeAndJustification = defaultSetting;
}
dsp.setWordCompatSetting("overrideTableStyleFontSizeAndJustification", "1");
} catch (Docx4JException e) {
log.error(e.getMessage(), (Throwable)e);
}
try {
styleRenamer.setDefaultParagraphStyle(wmlPackage.getMainDocumentPart().getStyleDefinitionsPart().getDefaultParagraphStyle().getStyleId());
} catch (NullPointerException npe) {
log.warn("No default paragraph style!!");
}
Style defaultTableStyle = wmlPackage.getMainDocumentPart().getStyleDefinitionsPart().getDefaultTableStyle();
if (defaultTableStyle != null)
styleRenamer.setDefaultTableStyle(defaultTableStyle);
Styles styles = wmlPackage.getMainDocumentPart().getStyleDefinitionsPart().getJaxbElement();
styleRenamer.propertyResolver = wmlPackage.getMainDocumentPart().getPropertyResolver();
styleRenamer.setStyles(styles);
try {
new TraversalUtil(wmlPackage.getMainDocumentPart().getContents(), styleRenamer);
} catch (Docx4JException e) {
log.error(e.getMessage(), (Throwable)e);
}
}
public static class StyleRenamer extends TraversalUtil.CallbackImpl {
protected static Logger log = LoggerFactory.getLogger(StyleRenamer.class);
CTCompatSetting overrideTableStyleFontSizeAndJustification = ParagraphStylesInTableFix.defaultSetting;
private PropertyResolver propertyResolver;
private String defaultParagraphStyle;
private Style defaultTableStyle;
public void setDefaultParagraphStyle(String defaultParagraphStyle) {
log.debug(defaultParagraphStyle);
this.defaultParagraphStyle = defaultParagraphStyle;
}
public void setDefaultTableStyle(Style defaultTableStyle) {
this.defaultTableStyle = defaultTableStyle;
}
private LinkedList<Tbl> tblStack = new LinkedList<Tbl>();
private Map<String, Style> allStyles = null;
public void setStyles(Styles newStyles) {
this.allStyles = new HashMap<String, Style>();
for (Style s : newStyles.getStyle())
this.allStyles.put(s.getStyleId(), s);
}
private Set<String> cellPStyles = new HashSet<String>();
private boolean isFalse(CTCompatSetting overrideTableStyleFontSizeAndJustification) {
return (overrideTableStyleFontSizeAndJustification.getVal().equals("0") || overrideTableStyleFontSizeAndJustification.getVal().toLowerCase().equals("false") || overrideTableStyleFontSizeAndJustification.getVal().toLowerCase().equals("no"));
}
private String getCellPStyle(String styleVal, boolean pStyleIsDefault) {
Style expressStyle = this.allStyles.get(styleVal);
Jc expressStyleJc = (expressStyle.getPPr() == null) ? null : expressStyle.getPPr().getJc();
HpsMeasure expressStyleFontSize = null;
if (expressStyle.getRPr() != null)
expressStyleFontSize = expressStyle.getRPr().getSz();
PPr effectivePPr = this.propertyResolver.getEffectivePPr(styleVal);
Jc effectiveJc = effectivePPr.getJc();
RPr effectiveRPr = this.propertyResolver.getEffectiveRPr(styleVal);
HpsMeasure effectiveFontSize = null;
if (effectiveRPr != null)
effectiveFontSize = effectiveRPr.getSz();
String tableStyle = null;
TblPr tblPr = this.tblStack.peek().getTblPr();
if (tblPr != null && tblPr.getTblStyle() != null) {
tableStyle = tblPr.getTblStyle().getVal();
} else {
if (this.defaultTableStyle == null) {
log.warn("No default table style defined in docx Style Definitions part");
return null;
}
if (this.defaultTableStyle.getName() != null && this.defaultTableStyle.getName().getVal() != null && this.defaultTableStyle.getName().getVal().equals("Normal Table")) {
log.debug("Ignoring style with name 'Normal Table' (mimicking Word)");
return null;
}
tableStyle = this.defaultTableStyle.getStyleId();
if (tableStyle == null) {
log.error("Default table style has no ID!");
log.error(XmlUtils.marshaltoString(tableStyle));
return null;
}
}
String resultStyleID = styleVal + "-" + tableStyle;
if (!tableStyle.endsWith("-BR"))
resultStyleID = resultStyleID + "-BR";
if (this.cellPStyles.contains(resultStyleID))
return resultStyleID;
List<Style> hierarchy = new ArrayList<Style>();
Style basedOn = null;
String currentStyle = styleVal;
do {
Style thisStyle = this.allStyles.get(currentStyle);
hierarchy.add(thisStyle);
if (thisStyle.getBasedOn() != null) {
currentStyle = thisStyle.getBasedOn().getVal();
} else {
currentStyle = null;
}
} while (currentStyle != null);
Style newStyle = Context.getWmlObjectFactory().createStyle();
newStyle.setType("paragraph");
Style styleToApply = hierarchy.get(hierarchy.size() - 1);
log.debug("DocDefault");
log.debug(XmlUtils.marshaltoString(styleToApply, true, true));
StyleUtil.apply(styleToApply, newStyle);
log.debug("Result");
log.debug(XmlUtils.marshaltoString(newStyle, true, true));
Style tableStyleContrib = null;
List<Style> tblStyles = new ArrayList<Style>();
if (tableStyle != null) {
currentStyle = tableStyle;
do {
log.debug(currentStyle);
Style thisStyle = this.allStyles.get(currentStyle);
if (thisStyle.getName().getVal().equals("Normal Table"))
break;
tblStyles.add(thisStyle);
if (thisStyle.getBasedOn() != null) {
currentStyle = thisStyle.getBasedOn().getVal();
} else {
currentStyle = null;
}
} while (currentStyle != null);
for (int j = tblStyles.size() - 1; j >= 0; j--) {
styleToApply = tblStyles.get(j);
log.debug("Applying " + styleToApply.getStyleId() + "\n" + XmlUtils.marshaltoString(styleToApply, true, true));
tableStyleContrib = StyleUtil.apply(styleToApply, tableStyleContrib);
log.debug(XmlUtils.marshaltoString(tableStyleContrib, true, true));
}
}
if (tableStyleContrib == null)
tableStyleContrib = Context.getWmlObjectFactory().createStyle();
Jc tableStyleJc = (tableStyleContrib.getPPr() == null) ? null : tableStyleContrib.getPPr().getJc();
HpsMeasure tableStyleFontSize = null;
if (tableStyleContrib.getRPr() != null)
tableStyleFontSize = tableStyleContrib.getRPr().getSz();
newStyle.setPPr(StyleUtil.apply(tableStyleContrib.getPPr(), newStyle.getPPr()));
newStyle.setRPr(StyleUtil.apply(tableStyleContrib.getRPr(), newStyle.getRPr()));
log.debug(XmlUtils.marshaltoString(newStyle, true, true));
for (int i = hierarchy.size() - 2; i >= 0; i--) {
styleToApply = hierarchy.get(i);
log.debug("Applying " + styleToApply.getStyleId() + "\n" + XmlUtils.marshaltoString(styleToApply, true, true));
StyleUtil.apply(styleToApply, newStyle);
log.debug("Result: \n" + XmlUtils.marshaltoString(newStyle, true, true));
}
if (isFalse(this.overrideTableStyleFontSizeAndJustification)) {
log.info("giving TableStyleFontSizeAndJustification primacy, as per this docx w:compatSetting");
if (styleVal.equals(this.defaultParagraphStyle) || expressStyleFontSize == null)
if (tableStyleFontSize != null)
if (effectiveFontSize != null && effectiveFontSize.getVal().intValue() == 24)
newStyle.getRPr().setSz(tableStyleFontSize);
if (styleVal.equals(this.defaultParagraphStyle) || expressStyleJc == null)
if (tableStyleJc != null)
if (effectiveJc != null && effectiveJc.getVal().equals(JcEnumeration.LEFT))
newStyle.getPPr().setJc(tableStyleJc);
}
Style.Name name = Context.getWmlObjectFactory().createStyleName();
name.setVal(resultStyleID);
newStyle.setName(name);
newStyle.setStyleId(resultStyleID);
this.cellPStyles.add(resultStyleID);
this.propertyResolver.activateStyle(newStyle);
log.debug(XmlUtils.marshaltoString(newStyle, true, true));
return resultStyleID;
}
public List<Object> apply(Object o) {
if (o instanceof P) {
P p = (P)o;
if (p.getPPr() == null)
p.setPPr(Context.getWmlObjectFactory().createPPr());
if (p.getPPr().getPStyle() == null) {
String newStyle = this.defaultParagraphStyle;
p.getPPr().setPStyle(Context.getWmlObjectFactory().createPPrBasePStyle());
if (this.tblStack.size() == 0) {
p.getPPr().getPStyle().setVal(newStyle);
} else {
String resultStyle = getCellPStyle(newStyle, true);
if (resultStyle == null) {
p.getPPr().getPStyle().setVal(newStyle);
} else {
p.getPPr().getPStyle().setVal(resultStyle);
}
}
} else {
PPrBase.PStyle pstyle = p.getPPr().getPStyle();
String styleVal = pstyle.getVal();
if (styleVal != null &&
this.tblStack.size() > 0) {
log.debug("Fixing " + pstyle.getVal());
String newStyle = getCellPStyle(styleVal, styleVal.equals(this.defaultParagraphStyle));
if (newStyle == null) {
log.debug("getCellPStyle returned null, so leave as is");
} else {
p.getPPr().getPStyle().setVal(newStyle);
}
}
}
}
return null;
}
public void walkJAXBElements(Object parent) {
List<Object> children = getChildren(parent);
if (children != null)
for (Object o : children) {
o = XmlUtils.unwrap(o);
if (o instanceof Child)
if (parent instanceof SdtBlock) {
((Child)o).setParent(((SdtBlock)parent).getSdtContent());
} else {
((Child)o).setParent(parent);
}
apply(o);
if (o instanceof Tbl)
this.tblStack.push((Tbl)o);
if (shouldTraverse(o))
walkJAXBElements(o);
if (o instanceof Tbl)
this.tblStack.pop();
}
}
}
}

View file

@ -0,0 +1,164 @@
package org.docx4j.convert.out.common.preprocess;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Set;
import org.docx4j.XmlUtils;
import org.docx4j.model.datastorage.CustomXmlDataStorage;
import org.docx4j.openpackaging.Base;
import org.docx4j.openpackaging.contenttype.ContentType;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart;
import org.docx4j.openpackaging.parts.JaxbXmlPart;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart;
import org.docx4j.openpackaging.parts.XmlPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.relationships.Relationships;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
public class PartialDeepCopy {
protected static Logger log = LoggerFactory.getLogger(PartialDeepCopy.class);
public static OpcPackage process(OpcPackage opcPackage, Set<String> relationshipTypes) throws Docx4JException {
OpcPackage ret = null;
RelationshipsPart relPart = null;
if (opcPackage != null)
if (relationshipTypes != null && relationshipTypes.isEmpty()) {
ret = opcPackage;
} else {
ret = createPackage(opcPackage);
if (ret == null)
log.error("createPackage returned null!");
deepCopyRelationships(ret, opcPackage, ret, relationshipTypes);
if (opcPackage instanceof WordprocessingMLPackage)
try {
((WordprocessingMLPackage)ret).setFontMapper(((WordprocessingMLPackage)opcPackage).getFontMapper(), false);
} catch (Exception e) {
log.error(e.getMessage(), (Throwable)e);
throw new Docx4JException("Error setting font mapper on copy", e);
}
}
return ret;
}
protected static OpcPackage createPackage(OpcPackage opcPackage) throws Docx4JException {
OpcPackage ret = null;
try {
ret = (OpcPackage)opcPackage.getClass().newInstance();
} catch (InstantiationException e) {
throw new Docx4JException("InstantiationException duplicating package", e);
} catch (IllegalAccessException e) {
throw new Docx4JException("IllegalAccessException duplicating package", e);
}
ret.setContentType(new ContentType(opcPackage.getContentType()));
ret.setPartName(opcPackage.getPartName());
ret.setContentTypeManager(opcPackage.getContentTypeManager());
ret.getCustomXmlDataStorageParts().putAll(opcPackage.getCustomXmlDataStorageParts());
ret.setPartShortcut(opcPackage.getDocPropsCorePart(), "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties");
ret.setPartShortcut(opcPackage.getDocPropsCustomPart(), "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties");
ret.setPartShortcut(opcPackage.getDocPropsExtendedPart(), "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties");
ret.getExternalResources().putAll(opcPackage.getExternalResources());
ret.setSourcePartStore(opcPackage.getSourcePartStore());
return ret;
}
protected static void deepCopyRelationships(OpcPackage opcPackage, Base sourcePart, Base targetPart, Set<String> relationshipTypes) throws Docx4JException {
RelationshipsPart sourceRelationshipsPart = sourcePart.getRelationshipsPart(false);
Relationships sourceRelationships = (sourceRelationshipsPart != null) ? sourceRelationshipsPart.getRelationships() : null;
List<Relationship> sourceRelationshipList = (sourceRelationships != null) ? sourceRelationships.getRelationship() : null;
RelationshipsPart targetRelationshipsPart = null;
Relationships targetRelationships = null;
Relationship sourceRelationship = null;
Relationship targetRelationship = null;
Part sourceChild = null;
Part targetChild = null;
if (sourceRelationshipList != null && !sourceRelationshipList.isEmpty()) {
targetRelationshipsPart = targetPart.getRelationshipsPart();
targetRelationships = targetRelationshipsPart.getRelationships();
for (int i = 0; i < sourceRelationshipList.size(); i++) {
sourceRelationship = sourceRelationshipList.get(i);
targetRelationships.getRelationship().add(sourceRelationship);
if (sourceRelationship.getTargetMode() == null || !"external".equals(sourceRelationship.getTargetMode().toLowerCase())) {
sourceChild = sourceRelationshipsPart.getPart(sourceRelationship);
targetChild = deepCopyPart(opcPackage, targetPart, sourceChild, relationshipTypes);
if (sourceChild != targetChild)
deepCopyRelationships(opcPackage, sourceChild, targetChild, relationshipTypes);
}
}
}
}
protected static Part deepCopyPart(OpcPackage opcPackage, Base targetParent, Part sourcePart, Set<String> relationshipTypes) throws Docx4JException {
Part ret = opcPackage.getParts().get(sourcePart.getPartName());
if (ret == null) {
ret = copyPart(sourcePart, opcPackage, (relationshipTypes == null || relationshipTypes.contains(sourcePart.getRelationshipType())));
opcPackage.getParts().put(ret);
targetParent.setPartShortcut(ret, ret.getRelationshipType());
}
return ret;
}
protected static Part copyPart(Part part, OpcPackage targetPackage, boolean deepCopy) throws Docx4JException {
Part ret = null;
try {
ret = part.getClass().getConstructor(PartName.class).newInstance(part.getPartName());
} catch (Exception e) {
throw new Docx4JException("Error cloning part of class " + part.getClass().getName(), e);
}
ret.setRelationshipType(part.getRelationshipType());
ret.setContentType(new ContentType(part.getContentType()));
if (targetPackage != null)
ret.setPackage(targetPackage);
if (deepCopy) {
deepCopyContent(part, ret);
} else {
shallowCopyContent(part, ret);
}
return ret;
}
protected static void deepCopyContent(Part source, Part destination) throws Docx4JException {
if (source instanceof BinaryPart) {
byte[] byteData = new byte[((BinaryPart)source).getBuffer().limit()];
((BinaryPart)source).getBuffer().get(byteData);
((BinaryPart)destination).setBinaryData(ByteBuffer.wrap(byteData));
} else if (source instanceof JaxbXmlPart) {
((JaxbXmlPart)destination).setJaxbElement(XmlUtils.deepCopy(((JaxbXmlPart)source).getJaxbElement(), ((JaxbXmlPart)source).getJAXBContext()));
((JaxbXmlPart)destination).setJAXBContext(((JaxbXmlPart)source).getJAXBContext());
if (log.isDebugEnabled() && source instanceof org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart) {
log.debug("source: " + ((JaxbXmlPart)source).getXML());
log.debug("destination: " + ((JaxbXmlPart)destination).getXML());
}
} else if (source instanceof CustomXmlDataStoragePart) {
CustomXmlDataStorage dataStorage = ((CustomXmlDataStoragePart)source).getData().factory();
dataStorage.setDocument((Document)((CustomXmlDataStoragePart)source).getData().getDocument().cloneNode(true));
((CustomXmlDataStoragePart)destination).setData(dataStorage);
} else if (source instanceof XmlPart) {
((XmlPart)destination).setDocument((Document)((XmlPart)source).getDocument().cloneNode(true));
} else {
throw new IllegalArgumentException("Dont know how to handle a part of type " + source.getClass().getName());
}
}
protected static void shallowCopyContent(Part source, Part destination) throws Docx4JException {
if (source instanceof BinaryPart) {
((BinaryPart)destination).setBinaryData(((BinaryPart)source).getBuffer());
} else if (source instanceof JaxbXmlPart) {
((JaxbXmlPart)destination).setJaxbElement(((JaxbXmlPart)source).getJaxbElement());
((JaxbXmlPart)destination).setJAXBContext(((JaxbXmlPart)source).getJAXBContext());
} else if (source instanceof CustomXmlDataStoragePart) {
((CustomXmlDataStoragePart)destination).setData(((CustomXmlDataStoragePart)source).getData());
} else if (source instanceof XmlPart) {
((XmlPart)destination).setDocument(((XmlPart)source).getDocument());
} else {
throw new IllegalArgumentException("Dont know how to handle a part of type " + source.getClass().getName());
}
}
}

View file

@ -0,0 +1,206 @@
package org.docx4j.convert.out.common.wrappers;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.ConversionSectionWrappers;
import org.docx4j.convert.out.common.preprocess.PageNumberInformation;
import org.docx4j.convert.out.common.preprocess.PageNumberInformationCollector;
import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.HeaderFooterPolicy;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.Document;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.STPageOrientation;
import org.docx4j.wml.SdtBlock;
import org.docx4j.wml.SectPr;
import org.jvnet.jaxb2_commons.ppp.Child;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConversionSectionWrapperFactory {
protected static Logger log = LoggerFactory.getLogger(ConversionSectionWrapperFactory.class);
protected static class SdtBlockFinder extends TraversalUtil.CallbackImpl {
List<SdtBlock> sdtBlocks = new ArrayList<SdtBlock>();
LinkedList<SdtBlock> ll = new LinkedList<SdtBlock>();
public List<Object> apply(Object o) {
if (o instanceof P && ((P)o).getPPr() != null && ((P)o).getPPr().getSectPr() != null)
for (SdtBlock sdt : this.ll) {
if (!this.sdtBlocks.contains(sdt))
this.sdtBlocks.add(sdt);
}
return null;
}
public void walkJAXBElements(Object parent) {
List<Object> children = getChildren(parent);
if (children != null)
for (Object o : children) {
o = XmlUtils.unwrap(o);
if (o instanceof Child)
if (parent instanceof SdtBlock) {
((Child)o).setParent(((SdtBlock)parent).getSdtContent().getContent());
} else {
((Child)o).setParent(parent);
}
apply(o);
if (o instanceof SdtBlock)
this.ll.addLast((SdtBlock)o);
if (shouldTraverse(o))
walkJAXBElements(o);
if (o instanceof SdtBlock)
this.ll.removeLast();
}
}
}
public static ConversionSectionWrappers process(WordprocessingMLPackage wmlPackage, boolean dummySections, boolean dummyPageNumbering) throws Docx4JException {
List<ConversionSectionWrapper> conversionSections = null;
Document document = wmlPackage.getMainDocumentPart().getContents();
RelationshipsPart rels = wmlPackage.getMainDocumentPart().getRelationshipsPart();
BooleanDefaultTrue evenAndOddHeaders = null;
if (wmlPackage.getMainDocumentPart().getDocumentSettingsPart() != null && wmlPackage.getMainDocumentPart().getDocumentSettingsPart().getContents() != null)
evenAndOddHeaders = wmlPackage.getMainDocumentPart().getDocumentSettingsPart().getContents().getEvenAndOddHeaders();
if (dummySections) {
conversionSections = processDummy(wmlPackage, document, rels, evenAndOddHeaders, dummyPageNumbering);
} else {
conversionSections = processComplete(wmlPackage, document, rels, evenAndOddHeaders, dummyPageNumbering);
}
return new ConversionSectionWrappers(conversionSections);
}
protected static List<ConversionSectionWrapper> processDummy(WordprocessingMLPackage wmlPackage, Document document, RelationshipsPart rels, BooleanDefaultTrue evenAndOddHeaders, boolean dummyPageNumbering) {
log.debug("starting");
List<ConversionSectionWrapper> conversionSections = new ArrayList<ConversionSectionWrapper>();
ConversionSectionWrapper currentSectionWrapper = null;
HeaderFooterPolicy previousHF = new HeaderFooterPolicy(document.getBody().getSectPr(), null, rels, evenAndOddHeaders);
currentSectionWrapper = createSectionWrapper(document.getBody().getSectPr(), previousHF, rels, evenAndOddHeaders, 1, document.getBody().getContent(), dummyPageNumbering);
conversionSections.add(currentSectionWrapper);
return conversionSections;
}
protected static ConversionSectionWrapper createSectionWrapper(SectPr sectPr, HeaderFooterPolicy headerFooterPolicy, RelationshipsPart rels, BooleanDefaultTrue evenAndOddHeaders, int conversionSectionIndex, List<Object> content, boolean dummyPageNumbering) {
ConversionSectionWrapper csw = new ConversionSectionWrapper(sectPr, headerFooterPolicy, rels, evenAndOddHeaders, "s" + Integer.toString(conversionSectionIndex), content);
PageNumberInformation pageNumberInformation = PageNumberInformationCollector.process(csw, dummyPageNumbering);
csw.setPageNumberInformation(pageNumberInformation);
return csw;
}
protected static List<ConversionSectionWrapper> processComplete(WordprocessingMLPackage wmlPackage, Document document, RelationshipsPart rels, BooleanDefaultTrue evenAndOddHeaders, boolean dummyPageNumbering) {
log.debug("starting");
removeContentControls(document);
List<SectPr> sectPrs = getSectPrs(document);
List<ConversionSectionWrapper> conversionSections = new ArrayList<ConversionSectionWrapper>();
ConversionSectionWrapper currentSectionWrapper = null;
HeaderFooterPolicy previousHF = null;
int conversionSectionIndex = 0;
List<Object> sectionContent = new ArrayList();
int sectPrIndex = 0;
for (Object o : document.getBody().getContent()) {
if (o instanceof P)
if (((P)o).getPPr() != null) {
PPr ppr = ((P)o).getPPr();
if (ppr.getSectPr() != null) {
boolean ignoreThisSection = false;
SectPr followingSectPr = sectPrs.get(++sectPrIndex);
if (followingSectPr.getType() != null && followingSectPr.getType().getVal().equals("continuous")) {
log.info("following sectPr is continuous; this section wrapper must include its contents ");
ignoreThisSection = true;
}
if (ignoreThisSection) {
previousHF = new HeaderFooterPolicy(ppr.getSectPr(), previousHF, rels, evenAndOddHeaders);
SectPr.PgSz pgSzThis = ppr.getSectPr().getPgSz();
SectPr.PgSz pgSzNext = followingSectPr.getPgSz();
if (insertPageBreak(pgSzThis, pgSzNext))
ppr.setPageBreakBefore(new BooleanDefaultTrue());
} else {
currentSectionWrapper = createSectionWrapper(ppr.getSectPr(), previousHF, rels, evenAndOddHeaders, ++conversionSectionIndex, sectionContent, dummyPageNumbering);
conversionSections.add(currentSectionWrapper);
previousHF = currentSectionWrapper.getHeaderFooterPolicy();
sectionContent = new ArrayList();
}
}
}
sectionContent.add(o);
}
currentSectionWrapper = createSectionWrapper(document.getBody().getSectPr(), previousHF, rels, evenAndOddHeaders, ++conversionSectionIndex, sectionContent, dummyPageNumbering);
conversionSections.add(currentSectionWrapper);
return conversionSections;
}
private static boolean insertPageBreak(SectPr.PgSz pgSzThis, SectPr.PgSz pgSzNext) {
boolean insertPageBreak = false;
if (pgSzThis != null && pgSzNext != null) {
if (pgSzThis.getH().compareTo(pgSzNext.getH()) != 0)
insertPageBreak = true;
if (pgSzThis.getW().compareTo(pgSzNext.getW()) != 0)
insertPageBreak = true;
boolean portraitThis = true;
if (pgSzThis.getOrient() != null)
portraitThis = pgSzThis.getOrient().equals(STPageOrientation.PORTRAIT);
boolean portraitNext = true;
if (pgSzNext.getOrient() != null)
portraitNext = pgSzNext.getOrient().equals(STPageOrientation.PORTRAIT);
if (portraitThis != portraitNext)
insertPageBreak = true;
}
return insertPageBreak;
}
private static void removeContentControls(Document document) {
SdtBlockFinder sbr = new SdtBlockFinder();
new TraversalUtil(document.getContent(), sbr);
for (int i = sbr.sdtBlocks.size() - 1; i >= 0; i--) {
SdtBlock sdtBlock = sbr.sdtBlocks.get(i);
List<Object> parentList = null;
if (sdtBlock.getParent() instanceof ArrayList) {
parentList = (ArrayList)sdtBlock.getParent();
} else {
log.error("Handle " + sdtBlock.getParent().getClass().getName());
}
int index = parentList.indexOf(sdtBlock);
parentList.remove(index);
parentList.addAll(index, sdtBlock.getSdtContent().getContent());
}
}
private static List<SectPr> getSectPrs(Document document) {
List<SectPr> sectPrs = new ArrayList<SectPr>();
for (Object o : document.getBody().getContent()) {
if (o instanceof P && (
(P)o).getPPr() != null) {
PPr ppr = ((P)o).getPPr();
if (ppr.getSectPr() != null)
sectPrs.add(ppr.getSectPr());
}
}
if (document.getBody().getSectPr() != null) {
sectPrs.add(document.getBody().getSectPr());
} else {
log.debug("No body level sectPr in document");
List<Object> all = document.getBody().getContent();
Object last = all.get(all.size() - 1);
if (last instanceof P && ((P)last).getPPr() != null && ((P)last).getPPr().getSectPr() != null) {
log.debug(".. but last p contains sectPr .. move it");
SectPr thisSectPr = ((P)last).getPPr().getSectPr();
document.getBody().setSectPr(thisSectPr);
((P)last).getPPr().setSectPr(null);
sectPrs.remove(thisSectPr);
} else {
document.getBody().setSectPr(Context.getWmlObjectFactory().createSectPr());
sectPrs.add(document.getBody().getSectPr());
}
}
return sectPrs;
}
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out.common.writer;
public abstract class AbstractBookmarkStartWriter extends AbstractSimpleWriter {
public static final String WRITER_ID = "w:bookmarkStart";
protected AbstractBookmarkStartWriter() {
super("w:bookmarkStart");
}
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out.common.writer;
public abstract class AbstractBrWriter extends AbstractSimpleWriter {
public static final String WRITER_ID = "w:br";
protected AbstractBrWriter() {
super("w:br");
}
}

View file

@ -0,0 +1,224 @@
package org.docx4j.convert.out.common.writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.model.fields.FieldValueException;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.docx4j.model.fields.docproperty.DocPropertyResolver;
import org.docx4j.model.properties.Property;
import org.docx4j.model.properties.PropertyFactory;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.wml.CTSimpleField;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public abstract class AbstractFldSimpleWriter extends AbstractSimpleWriter {
public static final String WRITER_ID = "w:fldSimple";
private static Logger log = LoggerFactory.getLogger(AbstractFldSimpleWriter.class);
protected static class DateHandler implements FldSimpleStringWriterHandler {
public String getName() {
return "DATE";
}
public String toString(AbstractWmlConversionContext context, FldSimpleModel model) throws TransformerException {
return FormattingSwitchHelper.formatDate(model);
}
}
protected static class TimeHandler implements FldSimpleStringWriterHandler {
public String getName() {
return "TIME";
}
public String toString(AbstractWmlConversionContext context, FldSimpleModel model) throws TransformerException {
return FormattingSwitchHelper.formatDate(model);
}
}
protected static class PrintdateHandler implements FldSimpleStringWriterHandler {
public String getName() {
return "PRINTDATE";
}
public String toString(AbstractWmlConversionContext context, FldSimpleModel model) throws TransformerException {
return FormattingSwitchHelper.formatDate(model);
}
}
protected static class DocPropertyHandler implements FldSimpleStringWriterHandler {
public String getName() {
return "DOCPROPERTY";
}
public String toString(AbstractWmlConversionContext context, FldSimpleModel model) throws TransformerException {
DocPropertyResolver dpr = new DocPropertyResolver(context.getWmlPackage());
List<String> params = model.getFldParameters();
String key = model.getFldParameterString();
try {
String value = dpr.getValue(key).toString();
AbstractFldSimpleWriter.log.debug("= " + value);
return FormattingSwitchHelper.applyFormattingSwitch(context.getWmlPackage(), model, value);
} catch (FieldValueException e) {
if (e.getMessage().contains("No value found for DOCPROPERTY PAGES"));
throw new TransformerException(e);
} catch (Docx4JException e) {
throw new TransformerException(e);
}
}
}
protected Map<String, FldSimpleWriterHandler> handlers = new HashMap<String, FldSimpleWriterHandler>();
protected FldSimpleNodeWriterHandler defaultHandler = null;
protected String elementNs = null;
protected String elementName = null;
protected AbstractFldSimpleWriter(String elementNs, String elementName) {
super("w:fldSimple");
registerHandlers();
this.defaultHandler = createDefaultHandler();
this.elementNs = elementNs;
this.elementName = elementName;
}
protected void registerHandlers() {
registerHandler(new DateHandler());
registerHandler(new TimeHandler());
registerHandler(new PrintdateHandler());
registerHandler(new DocPropertyHandler());
}
protected void registerHandler(FldSimpleWriterHandler handler) {
this.handlers.put(handler.getName(), handler);
}
protected FldSimpleNodeWriterHandler createDefaultHandler() {
return new FldSimpleNodeWriterHandler() {
public String getName() {
return "*";
}
public Node toNode(AbstractWmlConversionContext context, FldSimpleModel model, Document doc) throws TransformerException {
return model.getContent();
}
public int getProcessType() {
return 0;
}
};
}
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node content, Writer.TransformState state, Document doc) throws TransformerException {
FldSimpleModel fldSimpleModel = new FldSimpleModel();
fldSimpleModel.build((CTSimpleField)unmarshalledNode, content);
log.debug("looking for handler for " + fldSimpleModel.getFldName());
FldSimpleWriterHandler handler = this.handlers.get(fldSimpleModel.getFldName());
FldSimpleNodeWriterHandler nodeHandler = null;
Node ret = null;
String value = null;
if (handler == null) {
handler = this.defaultHandler;
log.debug(".. using defaultHandler");
} else {
log.debug(".. got it .. " + handler.getClass().getName());
}
if (handler instanceof FldSimpleNodeWriterHandler) {
nodeHandler = (FldSimpleNodeWriterHandler)handler;
ret = nodeHandler.toNode(context, fldSimpleModel, doc);
switch (nodeHandler.getProcessType()) {
case 1:
applyStyle(context, fldSimpleModel, ret);
break;
case 2:
ret = wrap(context, ret, doc);
applyStyle(context, fldSimpleModel, ret);
break;
}
} else {
value = ((FldSimpleStringWriterHandler)handler).toString(context, fldSimpleModel);
ret = wrap(context, value, doc);
applyStyle(context, fldSimpleModel, ret);
}
return ret;
}
protected Node wrap(AbstractWmlConversionContext context, String result, Document doc) {
RPr rPr = null;
Node node = null;
if (result != null) {
node = createNode(doc);
if (result.length() > 0)
node.setTextContent(result);
}
return node;
}
protected Node wrap(AbstractWmlConversionContext context, Node node, Document doc) {
Node wrapper = null;
if (node != null) {
wrapper = createNode(doc);
wrapper.appendChild(node);
}
return wrapper;
}
protected void applyStyle(AbstractWmlConversionContext context, FldSimpleModel fldSimpleModel, Node node) {
CTSimpleField ctSimpleField = fldSimpleModel.getFldSimple();
RPr rPr = null;
if (node != null) {
rPr = getRPr(ctSimpleField.getContent());
if (rPr != null) {
List<Property> properties = PropertyFactory.createProperties(context.getWmlPackage(), rPr);
if (properties != null && !properties.isEmpty())
applyProperties(properties, node);
}
}
}
private Node createNode(Document doc) {
return (this.elementNs != null && this.elementNs.length() > 0) ? doc.createElementNS(this.elementNs, this.elementName) : doc.createElement(this.elementName);
}
private RPr getRPr(List<Object> content) {
for (int i = 0; i < content.size(); i++) {
if (content.get(i) instanceof R)
return ((R)content.get(i)).getRPr();
}
return null;
}
protected abstract void applyProperties(List<Property> paramList, Node paramNode);
public static interface FldSimpleStringWriterHandler extends FldSimpleWriterHandler {
String toString(AbstractWmlConversionContext param1AbstractWmlConversionContext, FldSimpleModel param1FldSimpleModel) throws TransformerException;
}
public static interface FldSimpleNodeWriterHandler extends FldSimpleWriterHandler {
public static final int PROCESS_NONE = 0;
public static final int PROCESS_APPLY_STYLE = 1;
public static final int PROCESS_WRAP_APPLY_STYLE = 2;
int getProcessType();
Node toNode(AbstractWmlConversionContext param1AbstractWmlConversionContext, FldSimpleModel param1FldSimpleModel, Document param1Document) throws TransformerException;
}
public static interface FldSimpleWriterHandler {
String getName();
}
}

View file

@ -0,0 +1,42 @@
package org.docx4j.convert.out.common.writer;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.model.fields.FldSimpleModel;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public abstract class AbstractHyperlinkWriter extends AbstractSimpleWriter implements AbstractFldSimpleWriter.FldSimpleNodeWriterHandler {
public static final String WRITER_ID = "w:hyperlink";
protected static final String HYPERLINK_NAME = "HYPERLINK";
protected AbstractHyperlinkWriter() {
super("w:hyperlink");
}
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node content, Writer.TransformState state, Document doc) throws TransformerException {
AbstractHyperlinkWriterModel hyperlinkModel = new AbstractHyperlinkWriterModel();
Node ret = null;
hyperlinkModel.build(context, unmarshalledNode, content);
ret = toNode(context, hyperlinkModel, doc);
return ret;
}
protected abstract Node toNode(AbstractWmlConversionContext paramAbstractWmlConversionContext, AbstractHyperlinkWriterModel paramAbstractHyperlinkWriterModel, Document paramDocument) throws TransformerException;
public String getName() {
return "HYPERLINK";
}
public int getProcessType() {
return 0;
}
public Node toNode(AbstractWmlConversionContext context, FldSimpleModel model, Document doc) throws TransformerException {
AbstractHyperlinkWriterModel hyperlinkModel = new AbstractHyperlinkWriterModel();
hyperlinkModel.build(context, model, model.getContent());
return toNode(context, hyperlinkModel, doc);
}
}

View file

@ -0,0 +1,188 @@
package org.docx4j.convert.out.common.writer;
import java.util.List;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.ConversionHyperlinkHandler;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.P;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
public class AbstractHyperlinkWriterModel implements ConversionHyperlinkHandler.Model {
private static Logger log = LoggerFactory.getLogger(AbstractHyperlinkWriterModel.class);
protected Node content = null;
protected String target = null;
protected boolean external = false;
protected String anchor = null;
protected String docLocation = null;
protected String rId = null;
protected String tgtFrame = null;
protected String tooltip = null;
public void build(AbstractWmlConversionContext conversionContext, Object node, Node content) throws TransformerException {
Relationship relationship = null;
RelationshipsPart rPart = null;
P.Hyperlink pHyperlink = (P.Hyperlink)node;
this.content = content;
setAnchor(pHyperlink.getAnchor());
setDocLocation(pHyperlink.getDocLocation());
setRId(pHyperlink.getId());
setTgtFrame(pHyperlink.getTgtFrame());
setTooltip(pHyperlink.getTooltip());
if (conversionContext.getCurrentPart() == null) {
log.warn("set currentPart (via conversionContext)");
} else if (getRId() != null && getRId().length() > 0) {
rPart = conversionContext.getCurrentPart().getRelationshipsPart();
if (rPart == null) {
log.error("RelationshipsPart is missing!");
} else {
log.debug("looking for rel" + getRId());
relationship = rPart.getRelationshipByID(getRId());
if (relationship != null && "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink".equals(relationship.getType())) {
setTarget(relationship.getTarget());
setExternal("External".equals(relationship.getTargetMode()));
}
}
}
}
public void build(AbstractWmlConversionContext conversionContext, FldSimpleModel fldSimpleModel, Node content) throws TransformerException {
int idx = 0;
List<String> parameters = fldSimpleModel.getFldParameters();
String parameter = null;
boolean isSwitch = false;
char switchChar = '\000';
String switchParameter = null;
this.content = content;
while (idx < parameters.size()) {
parameter = parameters.get(idx);
if (parameter != null && parameter.length() > 0) {
isSwitch = (parameter.charAt(0) == '\\' && parameter.length() == 2);
if (isSwitch) {
switchChar = Character.toLowerCase(parameter.charAt(1));
switch (switchChar) {
case 'l':
switchParameter = FormattingSwitchHelper.getSwitchValue(idx + 1, parameters);
if (switchParameter != null) {
setTarget(switchParameter);
idx++;
}
break;
case 't':
switchParameter = FormattingSwitchHelper.getSwitchValue(idx + 1, parameters);
if (switchParameter != null) {
setTgtFrame(switchParameter);
idx++;
}
break;
case 'n':
setTgtFrame("_blank");
break;
case 'o':
switchParameter = FormattingSwitchHelper.getSwitchValue(idx + 1, parameters);
if (switchParameter != null) {
setTooltip(switchParameter);
idx++;
}
break;
}
} else if (idx == 0) {
setTarget(FormattingSwitchHelper.getSwitchValue(idx, parameters));
}
}
idx++;
}
if (getTarget() != null && getTarget().length() > 0 && (getTarget().indexOf('/') > -1 || getTarget().indexOf('\\') > -1 || getTarget().indexOf('.') > -1 || getTarget().indexOf(':') > -1))
setExternal(true);
}
public String getExternalTarget() {
return isExternal() ? getTarget() : null;
}
public String getInternalTarget() {
String ret = isExternal() ? null : getTarget();
if (ret == null)
ret = getAnchor();
if (ret == null)
ret = getDocLocation();
return ret;
}
public String getTarget() {
return this.target;
}
public void setTarget(String target) {
this.target = target;
}
public boolean isExternal() {
return this.external;
}
public void setExternal(boolean external) {
this.external = external;
}
public String getAnchor() {
return this.anchor;
}
public void setAnchor(String anchor) {
this.anchor = anchor;
}
public String getDocLocation() {
return this.docLocation;
}
public void setDocLocation(String docLocation) {
this.docLocation = docLocation;
}
public String getRId() {
return this.rId;
}
public void setRId(String rId) {
this.rId = rId;
}
public String getTgtFrame() {
return this.tgtFrame;
}
public void setTgtFrame(String tgtFrame) {
this.tgtFrame = tgtFrame;
}
public String getTooltip() {
return this.tooltip;
}
public void setTooltip(String tooltip) {
this.tooltip = tooltip;
}
public Node getContent() {
return this.content;
}
public String toString() {
return "HyperlinkModel [target=" + this.target + ", external=" + this.external + ", anchor=" + this.anchor + ", docLocation=" + this.docLocation + ", rId=" + this.rId + ", tgtFrame=" + this.tgtFrame + "]";
}
}

View file

@ -0,0 +1,47 @@
package org.docx4j.convert.out.common.writer;
import java.io.StringReader;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.AbstractConversionContext;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.InputSource;
public abstract class AbstractMessageWriter {
public DocumentFragment notImplemented(AbstractConversionContext context, NodeIterator nodes, String message) {
Node n = nodes.nextNode();
context.getLog().warn("NOT IMPLEMENTED: support for " + n.getNodeName() + "; " + message);
if (context.getLog().isDebugEnabled()) {
if (message == null)
message = "";
context.getLog().debug(XmlUtils.w3CDomNodeToString(n));
return message(context, "NOT IMPLEMENTED: support for " + n.getNodeName() + " - " + message);
}
return null;
}
public DocumentFragment message(AbstractConversionContext context, String message) {
if (!context.getLog().isDebugEnabled())
return null;
String documentFragment = getOutputPrefix() + message + getOutputSuffix();
context.getLog().debug(documentFragment);
StringReader reader = new StringReader(documentFragment);
InputSource inputSource = new InputSource(reader);
Document doc = null;
try {
doc = XmlUtils.getNewDocumentBuilder().parse(inputSource);
} catch (Exception e) {
context.getLog().error(e.getMessage(), (Throwable)e);
}
reader.close();
DocumentFragment docfrag = doc.createDocumentFragment();
docfrag.appendChild(doc.getDocumentElement());
return docfrag;
}
protected abstract String getOutputPrefix();
protected abstract String getOutputSuffix();
}

View file

@ -0,0 +1,133 @@
package org.docx4j.convert.out.common.writer;
import java.util.ArrayList;
import java.util.List;
import javax.xml.transform.TransformerException;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public abstract class AbstractPagerefHandler implements AbstractFldSimpleWriter.FldSimpleNodeWriterHandler {
protected int outputType = -1;
protected AbstractPagerefHandler(int outputType) {
this.outputType = outputType;
}
public String getName() {
return "PAGEREF";
}
public int getProcessType() {
return 0;
}
public Node toNode(AbstractWmlConversionContext context, FldSimpleModel model, Document doc) throws TransformerException {
String bookmarkId = model.getFldParameters().get(0);
Node content = model.getContent();
Node literalNode = null;
AbstractHyperlinkWriterModel hyperlinkModel = null;
DocumentFragment docFrag = null;
String textcontent = null;
List<String> textcontentitems = null;
String textcontentitem = null;
if (FormattingSwitchHelper.hasSwitch("\\p", model.getFldParameters())) {
textcontent = getTextcontent(content);
textcontentitems = splitTextcontent(textcontent);
if (textcontentitems != null) {
docFrag = doc.createDocumentFragment();
for (int i = 0; i < textcontentitems.size(); i++) {
textcontentitem = textcontentitems.get(i);
if ("#".equals(textcontentitem)) {
docFrag.appendChild(createPageref(context, doc, bookmarkId));
} else {
literalNode = doc.createDocumentFragment();
XmlUtils.treeCopy(content, literalNode);
literalNode = literalNode.getFirstChild();
setTextcontent(literalNode, textcontentitem);
docFrag.appendChild(literalNode);
}
}
content = docFrag;
}
} else {
content = doc.createDocumentFragment();
content.appendChild(createPageref(context, doc, bookmarkId));
}
if (FormattingSwitchHelper.hasSwitch("\\h", model.getFldParameters())) {
hyperlinkModel = new AbstractHyperlinkWriterModel();
hyperlinkModel.build(context, model, content);
content = HyperlinkUtil.toNode(this.outputType, context, hyperlinkModel, content, doc);
}
return content;
}
protected List<String> splitTextcontent(String textcontent) {
List<String> ret = null;
int startPos = 0;
int endPos = -1;
if (textcontent != null && textcontent.length() > 0) {
while (startPos < textcontent.length() && !Character.isDigit(textcontent.charAt(startPos)))
startPos++;
endPos = startPos + 1;
while (endPos < textcontent.length() && Character.isDigit(textcontent.charAt(endPos)))
endPos++;
if (startPos < endPos && endPos <= textcontent.length()) {
ret = new ArrayList<String>();
if (startPos > 0)
ret.add(textcontent.substring(0, startPos));
ret.add("#");
if (endPos < textcontent.length())
ret.add(textcontent.substring(endPos));
}
}
return ret;
}
protected String getTextcontent(Node root) {
Node textNode = findTextNode(root);
return (textNode != null) ? textNode.getNodeValue() : null;
}
protected void setTextcontent(Node root, String text) {
Node textNode = findTextNode(root);
if (textNode != null) {
if (text.charAt(text.length() - 1) == ' ')
text = text.substring(0, text.length() - 1) + '\u00A0';
if (text.charAt(0) == ' ')
if (text.length() > 1) {
text = '\u00A0' + text.substring(1);
} else {
text = Character.toString('\u00A0');
}
textNode.setNodeValue(text);
}
}
protected Node findTextNode(Node root) {
int i;
Node ret = null;
NodeList childNodes = null;
Node childNode = null;
switch (root.getNodeType()) {
case 3:
ret = (root.getNodeValue() != null && root.getNodeValue().length() > 0) ? root : null;
break;
case 1:
case 9:
case 11:
childNodes = root.getChildNodes();
for (i = 0; ret == null && i < childNodes.getLength(); i++)
ret = findTextNode(childNodes.item(i));
break;
}
return ret;
}
protected abstract Node createPageref(AbstractWmlConversionContext paramAbstractWmlConversionContext, Document paramDocument, String paramString);
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out.common.writer;
public abstract class AbstractPictWriter extends AbstractSimpleWriter {
public static final String WRITER_ID = "w:pict";
protected AbstractPictWriter() {
super("w:pict");
}
}

View file

@ -0,0 +1,19 @@
package org.docx4j.convert.out.common.writer;
import org.docx4j.convert.out.common.Writer;
public abstract class AbstractSimpleWriter implements Writer {
protected String writerId = null;
protected AbstractSimpleWriter(String writerId) {
this.writerId = writerId;
}
public String getID() {
return this.writerId;
}
public Writer.TransformState createTransformState() {
return null;
}
}

View file

@ -0,0 +1,9 @@
package org.docx4j.convert.out.common.writer;
public abstract class AbstractSymbolWriter extends AbstractSimpleWriter {
public static final String WRITER_ID = "w:sym";
protected AbstractSymbolWriter() {
super("w:sym");
}
}

View file

@ -0,0 +1,411 @@
package org.docx4j.convert.out.common.writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import org.docx4j.UnitsOfMeasurement;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.jaxb.Context;
import org.docx4j.model.properties.Property;
import org.docx4j.model.properties.PropertyFactory;
import org.docx4j.model.properties.table.BorderBottom;
import org.docx4j.model.properties.table.BorderLeft;
import org.docx4j.model.properties.table.BorderRight;
import org.docx4j.model.properties.table.BorderTop;
import org.docx4j.model.properties.table.CellMarginBottom;
import org.docx4j.model.properties.table.CellMarginLeft;
import org.docx4j.model.properties.table.CellMarginRight;
import org.docx4j.model.properties.table.CellMarginTop;
import org.docx4j.model.properties.table.tc.Shading;
import org.docx4j.model.properties.table.tc.TextAlignmentVertical;
import org.docx4j.model.properties.table.tr.TrCantSplit;
import org.docx4j.model.properties.table.tr.TrHeight;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.CTBorder;
import org.docx4j.wml.CTHeight;
import org.docx4j.wml.CTShd;
import org.docx4j.wml.CTTblCellMar;
import org.docx4j.wml.CTTblPrBase;
import org.docx4j.wml.CTTblPrEx;
import org.docx4j.wml.STBorder;
import org.docx4j.wml.STShd;
import org.docx4j.wml.TblBorders;
import org.docx4j.wml.TblGridCol;
import org.docx4j.wml.TcPr;
import org.docx4j.wml.TrPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public abstract class AbstractTableWriter extends AbstractSimpleWriter {
private static Logger log = LoggerFactory.getLogger(AbstractTableWriter.class);
public static final String WRITER_ID = "w:tbl";
protected static final int NODE_TABLE = 0;
protected static final int NODE_TABLE_COLUMN_GROUP = 1;
protected static final int NODE_TABLE_COLUMN = 2;
protected static final int NODE_TABLE_HEADER = 3;
protected static final int NODE_TABLE_HEADER_ROW = 4;
protected static final int NODE_TABLE_HEADER_CELL = 5;
protected static final int NODE_TABLE_BODY = 6;
protected static final int NODE_TABLE_BODY_ROW = 7;
protected static final int NODE_TABLE_BODY_CELL = 8;
protected static final Map<String, Integer> PATTERN_PERCENTAGES = new TreeMap<String, Integer>();
static {
PATTERN_PERCENTAGES.put("diagCross", Integer.valueOf(50));
PATTERN_PERCENTAGES.put("horzCross", Integer.valueOf(50));
PATTERN_PERCENTAGES.put("thinDiagCross", Integer.valueOf(25));
PATTERN_PERCENTAGES.put("thinHorzCross", Integer.valueOf(25));
PATTERN_PERCENTAGES.put("pct5", Integer.valueOf(5));
PATTERN_PERCENTAGES.put("pct10", Integer.valueOf(10));
PATTERN_PERCENTAGES.put("pct12", Integer.valueOf(12));
PATTERN_PERCENTAGES.put("pct15", Integer.valueOf(15));
PATTERN_PERCENTAGES.put("pct20", Integer.valueOf(20));
PATTERN_PERCENTAGES.put("pct25", Integer.valueOf(25));
PATTERN_PERCENTAGES.put("pct30", Integer.valueOf(30));
PATTERN_PERCENTAGES.put("pct35", Integer.valueOf(35));
PATTERN_PERCENTAGES.put("pct37", Integer.valueOf(37));
PATTERN_PERCENTAGES.put("pct40", Integer.valueOf(40));
PATTERN_PERCENTAGES.put("pct45", Integer.valueOf(45));
PATTERN_PERCENTAGES.put("pct50", Integer.valueOf(50));
PATTERN_PERCENTAGES.put("pct55", Integer.valueOf(55));
PATTERN_PERCENTAGES.put("pct60", Integer.valueOf(60));
PATTERN_PERCENTAGES.put("pct62", Integer.valueOf(62));
PATTERN_PERCENTAGES.put("pct65", Integer.valueOf(65));
PATTERN_PERCENTAGES.put("pct70", Integer.valueOf(70));
PATTERN_PERCENTAGES.put("pct75", Integer.valueOf(75));
PATTERN_PERCENTAGES.put("pct80", Integer.valueOf(80));
PATTERN_PERCENTAGES.put("pct85", Integer.valueOf(85));
PATTERN_PERCENTAGES.put("pct87", Integer.valueOf(87));
PATTERN_PERCENTAGES.put("pct90", Integer.valueOf(90));
PATTERN_PERCENTAGES.put("pct95", Integer.valueOf(95));
PATTERN_PERCENTAGES.put("solid", Integer.valueOf(100));
}
protected static class TableModelTransformState implements Writer.TransformState {
int idx = 0;
public int getIdx() {
return this.idx;
}
public void incrementIdx() {
this.idx++;
}
}
protected AbstractTableWriter() {
super("w:tbl");
}
public Writer.TransformState createTransformState() {
return new TableModelTransformState();
}
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node content, Writer.TransformState transformState, Document doc) throws TransformerException {
Node ret = null;
AbstractTableWriterModel table = new AbstractTableWriterModel();
table.build(context, unmarshalledNode, content);
if (log.isDebugEnabled())
log.debug("Table asXML:\n" + table.debugStr());
if (!table.getCells().isEmpty())
ret = toNode(context, table, transformState, doc);
return ret;
}
protected Node toNode(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Document doc) throws TransformerException {
DocumentFragment docfrag = doc.createDocumentFragment();
Element tableRoot = createNode(doc, null, 0);
List<Property> rowProperties = new ArrayList<Property>();
int rowPropertiesTableSize = -1;
List<Property> cellProperties = new ArrayList<Property>();
int cellPropertiesTableSize = -1;
int cellPropertiesRowSize = -1;
boolean inHeader = (table.getHeaderMaxRow() > -1);
AbstractTableWriterModelRow rowModel = null;
Element rowContainer = null;
Element row = null;
Element cellNode = null;
createRowProperties(rowProperties, table.getEffectiveTableStyle().getTrPr(), true);
rowPropertiesTableSize = rowProperties.size();
createCellProperties(cellProperties, table.getEffectiveTableStyle().getTrPr());
createCellProperties(cellProperties, table.getEffectiveTableStyle().getTcPr());
createCellProperties(cellProperties, table.getEffectiveTableStyle().getTblPr());
cellPropertiesTableSize = cellProperties.size();
docfrag.appendChild(tableRoot);
applyTableStyles(context, table, transformState, tableRoot);
createColumns(context, table, transformState, doc, tableRoot);
rowContainer = createNode(doc, tableRoot, inHeader ? 3 : 6);
tableRoot.appendChild(rowContainer);
applyTableRowContainerCustomAttributes(context, table, transformState, rowContainer, inHeader);
for (int rowIndex = 0; rowIndex < table.getCells().size(); rowIndex++) {
rowModel = table.getCells().get(rowIndex);
if (inHeader && rowIndex > table.getHeaderMaxRow()) {
rowContainer = createNode(doc, tableRoot, 6);
tableRoot.appendChild(rowContainer);
inHeader = false;
applyTableRowContainerCustomAttributes(context, table, transformState, rowContainer, inHeader);
}
row = createNode(doc, rowContainer, inHeader ? 4 : 7);
TrPr trPr = rowModel.getRowProperties();
CTTblPrEx tblPrEx = rowModel.getRowPropertiesExceptions();
createRowProperties(rowProperties, trPr, false);
processAttributes(context, rowProperties, row);
applyTableRowCustomAttributes(context, table, transformState, row, rowIndex, inHeader);
createCellProperties(cellProperties, trPr);
createCellProperties(cellProperties, tblPrEx);
cellPropertiesRowSize = cellProperties.size();
for (AbstractTableWriterModelCell cell : rowModel.getRowContents()) {
if (cell.isDummy()) {
if (!cell.isVMerged()) {
cellNode = createNode(doc, row, inHeader ? 5 : 8);
row.appendChild(cellNode);
applyTableCellCustomAttributes(context, table, transformState, cell, cellNode, inHeader, true);
}
continue;
}
cellNode = createNode(doc, row, inHeader ? 5 : 8);
row.appendChild(cellNode);
createCellProperties(cellProperties, cell.getTcPr());
processAttributes(context, cellProperties, cellNode);
applyTableCellCustomAttributes(context, table, transformState, cell, cellNode, inHeader, false);
resetProperties(cellProperties, cellPropertiesRowSize);
if (cell.getContent() == null) {
log.warn("model cell had no contents!");
continue;
}
log.debug("copying cell contents..");
XmlUtils.treeCopy(cell.getContent().getChildNodes(), cellNode);
}
resetProperties(cellProperties, cellPropertiesTableSize);
resetProperties(rowProperties, rowPropertiesTableSize);
}
return docfrag;
}
protected Element createNode(Document doc, Element parent, int nodeType) {
Element ret = createNode(doc, nodeType);
if (ret != null && parent != null)
parent.appendChild(ret);
return (ret != null) ? ret : parent;
}
protected void createColumns(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Document doc, Element tableRoot) throws DOMException {
List<TblGridCol> gridCols = (table.getTblGrid() != null) ? table.getTblGrid().getGridCol() : null;
Element columnGroup = createNode(doc, tableRoot, 1);
Element column = null;
applyColumnGroupCustomAttributes(context, table, transformState, columnGroup);
if (gridCols != null && !gridCols.isEmpty()) {
for (int i = 0; i < gridCols.size(); i++) {
column = createNode(doc, columnGroup, 2);
applyColumnCustomAttributes(context, table, transformState, column, i, gridCols.get(i).getW().intValue());
}
} else {
for (int i = 0; i < table.getColCount(); i++) {
column = createNode(doc, columnGroup, 2);
applyColumnCustomAttributes(context, table, transformState, column, i, -1);
}
}
}
protected void applyTableStyles(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Element tableRoot) {
List<Property> tableProperties = null;
if (table.getEffectiveTableStyle().getTblPr() == null) {
log.warn("table.getEffectiveTableStyle().getTblPr() is null, but should never be");
return;
}
tableProperties = PropertyFactory.createProperties(table.getEffectiveTableStyle().getTblPr());
if (table.getEffectiveTableStyle().getTcPr() != null)
PropertyFactory.createPropertiesTable(tableProperties, table.getEffectiveTableStyle().getTcPr());
if (table.getEffectiveTableStyle().getTcPr() == null || table.getEffectiveTableStyle().getTcPr().getVAlign() == null)
tableProperties.add(new TextAlignmentVertical());
if (!table.isDrawTableBorders()) {
for (int i = tableProperties.size() - 1; i >= 0; i--) {
if (tableProperties.get(i) instanceof Shading || tableProperties.get(i) instanceof org.docx4j.model.properties.table.AbstractBorder)
tableProperties.remove(i);
}
appendNoneBordersAndShading(tableProperties);
}
processAttributes(context, tableProperties, tableRoot);
applyTableCustomAttributes(context, table, transformState, tableRoot);
}
protected void appendNoneBordersAndShading(List<Property> tableProperties) {
CTBorder ctBrdr = null;
CTShd shd = Context.getWmlObjectFactory().createCTShd();
ctBrdr = Context.getWmlObjectFactory().createCTBorder();
ctBrdr.setVal(STBorder.NONE);
tableProperties.add(new BorderLeft(ctBrdr));
ctBrdr = Context.getWmlObjectFactory().createCTBorder();
ctBrdr.setVal(STBorder.NONE);
tableProperties.add(new BorderRight(ctBrdr));
ctBrdr = Context.getWmlObjectFactory().createCTBorder();
ctBrdr.setVal(STBorder.NONE);
tableProperties.add(new BorderTop(ctBrdr));
ctBrdr = Context.getWmlObjectFactory().createCTBorder();
ctBrdr.setVal(STBorder.NONE);
tableProperties.add(new BorderBottom(ctBrdr));
shd.setColor("auto");
shd.setFill("auto");
shd.setVal(STShd.CLEAR);
tableProperties.add(new Shading(shd));
}
protected void createRowProperties(List<Property> properties, TrPr trPr, boolean includeDefaultHeight) {
JAXBElement<CTHeight> trHeight = (trPr != null) ? (JAXBElement)getElement(trPr.getCnfStyleOrDivIdOrGridBefore(), "trHeight") : null;
if (trHeight != null)
properties.add(new TrHeight((CTHeight)trHeight.getValue()));
if (trPr != null) {
JAXBElement<?> cantSplit = XmlUtils.getListItemByQName(trPr.getCnfStyleOrDivIdOrGridBefore(), new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "cantSplit"));
if (cantSplit != null) {
BooleanDefaultTrue val = (BooleanDefaultTrue)XmlUtils.unwrap(cantSplit);
if (val.isVal())
properties.add(new TrCantSplit(cantSplit));
}
}
}
protected void createCellProperties(List<Property> properties, TrPr trPr) {}
protected void createCellProperties(List<Property> properties, CTTblPrBase tblPr) {
if (tblPr == null) {
log.warn("table.getEffectiveTableStyle().getTblPr() is null, but should never be");
return;
}
TblBorders tblBorders = tblPr.getTblBorders();
CTTblCellMar tblCellMargin = tblPr.getTblCellMar();
if (tblBorders != null) {
if (tblBorders.getInsideH() != null) {
properties.add(new BorderTop(tblBorders.getTop()));
properties.add(new BorderBottom(tblBorders.getBottom()));
}
if (tblBorders.getInsideV() != null) {
properties.add(new BorderRight(tblBorders.getRight()));
properties.add(new BorderLeft(tblBorders.getLeft()));
}
}
if (tblCellMargin != null) {
if (tblCellMargin.getTop() != null)
properties.add(new CellMarginTop(tblCellMargin.getTop()));
if (tblCellMargin.getBottom() != null)
properties.add(new CellMarginBottom(tblCellMargin.getBottom()));
if (tblCellMargin.getLeft() != null)
properties.add(new CellMarginLeft(tblCellMargin.getLeft()));
if (tblCellMargin.getRight() != null)
properties.add(new CellMarginRight(tblCellMargin.getRight()));
}
}
protected void createCellProperties(List<Property> properties, TcPr tcPr) {
if (tcPr != null)
PropertyFactory.createProperties(properties, tcPr);
}
protected void createCellProperties(List<Property> properties, CTTblPrEx tblPrEx) {}
protected JAXBElement<?> getElement(List<JAXBElement<?>> cnfStyleOrDivIdOrGridBefore, String localName) {
JAXBElement<?> element = null;
if (cnfStyleOrDivIdOrGridBefore != null && !cnfStyleOrDivIdOrGridBefore.isEmpty())
for (int i = 0; i < cnfStyleOrDivIdOrGridBefore.size(); i++) {
element = cnfStyleOrDivIdOrGridBefore.get(i);
if (localName.equals(element.getName().getLocalPart()))
return element;
}
return null;
}
protected void processAttributes(AbstractWmlConversionContext context, List<Property> properties, Element element) {
CTShd shd = null;
int bgColor = 16777215;
int fgColor = 0;
int pctPattern = -1;
for (int i = 0; i < properties.size(); i++) {
if (properties.get(i) instanceof Shading) {
shd = (CTShd)properties.get(i).getObject();
fgColor = extractColor(shd.getColor(), 0);
if (shd.getVal() != null && "clear".equals(shd.getVal().value()) && "auto".equals(shd.getFill())) {
bgColor = 16777215;
pctPattern = -2;
} else {
pctPattern = (shd.getVal() != null) ? extractPattern(shd.getVal().value()) : -1;
bgColor = extractColor(shd.getFill(), bgColor);
}
}
}
if (pctPattern == -1) {
applyAttributes(context, properties, element);
} else {
properties.add(createShading(fgColor, bgColor, pctPattern));
applyAttributes(context, properties, element);
properties.remove(properties.size() - 1);
}
}
protected int extractPattern(String pattern) {
return (pattern != null && PATTERN_PERCENTAGES.containsKey(pattern)) ? PATTERN_PERCENTAGES.get(pattern) : -1;
}
protected int extractColor(String value, int defaultColor) {
int ret = defaultColor;
if (value != null && !"auto".equals(value))
try {
ret = Integer.parseInt(value, 16);
} catch (NumberFormatException nfe) {}
return ret;
}
protected Property createShading(int fgColor, int bgColor, int pctFg) {
CTShd shd = null;
int resColor = UnitsOfMeasurement.combineColors(fgColor, bgColor, pctFg);
shd = Context.getWmlObjectFactory().createCTShd();
shd.setVal(STShd.CLEAR);
shd.setFill(calcHexColor(resColor));
return new Shading(shd);
}
protected String calcHexColor(int value) {
String ret = Integer.toHexString(value).toUpperCase();
return (ret.length() < 6) ? ("000000".substring(0, 6 - ret.length()) + ret) : ret;
}
protected void resetProperties(List<Property> properties, int size) {
for (; properties.size() > size; properties.remove(properties.size() - 1));
}
protected void applyTableCustomAttributes(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Element tableRoot) {}
protected void applyColumnGroupCustomAttributes(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Element columnGroup) {}
protected void applyColumnCustomAttributes(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Element column, int columnIndex, int columnWidth) {}
protected void applyTableRowContainerCustomAttributes(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Element rowContainer, boolean isHeader) {}
protected void applyTableRowCustomAttributes(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, Element row, int rowIndex, boolean isHeader) {}
protected void applyTableCellCustomAttributes(AbstractWmlConversionContext context, AbstractTableWriterModel table, Writer.TransformState transformState, AbstractTableWriterModelCell tableCell, Element cellNode, boolean isHeader, boolean isDummyCell) {}
protected abstract Element createNode(Document paramDocument, int paramInt);
protected abstract void applyAttributes(AbstractWmlConversionContext paramAbstractWmlConversionContext, List<Property> paramList, Element paramElement);
}

View file

@ -0,0 +1,345 @@
package org.docx4j.convert.out.common.writer;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.transform.TransformerException;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.finders.TcFinder;
import org.docx4j.jaxb.Context;
import org.docx4j.model.PropertyResolver;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.CTTblPrBase;
import org.docx4j.wml.CTTrPrBase;
import org.docx4j.wml.Style;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.TblGrid;
import org.docx4j.wml.TblGridCol;
import org.docx4j.wml.TblPr;
import org.docx4j.wml.Tc;
import org.docx4j.wml.Tr;
import org.docx4j.wml.TrPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class AbstractTableWriterModel {
private static final Logger log = LoggerFactory.getLogger(AbstractTableWriterModel.class);
private static final int DEFAULT_PAGE_WIDTH_TWIPS = 12240;
protected List<AbstractTableWriterModelRow> cells;
private int headerMaxRow;
private int row;
private int col;
public AbstractTableWriterModel() {
resetIndexes();
this.cells = new ArrayList<AbstractTableWriterModelRow>();
this.headerMaxRow = -1;
}
private int width = -1;
private boolean drawTableBorder = true;
protected String styleId;
protected Style effectiveTableStyle;
protected TblPr tblPr;
protected TblGrid tblGrid;
public String getStyleId() {
return this.styleId;
}
public Style getEffectiveTableStyle() {
return this.effectiveTableStyle;
}
public TblPr getTblPr() {
return this.tblPr;
}
public TblGrid getTblGrid() {
return this.tblGrid;
}
boolean borderConflictResolutionRequired = true;
public boolean isBorderConflictResolutionRequired() {
return this.borderConflictResolutionRequired;
}
public boolean isDrawTableBorders() {
return this.drawTableBorder;
}
public int getTableWidth() {
return this.width;
}
public void resetIndexes() {
this.row = -1;
this.col = -1;
}
public void startRow(Tr tr) {
this.cells.add(new AbstractTableWriterModelRow(tr));
this.row++;
this.col = -1;
}
public void addCell(Tc tc, Node content) {
addCell(new AbstractTableWriterModelCell(this, this.row, ++this.col, tc, content));
}
private void addDummyCell() {
addDummyCell(0);
}
private void addDummyCell(int colSpan) {
AbstractTableWriterModelCell cell = new AbstractTableWriterModelCell(this, this.row, ++this.col);
if (colSpan > 0)
cell.colspan = colSpan;
addCell(cell);
}
private void addCell(AbstractTableWriterModelCell cell) {
this.cells.get(this.row).add(cell);
}
public AbstractTableWriterModelCell getCell(int row, int col) {
return this.cells.get(row).get(col);
}
public String getColName(int col) {
return "col" + String.valueOf(col + 1);
}
public int getColCount() {
return this.cells.get(0).size();
}
public List<AbstractTableWriterModelRow> getCells() {
return this.cells;
}
public int getHeaderMaxRow() {
return this.headerMaxRow;
}
public void build(AbstractWmlConversionContext conversionContext, Object node, Node content) throws TransformerException {
Tbl tbl = null;
try {
tbl = (Tbl)node;
} catch (ClassCastException e) {
throw new TransformerException("Node is not of the type Tbl it is " + node.getClass().getName());
}
if (tbl.getTblPr() != null && tbl.getTblPr().getTblStyle() != null)
this.styleId = tbl.getTblPr().getTblStyle().getVal();
this.tblGrid = tbl.getTblGrid();
this.tblPr = tbl.getTblPr();
PropertyResolver pr = conversionContext.getPropertyResolver();
this.effectiveTableStyle = pr.getEffectiveTableStyle(tbl.getTblPr());
NodeList cellContents = content.getChildNodes();
TrFinder trFinder = new TrFinder();
new TraversalUtil(tbl, trFinder);
ensureFoTableBody(trFinder.trList);
int r = 0;
for (Tr tr : trFinder.trList) {
startRow(tr);
handleRow(cellContents, tr, r);
r++;
if (this.cells.get(this.row).getRowContents().isEmpty()) {
this.cells.remove(this.row);
this.row--;
r--;
}
}
CTTblPrBase tblPr = this.effectiveTableStyle.getTblPr();
if (tblPr != null &&
tblPr.getTblCellSpacing() != null)
this.borderConflictResolutionRequired = false;
this.width = calcTableWidth();
}
private void ensureFoTableBody(List<Tr> rows) {
int numRows = rows.size();
if (numRows == 0) {
log.warn("Encountered table with no rows");
return;
}
Tr lastRow = rows.get(numRows - 1);
if (isHeaderRow(lastRow)) {
List<JAXBElement<?>> cnfStyleOrDivIdOrGridBefore = lastRow.getTrPr().getCnfStyleOrDivIdOrGridBefore();
JAXBElement<?> tblHeader = getElement(cnfStyleOrDivIdOrGridBefore, "tblHeader");
cnfStyleOrDivIdOrGridBefore.remove(tblHeader);
}
int indexOfLastHeaderRow = -1;
for (int j = rows.size(); j > 0; j--) {
Tr tr = rows.get(j - 1);
if (isHeaderRow(tr)) {
indexOfLastHeaderRow = j - 1;
break;
}
}
for (int i = 0; i < indexOfLastHeaderRow; i++) {
Tr tr = rows.get(i);
if (!isHeaderRow(tr)) {
TrPr trpr = null;
if (tr.getTrPr() == null) {
trpr = Context.getWmlObjectFactory().createTrPr();
tr.setTrPr(trpr);
}
BooleanDefaultTrue booleandefaulttrue = Context.getWmlObjectFactory().createBooleanDefaultTrue();
JAXBElement<BooleanDefaultTrue> booleandefaulttrueWrapped = Context.getWmlObjectFactory().createCTTrPrBaseTblHeader(booleandefaulttrue);
trpr.getCnfStyleOrDivIdOrGridBefore().add(booleandefaulttrueWrapped);
}
}
}
static class TrFinder extends TraversalUtil.CallbackImpl {
List<Tr> trList = new ArrayList<Tr>();
public List<Object> apply(Object o) {
if (o instanceof Tr)
this.trList.add((Tr)o);
return null;
}
public boolean shouldTraverse(Object o) {
return !(o instanceof Tbl);
}
}
private void handleRow(NodeList cellContents, Tr tr, int r) {
int gridAfter = getGridAfter(tr);
int gridBefore = getGridBefore(tr);
boolean headerRow = isHeaderRow(tr);
log.debug("Processing r " + r);
if (this.borderConflictResolutionRequired && tr.getTblPrEx() != null && tr.getTblPrEx().getTblCellSpacing() != null)
this.borderConflictResolutionRequired = false;
if (headerRow && this.headerMaxRow < r)
this.headerMaxRow = r;
if (this.drawTableBorder)
this.drawTableBorder = (gridBefore == 0 && gridAfter == 0);
TcFinder tcFinder = new TcFinder();
new TraversalUtil(tr, tcFinder);
if (gridBefore > 0)
addDummyCell(gridBefore);
int c = 0;
log.debug("Processing c " + c);
for (Tc tc : tcFinder.tcList) {
Node wtrNode = cellContents.item(r);
if (wtrNode == null)
log.warn("Couldn't find item " + r);
addCell(tc, getTc(wtrNode, c, new IntRef(0)));
c++;
}
if (gridAfter > 0)
addDummyCell(gridAfter);
}
protected boolean isHeaderRow(Tr tr) {
List<JAXBElement<?>> cnfStyleOrDivIdOrGridBefore = (tr.getTrPr() != null) ? tr.getTrPr().getCnfStyleOrDivIdOrGridBefore() : null;
JAXBElement<?> element = getElement(cnfStyleOrDivIdOrGridBefore, "tblHeader");
BooleanDefaultTrue boolVal = (element != null) ? (BooleanDefaultTrue)element.getValue() : null;
return (boolVal != null) ? boolVal.isVal() : false;
}
protected int getGridAfter(Tr tr) {
List<JAXBElement<?>> cnfStyleOrDivIdOrGridBefore = (tr.getTrPr() != null) ? tr.getTrPr().getCnfStyleOrDivIdOrGridBefore() : null;
JAXBElement<?> element = getElement(cnfStyleOrDivIdOrGridBefore, "gridAfter");
CTTrPrBase.GridAfter gridAfter = (element != null) ? (CTTrPrBase.GridAfter)element.getValue() : null;
BigInteger val = (gridAfter != null) ? gridAfter.getVal() : null;
return (val != null) ? val.intValue() : 0;
}
protected int getGridBefore(Tr tr) {
List<JAXBElement<?>> cnfStyleOrDivIdOrGridBefore = (tr.getTrPr() != null) ? tr.getTrPr().getCnfStyleOrDivIdOrGridBefore() : null;
JAXBElement<?> element = getElement(cnfStyleOrDivIdOrGridBefore, "gridBefore");
CTTrPrBase.GridBefore gridBefore = (element != null) ? (CTTrPrBase.GridBefore)element.getValue() : null;
BigInteger val = (gridBefore != null) ? gridBefore.getVal() : null;
return (val != null) ? val.intValue() : 0;
}
protected JAXBElement<?> getElement(List<JAXBElement<?>> cnfStyleOrDivIdOrGridBefore, String localName) {
JAXBElement<?> element = null;
if (cnfStyleOrDivIdOrGridBefore != null && !cnfStyleOrDivIdOrGridBefore.isEmpty())
for (int i = 0; i < cnfStyleOrDivIdOrGridBefore.size(); i++) {
element = cnfStyleOrDivIdOrGridBefore.get(i);
if (localName.equals(element.getName().getLocalPart()))
return element;
}
return null;
}
protected int calcTableWidth() {
int ret = -1;
List<TblGridCol> gridCols = (getTblGrid() != null) ? getTblGrid().getGridCol() : null;
if (gridCols != null && !gridCols.isEmpty()) {
ret = 0;
for (int i = 0; i < gridCols.size(); i++)
ret += gridCols.get(i).getW().intValue();
}
return ret;
}
private Node getTc(Node wtrNode, int wanted, IntRef current) {
for (int i = 0; i < wtrNode.getChildNodes().getLength(); i++) {
Node thisChild = wtrNode.getChildNodes().item(i);
if (thisChild.getNodeType() == 1) {
log.debug("Looking at " + thisChild.getLocalName() + "; have encountered " + current.i);
if (thisChild.getLocalName().equals("tc")) {
if (current.i == wanted)
return thisChild;
current.increment();
} else {
Node n = getTc(thisChild, wanted, current);
if (n != null)
return n;
}
}
}
log.error("Couldn't find tc in: " + XmlUtils.w3CDomNodeToString(wtrNode));
return null;
}
static class IntRef {
int i;
IntRef(int i) {
this.i = i;
}
void increment() {
this.i++;
}
}
public String debugStr() {
StringBuffer buf = new StringBuffer();
for (AbstractTableWriterModelRow row : this.cells) {
List<AbstractTableWriterModelCell> rowContents = row.getRowContents();
for (AbstractTableWriterModelCell c : rowContents) {
if (c == null) {
buf.append("null ");
continue;
}
buf.append(c.debugStr());
}
buf.append("\n");
}
return buf.toString();
}
}

View file

@ -0,0 +1,114 @@
package org.docx4j.convert.out.common.writer;
import org.docx4j.XmlUtils;
import org.docx4j.wml.Tc;
import org.docx4j.wml.TcPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
public class AbstractTableWriterModelCell {
private static final Logger logger = LoggerFactory.getLogger(AbstractTableWriterModelCell.class);
private AbstractTableWriterModel table;
private int row;
private int col;
protected int rowspan = 0;
protected int colspan = 0;
protected boolean dummy = false;
protected Node content = null;
TcPr tcPr;
public TcPr getTcPr() {
return this.tcPr;
}
public AbstractTableWriterModelCell(AbstractTableWriterModel table, int row, int col) {
this.table = table;
this.row = row;
this.col = col;
this.dummy = true;
}
public AbstractTableWriterModelCell(AbstractTableWriterModel table, int row, int col, Tc tc, Node content) {
this(table, row, col);
this.dummy = false;
this.content = content;
this.tcPr = tc.getTcPr();
if (content == null) {
logger.error("No content for row " + row + ", col " + col + "\n" + XmlUtils.marshaltoString(tc, true, true));
} else {
logger.debug("Cell content: " + XmlUtils.w3CDomNodeToString(content));
}
try {
String vm = tc.getTcPr().getVMerge().getVal();
if (vm == null || vm.equals("continue"))
this.dummy = true;
incrementRowSpan();
} catch (NullPointerException ne) {}
if (this.dummy) {
this.colspan = (table.getCell(row - 1, col)).colspan;
} else {
try {
int gridSpan = tc.getTcPr().getGridSpan().getVal().intValue();
this.colspan = gridSpan;
} catch (NullPointerException ne) {}
}
}
public int getExtraCols() {
if (this.colspan < 2)
return 0;
return this.colspan - 1;
}
public int getExtraRows() {
if (this.rowspan > 1)
return this.rowspan - 1;
return 0;
}
public boolean isDummy() {
return this.dummy;
}
public Node getContent() {
return this.content;
}
public int getColumn() {
return this.col;
}
protected void incrementRowSpan() {
if (this.dummy) {
this.table.getCell(this.row - 1, this.col).incrementRowSpan();
} else {
this.rowspan++;
}
}
public String debugStr() {
String s = null;
if (this.dummy) {
s = "d";
} else {
s = "r";
}
s = s + "(" + this.row + "," + this.col + ")";
s = s + this.colspan;
s = s + this.rowspan;
return s + " ";
}
public boolean isVMerged() {
return (this.tcPr != null && this.tcPr.getVMerge() != null);
}
}

View file

@ -0,0 +1,44 @@
package org.docx4j.convert.out.common.writer;
import java.util.List;
import java.util.Vector;
import org.docx4j.wml.CTTblPrEx;
import org.docx4j.wml.Tr;
import org.docx4j.wml.TrPr;
public class AbstractTableWriterModelRow {
public AbstractTableWriterModelRow(Tr tr) {
this.trPr = tr.getTrPr();
this.tblPrEx = tr.getTblPrEx();
}
private List<AbstractTableWriterModelCell> rowContents = new Vector<AbstractTableWriterModelCell>();
private TrPr trPr;
private CTTblPrEx tblPrEx;
public TrPr getRowProperties() {
return this.trPr;
}
public CTTblPrEx getRowPropertiesExceptions() {
return this.tblPrEx;
}
public List<AbstractTableWriterModelCell> getRowContents() {
return this.rowContents;
}
public void add(AbstractTableWriterModelCell newCell) {
this.rowContents.add(newCell);
}
public AbstractTableWriterModelCell get(int i) {
return this.rowContents.get(i);
}
public int size() {
return this.rowContents.size();
}
}

View file

@ -0,0 +1,81 @@
package org.docx4j.convert.out.common.writer;
import javax.xml.transform.TransformerException;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class HyperlinkUtil {
private static final Logger log = LoggerFactory.getLogger(HyperlinkUtil.class);
public static final int HTML_OUTPUT = 1;
public static final int FO_OUTPUT = 2;
public static Node toNode(int outputType, AbstractWmlConversionContext context, AbstractHyperlinkWriterModel model, Node content, Document doc) throws TransformerException {
Node ret = content;
try {
context.handleHyperlink(model);
switch (outputType) {
case 1:
ret = toHtmlNode(context, model, content, doc);
break;
case 2:
ret = toFoNode(context, model, content, doc);
break;
default:
throw new IllegalArgumentException("Invalid output type: " + outputType);
}
XmlUtils.treeCopy(content.getChildNodes(), ret);
} catch (Docx4JException e) {
log.error("Excetion handling the hyperlinkModel: " + model, (Throwable)e);
}
return ret;
}
private static Node toFoNode(AbstractWmlConversionContext context, AbstractHyperlinkWriterModel model, Node content, Document doc) {
Element ret = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:basic-link");
String internalTarget = model.getInternalTarget();
String externalTarget = model.getExternalTarget();
if (internalTarget == null && externalTarget == null)
log.error("No targets found for ");
String location = null;
if (model.isExternal()) {
location = externalTarget;
if (internalTarget != null && internalTarget.length() > 0)
location = location + "#" + internalTarget;
location = "url(" + location + ")";
ret.setAttribute("external-destination", location);
} else {
ret.setAttribute("internal-destination", internalTarget);
}
if (model.getTooltip() != null && model.getTooltip().length() > 0)
ret.setAttribute("role", model.getTooltip());
return ret;
}
private static Node toHtmlNode(AbstractWmlConversionContext context, AbstractHyperlinkWriterModel model, Node content, Document doc) {
Element ret = doc.createElement("a");
String internalTarget = model.getInternalTarget();
String externalTarget = model.getExternalTarget();
String location = null;
if (model.isExternal()) {
location = externalTarget;
if (internalTarget != null && internalTarget.length() > 0)
location = location + "#" + internalTarget;
ret.setAttribute("href", location);
} else {
ret.setAttribute("href", "#" + internalTarget);
}
if (model.getTgtFrame() != null && model.getTgtFrame().length() > 0)
ret.setAttribute("target", model.getTgtFrame());
if (model.getTooltip() != null && model.getTooltip().length() > 0)
ret.setAttribute("alt", model.getTooltip());
return ret;
}
}

View file

@ -0,0 +1,35 @@
package org.docx4j.convert.out.common.writer;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class RefHandler implements AbstractFldSimpleWriter.FldSimpleNodeWriterHandler {
protected int outputType = -1;
public RefHandler(int outputType) {
this.outputType = outputType;
}
public String getName() {
return "REF";
}
public int getProcessType() {
return 0;
}
public Node toNode(AbstractWmlConversionContext context, FldSimpleModel model, Document doc) throws TransformerException {
Node ret = model.getContent();
AbstractHyperlinkWriterModel hyperlinkModel = null;
if (FormattingSwitchHelper.hasSwitch("\\h", model.getFldParameters())) {
hyperlinkModel = new AbstractHyperlinkWriterModel();
hyperlinkModel.build(context, model, model.getContent());
ret = HyperlinkUtil.toNode(this.outputType, context, hyperlinkModel, model.getContent(), doc);
}
return ret;
}
}

View file

@ -0,0 +1,258 @@
package org.docx4j.convert.out.flatOpcXml;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.HashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import org.apache.commons.io.FileUtils;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.Output;
import org.docx4j.jaxb.Context;
import org.docx4j.jaxb.NamespacePrefixMapperUtils;
import org.docx4j.openpackaging.URIHelper;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart;
import org.docx4j.openpackaging.parts.JaxbXmlPart;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart;
import org.docx4j.openpackaging.parts.XmlPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.xmlPackage.ObjectFactory;
import org.docx4j.xmlPackage.Package;
import org.docx4j.xmlPackage.XmlData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
public class FlatOpcXmlCreator implements Output {
private static Logger log = LoggerFactory.getLogger(FlatOpcXmlCreator.class);
public OpcPackage packageIn;
public FlatOpcXmlCreator(OpcPackage p) {
this.packageIn = p;
}
private HashMap<String, String> handled = new HashMap<String, String>();
private static ObjectFactory factory = new ObjectFactory();
private Package pkgResult;
public Package get() throws Docx4JException {
try {
this.pkgResult = factory.createPackage();
RelationshipsPart rp = this.packageIn.getRelationshipsPart();
saveRawXmlPart(rp);
addPartsFromRelationships(rp);
} catch (Exception e) {
e.printStackTrace();
if (e instanceof Docx4JException)
throw (Docx4JException)e;
throw new Docx4JException("Failed to save package", e);
}
log.info("...Done!");
return this.pkgResult;
}
public void marshal(OutputStream os) throws Docx4JException {
if (this.pkgResult == null) {
if (this.packageIn == null)
throw new Docx4JException("No zipped package to convert to Flat OPC Package");
get();
}
try {
JAXBContext jc = Context.jcXmlPackage;
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);
NamespacePrefixMapperUtils.setProperty(marshaller, NamespacePrefixMapperUtils.getPrefixMapper());
marshaller.marshal(this.pkgResult, os);
} catch (JAXBException e) {
throw new Docx4JException("Couldn't marshall Flat OPC Package", e);
}
}
public void saveRawXmlPart(Part part) throws Docx4JException {
org.docx4j.xmlPackage.Part partResult = createRawXmlPart(part);
this.pkgResult.getPart().add(partResult);
}
public static org.docx4j.xmlPackage.Part createRawXmlPart(Part part) throws Docx4JException {
String partName = part.getPartName().getName();
org.docx4j.xmlPackage.Part partResult = factory.createPart();
if (partName.startsWith("/")) {
partResult.setName(partName);
} else {
partResult.setName("/" + partName);
}
String ct = part.getContentType();
if (ct == null) {
log.error("Content type not set! ");
} else {
partResult.setContentType(ct);
}
XmlData dataResult = factory.createXmlData();
partResult.setXmlData(dataResult);
Document w3cDoc = null;
if (part instanceof JaxbXmlPart) {
try {
w3cDoc = XmlUtils.getNewDocumentBuilder().newDocument();
((JaxbXmlPart)part).marshal(w3cDoc, NamespacePrefixMapperUtils.getPrefixMapper());
dataResult.setAny(w3cDoc.getDocumentElement());
log.info("PUT SUCCESS: " + partName);
} catch (Exception e) {
e.printStackTrace();
log.error("Problem saving part " + partName, (Throwable)e);
throw new Docx4JException("Problem saving part " + partName, e);
}
} else if (part instanceof CustomXmlDataStoragePart) {
try {
dataResult.setAny(((CustomXmlDataStoragePart)part).getData().getDocument().getDocumentElement());
log.info("PUT SUCCESS: " + partName);
} catch (Exception e) {
e.printStackTrace();
log.error("Problem saving part " + partName, (Throwable)e);
throw new Docx4JException("Problem saving part " + partName, e);
}
} else if (part instanceof XmlPart) {
Document doc = ((XmlPart)part).getDocument();
dataResult.setAny(doc.getDocumentElement());
} else {
log.error("PROBLEM - No suitable part found for: " + partName);
}
return partResult;
}
public void addPartsFromRelationships(RelationshipsPart rp) throws Docx4JException {
for (Relationship r : rp.getRelationships().getRelationship()) {
log.info("For Relationship Id=" + r.getId() + " Source is " + rp.getSourceP().getPartName() + ", Target is " + r.getTarget());
if (r.getTargetMode() != null && r.getTargetMode().equals("External")) {
log.warn("Encountered external resource " + r.getTarget() + " of type " + r.getType());
continue;
}
try {
String resolvedPartUri = URIHelper.resolvePartUri(rp.getSourceURI(), new URI(r.getTarget())).toString();
resolvedPartUri = resolvedPartUri.substring(1);
log.info("Getting part /" + resolvedPartUri);
Part part = this.packageIn.getParts().get(new PartName("/" + resolvedPartUri));
if (part == null) {
log.error("Part " + resolvedPartUri + " not found!");
} else {
log.info(part.getClass().getName());
}
savePart(part);
} catch (Exception e) {
throw new Docx4JException("Failed to add parts from relationships", e);
}
}
}
public void savePart(Part part) throws Docx4JException, IOException {
String resolvedPartUri = part.getPartName().getName().substring(1);
if (this.handled.get(resolvedPartUri) != null) {
log.debug(".. duplicate save avoided ..");
return;
}
if (part instanceof BinaryPart) {
log.info(".. saving binary stuff");
saveRawBinaryPart(part);
} else {
log.info(".. saving ");
saveRawXmlPart(part);
}
this.handled.put(resolvedPartUri, resolvedPartUri);
if (part.getRelationshipsPart() != null && part.getRelationshipsPart().getJaxbElement() != null && part.getRelationshipsPart().getJaxbElement().getRelationship() != null && part.getRelationshipsPart().getJaxbElement().getRelationship().size() > 0) {
RelationshipsPart rrp = part.getRelationshipsPart();
log.info("Found relationships " + rrp.getPartName());
String relPart = PartName.getRelationshipsPartName(resolvedPartUri);
log.info("Cf constructed name " + relPart);
saveRawXmlPart(rrp);
addPartsFromRelationships(rrp);
} else {
log.info("No relationships for " + resolvedPartUri);
}
}
protected void saveRawBinaryPart(Part part) throws Docx4JException {
org.docx4j.xmlPackage.Part partResult = createRawBinaryPart(part);
this.pkgResult.getPart().add(partResult);
}
public static org.docx4j.xmlPackage.Part createRawBinaryPart(Part part) throws Docx4JException {
String resolvedPartUri = part.getPartName().getName();
org.docx4j.xmlPackage.Part partResult = factory.createPart();
partResult.setName(resolvedPartUri);
partResult.setContentType(part.getContentType());
try {
partResult.setCompression("store");
partResult.setBinaryData(((BinaryPart)part).getBytes());
} catch (Exception e) {
throw new Docx4JException("Failed to put binary part", e);
}
log.info("PUT SUCCESS: " + resolvedPartUri);
return partResult;
}
public static String wrapInXmlPart(String xml, String partName, String contentType) {
return "<pkg:part pkg:name=\"" + partName + "\"" + " pkg:contentType=\"" + contentType + "\"" + " xmlns:pkg=\"http://schemas.microsoft.com/office/2006/xmlPackage\">" + "<pkg:xmlData>" + xml + "</pkg:xmlData>" + "</pkg:part>";
}
public static String wrapInBinaryPart(byte[] base64, String partName, String contentType) {
try {
return "<pkg:part pkg:name=\"" + partName + "\"" + " pkg:contentType=\"" + contentType + "\"" + " xmlns:pkg=\"http://schemas.microsoft.com/office/2006/xmlPackage\">" + "<pkg:binaryData>" + new String(base64, "UTF-8") + "</pkg:binaryData>" + "</pkg:part>";
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), (Throwable)e);
return null;
}
}
public static Document getFlatDomDocument(WordprocessingMLPackage wordMLPackage) throws Docx4JException {
Document doc;
FlatOpcXmlCreator worker = new FlatOpcXmlCreator(wordMLPackage);
Package pkg = worker.get();
try {
JAXBContext jc = Context.jcXmlPackage;
Marshaller marshaller = jc.createMarshaller();
doc = XmlUtils.neww3cDomDocument();
marshaller.marshal(pkg, doc);
} catch (JAXBException e) {
throw new Docx4JException("Couldn't marshal Flat OPC to DOM", e);
}
return doc;
}
public void output(Result result) throws Docx4JException {
TransformerFactory tfactory = XmlUtils.getTransformerFactory();
try {
Transformer serializer = tfactory.newTransformer();
serializer.setOutputProperty("omit-xml-declaration", "yes");
serializer.transform(new DOMSource(getFlatDomDocument((WordprocessingMLPackage)this.packageIn)), result);
} catch (Exception e) {
throw new Docx4JException("Failed to create Flat OPC output", e);
}
}
public static void main(String[] args) throws Exception {
String inputfilepath = System.getProperty("user.dir") + "/ole_tests/wmv_CT.pptx";
OpcPackage wordMLPackage = OpcPackage.load(new File(inputfilepath));
FlatOpcXmlCreator worker = new FlatOpcXmlCreator(wordMLPackage);
Package result = worker.get();
boolean suppressDeclaration = true;
boolean prettyprint = true;
String data = XmlUtils.marshaltoString(result, suppressDeclaration, prettyprint, Context.jcXmlPackage);
FileUtils.writeStringToFile(new File(System.getProperty("user.dir") + "/ole_tests/wmv_CT.xml"), data);
}
}

View file

@ -0,0 +1,122 @@
package org.docx4j.convert.out.fo;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.convert.out.FORenderer;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.AbstractConversionContext;
import org.docx4j.convert.out.common.AbstractExporterDelegate;
import org.docx4j.convert.out.common.AbstractWmlExporter;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.ConversionSectionWrappers;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractFOExporter extends AbstractWmlExporter<FOSettings, FOConversionContext> {
private static Logger log = LoggerFactory.getLogger(AbstractFOExporter.class);
protected static final int DEFAULT_START_SIZE = 10240;
protected AbstractFOExporter(AbstractExporterDelegate<FOSettings, FOConversionContext> exporterDelegate) {
super(exporterDelegate);
}
protected static class FoSectionPageInformation implements FORenderer.SectionPageInformation {
protected String documentPageCountID = null;
protected String documentPageCountFoFormat = null;
protected String sectionPageCountID = null;
protected String sectionPageCountFoFormat = null;
public FoSectionPageInformation(String documentPageCountID, String documentPageCountFoFormat, String sectionPageCountID, String sectionPageCountFoFormat) {
this.documentPageCountID = documentPageCountID;
this.documentPageCountFoFormat = documentPageCountFoFormat;
this.sectionPageCountID = sectionPageCountID;
this.sectionPageCountFoFormat = sectionPageCountFoFormat;
}
public String getDocumentPageCountID() {
return this.documentPageCountID;
}
public String getDocumentPageCountFoFormat() {
return this.documentPageCountFoFormat;
}
public String getSectionPageCountID() {
return this.sectionPageCountID;
}
public String getSectionPageCountFoFormat() {
return this.sectionPageCountFoFormat;
}
}
protected FOConversionContext createContext(FOSettings conversionSettings, WordprocessingMLPackage preprocessedPackage, ConversionSectionWrappers sectionWrappers) {
return new FOConversionContext(conversionSettings, preprocessedPackage, sectionWrappers);
}
protected OutputStream createIntermediateOutputStream(OutputStream outputStream) throws Docx4JException {
return new ByteArrayOutputStream(10240);
}
protected void postprocess(FOSettings conversionSettings, AbstractConversionContext conversionContext, OutputStream intermediateOutputStream, OutputStream outputStream) throws Docx4JException {
String foDocument = null;
File dumpFoFile = conversionSettings.getFoDumpFile();
FOConversionContext foConversionContext = (FOConversionContext)conversionContext;
try {
foDocument = ((ByteArrayOutputStream)intermediateOutputStream).toString("UTF-8");
} catch (UnsupportedEncodingException e) {
foDocument = ((ByteArrayOutputStream)intermediateOutputStream).toString();
}
if (log.isDebugEnabled())
log.debug(foDocument);
if (dumpFoFile != null)
try {
FileUtils.writeStringToFile(dumpFoFile, foDocument, "UTF-8");
log.info("Saved " + dumpFoFile.getPath());
} catch (IOException e) {
log.warn("fo file couldn't be dumped to " + dumpFoFile.getPath() + ": " + e, (Throwable)e);
}
foConversionContext.getFORenderer().render(foDocument, conversionSettings, foConversionContext.isRequires2Pass(), createPageNumberInformation(foConversionContext), outputStream);
}
protected List<FORenderer.SectionPageInformation> createPageNumberInformation(FOConversionContext conversionContext) {
List<ConversionSectionWrapper> wrapperList = null;
List<FORenderer.SectionPageInformation> ret = Collections.EMPTY_LIST;
ConversionSectionWrapper section = null;
String sectionId = null;
String pageFoFormat = null;
String pageWordFormat = null;
FORenderer.SectionPageInformation pageNumberInformation = null;
if (conversionContext.isRequires2Pass()) {
wrapperList = conversionContext.getSections().getList();
ret = new ArrayList<FORenderer.SectionPageInformation>(wrapperList.size());
for (int i = 0; i < wrapperList.size(); i++) {
section = wrapperList.get(i);
pageWordFormat = section.getPageNumberInformation().getPageFormat();
pageFoFormat = FormattingSwitchHelper.getFoPageNumberFormat(pageWordFormat);
sectionId = section.getId();
if (pageFoFormat == null)
pageFoFormat = "1";
pageNumberInformation = new FoSectionPageInformation("field_numpages_" + sectionId + "_value", pageFoFormat, "field_sectionpages_" + sectionId + "_value", pageFoFormat);
ret.add(pageNumberInformation);
}
}
return ret;
}
}

View file

@ -0,0 +1,88 @@
package org.docx4j.convert.out.fo;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.docx4j.convert.out.FORenderer;
import org.docx4j.utils.FoNumberFormatUtil;
public class AbstractPlaceholderLookup implements PlaceholderReplacementHandler.PlaceholderLookup {
protected static final String PLACEHOLDER_PREFIX = "${";
protected static final String PLACEHOLDER_SUFFIX = "}";
protected static final int PLACEHOLDER_PREFIX_LENGTH = "${".length();
protected static final int PLACEHOLDER_SUFFIX_LENGTH = "}".length();
protected static final String FIRST_PASS_DUMMY_VALUE = "00";
protected List<FORenderer.SectionPageInformation> pageNumberInformation = null;
protected Map<String, String> placeholderValues = new TreeMap<String, String>();
protected AbstractPlaceholderLookup(List<FORenderer.SectionPageInformation> pageNumberInformation) {
this.pageNumberInformation = setupPageNumerInformation(pageNumberInformation);
}
protected List<FORenderer.SectionPageInformation> setupPageNumerInformation(List<FORenderer.SectionPageInformation> pageNumberInformation) {
FORenderer.SectionPageInformation item = null;
this.placeholderValues.clear();
for (int i = 0; i < pageNumberInformation.size(); i++) {
item = pageNumberInformation.get(i);
putValue(item.getDocumentPageCountID(), "00");
putValue(item.getSectionPageCountID(), "00");
}
return pageNumberInformation;
}
protected void putDocumentPageCount(int pageCount) {
String pageCountValue = null;
String foFormat = null;
String lastFoFormat = null;
FORenderer.SectionPageInformation item = null;
for (int i = 0; i < this.pageNumberInformation.size(); i++) {
item = this.pageNumberInformation.get(i);
foFormat = item.getDocumentPageCountFoFormat();
if (!foFormat.equals(lastFoFormat)) {
pageCountValue = FoNumberFormatUtil.format(pageCount, foFormat);
lastFoFormat = foFormat;
}
putValue(item.getDocumentPageCountID(), pageCountValue);
}
}
protected void putSectionPageCount(int sectionIndex, int pageCount) {
FORenderer.SectionPageInformation item = this.pageNumberInformation.get(sectionIndex);
String pageCountValue = FoNumberFormatUtil.format(pageCount, item.getSectionPageCountFoFormat());
this.placeholderValues.put(createPlaceholder(item.getSectionPageCountID()), pageCountValue);
}
protected void putValue(String placeholderID, String value) {
this.placeholderValues.put(createPlaceholder(placeholderID), value);
}
protected String createPlaceholder(String placeholderID) {
return "${" + placeholderID + "}";
}
public boolean hasPlaceholders(StringBuilder buffer) {
return (buffer.indexOf("${") > -1);
}
public void replaceValues(StringBuilder buffer) {
int stIdx = buffer.lastIndexOf("${");
int enIdx = -1;
String value = null;
while (stIdx > -1) {
enIdx = buffer.indexOf("}", stIdx + PLACEHOLDER_PREFIX_LENGTH);
if (enIdx > -1) {
enIdx += PLACEHOLDER_SUFFIX_LENGTH;
value = this.placeholderValues.get(buffer.substring(stIdx, enIdx));
if (value != null)
buffer.replace(stIdx, enIdx, value);
}
stIdx = (stIdx > 0) ? buffer.lastIndexOf("${", stIdx - 1) : -1;
}
}
}

View file

@ -0,0 +1,25 @@
package org.docx4j.convert.out.fo;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.convert.out.common.writer.AbstractBookmarkStartWriter;
import org.docx4j.wml.CTBookmark;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class BookmarkStartWriter extends AbstractBookmarkStartWriter {
private static final Logger log = LoggerFactory.getLogger(BookmarkStartWriter.class);
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node modelContent, Writer.TransformState state, Document doc) throws TransformerException {
CTBookmark modelData = (CTBookmark)unmarshalledNode;
if (modelData.getName().equals("_GoBack"))
return null;
Element ret = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:inline");
ret.setAttribute("id", modelData.getName());
return ret;
}
}

View file

@ -0,0 +1,31 @@
package org.docx4j.convert.out.fo;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.convert.out.common.writer.AbstractBrWriter;
import org.docx4j.wml.Br;
import org.docx4j.wml.STBrType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class BrWriter extends AbstractBrWriter {
private static String XSL_FO = "http://www.w3.org/1999/XSL/Format";
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node modelContent, Writer.TransformState state, Document doc) throws TransformerException {
Element ret;
Br modelData = (Br)unmarshalledNode;
if (modelData.getType() != null && modelData.getType().equals(STBrType.PAGE)) {
ret = doc.createElementNS(XSL_FO, "block");
ret.setAttribute("break-before", "page");
} else {
ret = doc.createElementNS(XSL_FO, "block");
ret.setAttribute("linefeed-treatment", "preserve");
ret.setAttribute("white-space-treatment", "preserve");
ret.setAttribute("line-height", "0pt");
ret.setTextContent("\n");
}
return ret;
}
}

View file

@ -0,0 +1,186 @@
package org.docx4j.convert.out.fo;
import java.util.List;
import org.docx4j.convert.out.AbstractConversionSettings;
import org.docx4j.convert.out.FORenderer;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.AbstractWriterRegistry;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.ConversionSectionWrappers;
import org.docx4j.convert.out.common.writer.AbstractMessageWriter;
import org.docx4j.convert.out.fo.renderers.FORendererApacheFOP;
import org.docx4j.convert.out.fo.renderers.FORendererDummy;
import org.docx4j.fonts.RunFontSelector;
import org.docx4j.model.images.ConversionImageHandler;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
public class FOConversionContext extends AbstractWmlConversionContext {
private static Logger log = LoggerFactory.getLogger(FOConversionContext.class);
protected boolean requires2PassChecked = false;
protected boolean requires2Pass = false;
protected FORenderer foRenderer;
protected static final AbstractWriterRegistry FO_WRITER_REGISTRY = new AbstractWriterRegistry() {
protected void registerDefaultWriterInstances() {
registerWriter(new TableWriter());
registerWriter(new SymbolWriter());
registerWriter(new BrWriter());
registerWriter(new FldSimpleWriter());
registerWriter(new BookmarkStartWriter());
registerWriter(new HyperlinkWriter());
registerWriter(new FOPictWriterFloatAvoided());
}
};
protected static final AbstractMessageWriter FO_MESSAGE_WRITER = new AbstractMessageWriter() {
protected String getOutputPrefix() {
return "<fo:block xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" font-size=\"12pt\" color=\"red\" font-family=\"sans-serif\" line-height=\"15pt\" space-after.optimum=\"3pt\" text-align=\"justify\"> ";
}
protected String getOutputSuffix() {
return "</fo:block>";
}
};
public FOConversionContext(FOSettings settings, WordprocessingMLPackage wmlPackage, ConversionSectionWrappers conversionSectionWrappers) {
super(FO_WRITER_REGISTRY, FO_MESSAGE_WRITER, settings, wmlPackage, conversionSectionWrappers, createRunFontSelector(wmlPackage));
this.foRenderer = initializeFoRenderer(settings);
}
private static RunFontSelector createRunFontSelector(WordprocessingMLPackage wmlPackage) {
return new RunFontSelector(wmlPackage, new RunFontSelector.RunFontCharacterVisitor() {
DocumentFragment df;
StringBuilder sb = new StringBuilder(1024);
Element span;
String lastFont;
String fallbackFontName;
private Document document;
public void setDocument(Document document) {
this.document = document;
this.df = document.createDocumentFragment();
}
private boolean spanReusable = true;
private RunFontSelector runFontSelector;
public boolean isReusable() {
return this.spanReusable;
}
public void addCharacterToCurrent(char c) {
this.sb.append(c);
}
public void finishPrevious() {
if (this.sb.length() > 0) {
if (this.span == null) {
this.span = this.runFontSelector.createElement(this.document);
if (this.lastFont != null)
this.runFontSelector.setAttribute(this.span, this.lastFont);
}
this.df.appendChild(this.span);
this.span.setTextContent(this.sb.toString());
this.sb.setLength(0);
}
}
public void createNew() {
this.span = this.runFontSelector.createElement(this.document);
}
public void setMustCreateNewFlag(boolean val) {
this.spanReusable = !val;
}
public void fontAction(String fontname) {
if (fontname == null) {
this.runFontSelector.setAttribute(this.span, this.fallbackFontName);
} else {
this.runFontSelector.setAttribute(this.span, fontname);
this.lastFont = fontname;
}
}
public Object getResult() {
this.span = null;
return this.df;
}
public void setRunFontSelector(RunFontSelector runFontSelector) {
this.runFontSelector = runFontSelector;
}
public void setFallbackFont(String fontname) {
this.fallbackFontName = fontname;
}
}, RunFontSelector.RunFontActionType.XSL_FO);
}
protected FORenderer initializeFoRenderer(FOSettings settings) {
FORenderer ret = settings.getCustomFoRenderer();
if (ret == null) {
if ("application/xml-fo".equals(settings.getApacheFopMime())) {
ret = FORendererDummy.getInstance();
forceRequires1Pass();
} else {
ret = FORendererApacheFOP.getInstance();
}
settings.setCustomFoRenderer(ret);
}
return ret;
}
protected ConversionImageHandler initializeImageHandler(AbstractConversionSettings settings, ConversionImageHandler handler) {
if (handler == null)
handler = (settings.getImageDirPath() != null) ? new FOConversionImageHandler(settings.getImageDirPath(), true) : new FOConversionImageHandler();
return handler;
}
public FORenderer getFORenderer() {
return this.foRenderer;
}
public void forceRequires1Pass() {
this.requires2PassChecked = true;
this.requires2Pass = false;
}
public boolean isRequires2Pass() {
if (!this.requires2PassChecked) {
this.requires2Pass = checkRequires2Pass();
this.requires2PassChecked = true;
}
return this.requires2Pass;
}
protected boolean checkRequires2Pass() {
boolean ret = false;
boolean sectionPagesUsed = false;
ConversionSectionWrapper wrapper = null;
List<ConversionSectionWrapper> wrapperList = getSections().getList();
for (int i = 0; !ret && i < wrapperList.size(); i++) {
wrapper = wrapperList.get(i);
if (wrapper.getPageNumberInformation().getPageStart() > -1)
ret = ((i == 0 && wrapper.getPageNumberInformation().getPageStart() != 1) || i > 0);
if (wrapper.getPageNumberInformation().isSectionpagesPresent())
sectionPagesUsed = true;
}
return (ret || (sectionPagesUsed && wrapperList.size() > 1));
}
}

View file

@ -0,0 +1,28 @@
package org.docx4j.convert.out.fo;
import java.io.File;
import java.net.MalformedURLException;
import org.docx4j.model.images.FileConversionImageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FOConversionImageHandler extends FileConversionImageHandler {
private static final Logger log = LoggerFactory.getLogger(FOConversionImageHandler.class);
public FOConversionImageHandler() {
super(null, true);
}
public FOConversionImageHandler(String imageDirPath, boolean includeUUID) {
super(imageDirPath, includeUUID);
}
protected String setupImageUri(File imageFile) {
try {
return imageFile.toURI().toURL().toString();
} catch (MalformedURLException e) {
log.error(e.getMessage(), (Throwable)e);
return imageFile.getName();
}
}
}

View file

@ -0,0 +1,23 @@
package org.docx4j.convert.out.fo;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.Exporter;
public class FOExporterVisitor extends AbstractFOExporter {
protected static final FOExporterVisitorDelegate EXPORTER_DELEGATE_INSTANCE = new FOExporterVisitorDelegate();
protected static FOExporterVisitor instance = null;
protected FOExporterVisitor() {
super(EXPORTER_DELEGATE_INSTANCE);
}
public static Exporter<FOSettings> getInstance() {
if (instance == null)
synchronized (FOExporterVisitor.class) {
if (instance == null)
instance = new FOExporterVisitor();
}
return instance;
}
}

View file

@ -0,0 +1,72 @@
package org.docx4j.convert.out.fo;
import java.util.List;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.AbstractVisitorExporterDelegate;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.XsltCommonFunctions;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.parts.Part;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class FOExporterVisitorDelegate extends AbstractVisitorExporterDelegate<FOSettings, FOConversionContext> {
protected FOExporterVisitorDelegate() {
super(FOExporterVisitorGenerator.GENERATOR_FACTORY);
}
private static String XSL_FO = "http://www.w3.org/1999/XSL/Format";
protected Element createDocumentRoot(FOConversionContext conversionContext, Document document) throws Docx4JException {
return document.createElementNS(XSL_FO, "root");
}
protected void appendDocumentHeader(FOConversionContext conversionContext, Document document, Element documentRoot) throws Docx4JException {
LayoutMasterSetBuilder.appendLayoutMasterSetFragment(conversionContext, documentRoot);
}
protected Element createSectionRoot(FOConversionContext conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {
Element pageSequence = document.createElementNS(XSL_FO, "page-sequence");
int pageNumberInitial = sectionWrapper.getPageNumberInformation().getPageStart();
String pageFormat = sectionWrapper.getPageNumberInformation().getPageFormat();
pageSequence.setAttribute("master-reference", sectionWrapper.getId());
pageSequence.setAttribute("id", "section_" + sectionWrapper.getId());
pageFormat = FormattingSwitchHelper.getFoPageNumberFormat(pageFormat);
if (pageNumberInitial > -1)
pageSequence.setAttribute("initial-page-number", Integer.toString(pageNumberInitial));
if (pageFormat != null)
pageSequence.setAttribute("format", pageFormat);
return pageSequence;
}
protected void appendSectionHeader(FOConversionContext conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {
Element staticContent = null;
if (XsltCommonFunctions.hasFirstHeader(conversionContext))
appendPartContent(conversionContext, document, currentParent, "xsl-region-before-firstpage", sectionWrapper.getHeaderFooterPolicy().getFirstHeader(), sectionWrapper.getHeaderFooterPolicy().getFirstHeader().getJaxbElement().getContent());
if (XsltCommonFunctions.hasFirstFooter(conversionContext))
appendPartContent(conversionContext, document, currentParent, "xsl-region-after-firstpage", sectionWrapper.getHeaderFooterPolicy().getFirstFooter(), sectionWrapper.getHeaderFooterPolicy().getFirstFooter().getJaxbElement().getContent());
if (XsltCommonFunctions.hasEvenHeader(conversionContext))
appendPartContent(conversionContext, document, currentParent, "xsl-region-before-evenpage", sectionWrapper.getHeaderFooterPolicy().getEvenHeader(), sectionWrapper.getHeaderFooterPolicy().getEvenHeader().getJaxbElement().getContent());
if (XsltCommonFunctions.hasEvenFooter(conversionContext))
appendPartContent(conversionContext, document, currentParent, "xsl-region-after-evenpage", sectionWrapper.getHeaderFooterPolicy().getEvenFooter(), sectionWrapper.getHeaderFooterPolicy().getEvenFooter().getJaxbElement().getContent());
if (XsltCommonFunctions.hasDefaultHeader(conversionContext))
appendPartContent(conversionContext, document, currentParent, "xsl-region-before-default", sectionWrapper.getHeaderFooterPolicy().getDefaultHeader(), sectionWrapper.getHeaderFooterPolicy().getDefaultHeader().getJaxbElement().getContent());
if (XsltCommonFunctions.hasDefaultFooter(conversionContext))
appendPartContent(conversionContext, document, currentParent, "xsl-region-after-default", sectionWrapper.getHeaderFooterPolicy().getDefaultFooter(), sectionWrapper.getHeaderFooterPolicy().getDefaultFooter().getJaxbElement().getContent());
}
protected void appendPartContent(FOConversionContext conversionContext, Document document, Element currentParent, String name, Part part, List<Object> content) throws Docx4JException {
Element flow = document.createElementNS(XSL_FO, "static-content");
currentParent.appendChild(flow);
flow.setAttribute("flow-name", name);
appendPartContent(conversionContext, document, part, content, flow);
}
protected Element createSectionBody(FOConversionContext conversionContext, Document document, ConversionSectionWrapper sectionWrapper, Element currentParent) throws Docx4JException {
Element ret = document.createElementNS(XSL_FO, "flow");
ret.setAttribute("flow-name", "xsl-region-body");
return ret;
}
}

View file

@ -0,0 +1,337 @@
package org.docx4j.convert.out.fo;
import java.util.List;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.AbstractVisitorExporterDelegate;
import org.docx4j.convert.out.common.AbstractVisitorExporterGenerator;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.model.PropertyResolver;
import org.docx4j.model.images.WordXmlPictureE10;
import org.docx4j.model.images.WordXmlPictureE20;
import org.docx4j.model.listnumbering.Emulator;
import org.docx4j.model.properties.Property;
import org.docx4j.model.properties.PropertyFactory;
import org.docx4j.model.properties.paragraph.Indent;
import org.docx4j.model.properties.paragraph.PShading;
import org.docx4j.model.styles.StyleUtil;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.Br;
import org.docx4j.wml.CTTabStop;
import org.docx4j.wml.JcEnumeration;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.PPrBase;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.docx4j.wml.STBrType;
import org.docx4j.wml.STTabJc;
import org.docx4j.wml.STTabTlc;
import org.docx4j.wml.Style;
import org.docx4j.wml.TcPr;
import org.docx4j.wml.TrPr;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
public class FOExporterVisitorGenerator extends AbstractVisitorExporterGenerator<FOConversionContext> {
private static Logger log = LoggerFactory.getLogger(FOExporterVisitorGenerator.class);
private static String XSL_FO = "http://www.w3.org/1999/XSL/Format";
public static final AbstractVisitorExporterDelegate.AbstractVisitorExporterGeneratorFactory<FOConversionContext> GENERATOR_FACTORY = new AbstractVisitorExporterDelegate.AbstractVisitorExporterGeneratorFactory<FOConversionContext>() {
public AbstractVisitorExporterGenerator<FOConversionContext> createInstance(FOConversionContext conversionContext, Document document, Node parentNode) {
return new FOExporterVisitorGenerator(conversionContext, document, parentNode);
}
};
private FOExporterVisitorGenerator(FOConversionContext conversionContext, Document document, Node parentNode) {
super(conversionContext, document, parentNode);
}
protected AbstractVisitorExporterDelegate.AbstractVisitorExporterGeneratorFactory<FOConversionContext> getFactory() {
return GENERATOR_FACTORY;
}
protected DocumentFragment createImage(int imgType, FOConversionContext conversionContext, Object anchorOrInline) {
switch (imgType) {
case 1:
return WordXmlPictureE10.createXslFoImgE10(conversionContext, anchorOrInline);
case 2:
return WordXmlPictureE20.createXslFoImgE20(conversionContext, anchorOrInline);
}
return null;
}
protected Element createNode(Document doc, int nodeType) {
switch (nodeType) {
case 1:
return this.document.createElementNS(XSL_FO, "block");
case 2:
return this.document.createElementNS(XSL_FO, "inline");
}
return null;
}
protected void handleBr(Br br) {
boolean firstBr = true;
R r = (R)br.getParent();
int pos = getPos(r.getContent(), br);
if (pos < 0) {
log.error("Couldn't locate w:br in w:r");
} else if (pos == 0) {
Object rParent = r.getParent();
if (rParent instanceof P) {
P parentP = (P)rParent;
pos = getPos(parentP.getContent(), r);
if (pos < 0) {
log.error("Couldn't locate w:r in w:p");
} else if (pos > 0) {
Object beforeR = parentP.getContent().get(pos - 1);
if (beforeR instanceof R) {
List<Object> list = ((R)beforeR).getContent();
Object previous = list.get(list.size() - 1);
if (previous instanceof Br)
firstBr = false;
}
}
} else {
log.info("TODO: handle run parent " + rParent.getClass().getName());
}
} else {
Object previous = r.getContent().get(pos - 1);
if (previous instanceof Br)
firstBr = false;
}
if (!firstBr && (br.getType() == null || br.getType().equals(STBrType.TEXT_WRAPPING))) {
Element ret = createNode(this.document, 1);
ret.setAttribute("linefeed-treatment", "preserve");
ret.setAttribute("white-space-treatment", "preserve");
ret.setTextContent("\n");
getCurrentParent().appendChild(ret);
} else {
convertToNode(this.conversionContext, br, "w:br", this.document, getCurrentParent());
}
if (br.getType() != null && br.getType().equals(STBrType.PAGE))
this.currentSpan = null;
}
protected void convertTabToNode(FOConversionContext conversionContext, Document document) throws DOMException {
if (!conversionContext.isInComplexFieldDefinition())
if (this.pPr != null && this.pPr.getTabs() != null) {
CTTabStop tabStop = this.pPr.getTabs().getTab().get(0);
if (tabStop != null && tabStop.getLeader().equals(STTabTlc.DOT) && tabStop.getVal().equals(STTabJc.RIGHT)) {
Element foLeader = document.createElementNS(XSL_FO, "leader");
foLeader.setAttribute("leader-length.minimum", "12pt");
foLeader.setAttribute("leader-length.maximum", "100%");
foLeader.setAttribute("leader-length.optimum", "40pt");
foLeader.setAttribute("leader-pattern", "dots");
getCurrentParent().appendChild(foLeader);
} else {
getCurrentParent().appendChild(document.createTextNode("   "));
}
} else {
getCurrentParent().appendChild(document.createTextNode("   "));
}
}
protected Element handlePPr(FOConversionContext conversionContext, PPr pPrDirect, boolean sdt, Element currentParent) {
Element ret = currentParent;
PropertyResolver propertyResolver = conversionContext.getPropertyResolver();
String defaultParagraphStyleId = "Normal";
if (conversionContext.getWmlPackage().getMainDocumentPart().getStyleDefinitionsPart(false) != null) {
Style defaultParagraphStyle = conversionContext.getWmlPackage().getMainDocumentPart().getStyleDefinitionsPart(false).getDefaultParagraphStyle();
if (defaultParagraphStyle != null)
defaultParagraphStyleId = defaultParagraphStyle.getStyleId();
}
String pStyleVal = null;
if (pPrDirect != null && pPrDirect.getPStyle() != null) {
pStyleVal = pPrDirect.getPStyle().getVal();
} else {
pStyleVal = defaultParagraphStyleId;
}
getLog().debug("style '" + pStyleVal);
try {
this.pPr = propertyResolver.getEffectivePPr(pPrDirect);
getLog().debug("getting rPr for paragraph style");
this.rPr = propertyResolver.getEffectiveRPr(null, pPrDirect);
RPr rPrParagraphMark = XmlUtils.<RPr>deepCopy(this.rPr);
if (pPrDirect != null)
StyleUtil.apply(pPrDirect.getRPr(), rPrParagraphMark);
if (getLog().isDebugEnabled() && this.pPr != null)
getLog().debug(XmlUtils.marshaltoString(this.pPr, true, true));
boolean inlist = false;
boolean indentHandledByNumbering = false;
Element foBlockElement = null;
Element foListBlock = null;
if (this.pPr != null && this.pPr.getNumPr() != null && this.pPr.getNumPr().getNumId() != null && this.pPr.getNumPr().getNumId().getVal().longValue() != 0L) {
Emulator.ResultTriple triple;
inlist = true;
foListBlock = this.document.createElementNS(XSL_FO, "list-block");
currentParent.appendChild(foListBlock);
if (this.pPr.getShd() != null) {
PShading pShading = new PShading(this.pPr.getShd());
pShading.setXslFO(foListBlock);
}
Element foListItem = this.document.createElementNS(XSL_FO, "list-item");
foListBlock.appendChild(foListItem);
Element foListItemLabel = this.document.createElementNS(XSL_FO, "list-item-label");
foListItem.appendChild(foListItemLabel);
Element foListItemLabelBody = this.document.createElementNS(XSL_FO, "block");
foListItemLabel.appendChild(foListItemLabelBody);
Element foListItemBody = this.document.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:list-item-body");
foListItem.appendChild(foListItemBody);
foListItemBody.setAttribute("start-indent", "body-start()");
if (pPrDirect != null && pPrDirect.getNumPr() != null) {
triple = Emulator.getNumber(conversionContext.getWmlPackage(), pStyleVal, pPrDirect.getNumPr().getNumId().getVal().toString(), pPrDirect.getNumPr().getIlvl().getVal().toString());
} else {
PPrBase.NumPr.Ilvl ilvl = this.pPr.getNumPr().getIlvl();
String ilvlString = (ilvl == null) ? "0" : ilvl.getVal().toString();
triple = null;
if (this.pPr.getNumPr().getNumId() != null)
triple = Emulator.getNumber(conversionContext.getWmlPackage(), pStyleVal, this.pPr.getNumPr().getNumId().getVal().toString(), ilvlString);
}
if (triple == null) {
getLog().warn("computed number ResultTriple was null");
if (getLog().isDebugEnabled())
foListItemLabelBody.setTextContent("nrt");
} else if (triple.getRPr() == null) {
if (this.pPr.getRPr() == null) {
XsltFOFunctions.setFont(conversionContext, foListItemLabelBody, this.pPr, this.rPr, triple.getNumString());
} else {
createFoAttributes(conversionContext.getWmlPackage(), rPrParagraphMark, foListItemLabel);
createFoAttributes(conversionContext.getWmlPackage(), rPrParagraphMark, foListItemBody);
XsltFOFunctions.setFont(conversionContext, foListItemLabelBody, this.pPr, rPrParagraphMark, triple.getNumString());
}
} else {
RPr actual = XmlUtils.<RPr>deepCopy(triple.getRPr());
XsltFOFunctions.setFont(conversionContext, foListItemLabelBody, this.pPr, actual, triple.getNumString());
StyleUtil.apply(rPrParagraphMark, actual);
createFoAttributes(conversionContext.getWmlPackage(), actual, foListItemLabel);
createFoAttributes(conversionContext.getWmlPackage(), actual, foListItemBody);
}
int numChars = 1;
if (triple.getBullet() != null) {
foListItemLabelBody.setTextContent(triple.getBullet());
} else if (triple.getNumString() == null) {
getLog().warn("computed NumString was null!");
if (getLog().isDebugEnabled())
foListItemLabelBody.setTextContent("nns");
numChars = 0;
} else {
Text number = this.document.createTextNode(triple.getNumString());
foListItemLabelBody.appendChild(number);
numChars = triple.getNumString().length();
}
Indent indent = new Indent(pPrDirect.getInd(), triple.getIndent());
if (indent.isHanging()) {
indent.setXslFOListBlock(foListBlock, -1);
} else {
int numWidth = 90 * numChars;
int pdbs = XsltFOFunctions.getDistanceToNextTabStop(conversionContext, indent.getNumberPosition(), numWidth, pPrDirect.getTabs(), conversionContext.getWmlPackage().getMainDocumentPart().getDocumentSettingsPart());
indent.setXslFOListBlock(foListBlock, pdbs);
}
indentHandledByNumbering = true;
foBlockElement = this.document.createElementNS(XSL_FO, "block");
foListItemBody.appendChild(foBlockElement);
ret = foBlockElement;
}
if (this.pPr != null) {
boolean ignoreBorders = !sdt;
createFoAttributes(conversionContext, this.pPr, currentParent, inlist, ignoreBorders);
}
if (this.rPr != null)
if (foListBlock == null) {
createFoAttributes(conversionContext.getWmlPackage(), this.rPr, currentParent);
} else {
createFoAttributes(conversionContext.getWmlPackage(), this.rPr, foListBlock);
}
} catch (Exception e) {
getLog().error(e.getMessage(), (Throwable)e);
}
return ret;
}
protected void createFoAttributes(FOConversionContext conversionContext, PPr pPr, Element foBlockElement, boolean inList, boolean ignoreBorders) {
List<Property> properties = PropertyFactory.createProperties(conversionContext.getWmlPackage(), pPr);
for (Property p : properties) {
if (p != null) {
if (ignoreBorders && (p instanceof org.docx4j.model.properties.paragraph.PBorderTop || p instanceof org.docx4j.model.properties.paragraph.PBorderBottom))
continue;
if (inList && !(p instanceof Indent)) {
p.setXslFO(foBlockElement);
continue;
}
if (!inList)
p.setXslFO(foBlockElement);
}
}
if (pPr == null)
return;
if (pPr.getBidi() != null && pPr.getBidi().isVal())
if (pPr.getJc() != null)
if (pPr.getJc().getVal().equals(JcEnumeration.RIGHT)) {
foBlockElement.setAttribute("text-align", "left");
} else if (pPr.getJc().getVal().equals(JcEnumeration.LEFT)) {
foBlockElement.setAttribute("text-align", "right");
}
if (pPr.getTabs() != null) {
CTTabStop tabStop = pPr.getTabs().getTab().get(0);
if (tabStop != null && tabStop.getVal().equals(STTabJc.RIGHT))
foBlockElement.setAttribute("text-align-last", "justify");
}
}
protected static void applyFoAttributes(List<Property> properties, Element foElement) {
if (properties != null && !properties.isEmpty())
for (int i = 0; i < properties.size(); i++)
properties.get(i).setXslFO(foElement);
}
protected static void createFoAttributes(TrPr trPr, Element foBlockElement) {
if (trPr == null)
return;
applyFoAttributes(PropertyFactory.createProperties(trPr), foBlockElement);
}
protected static void createFoAttributes(TcPr tcPr, Element foBlockElement) {
if (tcPr == null)
return;
applyFoAttributes(PropertyFactory.createProperties(tcPr), foBlockElement);
}
protected void handleRPr(FOConversionContext conversionContext, PPr pPrDirect, RPr rPrDirect, Element currentParent) {
PropertyResolver propertyResolver = conversionContext.getPropertyResolver();
try {
RPr rPr = propertyResolver.getEffectiveRPr(rPrDirect, pPrDirect);
if (getLog().isDebugEnabled() && rPr != null)
getLog().debug(XmlUtils.marshaltoString(rPr, true, true));
createFoAttributes(conversionContext.getWmlPackage(), rPr, currentParent);
} catch (Exception e) {
getLog().error(e.getMessage(), (Throwable)e);
}
}
protected static void createFoAttributes(WordprocessingMLPackage wmlPackage, RPr rPr, Element foInlineElement) {
List<Property> properties = PropertyFactory.createProperties(wmlPackage, rPr);
for (Property p : properties)
p.setXslFO(foInlineElement);
}
protected void rtlAwareAppendChildToCurrentP(Element spanEl) {
if (this.rPr != null && this.rPr.getRtl() != null && this.rPr.getRtl().isVal()) {
spanEl.removeAttribute("direction");
Element bidiOverride = this.document.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:bidi-override");
bidiOverride.setAttribute("unicode-bidi", "embed");
bidiOverride.setAttribute("direction", "rtl");
bidiOverride.appendChild(spanEl);
this.currentP.appendChild(bidiOverride);
} else {
this.currentP.appendChild(spanEl);
}
}
}

View file

@ -0,0 +1,26 @@
package org.docx4j.convert.out.fo;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.Exporter;
import org.docx4j.convert.out.common.WmlXsltExporterDelegate;
public class FOExporterXslt extends AbstractFOExporter {
protected static final String DEFAULT_TEMPLATES_RESOURCE = "org/docx4j/convert/out/fo/docx2fo.xslt";
protected static final WmlXsltExporterDelegate<FOSettings, FOConversionContext> EXPORTER_DELEGATE = new WmlXsltExporterDelegate<FOSettings, FOConversionContext>("org/docx4j/convert/out/fo/docx2fo.xslt");
protected static FOExporterXslt instance = null;
protected FOExporterXslt() {
super(EXPORTER_DELEGATE);
}
public static Exporter<FOSettings> getInstance() {
if (instance == null)
synchronized (FOExporterXslt.class) {
if (instance == null)
instance = new FOExporterXslt();
}
return instance;
}
}

View file

@ -0,0 +1,226 @@
package org.docx4j.convert.out.fo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBElement;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.docx4j.Docx4J;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.ConversionSectionWrappers;
import org.docx4j.finders.SectPrFinder;
import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.PageDimensions;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.HpsMeasure;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.PPrBase;
import org.docx4j.wml.ParaRPr;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.docx4j.wml.SectPr;
import org.docx4j.wml.Text;
import org.plutext.jaxb.xslfo.LayoutMasterSet;
import org.plutext.jaxb.xslfo.SimplePageMaster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class FOPAreaTreeHelper {
protected static Logger log = LoggerFactory.getLogger(FOPAreaTreeHelper.class);
static void trimContent(WordprocessingMLPackage hfPkg) {
SectPrFinder sf = new SectPrFinder(hfPkg.getMainDocumentPart());
try {
new TraversalUtil(hfPkg.getMainDocumentPart().getContents(), sf);
} catch (Docx4JException e) {
log.error(e.getMessage(), (Throwable)e);
}
List<SectPr> sectPrList = sf.getSectPrList();
if (hfPkg.getMainDocumentPart().getJaxbElement().getBody().getSectPr() != null)
sectPrList.remove(0);
P filler = createFillerP();
List<Object> contents = hfPkg.getMainDocumentPart().getContent();
contents.clear();
for (SectPr sectPr : sectPrList) {
contents.add(filler);
contents.add(filler);
contents.add(filler);
contents.add(filler);
P p = Context.getWmlObjectFactory().createP();
PPr ppr = Context.getWmlObjectFactory().createPPr();
p.setPPr(ppr);
ppr.setSectPr(sectPr);
contents.add(p);
}
if (hfPkg.getMainDocumentPart().getJaxbElement().getBody().getSectPr() != null) {
contents.add(filler);
contents.add(filler);
contents.add(filler);
contents.add(filler);
}
}
private static P createFillerP() {
ObjectFactory wmlObjectFactory = Context.getWmlObjectFactory();
P p = wmlObjectFactory.createP();
PPr ppr = wmlObjectFactory.createPPr();
p.setPPr(ppr);
ParaRPr pararpr = wmlObjectFactory.createParaRPr();
PPrBase.Spacing pprbasespacing = wmlObjectFactory.createPPrBaseSpacing();
ppr.setSpacing(pprbasespacing);
pprbasespacing.setBefore(BigInteger.valueOf(800L));
pprbasespacing.setAfter(BigInteger.valueOf(800L));
R r = wmlObjectFactory.createR();
p.getContent().add(r);
RPr rpr = wmlObjectFactory.createRPr();
r.setRPr(rpr);
HpsMeasure hpsmeasure3 = wmlObjectFactory.createHpsMeasure();
rpr.setSz(hpsmeasure3);
hpsmeasure3.setVal(BigInteger.valueOf(96L));
Text text = wmlObjectFactory.createText();
JAXBElement<Text> textWrapped = wmlObjectFactory.createRT(text);
r.getContent().add(textWrapped);
text.setValue("BODY CONTENT");
return p;
}
static Document getAreaTreeViaFOP(WordprocessingMLPackage hfPkg, boolean useXSLT) throws Docx4JException, ParserConfigurationException, SAXException, IOException {
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(hfPkg);
foSettings.setApacheFopMime("application/X-fop-areatree");
foSettings.setLayoutMasterSetCalculationInProgress(true);
if (log.isDebugEnabled())
foSettings.setFoDumpFile(new File(System.getProperty("user.dir") + "/hf.fo"));
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (useXSLT) {
Docx4J.toFO(foSettings, os, 1);
} else {
Docx4J.toFO(foSettings, os, 2);
}
InputStream is = new ByteArrayInputStream(os.toByteArray());
DocumentBuilder builder = XmlUtils.getNewDocumentBuilder();
return builder.parse(is);
}
static void calculateHFExtents(Document areaTree, Map<String, Integer> headerBpda, Map<String, Integer> footerBpda) {
if (log.isDebugEnabled())
log.debug(XmlUtils.w3CDomNodeToString(areaTree));
for (int i = 0; i < areaTree.getDocumentElement().getChildNodes().getLength(); i++) {
Node pageSequence = areaTree.getDocumentElement().getChildNodes().item(i);
if (pageSequence instanceof Element)
if (!pageSequence.getLocalName().equals("pageSequence")) {
log.error("Unexpected element: " + pageSequence.getLocalName());
} else {
for (int j = 0; j < pageSequence.getChildNodes().getLength(); j++) {
Node pageViewport = pageSequence.getChildNodes().item(j);
if (pageViewport instanceof Element)
if (!pageViewport.getLocalName().equals("pageViewport")) {
log.error("Unexpected element: " + pageViewport.getLocalName());
} else {
String simplePageMasterName = ((Element)pageViewport).getAttribute("simple-page-master-name");
log.debug("processing simple-page-master-name: " + simplePageMasterName);
if (headerBpda.containsKey(simplePageMasterName)) {
log.debug(".. dupe .. ignore");
} else {
Element page = (Element)pageViewport.getFirstChild();
for (int k = 0; k < page.getChildNodes().getLength(); k++) {
Node regionViewport = page.getChildNodes().item(k);
if (regionViewport instanceof Element) {
Element region = (Element)regionViewport.getFirstChild();
int bpda = 0;
if (region.getLocalName().equals("regionBefore") || region.getLocalName().equals("regionAfter"))
for (int m = 0; m < region.getChildNodes().getLength(); m++) {
Element block = (Element)region.getChildNodes().item(m);
if (block.getLocalName().equals("block")) {
try {
bpda += Integer.parseInt(block.getAttribute("bpda"));
} catch (NumberFormatException nfe) {
log.error("For @bpda, \n" + XmlUtils.w3CDomNodeToString(block));
log.error(nfe.getMessage(), (Throwable)nfe);
}
} else {
log.debug(simplePageMasterName + " - Unexpected element: " + block.getLocalName());
}
}
if (region.getLocalName().equals("regionBefore")) {
headerBpda.put(simplePageMasterName, Integer.valueOf(bpda));
} else if (region.getLocalName().equals("regionAfter")) {
footerBpda.put(simplePageMasterName, Integer.valueOf(bpda));
} else if (!region.getLocalName().equals("regionBody")) {
log.error("unexpected region: " + region.getLocalName());
}
}
}
}
}
}
}
}
}
static void adjustLayoutMasterSet(LayoutMasterSet layoutMasterSet, ConversionSectionWrappers conversionSectionWrappers, Map<String, Integer> headerBpda, Map<String, Integer> footerBpda) {
List<ConversionSectionWrapper> sections = conversionSectionWrappers.getList();
ConversionSectionWrapper section = null;
for (Object o : (Iterable<Object>)layoutMasterSet.getSimplePageMasterOrPageSequenceMaster()) {
if (o instanceof SimplePageMaster) {
SimplePageMaster spm = (SimplePageMaster)o;
String simplePageMasterName = spm.getMasterName();
int index = -1 + Integer.parseInt(simplePageMasterName.substring(1, simplePageMasterName.indexOf("-")));
PageDimensions page = null;
if (sections.get(index) == null) {
log.error("Couldn't find section " + index + " from " + simplePageMasterName);
} else {
page = sections.get(index).getPageDimensions();
}
if (spm.getRegionBefore() != null) {
Integer hBpdaMilliPts = headerBpda.get(simplePageMasterName);
if (hBpdaMilliPts == null) {
log.error("No headerBpda for " + simplePageMasterName);
} else {
float hBpdaPts = (float)(hBpdaMilliPts / 1000);
spm.getRegionBefore().setExtent(hBpdaPts + "pt");
spm.getRegionBody().setMarginTop(hBpdaPts + "pt");
float totalHeight = (float)(page.getHeaderMargin() / 20) + hBpdaPts;
float extraMargin = (float)(page.getPgMar().getTop().intValue() / 20) - totalHeight;
if (extraMargin > 0.0F) {
float required = (float)((page.getPgMar().getTop().intValue() - page.getHeaderMargin()) / 20);
spm.getRegionBody().setMarginTop(required + "pt");
}
}
}
if (spm.getRegionAfter() != null) {
Integer fBpdaMilliPts = footerBpda.get(simplePageMasterName);
if (fBpdaMilliPts == null) {
log.error("No footerBpda for " + simplePageMasterName);
continue;
}
float fBpdaPts = (float)(fBpdaMilliPts / 1000);
spm.getRegionAfter().setExtent(fBpdaPts + "pt");
spm.getRegionBody().setMarginBottom(fBpdaPts + "pt");
float totalHeight = (float)(page.getFooterMargin() / 20) + fBpdaPts;
float extraMargin = (float)(page.getPgMar().getBottom().intValue() / 20) - totalHeight;
if (extraMargin > 0.0F) {
float required = (float)((page.getPgMar().getBottom().intValue() - page.getFooterMargin()) / 20);
spm.getRegionBody().setMarginBottom(required + "pt");
}
}
}
}
}
}

View file

@ -0,0 +1,445 @@
package org.docx4j.convert.out.fo;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBElement;
import javax.xml.transform.TransformerException;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FORenderer;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.convert.out.common.writer.AbstractPictWriter;
import org.docx4j.convert.out.fo.renderers.AbstractFORenderer;
import org.docx4j.model.structure.PageDimensions;
import org.docx4j.vml.CTTextbox;
import org.docx4j.vml.VmlAllCoreAttributes;
import org.docx4j.vml.VmlShapeElements;
import org.docx4j.vml.wordprocessingDrawing.CTWrap;
import org.docx4j.vml.wordprocessingDrawing.STVerticalAnchor;
import org.docx4j.vml.wordprocessingDrawing.STWrapType;
import org.docx4j.wml.Pict;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public abstract class FOPictWriterAbstract extends AbstractPictWriter {
protected static Logger log = LoggerFactory.getLogger(FOPictWriterAbstract.class);
private static String XSL_FO = "http://www.w3.org/1999/XSL/Format";
public abstract boolean foRendererSupportsFoFloat();
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node modelContent, Writer.TransformState state, Document doc) throws TransformerException {
Pict pict = (Pict)unmarshalledNode;
VmlShapeElements shape = null;
for (Object o : pict.getAnyAndAny()) {
o = XmlUtils.unwrap(o);
if (o instanceof VmlShapeElements && !(o instanceof org.docx4j.vml.CTShapetype)) {
shape = (VmlShapeElements)o;
log.debug("Found " + shape.getClass().getName());
break;
}
}
if (shape == null)
return context.getMessageWriter().message(context, "Couldn't find v:shape (or v:rectangle etc) in w:pict.");
CTTextbox textBox = null;
CTWrap w10Wrap = null;
for (JAXBElement<?> o : shape.getEGShapeElements()) {
o = (JAXBElement<?>)XmlUtils.unwrap(o);
if (o instanceof CTTextbox)
textBox = (CTTextbox)o;
if (o instanceof CTWrap)
w10Wrap = (CTWrap)o;
}
if (textBox == null)
return context.getMessageWriter().message(context, "Couldn't find v:textbox in w:shape.");
Map<String, String> props = null;
if (shape instanceof VmlAllCoreAttributes) {
props = getProperties(((VmlAllCoreAttributes)shape).getStyle());
} else {
log.warn(shape.getClass().getName() + " does not implement VmlAllCoreAttributes, so can't access @style if present");
return context.getMessageWriter().message(context, shape.getClass().getName() + " does not implement VmlAllCoreAttributes, so can't access @style if present");
}
boolean wrap = true;
if (w10Wrap != null) {
if (w10Wrap.getType() != null && (w10Wrap.getType().equals(STWrapType.TOP_AND_BOTTOM) || w10Wrap.getType().equals(STWrapType.SQUARE) || w10Wrap.getType().equals(STWrapType.TIGHT) || w10Wrap.getType().equals(STWrapType.THROUGH)))
wrap = false;
if (w10Wrap.getAnchory() != null && w10Wrap.getAnchory().equals(STVerticalAnchor.PAGE))
wrap = false;
}
return handleVTextBox(context, modelContent, doc, shape, props, wrap);
}
public Node handleVTextBox(AbstractWmlConversionContext context, Node modelContent, Document doc, VmlShapeElements shape, Map<String, String> props, boolean wrap) {
String mso_position_vertical_relative = props.get("mso-position-vertical-relative");
String mso_position_vertical = props.get("mso-position-vertical");
ConversionSectionWrapper csw = context.getSections().getCurrentSection();
PageDimensions pageDimensions = csw.getPageDimensions();
int writableWidthTwips = pageDimensions.getWritableWidthTwips();
float writableWidthPts = (float)(writableWidthTwips / 20);
int writableHeightTwips = pageDimensions.getWritableHeightTwips();
float writableHeightPts = (float)(writableHeightTwips / 20);
FORenderer foRenderer = ((FOSettings)context.getConversionSettings()).getCustomFoRenderer();
log.debug(foRenderer.getClass().getName());
if (wrap) {
log.debug("textbox - wrapped text");
if (mso_position_vertical_relative == null) {
try {
log.warn(XmlUtils.marshaltoString(shape));
} catch (Exception e) {
log.warn(e.getMessage());
}
return context.getMessageWriter().message(context, "mso_position_vertical_relative==null. What to do?");
}
if (mso_position_vertical_relative.equals("text")) {
Element element = doc.createElementNS(XSL_FO, "block");
setBorders(element);
String str = props.get("margin-top");
if (str == null) {
log.error("margin top prop not found. What to do?");
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
return element;
}
float marginTop = parsePtsVal(str);
if (foRendererSupportsFoFloat()) {
String str1 = props.get("mso-position-horizontal-relative");
String str2 = props.get("mso-position-horizontal");
if (str1 == null) {
log.warn("No support for mso_position_horizontal_relative==null");
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
return element;
}
if (!str1.equals("text")) {
log.warn("No support for mso_position_horizontal_relative==" + str1.equals("text"));
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
return element;
}
float ml = parsePtsVal(props.get("margin-left"));
if (str2 == null) {
log.warn("No support for mso_position_horizontal==null");
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
return element;
}
if (str2.equals("absolute")) {
log.warn("Degrading absolute position to left/right");
if ((double)(ml / writableWidthPts) <= 0.5D) {
str2 = "left";
} else {
str2 = "right";
}
}
element = doc.createElementNS(XSL_FO, "float");
setBorders(element);
if (str2.equals("left")) {
element.setAttribute("float", "start");
} else if (str2.equals("center")) {
log.warn("Degrading center to right");
element.setAttribute("float", "end");
} else if (str2.equals("right")) {
element.setAttribute("float", "end");
}
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
} else if (marginTop <= 0.0F) {
marginTopZeroCase(props, element, writableWidthPts);
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
} else {
element = doc.createElementNS(XSL_FO, "table");
if (!marginTopPositiveCase(foRenderer, props, doc, element, writableWidthPts, modelContent.getChildNodes())) {
element = doc.createElementNS(XSL_FO, "block");
setBorders(element);
XmlUtils.treeCopy(modelContent.getChildNodes(), element);
}
}
log.debug(XmlUtils.w3CDomNodeToString(element));
return element;
}
if (foRendererSupportsFoFloat()) {
if (mso_position_vertical_relative.equals("page") || mso_position_vertical_relative.equals("top-margin-area") || mso_position_vertical_relative.equals("bottom-margin-area")) {
if (mso_position_vertical_relative.equals("page")) {
if (mso_position_vertical.equals("top")) {
Element element = doc.createElementNS(XSL_FO, "float");
element.setAttribute("float", "before");
setBorders(element);
log.debug(XmlUtils.w3CDomNodeToString(element));
return element;
}
if (mso_position_vertical.equals("bottom")) {
Element element1 = doc.createElementNS(XSL_FO, "footnote");
Element footnoteBody = doc.createElementNS(XSL_FO, "footnote-body");
element1.appendChild(footnoteBody);
Element block = doc.createElementNS(XSL_FO, "block");
footnoteBody.appendChild(block);
setBorders(block);
XmlUtils.treeCopy(modelContent.getChildNodes(), block);
return element1;
}
log.warn("No support for mso_position_vertical==" + mso_position_vertical);
return context.getMessageWriter().message(context, "TODO for fo:float capable renderer, support no-wrap + mso-position-vertical=" + mso_position_vertical);
}
if (mso_position_vertical_relative.equals("top-margin-area")) {
Element element = doc.createElementNS(XSL_FO, "float");
element.setAttribute("float", "before");
setBorders(element);
log.debug(XmlUtils.w3CDomNodeToString(element));
return element;
}
if (mso_position_vertical_relative.equals("bottom-margin-area")) {
Element element1 = doc.createElementNS(XSL_FO, "footnote");
Element footnoteBody = doc.createElementNS(XSL_FO, "footnote-body");
element1.appendChild(footnoteBody);
Element block = doc.createElementNS(XSL_FO, "block");
footnoteBody.appendChild(block);
setBorders(block);
XmlUtils.treeCopy(modelContent.getChildNodes(), block);
return element1;
}
return context.getMessageWriter().message(context, "TODO (how did we get here?) mso-position-vertical-relative=" + mso_position_vertical_relative);
}
return context.getMessageWriter().message(context, "TODO for fo:float capable renderer, support no-wrap + mso-position-vertical-relative=" + mso_position_vertical_relative);
}
return context.getMessageWriter().message(context, "TODO for fo:float INcapable renderer, support no-wrap + mso-position-vertical-relative=" + mso_position_vertical_relative);
}
log.debug("textbox - over/behind docx text");
Element ret = doc.createElementNS(XSL_FO, "block-container");
XmlUtils.treeCopy(modelContent.getChildNodes(), ret);
setBorders(ret);
String mso_position_horizontal_relative = props.get("mso-position-horizontal-relative");
String mso_position_horizontal = props.get("mso-position-horizontal");
if (mso_position_horizontal_relative == null) {
log.warn("No support for mso_position_horizontal_relative==null");
} else if (!mso_position_horizontal_relative.equals("text")) {
log.warn("No support for mso_position_horizontal_relative==" + mso_position_horizontal_relative.equals("text"));
} else {
float boxWidth = parsePtsVal(props.get("width"));
ret.setAttribute("width", props.get("width"));
ret.setAttribute("height", props.get("height"));
if (mso_position_horizontal == null) {
log.warn("No support for mso_position_horizontal==null");
} else if (mso_position_horizontal.equals("left")) {
ret.setAttribute("left", "0pt");
} else if (mso_position_horizontal.equals("center")) {
int marginLeft = Math.round((writableWidthPts - boxWidth) / 2.0F);
ret.setAttribute("left", marginLeft + "pt");
} else if (mso_position_horizontal.equals("right")) {
int marginLeft = Math.round(writableWidthPts - boxWidth);
ret.setAttribute("left", marginLeft + "pt");
} else if (mso_position_horizontal.equals("absolute")) {
ret.setAttribute("margin-left", props.get("margin-left"));
}
}
ret.setAttribute("z-index", props.get("z-index"));
String margin_top = props.get("margin-top");
if (mso_position_vertical_relative == null) {
log.warn(XmlUtils.marshaltoString(shape));
return context.getMessageWriter().message(context, "mso_position_vertical_relative==null. What to do?");
}
if (mso_position_vertical_relative.equals("text")) {
ret.setAttribute("position", "absolute");
if (margin_top != null)
ret.setAttribute("top", margin_top);
log.debug(XmlUtils.w3CDomNodeToString(ret));
return ret;
}
if (mso_position_vertical_relative.equals("page") || mso_position_vertical_relative.equals("top-margin-area") || mso_position_vertical_relative.equals("bottom-margin-area")) {
ret.setAttribute("position", "fixed");
if (mso_position_vertical_relative.equals("page")) {
if (mso_position_vertical.equals("top")) {
if (margin_top != null)
ret.setAttribute("top", margin_top);
} else if (mso_position_vertical.equals("bottom")) {
int top = Math.round(writableHeightPts);
ret.setAttribute("top", top + "pt");
} else {
log.warn("No support for mso_position_vertical==" + mso_position_vertical);
}
log.debug(XmlUtils.w3CDomNodeToString(ret));
return ret;
}
if (mso_position_vertical_relative.equals("top-margin-area")) {
if (margin_top != null)
ret.setAttribute("top", margin_top);
log.debug(XmlUtils.w3CDomNodeToString(ret));
return ret;
}
if (mso_position_vertical_relative.equals("bottom-margin-area")) {
int top = Math.round(writableHeightPts);
ret.setAttribute("top", top + "pt");
log.debug(XmlUtils.w3CDomNodeToString(ret));
return ret;
}
return context.getMessageWriter().message(context, "TODO (how did we get here?) mso-position-vertical-relative=" + mso_position_vertical_relative);
}
return context.getMessageWriter().message(context, "TODO support no-wrap + mso-position-vertical-relative=" + mso_position_vertical_relative);
}
private void setBorders(Element ret) {
ret.setAttribute("border-left-style", "solid");
ret.setAttribute("border-top-style", "solid");
ret.setAttribute("border-bottom-style", "solid");
ret.setAttribute("border-right-style", "solid");
}
private Map<String, String> getProperties(String s) {
Map<String, String> map = new HashMap<String, String>();
if (s == null) {
log.warn("shape has no @style");
return map;
}
for (String entry : s.split(";")) {
String[] parts = entry.split(":");
assert parts.length == 2 : "Invalid entry: " + entry;
map.put(parts[0], parts[1]);
}
return map;
}
private float parsePtsVal(String pts) {
if (pts == null) {
log.warn("No val!");
return -99.0F;
}
if (pts.contains("pt")) {
pts = pts.substring(0, pts.indexOf("pt"));
return Float.parseFloat(pts);
}
if (pts.equals("0"))
return 0.0F;
log.warn("Unit is not points! " + pts);
return -99.0F;
}
private void marginTopZeroCase(Map<String, String> props, Element ret, float widthPts) {
String mso_position_horizontal_relative = props.get("mso-position-horizontal-relative");
String mso_position_horizontal = props.get("mso-position-horizontal");
if (mso_position_horizontal_relative == null) {
log.warn("No support for mso_position_horizontal_relative==null");
} else if (!mso_position_horizontal_relative.equals("text")) {
log.warn("No support for mso_position_horizontal_relative==" + mso_position_horizontal_relative.equals("text"));
} else {
float boxWidth = parsePtsVal(props.get("width"));
if (mso_position_horizontal == null) {
log.warn("No support for mso_position_horizontal==null");
} else if (mso_position_horizontal.equals("left")) {
ret.setAttribute("margin-left", "0pt");
int marginRight = Math.round(widthPts - boxWidth);
ret.setAttribute("margin-right", marginRight + "pt");
} else if (mso_position_horizontal.equals("center")) {
int marginLeft = Math.round((widthPts - boxWidth) / 2.0F);
ret.setAttribute("margin-left", marginLeft + "pt");
ret.setAttribute("margin-right", marginLeft + "pt");
} else if (mso_position_horizontal.equals("right")) {
ret.setAttribute("margin-right", "0pt");
int marginLeft = Math.round(widthPts - boxWidth);
ret.setAttribute("margin-left", marginLeft + "pt");
} else if (mso_position_horizontal.equals("absolute")) {
ret.setAttribute("margin-left", props.get("margin-left"));
float ml = parsePtsVal(props.get("margin-left"));
int mRight = Math.round(widthPts - (boxWidth + ml));
ret.setAttribute("margin-right", mRight + "pt");
}
}
}
private boolean marginTopPositiveCase(FORenderer foRenderer, Map<String, String> props, Document doc, Element ret, float widthPts, NodeList childNodes) {
String mso_position_horizontal_relative = props.get("mso-position-horizontal-relative");
String mso_position_horizontal = props.get("mso-position-horizontal");
if (mso_position_horizontal_relative == null) {
log.warn("No support for mso_position_horizontal_relative==null");
return false;
}
if (!mso_position_horizontal_relative.equals("text")) {
log.warn("No support for mso_position_horizontal_relative==" + mso_position_horizontal_relative.equals("text"));
return false;
}
float boxWidth = parsePtsVal(props.get("width"));
if (mso_position_horizontal == null) {
log.warn("No support for mso_position_horizontal==null");
return false;
}
float ml = parsePtsVal(props.get("margin-left"));
if (mso_position_horizontal.equals("absolute"))
if ((double)(ml / widthPts) < 0.334D) {
mso_position_horizontal = "left";
} else if ((double)(ml / widthPts) < 0.665D) {
mso_position_horizontal = "right";
} else {
mso_position_horizontal = "center";
}
if (mso_position_horizontal.equals("left")) {
Element tcol1 = doc.createElementNS(XSL_FO, "table-column");
ret.appendChild(tcol1);
tcol1.setAttribute("column-number", "1");
int col1W = Math.round(ml + boxWidth);
tcol1.setAttribute("column-width", col1W + "pt");
Element tcol2 = doc.createElementNS(XSL_FO, "table-column");
ret.appendChild(tcol2);
tcol2.setAttribute("column-number", "2");
int col2W = Math.round(widthPts - (float)col1W);
tcol2.setAttribute("column-width", col2W + "pt");
Element tbody = doc.createElementNS(XSL_FO, "table-body");
ret.appendChild(tbody);
Element trow = doc.createElementNS(XSL_FO, "table-row");
tbody.appendChild(trow);
Element tc1 = doc.createElementNS(XSL_FO, "table-cell");
trow.appendChild(tc1);
Element block = doc.createElementNS(XSL_FO, "block");
setBorders(block);
tc1.appendChild(block);
XmlUtils.treeCopy(childNodes, block);
Element tc2 = doc.createElementNS(XSL_FO, "table-cell");
trow.appendChild(tc2);
Element placeholder = doc.createElementNS(XSL_FO, "block");
placeholder.setTextContent("#TEXTBOX#");
tc2.appendChild(placeholder);
if (foRenderer instanceof AbstractFORenderer) {
((AbstractFORenderer)foRenderer).TEXTBOX_POSTPROCESSING_REQUIRED = true;
} else {
log.warn("TODO: implement TEXTBOX_POSTPROCESSING_REQUIRED for " + foRenderer.getClass().getName());
}
return true;
}
if (mso_position_horizontal.equals("center")) {
log.warn("Can't support mso_position_horizontal:center");
return false;
}
if (mso_position_horizontal.equals("right")) {
Element tcol1 = doc.createElementNS(XSL_FO, "table-column");
ret.appendChild(tcol1);
tcol1.setAttribute("column-number", "1");
int col1W = Math.round(widthPts - boxWidth);
tcol1.setAttribute("column-width", col1W + "pt");
Element tcol2 = doc.createElementNS(XSL_FO, "table-column");
ret.appendChild(tcol2);
tcol2.setAttribute("column-number", "2");
int col2W = Math.round(boxWidth);
tcol2.setAttribute("column-width", col2W + "pt");
Element tbody = doc.createElementNS(XSL_FO, "table-body");
ret.appendChild(tbody);
Element trow = doc.createElementNS(XSL_FO, "table-row");
tbody.appendChild(trow);
Element tc1 = doc.createElementNS(XSL_FO, "table-cell");
trow.appendChild(tc1);
Element placeholder = doc.createElementNS(XSL_FO, "block");
placeholder.setTextContent("#TEXTBOX#");
tc1.appendChild(placeholder);
Element tc2 = doc.createElementNS(XSL_FO, "table-cell");
trow.appendChild(tc2);
Element block = doc.createElementNS(XSL_FO, "block");
setBorders(block);
tc2.appendChild(block);
XmlUtils.treeCopy(childNodes, block);
if (foRenderer instanceof AbstractFORenderer) {
((AbstractFORenderer)foRenderer).TEXTBOX_POSTPROCESSING_REQUIRED = true;
} else {
log.warn("TODO: implement TEXTBOX_POSTPROCESSING_REQUIRED for " + foRenderer.getClass().getName());
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,12 @@
package org.docx4j.convert.out.fo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FOPictWriterFloatAvoided extends FOPictWriterAbstract {
protected static Logger log = LoggerFactory.getLogger(FOPictWriterFloatAvoided.class);
public boolean foRendererSupportsFoFloat() {
return false;
}
}

View file

@ -0,0 +1,12 @@
package org.docx4j.convert.out.fo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FOPictWriterFloatUsed extends FOPictWriterAbstract {
protected static Logger log = LoggerFactory.getLogger(FOPictWriterFloatUsed.class);
public boolean foRendererSupportsFoFloat() {
return true;
}
}

View file

@ -0,0 +1,129 @@
package org.docx4j.convert.out.fo;
import java.util.List;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.writer.AbstractFldSimpleWriter;
import org.docx4j.convert.out.common.writer.AbstractPagerefHandler;
import org.docx4j.convert.out.common.writer.RefHandler;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.properties.Property;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class FldSimpleWriter extends AbstractFldSimpleWriter {
protected static final String FO_NS = "http://www.w3.org/1999/XSL/Format";
protected static final String XSL_NS = "http://www.w3.org/1999/XSL/Transform";
protected static class PageHandler implements AbstractFldSimpleWriter.FldSimpleNodeWriterHandler {
public String getName() {
return "PAGE";
}
public int getProcessType() {
return 1;
}
public Node toNode(AbstractWmlConversionContext context, FldSimpleModel model, Document doc) throws TransformerException {
return doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:page-number");
}
}
protected static abstract class AbstractPagesHandler implements AbstractFldSimpleWriter.FldSimpleNodeWriterHandler {
protected String fieldName = null;
protected AbstractPagesHandler(String fieldName) {
this.fieldName = fieldName;
}
public String getName() {
return this.fieldName;
}
public int getProcessType() {
return 1;
}
public Node toNode(AbstractWmlConversionContext context, FldSimpleModel model, Document doc) throws TransformerException {
Element ret = null;
if (((FOConversionContext)context).isRequires2Pass()) {
ret = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:inline");
ret.appendChild(doc.createTextNode("${" + getParameterName(context) + "}"));
} else {
ret = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:wrapper");
Element pncl = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:page-number-citation-last");
String refId = getRefid(context);
pncl.setAttribute("ref-id", getRefid(context));
ret.appendChild(pncl);
ret.appendChild(doc.createTextNode(""));
}
return ret;
}
protected abstract String getRefid(AbstractWmlConversionContext param1AbstractWmlConversionContext);
protected abstract String getParameterName(AbstractWmlConversionContext param1AbstractWmlConversionContext);
}
protected static class NumpagesHandler extends AbstractPagesHandler {
protected NumpagesHandler() {
super("NUMPAGES");
}
protected String getParameterName(AbstractWmlConversionContext context) {
return "field_numpages_" + context.getSections().getCurrentSection().getId() + "_value";
}
protected String getRefid(AbstractWmlConversionContext context) {
List<ConversionSectionWrapper> wrappers = context.getSections().getList();
return "section_" + wrappers.get(wrappers.size() - 1).getId();
}
}
protected static class SectionpagesHandler extends AbstractPagesHandler {
protected SectionpagesHandler() {
super("SECTIONPAGES");
}
protected String getParameterName(AbstractWmlConversionContext context) {
return "field_sectionpages_" + context.getSections().getCurrentSection().getId() + "_value";
}
protected String getRefid(AbstractWmlConversionContext context) {
return "section_" + context.getSections().getCurrentSection().getId();
}
}
protected static class PagerefHandler extends AbstractPagerefHandler {
protected PagerefHandler() {
super(2);
}
protected Node createPageref(AbstractWmlConversionContext context, Document doc, String bookmarkId) {
Element ret = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:page-number-citation");
ret.setAttribute("ref-id", bookmarkId);
return ret;
}
}
protected FldSimpleWriter() {
super("http://www.w3.org/1999/XSL/Format", "fo:inline");
}
protected void registerHandlers() {
super.registerHandlers();
registerHandler(new PageHandler());
registerHandler(new HyperlinkWriter());
registerHandler(new RefHandler(2));
registerHandler(new PagerefHandler());
registerHandler(new NumpagesHandler());
registerHandler(new SectionpagesHandler());
}
protected void applyProperties(List<Property> properties, Node node) {
XsltFOFunctions.applyFoAttributes(properties, (Element)node);
}
}

View file

@ -0,0 +1,15 @@
package org.docx4j.convert.out.fo;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.writer.AbstractHyperlinkWriter;
import org.docx4j.convert.out.common.writer.AbstractHyperlinkWriterModel;
import org.docx4j.convert.out.common.writer.HyperlinkUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class HyperlinkWriter extends AbstractHyperlinkWriter {
protected Node toNode(AbstractWmlConversionContext context, AbstractHyperlinkWriterModel model, Document doc) throws TransformerException {
return HyperlinkUtil.toNode(2, context, model, model.getContent(), doc);
}
}

View file

@ -0,0 +1,191 @@
package org.docx4j.convert.out.fo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.docx4j.UnitsOfMeasurement;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.ConversionSectionWrapper;
import org.docx4j.convert.out.common.preprocess.PartialDeepCopy;
import org.docx4j.events.EventFinished;
import org.docx4j.events.StartEvent;
import org.docx4j.events.WellKnownProcessSteps;
import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.HeaderFooterPolicy;
import org.docx4j.model.structure.PageDimensions;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.plutext.jaxb.xslfo.ConditionalPageMasterReference;
import org.plutext.jaxb.xslfo.LayoutMasterSet;
import org.plutext.jaxb.xslfo.ObjectFactory;
import org.plutext.jaxb.xslfo.OddOrEvenType;
import org.plutext.jaxb.xslfo.PagePositionType;
import org.plutext.jaxb.xslfo.PageSequenceMaster;
import org.plutext.jaxb.xslfo.RegionAfter;
import org.plutext.jaxb.xslfo.RegionBefore;
import org.plutext.jaxb.xslfo.RegionBody;
import org.plutext.jaxb.xslfo.RepeatablePageMasterAlternatives;
import org.plutext.jaxb.xslfo.SimplePageMaster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
public class LayoutMasterSetBuilder {
protected static Logger log = LoggerFactory.getLogger(LayoutMasterSetBuilder.class);
private static ObjectFactory factory;
public static DocumentFragment getLayoutMasterSetFragment(AbstractWmlConversionContext context) {
LayoutMasterSet lms = getFoLayoutMasterSet(context);
FOSettings foSettings = (FOSettings)context.getConversionSettings();
if (!foSettings.lsLayoutMasterSetCalculationInProgress())
fixExtents(lms, context, true);
Document document = XmlUtils.marshaltoW3CDomDocument(lms, Context.getXslFoContext());
DocumentFragment docfrag = document.createDocumentFragment();
docfrag.appendChild(document.getDocumentElement());
return docfrag;
}
private static void fixExtents(LayoutMasterSet lms, AbstractWmlConversionContext context, boolean useXSLT) {
WordprocessingMLPackage wordMLPackage = context.getWmlPackage();
StartEvent startEvent = new StartEvent(wordMLPackage, WellKnownProcessSteps.FO_EXTENTS);
startEvent.publish();
log.debug("incoming LMS: " + XmlUtils.marshaltoString(lms, Context.getXslFoContext()));
Set<String> relationshipTypes = new TreeSet<String>();
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes");
relationshipTypes.add("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments");
try {
WordprocessingMLPackage hfPkg = (WordprocessingMLPackage)PartialDeepCopy.process(wordMLPackage, relationshipTypes);
FOPAreaTreeHelper.trimContent(hfPkg);
Document areaTree = FOPAreaTreeHelper.getAreaTreeViaFOP(hfPkg, useXSLT);
log.debug(XmlUtils.w3CDomNodeToString(areaTree));
Map<String, Integer> headerBpda = new HashMap<String, Integer>();
Map<String, Integer> footerBpda = new HashMap<String, Integer>();
FOPAreaTreeHelper.calculateHFExtents(areaTree, headerBpda, footerBpda);
FOPAreaTreeHelper.adjustLayoutMasterSet(lms, context.getSections(), headerBpda, footerBpda);
} catch (Exception e) {
e.printStackTrace();
}
log.debug("resulting LMS: " + XmlUtils.marshaltoString(lms, Context.getXslFoContext()));
new EventFinished(startEvent).publish();
}
public static void appendLayoutMasterSetFragment(AbstractWmlConversionContext context, Node foRoot) {
LayoutMasterSet lms = getFoLayoutMasterSet(context);
FOSettings foSettings = (FOSettings)context.getConversionSettings();
if (!foSettings.lsLayoutMasterSetCalculationInProgress())
fixExtents(lms, context, false);
Document document = XmlUtils.marshaltoW3CDomDocument(lms, Context.getXslFoContext());
XmlUtils.treeCopy(document.getDocumentElement(), foRoot);
}
private static LayoutMasterSet getFoLayoutMasterSet(AbstractWmlConversionContext context) {
LayoutMasterSet lms = getFactory().createLayoutMasterSet();
List<ConversionSectionWrapper> sections = context.getSections().getList();
ConversionSectionWrapper section = null;
for (int i = 0; i < sections.size(); i++) {
section = sections.get(i);
HeaderFooterPolicy hf = section.getHeaderFooterPolicy();
String sectionName = "s" + Integer.toString(i + 1);
if (hf.getFirstHeader() != null || hf.getFirstFooter() != null)
lms.getSimplePageMasterOrPageSequenceMaster().add(createSimplePageMaster(sectionName + "-firstpage", section.getPageDimensions(), "firstpage", (hf.getFirstHeader() != null), (hf.getFirstFooter() != null)));
if (hf.getEvenHeader() != null || hf.getEvenFooter() != null)
lms.getSimplePageMasterOrPageSequenceMaster().add(createSimplePageMaster(sectionName + "-evenpage", section.getPageDimensions(), "evenpage", (hf.getEvenHeader() != null), (hf.getEvenFooter() != null)));
if (hf.getDefaultHeader() != null || hf.getDefaultFooter() != null)
lms.getSimplePageMasterOrPageSequenceMaster().add(createSimplePageMaster(sectionName + "-default", section.getPageDimensions(), "default", (hf.getDefaultHeader() != null), (hf.getDefaultFooter() != null)));
if (hf.getDefaultHeader() == null && hf.getDefaultFooter() == null)
lms.getSimplePageMasterOrPageSequenceMaster().add(createSimplePageMaster(sectionName + "-simple", section.getPageDimensions(), "simple", true, true));
lms.getSimplePageMasterOrPageSequenceMaster().add(createPageSequenceMaster(hf, sectionName));
}
return lms;
}
private static PageSequenceMaster createPageSequenceMaster(HeaderFooterPolicy hf, String sectionName) {
boolean noHeadersFootersAfterFirstPage = true;
PageSequenceMaster psm = getFactory().createPageSequenceMaster();
psm.setMasterName(sectionName);
RepeatablePageMasterAlternatives rpma = getFactory().createRepeatablePageMasterAlternatives();
psm.getSinglePageMasterReferenceOrRepeatablePageMasterReferenceOrRepeatablePageMasterAlternatives().add(rpma);
if (hf.getFirstHeader() != null || hf.getFirstFooter() != null) {
ConditionalPageMasterReference cpmr1 = getFactory().createConditionalPageMasterReference();
cpmr1.setMasterReference(sectionName + "-firstpage");
cpmr1.setPagePosition(PagePositionType.FIRST);
rpma.getConditionalPageMasterReference().add(cpmr1);
}
if (hf.getEvenHeader() != null || hf.getEvenFooter() != null) {
ConditionalPageMasterReference cpmr2 = getFactory().createConditionalPageMasterReference();
cpmr2.setMasterReference(sectionName + "-evenpage");
cpmr2.setOddOrEven(OddOrEvenType.EVEN);
rpma.getConditionalPageMasterReference().add(cpmr2);
ConditionalPageMasterReference cpmr3 = getFactory().createConditionalPageMasterReference();
cpmr3.setMasterReference(sectionName + "-default");
cpmr3.setOddOrEven(OddOrEvenType.ODD);
rpma.getConditionalPageMasterReference().add(cpmr3);
noHeadersFootersAfterFirstPage = false;
} else if (hf.getDefaultHeader() != null || hf.getDefaultFooter() != null) {
ConditionalPageMasterReference cpmr4 = getFactory().createConditionalPageMasterReference();
cpmr4.setMasterReference(sectionName + "-default");
rpma.getConditionalPageMasterReference().add(cpmr4);
noHeadersFootersAfterFirstPage = false;
}
if (noHeadersFootersAfterFirstPage) {
ConditionalPageMasterReference cpmr5 = getFactory().createConditionalPageMasterReference();
cpmr5.setMasterReference(sectionName + "-simple");
rpma.getConditionalPageMasterReference().add(cpmr5);
}
return psm;
}
private static SimplePageMaster createSimplePageMaster(String masterName, PageDimensions page, String appendRegionName, boolean needBefore, boolean needAfter) {
SimplePageMaster spm = getFactory().createSimplePageMaster();
spm.setMasterName(masterName);
spm.setPageHeight(UnitsOfMeasurement.twipToBest(page.getPgSz().getH().intValue()));
spm.setPageWidth(UnitsOfMeasurement.twipToBest(page.getPgSz().getW().intValue()));
spm.setMarginLeft(UnitsOfMeasurement.twipToBest(page.getPgMar().getLeft().intValue()));
spm.setMarginRight(UnitsOfMeasurement.twipToBest(page.getPgMar().getRight().intValue()));
RegionBody rb = getFactory().createRegionBody();
rb.setMarginLeft("0mm");
rb.setMarginRight("0mm");
float halfPageHeight = (float)(page.getPgSz().getH().intValue() / 40);
String halfPageHeightPts = halfPageHeight + "pt";
spm.setRegionBody(rb);
if (needBefore) {
RegionBefore rBefore = getFactory().createRegionBefore();
rBefore.setRegionName("xsl-region-before-" + appendRegionName);
spm.setRegionBefore(rBefore);
int marginTopTwips = page.getHeaderMargin();
spm.setMarginTop(UnitsOfMeasurement.twipToBest(marginTopTwips));
rBefore.setExtent(halfPageHeightPts);
rb.setMarginTop(halfPageHeightPts);
} else {
spm.setMarginTop(UnitsOfMeasurement.twipToBest(page.getPgMar().getTop().intValue()));
}
if (needAfter) {
RegionAfter rAfter = getFactory().createRegionAfter();
rAfter.setRegionName("xsl-region-after-" + appendRegionName);
spm.setRegionAfter(rAfter);
int marginBottomTwips = page.getFooterMargin();
spm.setMarginBottom(UnitsOfMeasurement.twipToBest(marginBottomTwips));
rAfter.setExtent(halfPageHeightPts);
rb.setMarginBottom(halfPageHeightPts);
} else {
spm.setMarginBottom(UnitsOfMeasurement.twipToBest(page.getPgMar().getBottom().intValue()));
}
return spm;
}
private static ObjectFactory getFactory() {
if (factory == null)
factory = new ObjectFactory();
return factory;
}
}

View file

@ -0,0 +1,121 @@
package org.docx4j.convert.out.fo;
import java.io.IOException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
public class PlaceholderReplacementHandler extends DefaultHandler {
protected PlaceholderLookup placeholderLookup = null;
protected DefaultHandler defaultHandler = null;
protected StringBuilder buffer = new StringBuilder();
protected char[] tmpCharArray = new char[10240];
public PlaceholderReplacementHandler(DefaultHandler defaultHandler, PlaceholderLookup variableLookup) {
this.placeholderLookup = variableLookup;
this.defaultHandler = defaultHandler;
}
public int hashCode() {
return this.defaultHandler.hashCode();
}
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
return this.defaultHandler.resolveEntity(publicId, systemId);
}
public void notationDecl(String name, String publicId, String systemId) throws SAXException {
this.defaultHandler.notationDecl(name, publicId, systemId);
}
public boolean equals(Object obj) {
return this.defaultHandler.equals(obj);
}
public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
this.defaultHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
}
public void setDocumentLocator(Locator locator) {
this.defaultHandler.setDocumentLocator(locator);
}
public void startDocument() throws SAXException {
this.defaultHandler.startDocument();
}
public void endDocument() throws SAXException {
this.defaultHandler.endDocument();
}
public void startPrefixMapping(String prefix, String uri) throws SAXException {
this.defaultHandler.startPrefixMapping(prefix, uri);
}
public void endPrefixMapping(String prefix) throws SAXException {
this.defaultHandler.endPrefixMapping(prefix);
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
this.defaultHandler.startElement(uri, localName, qName, attributes);
}
public String toString() {
return this.defaultHandler.toString();
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (this.buffer.length() > 0) {
if (this.placeholderLookup.hasPlaceholders(this.buffer))
this.placeholderLookup.replaceValues(this.buffer);
if (this.buffer.length() > 0) {
if (this.buffer.length() > this.tmpCharArray.length)
this.tmpCharArray = new char[(this.buffer.length() / 1024 + 1) * 1024];
this.buffer.getChars(0, this.buffer.length(), this.tmpCharArray, 0);
this.defaultHandler.characters(this.tmpCharArray, 0, this.buffer.length());
this.buffer.setLength(0);
}
}
this.defaultHandler.endElement(uri, localName, qName);
}
public void characters(char[] ch, int start, int length) throws SAXException {
this.buffer.append(ch, start, length);
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
this.defaultHandler.ignorableWhitespace(ch, start, length);
}
public void processingInstruction(String target, String data) throws SAXException {
this.defaultHandler.processingInstruction(target, data);
}
public void skippedEntity(String name) throws SAXException {
this.defaultHandler.skippedEntity(name);
}
public void warning(SAXParseException e) throws SAXException {
this.defaultHandler.warning(e);
}
public void error(SAXParseException e) throws SAXException {
this.defaultHandler.error(e);
}
public void fatalError(SAXParseException e) throws SAXException {
this.defaultHandler.fatalError(e);
}
public static interface PlaceholderLookup {
boolean hasPlaceholders(StringBuilder param1StringBuilder);
void replaceValues(StringBuilder param1StringBuilder);
}
}

View file

@ -0,0 +1,66 @@
package org.docx4j.convert.out.fo;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.convert.out.common.Writer;
import org.docx4j.convert.out.common.writer.AbstractSymbolWriter;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.fop.fonts.Typeface;
import org.docx4j.wml.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
public class SymbolWriter extends AbstractSymbolWriter {
private static final Logger log = LoggerFactory.getLogger(SymbolWriter.class);
public Node toNode(AbstractWmlConversionContext context, Object unmarshalledNode, Node modelContent, Writer.TransformState state, Document doc) throws TransformerException {
R.Sym modelData = (R.Sym)unmarshalledNode;
String fontName = modelData.getFont();
String textValue = modelData.getChar();
PhysicalFont pf = context.getWmlPackage().getFontMapper().get(fontName);
char chValue = '\000';
Typeface typeface = null;
if (pf != null) {
typeface = pf.getTypeface();
if (typeface != null) {
if (textValue.length() > 1) {
try {
chValue = (char)Integer.parseInt(textValue, 16);
} catch (NumberFormatException nfe) {
chValue = '\000';
}
} else {
chValue = textValue.charAt(0);
}
if (chValue != '\000') {
if (chValue > '')
chValue = (char)(chValue - 61440);
if (typeface.mapChar(chValue) == '\000') {
chValue = (char)(chValue + 61440);
if (typeface.mapChar(chValue) == '\000')
chValue = '\000';
}
if (chValue != '\000')
textValue = Character.toString(chValue);
}
}
}
Text theChar = doc.createTextNode(textValue);
DocumentFragment docfrag = doc.createDocumentFragment();
if (pf == null) {
log.warn("No physical font present for:" + fontName);
docfrag.appendChild(theChar);
} else {
Element foInline = doc.createElementNS("http://www.w3.org/1999/XSL/Format", "fo:inline");
docfrag.appendChild(foInline);
foInline.setAttribute("font-family", pf.getName());
foInline.appendChild(theChar);
}
return docfrag;
}
}

Some files were not shown because too many files have changed in this diff Show more