1 25 package org.apache.taglibs.standard.tag.common.xml; 26 27 28 import javax.xml.namespace.QName ; 29 import javax.xml.namespace.NamespaceContext ; 30 import javax.xml.xpath.XPathExpressionException ; 31 import javax.xml.xpath.XPathConstants ; 32 import javax.xml.xpath.XPathFunctionResolver ; 33 import javax.xml.xpath.XPathVariableResolver ; 34 import javax.xml.xpath.XPathExpression ; 35 36 import com.sun.org.apache.xml.internal.dtm.DTM; 37 import com.sun.org.apache.xpath.internal.*; 38 import com.sun.org.apache.xpath.internal.objects.XObject; 39 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; 40 import com.sun.org.apache.xalan.internal.res.XSLMessages; 41 42 import org.w3c.dom.Node ; 43 import org.w3c.dom.DOMImplementation ; 44 import org.w3c.dom.Document ; 45 import org.w3c.dom.traversal.NodeIterator; 46 47 import org.xml.sax.InputSource ; 48 import org.xml.sax.SAXException ; 49 50 import javax.xml.parsers.*; 51 52 import java.io.IOException ; 53 54 66 public class JSTLXPathImpl implements javax.xml.xpath.XPath { 67 68 private XPathVariableResolver variableResolver; 70 private XPathFunctionResolver functionResolver; 71 private XPathVariableResolver origVariableResolver; 72 private XPathFunctionResolver origFunctionResolver; 73 private NamespaceContext namespaceContext=null; 74 private com.sun.org.apache.xpath.internal.jaxp.JAXPPrefixResolver prefixResolver; 75 private boolean featureSecureProcessing = false; 79 80 JSTLXPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) { 81 this.origVariableResolver = this.variableResolver = vr; 82 this.origFunctionResolver = this.functionResolver = fr; 83 } 84 85 JSTLXPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, 86 boolean featureSecureProcessing ) { 87 this.origVariableResolver = this.variableResolver = vr; 88 this.origFunctionResolver = this.functionResolver = fr; 89 this.featureSecureProcessing = featureSecureProcessing; 90 } 91 92 97 public void setXPathVariableResolver(XPathVariableResolver resolver) { 98 if ( resolver == null ) { 99 String fmsg = XSLMessages.createXPATHMessage( 100 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 101 new Object [] {"XPathVariableResolver"} ); 102 throw new NullPointerException ( fmsg ); 103 } 104 this.variableResolver = resolver; 105 } 106 107 112 public XPathVariableResolver getXPathVariableResolver() { 113 return variableResolver; 114 } 115 116 121 public void setXPathFunctionResolver(XPathFunctionResolver resolver) { 122 if ( resolver == null ) { 123 String fmsg = XSLMessages.createXPATHMessage( 124 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 125 new Object [] {"XPathFunctionResolver"} ); 126 throw new NullPointerException ( fmsg ); 127 } 128 this.functionResolver = resolver; 129 } 130 131 136 public XPathFunctionResolver getXPathFunctionResolver() { 137 return functionResolver; 138 } 139 140 145 public void setNamespaceContext(NamespaceContext nsContext) { 146 if ( nsContext == null ) { 147 String fmsg = XSLMessages.createXPATHMessage( 148 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 149 new Object [] {"NamespaceContext"} ); 150 throw new NullPointerException ( fmsg ); 151 } 152 this.namespaceContext = nsContext; 153 this.prefixResolver = new com.sun.org.apache.xpath.internal.jaxp.JAXPPrefixResolver ( nsContext ); 154 } 155 156 161 public NamespaceContext getNamespaceContext() { 162 return namespaceContext; 163 } 164 165 private static Document d = null; 166 167 private static DocumentBuilder getParser() { 168 try { 169 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 181 dbf.setNamespaceAware( true ); 182 dbf.setValidating( false ); 183 return dbf.newDocumentBuilder(); 184 } catch (ParserConfigurationException e) { 185 throw new Error (e); 187 } 188 } 189 190 private static Document getDummyDocument( ) { 191 if(d==null) { 194 DOMImplementation dim = getParser().getDOMImplementation(); 195 d = dim.createDocument("http://java.sun.com/jaxp/xpath", 196 "dummyroot", null); 197 } 198 return d; 199 } 200 201 202 private XObject eval(String expression, Object contextItem) 203 throws javax.xml.transform.TransformerException { 204 com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression, 205 null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT ); 206 com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null; 207 if ( functionResolver != null ) { 208 com.sun.org.apache.xpath.internal.jaxp.JAXPExtensionsProvider jep = 209 new com.sun.org.apache.xpath.internal.jaxp.JAXPExtensionsProvider( 210 functionResolver, featureSecureProcessing ); 211 xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep ); 212 } else { 213 xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext(); 214 } 215 216 XObject xobj = null; 217 218 xpathSupport.setVarStack(new com.sun.org.apache.xpath.internal.jaxp.JAXPVariableStack(variableResolver)); 219 220 if ( contextItem instanceof Node ) { 222 xobj = xpath.execute (xpathSupport, (Node )contextItem, 223 prefixResolver ); 224 } else { 225 xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver ); 226 } 227 228 return xobj; 229 } 230 231 262 public Object evaluate(String expression, Object item, QName returnType) 263 throws XPathExpressionException { 264 if ( expression == null ) { 265 String fmsg = XSLMessages.createXPATHMessage( 266 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 267 new Object [] {"XPath expression"} ); 268 throw new NullPointerException ( fmsg ); 269 } 270 if ( returnType == null ) { 271 String fmsg = XSLMessages.createXPATHMessage( 272 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 273 new Object [] {"returnType"} ); 274 throw new NullPointerException ( fmsg ); 275 } 276 if ( !isSupported ( returnType ) ) { 279 String fmsg = XSLMessages.createXPATHMessage( 280 XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 281 new Object [] { returnType.toString() } ); 282 throw new IllegalArgumentException ( fmsg ); 283 } 284 285 try { 286 287 XObject resultObject = eval( expression, item ); 288 return getResultAsType( resultObject, returnType ); 289 } catch ( java.lang.NullPointerException npe ) { 290 throw new XPathExpressionException ( npe ); 294 } catch ( javax.xml.transform.TransformerException te ) { 295 Throwable nestedException = te.getException(); 296 if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { 297 throw (javax.xml.xpath.XPathFunctionException )nestedException; 298 } else { 299 throw new XPathExpressionException ( te ); 302 } 303 } 304 305 } 306 307 private boolean isSupported( QName returnType ) { 308 if ( ( returnType.equals( XPathConstants.STRING ) ) || 309 ( returnType.equals( XPathConstants.NUMBER ) ) || 310 ( returnType.equals( XPathConstants.BOOLEAN ) ) || 311 ( returnType.equals( XPathConstants.NODE ) ) || 312 ( returnType.equals( XPathConstants.NODESET ) ) || 313 ( returnType.equals( JSTLXPathConstants.OBJECT ) ) ) { 314 315 return true; 316 } 317 return false; 318 } 319 320 private Object getResultAsType( XObject resultObject, QName returnType ) 321 throws javax.xml.transform.TransformerException { 322 if ( returnType.equals( XPathConstants.STRING ) ) { 324 return resultObject.str(); 325 } 326 if ( returnType.equals( XPathConstants.NUMBER ) ) { 328 return new Double ( resultObject.num()); 329 } 330 if ( returnType.equals( XPathConstants.BOOLEAN ) ) { 332 return new Boolean ( resultObject.bool()); 333 } 334 if ( returnType.equals( XPathConstants.NODESET ) ) { 336 return resultObject.nodelist(); 337 } 338 if ( returnType.equals( XPathConstants.NODE ) ) { 340 NodeIterator ni = resultObject.nodeset(); 341 return ni.nextNode(); 343 } 344 if ( returnType.equals( JSTLXPathConstants.OBJECT ) ) { 346 if (resultObject instanceof com.sun.org.apache.xpath.internal.objects.XNodeSet) 347 return resultObject.nodelist(); 348 else 349 return resultObject.object(); 350 } 351 String fmsg = XSLMessages.createXPATHMessage( 352 XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 353 new Object [] { returnType.toString()}); 354 throw new IllegalArgumentException ( fmsg ); 355 } 356 357 358 359 383 public String evaluate(String expression, Object item) 384 throws XPathExpressionException { 385 return (String )this.evaluate( expression, item, XPathConstants.STRING ); 386 } 387 388 405 public XPathExpression compile(String expression) 406 throws XPathExpressionException { 407 if ( expression == null ) { 409 String fmsg = XSLMessages.createXPATHMessage( 410 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 411 new Object [] {"XPath expression"} ); 412 throw new NullPointerException ( fmsg ); 413 } 414 return null; 415 429 } 430 431 432 460 public Object evaluate(String expression, InputSource source, 461 QName returnType) throws XPathExpressionException { 462 if( source== null ) { 464 String fmsg = XSLMessages.createXPATHMessage( 465 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 466 new Object [] {"source"} ); 467 throw new NullPointerException ( fmsg ); 468 } 469 if ( expression == null ) { 470 String fmsg = XSLMessages.createXPATHMessage( 471 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 472 new Object [] {"XPath expression"} ); 473 throw new NullPointerException ( fmsg ); 474 } 475 if ( returnType == null ) { 476 String fmsg = XSLMessages.createXPATHMessage( 477 XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 478 new Object [] {"returnType"} ); 479 throw new NullPointerException ( fmsg ); 480 } 481 482 if ( !isSupported ( returnType ) ) { 485 String fmsg = XSLMessages.createXPATHMessage( 486 XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 487 new Object [] { returnType.toString() } ); 488 throw new IllegalArgumentException ( fmsg ); 489 } 490 491 try { 492 493 Document document = getParser().parse( source ); 494 495 XObject resultObject = eval( expression, document ); 496 return getResultAsType( resultObject, returnType ); 497 } catch ( SAXException e ) { 498 throw new XPathExpressionException ( e ); 499 } catch( IOException e ) { 500 throw new XPathExpressionException ( e ); 501 } catch ( javax.xml.transform.TransformerException te ) { 502 Throwable nestedException = te.getException(); 503 if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { 504 throw (javax.xml.xpath.XPathFunctionException )nestedException; 505 } else { 506 throw new XPathExpressionException ( te ); 507 } 508 } 509 510 } 511 512 513 514 515 538 public String evaluate(String expression, InputSource source) 539 throws XPathExpressionException { 540 return (String )this.evaluate( expression, source, XPathConstants.STRING ); 541 } 542 543 558 public void reset() { 559 this.variableResolver = this.origVariableResolver; 560 this.functionResolver = this.origFunctionResolver; 561 this.namespaceContext = null; 562 } 563 564 } 565 | Popular Tags |