org.docx4j.convert.out.common.AbstractVisitorExporterGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docx4j-core Show documentation
Show all versions of docx4j-core Show documentation
docx4j is a library which helps you to work with the Office Open
XML file format as used in docx
documents, pptx presentations, and xlsx spreadsheets.
/*
Licensed to Plutext Pty Ltd under one or more contributor license agreements.
* This file is part of docx4j.
docx4j is licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.docx4j.convert.out.common;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.common.writer.AbstractBookmarkStartWriter;
import org.docx4j.convert.out.common.writer.AbstractFldSimpleWriter;
import org.docx4j.convert.out.common.writer.AbstractHyperlinkWriter;
import org.docx4j.convert.out.common.writer.AbstractPictWriter;
import org.docx4j.convert.out.common.writer.AbstractSymbolWriter;
import org.docx4j.convert.out.common.writer.AbstractTableWriter;
import org.docx4j.openpackaging.parts.relationships.Namespaces;
import org.docx4j.wml.Br;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
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;
import java.util.LinkedList;
import java.util.List;
/**
* The …ExporterGenerator is the visitor, that gets used in those cases where a document is done
* as a NonXSLT. (docx4j supports convert.out via both xslt and non-xslt based approaches)
*
* @since 3.0
*/
public abstract class AbstractVisitorExporterGenerator extends TraversalUtil.CallbackImpl {
private static Logger log = LoggerFactory.getLogger(AbstractVisitorExporterGenerator.class);
protected static final String TAB_DUMMY = "\u00A0\u00A0\u00A0";
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 tr = new LinkedList();
protected LinkedList tc = new LinkedList();
//current paragraph style to inherit styles in rPr
protected PPr pPr = null;
protected RPr rPr = null;
// E20 image
protected Object anchorOrInline;
protected AbstractVisitorExporterGenerator(CC conversionContext, Document document, Node parentNode) {
this.conversionContext = conversionContext;
this.document = document;
this.parentNode = parentNode;
}
@Override
public boolean shouldTraverse(Object o) {
if ((o instanceof org.docx4j.wml.Tbl) ||
(o instanceof org.docx4j.wml.P.Hyperlink) ||
(o instanceof org.docx4j.wml.CTSimpleField) ||
(o instanceof org.docx4j.vml.CTTextbox) ||
(o instanceof org.docx4j.wml.FldChar)) {
return false;
} else {
return true;
}
}
protected Node getCurrentParent() {
//this might be executed within a new level of traversal util
//currentSpan or currentP might be null
return (currentSpan != null ?
currentSpan :
(currentP != null ? currentP : parentNode)
);
}
protected void convertToNode(CC conversionContext,
Object unmarshalledNode, String modelId,
Document document, Node parentNode) throws DOMException {
// To use our existing model, first we need childResults.
// We get these using a new Generator object.
log.debug(modelId);
DocumentFragment childResults = null;
if (unmarshalledNode instanceof ContentAccessor) {
childResults = document.createDocumentFragment();
AbstractVisitorExporterGenerator generator = getFactory().createInstance(conversionContext, document, childResults);
new TraversalUtil(((ContentAccessor)unmarshalledNode).getContent(), generator);
} else if (unmarshalledNode instanceof org.docx4j.wml.Pict) {
// if it contains a textbox..
// repeating this...
org.docx4j.vml.CTTextbox textBox = getTextBox((org.docx4j.wml.Pict)unmarshalledNode);
if (textBox!=null) {
childResults = document.createDocumentFragment();
AbstractVisitorExporterGenerator 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) {
parentNode.appendChild(child);
}
@Override
public void walkJAXBElements(Object o) {
Node existingParentNode = parentNode;
if (o instanceof org.docx4j.wml.Tr) {
tr.push(document.createElementNS(Namespaces.NS_WORD12, "tr"));
//parentNode is in this case the DocumentFragment, that get's passed
//to the TableModel/TableModelWriter
parentNode.appendChild(tr.peek());
} else if (o instanceof org.docx4j.wml.Tc) {
tc.push(document.createElementNS(Namespaces.NS_WORD12, "tc"));
(tr.peek()).appendChild(tc.peek());
// now the html p content will go temporarily go in w:tc,
// which is what we need for our existing table model.
parentNode = tc.peek();
}
super.walkJAXBElements(o);
if (o instanceof org.docx4j.wml.Tr) {
tr.pop();
} else if (o instanceof org.docx4j.wml.Tc) {
tc.pop();
parentNode = existingParentNode; // restore
}
}
@Override
public List