package org.krakenapps.docxcod;
import static org.krakenapps.docxcod.util.CloseableHelper.safeClose;
import static org.krakenapps.docxcod.util.XMLDocHelper.evaluateXPath;
import static org.krakenapps.docxcod.util.XMLDocHelper.newDocumentBuilder;
import static org.krakenapps.docxcod.util.XMLDocHelper.newXPath;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import javax.xml.xpath.XPath;
import org.krakenapps.docxcod.util.XMLDocHelper;
import org.krakenapps.docxcod.util.XMLDocHelper.NodeListWrapper;
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 class AugmentedDirectiveProcessor implements OOXMLProcessor {
private Logger logger = LoggerFactory.getLogger(getClass().getName());
static String[] augmentedDirectives = {
"@before-row",
"@after-row",
// "@before-paragraph",
// "@after-paragraph"
};
@Override
public void process(OOXMLPackage pkg, Map<String, Object> rootMap) {
InputStream f = null;
try {
f = new FileInputStream(new File(pkg.getDataDir(), "word/document.xml"));
Document doc = newDocumentBuilder().parse(f);
XPath xpath = newXPath(doc);
NodeList nodeList = evaluateXPath(xpath, "//KMagicNode", doc);
for (Node n : new NodeListWrapper(nodeList)) {
String directive = n.getTextContent();
if (directive.charAt(0) != '@')
continue;
String prefix = findPrefix(directive);
if (prefix == null) {
logger.warn("unsupported augmented directive({})", directive);
continue;
}
Node runNode;
Node parentOfPara = null;
Node targetPara = runNode = n.getParentNode().getParentNode(); // maybe w:r
if (!runNode.getNodeName().equals("w:r")) {
logger.warn("runNode is not w:r({}, directive: {})", runNode.getNodeName(), directive);
}
// find table row element following parent nodes.
if (prefix.contains("row"))
do {
targetPara = targetPara.getParentNode();
} while (!targetPara.getNodeName().equals("w:tr"));
else if (prefix.contains("paragraph"))
{
logger.debug("not supported yet");
continue;
}
parentOfPara = targetPara.getParentNode();
if (directive.startsWith("@after-row")) {
targetPara = targetPara.getNextSibling();
}
// insert magic node
parentOfPara.insertBefore(getMagicNode(doc, unwrapAugmentedDirective(directive)), targetPara);
// remove annotated node
runNode.getParentNode().removeChild(runNode);
}
XMLDocHelper.save(doc, new File(pkg.getDataDir(), "word/document.xml"), true);
} catch (Exception e) {
e.printStackTrace();
} finally {
safeClose(f);
}
}
private String findPrefix(String directive) {
for (String ad : augmentedDirectives) {
if (directive.startsWith(ad)) {
return ad;
}
}
return null;
}
private String unwrapAugmentedDirective(String directive) {
for (String ad : augmentedDirectives) {
if (directive.startsWith(ad)) {
return directive.substring(ad.length()).trim();
}
}
return directive;
}
private Node getMagicNode(Document doc, String content) {
Element magicNode = doc.createElement("KMagicNode");
magicNode.appendChild(doc.createCDATASection(content));
return magicNode;
}
}