Fields Summary |
---|
private static final String | PAGE_NS_URL |
private static final String | REQUEST_NS_URL |
private static final String | SESSION_NS_URL |
private static final String | APP_NS_URL |
private static final String | PARAM_NS_URL |
private static final String | INITPARAM_NS_URL |
private static final String | COOKIE_NS_URL |
private static final String | HEADER_NS_URL |
private javax.servlet.jsp.PageContext | pageContext |
private static HashMap | exprCache |
private static JSTLXPathNamespaceContext | jstlXPathNamespaceContext |
private static final String | XPATH_FACTORY_CLASS_NAME |
private static XPathFactory | XPATH_FACTORY |
static DocumentBuilderFactory | dbf |
static DocumentBuilder | db |
static Document | d |
String | modifiedXPath |
Methods Summary |
---|
protected org.w3c.dom.Node | adaptParamsForXalan(org.w3c.dom.Node n, java.lang.String xpath, javax.xml.xpath.XPathVariableResolver jxvr)To evaluate an XPath expression using Xalan, we need
to create an XPath object, which wraps an expression object and provides
general services for execution of that expression.
An XPath object can be instantiated with the following information:
- XPath expression to evaluate
- SourceLocator
(reports where an error occurred in the XML source or
transformation instructions)
- PrefixResolver
(resolve prefixes to namespace URIs)
- type
(one of SELECT or MATCH)
- ErrorListener
(customized error handling)
Execution of the XPath expression represented by an XPath object
is done via method execute which takes the following parameters:
- XPathContext
The execution context
- Node contextNode
The node that "." expresses
- PrefixResolver namespaceContext
The context in which namespaces in the XPath are supposed to be
expanded.
Given all of this, if no context node is set for the evaluation
of the XPath expression, one must be set so Xalan
can successfully evaluate a JSTL XPath expression.
(it will not work if the context node is given as a varialbe
at the beginning of the expression)
Node boundDocument = null;
modifiedXPath = xpath;
String origXPath = xpath;
boolean whetherOrigXPath = true;
// If contextNode is not null then just pass the values to Xalan XPath
if ( n != null ) {
return n;
}
if ( xpath.startsWith("$") ) {
// JSTL uses $scopePrefix:varLocalName/xpath expression
String varQName= xpath.substring( xpath.indexOf("$")+1);
if ( varQName.indexOf("/") > 0 ) {
varQName = varQName.substring( 0, varQName.indexOf("/"));
}
String varPrefix = null;
String varLocalName = varQName;
if ( varQName.indexOf( ":") >= 0 ) {
varPrefix = varQName.substring( 0, varQName.indexOf(":") );
varLocalName = varQName.substring( varQName.indexOf(":")+1 );
}
if ( xpath.indexOf("/") > 0 ) {
xpath = xpath.substring( xpath.indexOf("/"));
} else {
xpath = "/*";
whetherOrigXPath = false;
}
try {
Object varObject=((JSTLXPathVariableResolver) jxvr).getVariableValue("", varPrefix,
varLocalName);
//p( "varObject => : its Class " +varObject +
// ":" + varObject.getClass() );
if ( Class.forName("org.w3c.dom.Document").isInstance(
varObject ) ) {
//boundDocument = ((Document)varObject).getDocumentElement();
boundDocument = ((Document)varObject);
} else {
//p("Creating a Dummy document to pass " +
// " onto as context node " );
if ( Class.forName("org.apache.taglibs.standard.tag.common.xml.JSTLNodeList").isInstance( varObject ) ) {
Document newDocument = getDummyDocument();
JSTLNodeList jstlNodeList = (JSTLNodeList)varObject;
if ( jstlNodeList.getLength() == 1 ) {
if ( Class.forName("org.w3c.dom.Node").isInstance(
jstlNodeList.elementAt(0) ) ) {
Node node = (Node)jstlNodeList.elementAt(0);
Document doc = getDummyDocumentWithoutRoot();
Node importedNode = doc.importNode( node, true);
doc.appendChild (importedNode );
boundDocument = doc;
if ( whetherOrigXPath ) {
xpath="/*" + xpath;
}
} else {
//Nodelist with primitive type
Object myObject = jstlNodeList.elementAt(0);
//p("Single Element of primitive type");
//p("Type => " + myObject.getClass());
xpath = myObject.toString();
//p("String value ( xpathwould be this) => " + xpath);
boundDocument = newDocument;
}
} else {
Element dummyroot = newDocument.getDocumentElement();
for ( int i=0; i< jstlNodeList.getLength(); i++ ) {
Node currNode = (Node)jstlNodeList.item(i);
Node importedNode = newDocument.importNode(
currNode, true );
//printDetails ( newDocument);
dummyroot.appendChild( importedNode );
//p( "Details of the document After importing");
//printDetails ( newDocument);
}
boundDocument = newDocument;
// printDetails ( boundDocument );
//Verify :As we are adding Document element we need
// to change the xpath expression.Hopefully this
// won't change the result
xpath = "/*" + xpath;
}
} else if ( Class.forName("org.w3c.dom.Node").isInstance(
varObject ) ) {
boundDocument = (Node)varObject;
} else {
boundDocument = getDummyDocument();
xpath = origXPath;
}
}
} catch ( UnresolvableException ue ) {
// FIXME: LOG
// p("Variable Unresolvable :" + ue.getMessage());
ue.printStackTrace();
} catch ( ClassNotFoundException cnf ) {
// Will never happen
}
} else {
//p("Not encountered $ Creating a Dummydocument 2 "+
// "pass onto as context node " );
boundDocument = getDummyDocument();
}
modifiedXPath = xpath;
//p("Modified XPath::boundDocument =>" + modifiedXPath +
// "::" + boundDocument );
return boundDocument;
|
public boolean | booleanValueOf(org.w3c.dom.Node n, java.lang.String xpathString)Evaluate an XPath expression to a boolean value.
staticInit();
XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
Node contextNode = adaptParamsForXalan(n, xpathString.trim(), jxvr);
xpathString = modifiedXPath;
XPath xpath = XPATH_FACTORY.newXPath();
xpath.setNamespaceContext(jstlXPathNamespaceContext);
xpath.setXPathVariableResolver(jxvr);
try {
return ((Boolean) xpath.evaluate(
xpathString, contextNode, XPathConstants.BOOLEAN)).booleanValue();
} catch (XPathExpressionException ex) {
throw new JspTagException(
Resources.getMessage("XPATH_ERROR_XOBJECT", ex.toString()), ex);
}
|
public static org.w3c.dom.Node | getContext(javax.servlet.jsp.tagext.Tag t)
ForEachTag xt =
(ForEachTag) TagSupport.findAncestorWithClass(
t, ForEachTag.class);
if (xt == null)
return null;
else
return (xt.getContext());
|
static org.w3c.dom.Document | getDummyDocument()
try {
if ( dbf == null ) {
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware( true );
dbf.setValidating( false );
}
db = dbf.newDocumentBuilder();
DOMImplementation dim = db.getDOMImplementation();
d = dim.createDocument("http://java.sun.com/jstl", "dummyroot", null);
//d = db.newDocument();
return d;
} catch ( Exception e ) {
e.printStackTrace();
}
return null;
|
static org.w3c.dom.Document | getDummyDocumentWithoutRoot()
try {
if ( dbf == null ) {
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware( true );
dbf.setValidating( false );
}
db = dbf.newDocumentBuilder();
d = db.newDocument();
return d;
} catch ( Exception e ) {
e.printStackTrace();
}
return null;
|
private static void | p(java.lang.String s)
System.out.println("[XPathUtil] " + s);
|
public static void | printDetails(org.w3c.dom.Node n)
p("\n\nDetails of Node = > " + n ) ;
p("Name:Type:Node Value = > " + n.getNodeName() +
":" + n.getNodeType() + ":" + n.getNodeValue() ) ;
p("Namespace URI : Prefix : localName = > " +
n.getNamespaceURI() + ":" +n.getPrefix() + ":" + n.getLocalName());
p("\n Node has children => " + n.hasChildNodes() );
if ( n.hasChildNodes() ) {
NodeList nl = n.getChildNodes();
p("Number of Children => " + nl.getLength() );
for ( int i=0; i<nl.getLength(); i++ ) {
Node childNode = nl.item(i);
printDetails( childNode );
}
}
|
public java.util.List | selectNodes(org.w3c.dom.Node n, java.lang.String xpathString)Evaluate an XPath expression to a List of nodes.
staticInit();
XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
Node contextNode = adaptParamsForXalan(n, xpathString.trim(), jxvr);
xpathString = modifiedXPath;
try {
XPath xpath = XPATH_FACTORY.newXPath();
xpath.setNamespaceContext(jstlXPathNamespaceContext);
xpath.setXPathVariableResolver(jxvr);
Object nl = xpath.evaluate(
xpathString, contextNode, JSTLXPathConstants.OBJECT);
return new JSTLNodeList( nl );
} catch (XPathExpressionException ex ) {
throw new JspTagException(ex.toString(), ex);
}
|
public org.w3c.dom.Node | selectSingleNode(org.w3c.dom.Node n, java.lang.String xpathString)Evaluate an XPath expression to a single node.
//p("selectSingleNode of XPathUtil = passed node:" +
// "xpathString => " + n + " : " + xpathString );
staticInit();
XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
Node contextNode = adaptParamsForXalan(n, xpathString.trim(), jxvr);
xpathString = modifiedXPath;
try {
XPath xpath = XPATH_FACTORY.newXPath();
xpath.setNamespaceContext(jstlXPathNamespaceContext);
xpath.setXPathVariableResolver(jxvr);
return (Node) xpath.evaluate(
xpathString, contextNode, XPathConstants.NODE);
} catch (XPathExpressionException ex) {
throw new JspTagException(ex.toString(), ex);
}
|
private static synchronized void | staticInit()Initialize globally useful data.
// If the system property DEFAULT_PROPERTY_NAME + ":uri" is present,
// where uri is the parameter to this method, then its value is read
// as a class name. The method will try to create a new instance of
// this class by using the class loader, and returns it if it is
// successfully created.
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction(){
public Object run(){
System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME +
":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
XPATH_FACTORY_CLASS_NAME);
return null;
}
});
} else {
System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME +
":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
XPATH_FACTORY_CLASS_NAME);
}
try {
XPATH_FACTORY = XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI);
} catch (XPathFactoryConfigurationException xpce) {
xpce.printStackTrace();
}
if (jstlXPathNamespaceContext == null) {
// register supported namespaces
jstlXPathNamespaceContext = new JSTLXPathNamespaceContext();
jstlXPathNamespaceContext.addNamespace("pageScope", PAGE_NS_URL);
jstlXPathNamespaceContext.addNamespace("requestScope", REQUEST_NS_URL);
jstlXPathNamespaceContext.addNamespace("sessionScope", SESSION_NS_URL);
jstlXPathNamespaceContext.addNamespace("applicationScope", APP_NS_URL);
jstlXPathNamespaceContext.addNamespace("param", PARAM_NS_URL);
jstlXPathNamespaceContext.addNamespace("initParam", INITPARAM_NS_URL);
jstlXPathNamespaceContext.addNamespace("header", HEADER_NS_URL);
jstlXPathNamespaceContext.addNamespace("cookie", COOKIE_NS_URL);
// create a HashMap to cache the expressions
exprCache = new HashMap();
}
|
public java.lang.String | valueOf(org.w3c.dom.Node n, java.lang.String xpathString)Evaluate an XPath expression to a String value.
// p("******** valueOf(" + n + ", " + xpathString + ")");
staticInit();
XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
Node contextNode = adaptParamsForXalan(n, xpathString.trim(), jxvr);
XPath xpath = XPATH_FACTORY.newXPath();
xpath.setNamespaceContext(jstlXPathNamespaceContext);
xpath.setXPathVariableResolver(jxvr);
try {
return xpath.evaluate(xpathString, contextNode);
} catch (XPathExpressionException ex) {
throw new JspTagException(ex.toString(), ex);
}
|