wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

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
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.
Now let us have a quick look at the Java class./**
* 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;
 
}
}

Posted by on 21 March 2008 | Comments (0) | categories: Show-N-Tell Thursday

Comments

  1. No comments yet, be the first to comment