Search

Mobile tag

About Me

I am the "IBM Collaboration & Productivity Advisor" for IBM Asia Pacific. I'm based in Singapore.
Reach out to me via:
Follow notessensei on Twitter
(posts)
Skype
Sametime
IBM
Facebook
LinkedIn
XING
Amazon Store
Amazon Kindle

Twitter

Domino Upgrade

VersionSupport end
5.0
6.0
6.5
7.0
Upgrade to 8.5x now!
(see the full Lotus lifcyle) To make your upgrade a success use the Upgrade Cheat Sheet.
Contemplating to replace Notes? You have to read this! (also available on Slideshare)

Languages

Other languages on request.

Visitors

Useful Tools

Get Firefox
Use OpenDNS
The support for Windows XP is coming to an end and has . Time to consider an alternative to move on. sounds like a lot of time, but, like an object in a mirror, it is closer than you think.

« Domino Design Code Injection | Main| Domino next++ »

Domino Design Code Injection - Part 2

QuickImage 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;
 
}
}

Post A Comment

Please note: Comments without a valid and working eMail address will be removed. This is my site, so I decide what stays here and what goes.

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::rolleyes:;-)

Disclaimer

This site is in no way affiliated, endorsed, sanctioned, supported, nor enlightened by Lotus Software nor IBM Corporation. I may be an employee, but the opinions, theories, facts, etc. presented here are my own and are in now way given in any official capacity. In short, these are my words and this is my site, not IBM's - and don't even begin to think otherwise. (Disclaimer shamelessly plugged from Rocky Oliver)
© 2003 - 2013 Stephan H. Wissel - some rights reserved as listed here: Creative Commons License
Unless otherwise labeled by its originating author, the content found on this site is made available under the terms of an Attribution/NonCommercial/ShareAlike Creative Commons License, with the exception that no rights are granted -- since they are not mine to grant -- in any logo, graphic design, trademarks or trade names of any type. Code samples and code downloads on this site are, unless otherwise labeled, made available under an Apache 2.0 license. Other license models are available on written request and written confirmation.