I would like to cache the Verifier object created from the schema so that it can be used across multiple input screens.
Peter,
First something that you could not know, but you should not use instance variables in your processor, as the same instance of your processor might be used at the same time by multiple threads. In your case you can just move those variables to the generateXpath() method.
I have modified your code to call the readCacheInputAsObject() method. Basically you do:
Verifier verifier = (Verifier) readCacheInputAsObject(context,
getInputByName("xpath"), new CacheableInputReader() {
public Object read(PipelineContext context, ProcessorInput input){
Document xpathDOM = readInputAsDOM(context, input);
...
return BuildVerifier(is);
}
});OXF will call your code to create the verifier (the "Object read(...)" method) if it can't find a version in cache that was build based on the same input document.
Alex
package edu.berkeley.cde.processors;
import javax.xml.transform.TransformerException;
import org.orbeon.oxf.processor.ProcessorInputOutputInfo;
import org.orbeon.oxf.processor.SimpleProcessor;
import org.orbeon.oxf.processor.CacheableInputReader;
import org.orbeon.oxf.processor.ProcessorInput;
import org.orbeon.oxf.processor.pipeline.PipelineContext;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import javax.xml.transform.sax.SAXResult;
import org.iso_relax.verifier.*;
import org.w3c.dom.*;
import java.io.*;
import org.apache.xpath.XPathAPI;
import org.apache.xpath.objects.XObject;
import org.orbeon.oxf.xml.TransformerUtils;
import javax.xml.transform.dom.DOMSource;
import org.orbeon.oxf.resources.*;
/**
* @author peter charles
*This Class takes an xform input and an xml document in the form of
*<ValidateElements schema="Location">
* <Xpath valid="false">/Element/Element/ElementToValidate</Xpath>
* <Xpath valid="false">/Element/ElementToValidate</Xpath>
* ........
*</ValidateElements>
*It will return the same document with the valid attribute set to
*the outcome of a validation using the xform input and the schema
*
*/
public class NodeValidationProcessor extends SimpleProcessor {
public NodeValidationProcessor() {
addInputInfo(new ProcessorInputOutputInfo("xform"));
addInputInfo(new ProcessorInputOutputInfo("xpath"));
addOutputInfo(new ProcessorInputOutputInfo("xpath"));
}
public void generateXpath(PipelineContext context, ContentHandler contentHandler)
throws SAXException{
org.w3c.dom.Document xformToBeValidated;
xformToBeValidated = readInputAsDOM(context,"xform");
//get schema reference
Verifier verifier = (Verifier) readCacheInputAsObject(context,
getInputByName("xpath"), new CacheableInputReader() {
public Object read(PipelineContext context, ProcessorInput input) {
Document xpathDOM = readInputAsDOM(context, input);
Element root = xpathDOM.getDocumentElement();
String schema = root.getAttribute("schema");
InputStream is =
ResourceManagerWrapper.instance().getContentAsStream(schema);
//build verifier from schema
return BuildVerifier(is);
}
});
Document xpathDOM = readInputAsDOM(context, "xpath");
//Retrive all Xpath Elements as a node list
NodeList xpathList = xpathDOM.getElementsByTagName("Xpath");
//Run through each xpath node and validate corisponding node of xform
for(int x=0;x<xpathList.getLength();x++)
{
try{
//get list of xpaths to evaluate
XObject nodeValue = XPathAPI.eval(xpathList.item(x),"string()");
String xpathValue = nodeValue.str();
//call for validation
boolean valid = ValidateNode(verifier, xpathValue, xformToBeValidated);
//Get attributes from Xpath node and set validity
NamedNodeMap nm = xpathList.item(x).getAttributes();
nm.item(0).setNodeValue(valid+"");
}catch(TransformerException te){//System.out.println("Start TE: "+ te);
}
}
//Hook up to output
try {
TransformerUtils.getXMLIdentityTransformer().transform (new
DOMSource(xpathDOM), new SAXResult(contentHandler));
}catch (TransformerException te) {
//System.out.println(te);
//return te.toString();
}
}
/**
* Validates a Node in a xform document when give an xpath statement
*
*/
private boolean ValidateNode(Verifier verifier, String xpath, Document
xformToBeValidated){
boolean valid = false;
try{
Node testNode = XPathAPI.selectSingleNode(xformToBeValidated,xpath);
valid =verifier.verify(testNode);
return valid;
}catch(TransformerException te){//System.out.println("vN TE: "+te);
}catch(Exception e){//e.getLocalizedMessage();e.getCause();e.printStackTrace();
}
return valid;
}
/**
* Builds a Verifer given a schema
* Should I overload method to take other forms of input?
*/
private Verifier BuildVerifier(InputStream schema){
// Use MSV JARV API and compile a schema.
try{
VerifierFactory factory = new com.sun.msv.verifier.jarv.TheFactoryImpl();
return factory.compileSchema(schema).newVerifier();
}catch(IOException io){//System.out.println("BV IO: "+io);
}catch(SAXException se){//System.out.println("BV SaxE: "+ se);
}catch(VerifierConfigurationException vce){//System.out.println("BV VCE:
"+vce);
}
return null;
}
}
_______________________________________________ oxf-users mailing list [EMAIL PROTECTED] http://mail.orbeon.com/mailman/listinfo/oxf-users
