log.debug("convertXHTML extension function for: " + sdtParent + "/w:sdt/w:sdtContent/" + contentChild);
org.w3c.dom.Document docContainer = XmlUtils.neww3cDomDocument();
DocumentFragment docfrag = docContainer.createDocumentFragment();
XHTMLImporter xHTMLImporter= null;
Class<?> xhtmlImporterClass = null;
try {
xhtmlImporterClass = Class.forName("org.docx4j.convert.in.xhtml.XHTMLImporterImpl");
Constructor<?> ctor = xhtmlImporterClass.getConstructor(WordprocessingMLPackage.class);
xHTMLImporter = (XHTMLImporter) ctor.newInstance(pkg);
} catch (Exception e) {
log.error("docx4j-XHTMLImport jar not found. Please add this to your classpath.");
log.error(e.getMessage(), e);
return xhtmlError(sdtParent, docContainer, docfrag, "Missing XHTML Handler!");
}
xHTMLImporter.setSequenceCounters(sequenceCounters);
/* Find setBookmarkIdNext method.
* It's not part of the interface until 3.3.0, so use reflection
*/
Method[] methods = xhtmlImporterClass.getMethods();
Method method = null;
for (int j=0; j<methods.length; j++) {
if (methods[j].getName().equals("setBookmarkIdNext")
&& methods[j].getParameterTypes().length==1) {
method = methods[j];
break;
}
}
if (method==null) {
log.info("setBookmarkIdNext method not found. If you are using docx4j-ImportXHTML v3.2.1 or later, it should be present.");
} else {
try {
//xHTMLImporter.setBookmarkIdNext(bookmarkCounter.bookmarkId);
method.invoke(xHTMLImporter, bookmarkCounter.bookmarkId);
} catch (Exception e1) {
log.error(e1.getMessage(), e1);
}
}
QueryString qs = new QueryString();
HashMap<String, String> map = qs.parseQueryString(tag, true);
String xpathId = map.get(OpenDoPEHandler.BINDING_ROLE_XPATH);
log.info("Looking for xpath by id: " + xpathId);
Xpath xpath = xPathsPart.getXPathById(xPathsPart.getJaxbElement(), xpathId);
if (xpath==null) {
log.warn("Couldn't find xpath with id: " + xpathId);
return null;
}
String storeItemId = xpath.getDataBinding().getStoreItemID();
String xpathExp = xpath.getDataBinding().getXpath();
String prefixMappings = xpath.getDataBinding().getPrefixMappings();
String r = BindingHandler.xpathGetString(pkg, customXmlDataStorageParts, storeItemId, xpathExp, prefixMappings);
try {
RPr rPrSDT = null;
Node rPrNode = rPrNodeIt.nextNode();
if (rPrNode!=null) {
rPrSDT = (RPr)XmlUtils.unmarshal(rPrNode);
}
if (r==null || r.trim().equals("")) {
return createPlaceholder(rPrSDT, sdtParent);
}
r = r.trim();
// log.debug(r);
//String unescaped = StringEscapeUtils.unescapeHtml(r);
//log.info("Unescaped: " + unescaped);
// It comes to us unescaped, so the above is unnecessary.
if (r.startsWith("<span")) {
// Wrap the XHTML in a span element with @class, @style as appropriate
// so FS uses suitable CSS
// Code copied from XsltHTMLFunctions.createBlockForRPr
Style defaultRunStyle =
(pkg.getMainDocumentPart().getStyleDefinitionsPart(false) != null ?
pkg.getMainDocumentPart().getStyleDefinitionsPart(false).getDefaultCharacterStyle() :
null);
String defaultCharacterStyleId;
if (defaultRunStyle.getStyleId()==null) // possible, for non MS source docx
defaultCharacterStyleId = "DefaultParagraphFont";
else defaultCharacterStyleId = defaultRunStyle.getStyleId();
StyleTree styleTree = pkg.getMainDocumentPart().getStyleTree();
// Set @class
String classVal =null;
String rStyleVal = defaultCharacterStyleId;
if ( rPrSDT!=null && rPrSDT.getRStyle()!=null) {
rStyleVal = rPrSDT.getRStyle().getVal();
}
Tree<AugmentedStyle> cTree = styleTree.getCharacterStylesTree();
org.docx4j.model.styles.Node<AugmentedStyle> asn = cTree.get(rStyleVal);
if (asn==null) {
log.warn("No style node for: " + rStyleVal);
} else {
classVal = StyleTree.getHtmlClassAttributeValue(cTree, asn);
}
String css = null;
if ( rPrSDT!=null) {
StringBuilder result = new StringBuilder();
HtmlCssHelper.createCss(pkg, rPrSDT, result);
css = result.toString();
if (css.equals("")) {
css =null;
}
}
if (css==null && classVal==null) {
// Do nothing
} else if (classVal==null) {
// just @style
r = "<span style=\"" + css + "\">" + r + "</span>";
} else if (css==null) {
// just @class
r = "<span class=\"" + classVal + "\">" + r + "</span>";
} else {
r = "<span style=\"" + css + "\" class=\"" + classVal + "\">" + r + "</span>";
}
log.debug("\nenhanced with css: \n" + r);
} else if (Docx4jProperties.getProperty("docx4j.model.datastorage.BindingTraverser.XHTML.Block.rStyle.Adopt", false)) {
log.debug("Block.rStyle.Adopt..");
// its block level, and we're instructed to apply the paragraph style
// linked to w:sdtPr/w:rPr/w:rStyle (if any)
String rStyleVal=null;
if ( rPrSDT!=null && rPrSDT.getRStyle()!=null) {
rStyleVal = rPrSDT.getRStyle().getVal();
log.debug(".." + rStyleVal);
}
if (rStyleVal==null) {
log.debug("No rStyle specified ");
} else {
Style pStyle = pkg.getMainDocumentPart().getStyleDefinitionsPart(false).getLinkedStyle(rStyleVal);
if (pStyle==null) {
log.warn("No linked style for " + rStyleVal);
} else {
// Got the pStyle .. now apply it in the XHTML
StyleTree styleTree = pkg.getMainDocumentPart().getStyleTree();
String pStyleVal = pStyle.getStyleId();
log.debug(".." + pStyleVal);
// Set @class
String classVal =null;
Tree<AugmentedStyle> pTree = styleTree.getParagraphStylesTree();
org.docx4j.model.styles.Node<AugmentedStyle> asn = pTree.get(pStyleVal);
if (asn==null) {
log.warn("No style node for: " + pStyleVal);
} else {
classVal = StyleTree.getHtmlClassAttributeValue(pTree, asn);
}
String css = null;
if ( rPrSDT!=null) {
StringBuilder result = new StringBuilder();
HtmlCssHelper.createCss(pkg, rPrSDT, result);
css = result.toString();
if (css.equals("")) {
css =null;
}
}
// Recurse the XHTML, adding @class and @style
r = XHTMLAttrInjector.injectAttrs(r, classVal, css);
log.debug(".." + r);
}
}
}
xHTMLImporter.setHyperlinkStyle(BindingHandler.getHyperlinkResolver().getHyperlinkStyleId());
// Method setHyperlinkStyleMethod = xhtmlImporterClass.getMethod("setHyperlinkStyle", String.class);
// setHyperlinkStyleMethod.invoke(null,
// BindingHandler.getHyperlinkResolver().getHyperlinkStyleId());
String baseUrl = null;
List<Object> results = null;
try {
results = xHTMLImporter.convert(r, baseUrl );
// Method convertMethod = xhtmlImporterClass.getMethod("convert", String.class, String.class, WordprocessingMLPackage.class );
// results = (List<Object>)convertMethod.invoke(null, r, baseUrl, pkg);
} catch (Exception e) {
if (e instanceof NullPointerException) {