Domino Design Code Injection - Part 2
In Part 1 I introduced the approach to code injection and some sample LotusScript Code to pull a design element, transform it and push it back. Missing there was the function that actually implemented that method. I'm using a Java class to do that, which I wrap into LS2J. The LotusScript function looks like this:
Option Public Option Declare Uselsx "*javacon" Use "CodeInjector" Function injectCode(rawDXL As String, xPath As String, codeSnippet As String) As String 'Dummy doesn't do anything Dim jSession As JAVASESSION Dim injectorClass As JAVACLASS Dim injector As JavaObject Set jSession = New JAVASESSION injectCode = rawDXL Set injectorClass = jSession.GetClass("DominoXPathInjector") Set injector = injectorClass.CreateObject 'Now set the document Call injector.setDocument(rawDXL) 'and execute the function injectCode = injector.injectCode(codeSnippet, xPath, 4) End Function
provided by Julian Robichaux at nsftools.com.
* Sample Code without warranty, use at your own risk
* (C) 2008, stephan@wissel.net
* Proper error handling omitted for clarity
*/
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
public class XPathInjector {
public static final int IMPORT_BEFORE = 0;
public static final int IMPORT_AFTER = 1;
public static final int IMPORT_REPLACE = 2;
public static final int IMPORT_FIRSTCHILD = 3;
public static final int IMPORT_LASTCHILD = 4;
Document doc;
private DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setValidating(false);
documentBuilderFactory.setSchema(null);
documentBuilderFactory.setNamespaceAware(false);
documentBuilderFactory.setIgnoringComments(false);
documentBuilderFactory.setIgnoringElementContentWhitespace(false);
documentBuilderFactory.setXIncludeAware(false);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
return documentBuilder;
}
private NodeList getMachingNodes(String xPathString) {
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr;
try {
expr = xpath.compile(xPathString);
Object result = expr.evaluate(doc, XPathConstants.NODESET);
return (NodeList) result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Node getNodeFromString(String codeFragment) {
String workString = "<wrapper>" + codeFragment + "</wrapper>";
InputSource in = new InputSource(new StringReader(workString));
try {
DocumentBuilder documentBuilder = this.getDocumentBuilder();
Document miniDoc = documentBuilder.parse(in);
Node wrapper = doc.importNode(miniDoc.getDocumentElement(), true);
return wrapper;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String injectCode(String codeFragment, String xPath, int importOption) {
Node codeToInsert = this.getNodeFromString(codeFragment);
NodeList replaceCandidates = this.getMachingNodes(xPath);
boolean appendToNode = true;
if (replaceCandidates != null) {
for (int i = 0, size = replaceCandidates.getLength(); i < size; i++) {
Node curNode = replaceCandidates.item(i);
Node referenceNode = null;
if (importOption == XPathInjector.IMPORT_BEFORE) {
appendToNode = false;
referenceNode = curNode;
} else if (importOption == XPathInjector.IMPORT_AFTER) {
if (curNode.getNextSibling() == null) {
referenceNode = curNode.getParentNode();
appendToNode = true;
} else {
referenceNode = curNode.getNextSibling();
appendToNode = false;
}
} else if (importOption == XPathInjector.IMPORT_FIRSTCHILD) {
if (curNode.getFirstChild() == null) {
referenceNode = curNode;
appendToNode = true;
} else {
referenceNode = curNode.getFirstChild();
appendToNode = false;
}
} else if (importOption == XPathInjector.IMPORT_LASTCHILD) {
referenceNode = curNode;
appendToNode = true;
} else if (importOption == XPathInjector.IMPORT_REPLACE) {
if (curNode.getNextSibling() == null) {
referenceNode = curNode.getParentNode();
appendToNode = true;
} else {
referenceNode = curNode.getNextSibling();
appendToNode = false;
}
curNode.getParentNode().removeChild(curNode);
} else {
return this.toString();
}
NodeList newNodes = codeToInsert.getChildNodes();
for (int k = 0, insertSize = newNodes.getLength(); k < insertSize; k++) {
if (appendToNode) {
referenceNode.appendChild(newNodes.item(k));
} else {
referenceNode.getParentNode().insertBefore(newNodes.item(i), referenceNode);
}
}
}
}
return this.toString();
}
public void setDocument(String docString) {
InputSource in = new InputSource(new StringReader(docString));
try {
DocumentBuilder documentBuilder = this.getDocumentBuilder();
this.doc = documentBuilder.parse(in);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String toString() {
try {
StreamResult result = null;
ByteArrayOutputStream byteResult = new ByteArrayOutputStream();
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(doc);
result = new StreamResult(byteResult);
transformer.transform(source, result);
return byteResult.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
- 

