1 16 17 package org.apache.taglibs.standard.tag.common.xml; 18 19 import java.util.Enumeration ; 20 import java.util.HashMap ; 21 import java.util.List ; 22 import java.util.Vector ; 23 24 import javax.servlet.http.Cookie ; 25 import javax.servlet.http.HttpServletRequest ; 26 import javax.servlet.jsp.JspTagException ; 27 import javax.servlet.jsp.PageContext ; 28 import javax.servlet.jsp.tagext.Tag ; 29 import javax.servlet.jsp.tagext.TagSupport ; 30 import javax.xml.parsers.DocumentBuilder ; 31 import javax.xml.parsers.DocumentBuilderFactory ; 32 import javax.xml.transform.TransformerException ; 33 34 import org.apache.taglibs.standard.resources.Resources; 35 import org.apache.xml.utils.QName; 36 import org.apache.xpath.VariableStack; 37 import org.apache.xpath.XPathContext; 38 import org.apache.xpath.objects.XBoolean; 39 import org.apache.xpath.objects.XNodeSetForDOM; 40 import org.apache.xpath.objects.XNumber; 41 import org.apache.xpath.objects.XObject; 42 import org.apache.xpath.objects.XString; 43 import org.w3c.dom.DOMImplementation ; 44 import org.w3c.dom.Document ; 45 import org.w3c.dom.Element ; 46 import org.w3c.dom.Node ; 47 import org.w3c.dom.NodeList ; 48 49 56 public class XPathUtil { 59 60 63 67 public XPathUtil(PageContext pc) { 68 pageContext = pc; 69 } 70 71 int globalVarSize=0; 72 public Vector getVariableQNames ( ) { 73 74 globalVarSize = 0; 75 Vector variableVector = new Vector ( ); 76 Enumeration enum_ = pageContext.getAttributeNamesInScope( 78 PageContext.PAGE_SCOPE ); 79 while ( enum_.hasMoreElements() ) { 80 String varName = (String )enum_.nextElement(); 81 QName varQName = new QName ( PAGE_NS_URL, PAGE_P, varName); 82 variableVector.addElement( varQName ); 84 globalVarSize++; 85 86 variableVector.addElement( new QName(null, varName ) ); 87 globalVarSize++; 88 } 89 enum_ = pageContext.getAttributeNamesInScope( 90 PageContext.REQUEST_SCOPE ); 91 while ( enum_.hasMoreElements() ) { 92 String varName = (String )enum_.nextElement(); 93 QName varQName = new QName ( REQUEST_NS_URL,REQUEST_P, varName); 94 variableVector.addElement( varQName ); 96 globalVarSize++; 97 variableVector.addElement( new QName(null, varName ) ); 98 globalVarSize++; 99 } 100 enum_ = pageContext.getAttributeNamesInScope( 101 PageContext.SESSION_SCOPE ); 102 while ( enum_.hasMoreElements() ) { 103 String varName = (String )enum_.nextElement(); 104 QName varQName = new QName ( SESSION_NS_URL, SESSION_P,varName); 105 variableVector.addElement( varQName ); 107 globalVarSize++; 108 variableVector.addElement( new QName(null, varName ) ); 109 globalVarSize++; 110 } 111 enum_ = pageContext.getAttributeNamesInScope( 112 PageContext.APPLICATION_SCOPE ); 113 while ( enum_.hasMoreElements() ) { 114 String varName = (String )enum_.nextElement(); 115 QName varQName = new QName ( APP_NS_URL, APP_P,varName ); 116 variableVector.addElement( varQName ); 118 globalVarSize++; 119 variableVector.addElement( new QName(null, varName ) ); 120 globalVarSize++; 121 } 122 enum_ = pageContext.getRequest().getParameterNames(); 123 while ( enum_.hasMoreElements() ) { 124 String varName = (String )enum_.nextElement(); 125 QName varQName = new QName ( PARAM_NS_URL, PARAM_P,varName ); 126 variableVector.addElement( varQName ); 128 globalVarSize++; 129 } 130 enum_ = pageContext.getServletContext().getInitParameterNames(); 131 while ( enum_.hasMoreElements() ) { 132 String varName = (String )enum_.nextElement(); 133 QName varQName = new QName ( INITPARAM_NS_URL, INITPARAM_P,varName ); 134 variableVector.addElement( varQName ); 136 globalVarSize++; 137 } 138 enum_ = ((HttpServletRequest )pageContext.getRequest()).getHeaderNames(); 139 while ( enum_.hasMoreElements() ) { 140 String varName = (String )enum_.nextElement(); 141 QName varQName = new QName ( HEADER_NS_URL, HEADER_P,varName ); 142 variableVector.addElement( varQName ); 144 globalVarSize++; 145 } 146 Cookie [] c= ((HttpServletRequest )pageContext.getRequest()).getCookies(); 147 if ( c!= null ) { 148 for (int i = 0; i < c.length; i++) { 149 String varName = c[i].getName(); 150 QName varQName = new QName ( COOKIE_NS_URL, COOKIE_P,varName ); 151 variableVector.addElement( varQName ); 153 globalVarSize++; 154 } 155 } 156 157 return variableVector; 158 159 } 160 161 164 private static final String PAGE_NS_URL 166 = "http://java.sun.com/jstl/xpath/page"; 167 private static final String REQUEST_NS_URL 168 = "http://java.sun.com/jstl/xpath/request"; 169 private static final String SESSION_NS_URL 170 = "http://java.sun.com/jstl/xpath/session"; 171 private static final String APP_NS_URL 172 = "http://java.sun.com/jstl/xpath/app"; 173 private static final String PARAM_NS_URL 174 = "http://java.sun.com/jstl/xpath/param"; 175 private static final String INITPARAM_NS_URL 176 = "http://java.sun.com/jstl/xpath/initParam"; 177 private static final String COOKIE_NS_URL 178 = "http://java.sun.com/jstl/xpath/cookie"; 179 private static final String HEADER_NS_URL 180 = "http://java.sun.com/jstl/xpath/header"; 181 182 private static final String PAGE_P = "pageScope"; 184 private static final String REQUEST_P = "requestScope"; 185 private static final String SESSION_P = "sessionScope"; 186 private static final String APP_P = "applicationScope"; 187 private static final String PARAM_P = "param"; 188 private static final String INITPARAM_P = "initParam"; 189 private static final String COOKIE_P = "cookie"; 190 private static final String HEADER_P = "header"; 191 192 198 protected class JstlVariableContext extends org.apache.xpath.VariableStack { 199 200 public JstlVariableContext( ) { 201 super(); 202 } 203 204 213 public XObject getVariableOrParam( 214 XPathContext xctxt, 215 org.apache.xml.utils.QName qname) 216 throws javax.xml.transform.TransformerException , UnresolvableException 217 { 218 String namespace = qname.getNamespaceURI(); 220 String prefix = qname.getPrefix(); 221 String localName = qname.getLocalName(); 222 223 226 try { 227 Object varObject = getVariableValue(namespace,prefix,localName); 228 229 230 XObject newXObject = new XObject( varObject); 232 233 if ( Class.forName("org.w3c.dom.Document").isInstance( varObject) ) { 234 235 NodeList nl= ((Document )varObject).getChildNodes(); 236 Vector nodeVector = new Vector (); 238 for ( int i=0; i<nl.getLength(); i++ ) { 239 Node currNode = nl.item(i); 240 if ( currNode.getNodeType() == Node.ELEMENT_NODE ) { 241 nodeVector.addElement( currNode); 242 } 243 } 244 JSTLNodeList jstlNodeList = new JSTLNodeList( nodeVector); 245 newXObject = new XNodeSetForDOM( jstlNodeList, xctxt ); 246 247 return newXObject; 248 249 } 250 if ( Class.forName( 251 "org.apache.taglibs.standard.tag.common.xml.JSTLNodeList").isInstance( 252 varObject) ) { 253 JSTLNodeList jstlNodeList = (JSTLNodeList)varObject; 254 if ( ( jstlNodeList.getLength() == 1 ) && 255 (!Class.forName("org.w3c.dom.Node").isInstance( jstlNodeList.elementAt(0) ) ) ) { 256 varObject = jstlNodeList.elementAt(0); 257 } else { 260 return new XNodeSetForDOM ( jstlNodeList ,xctxt ); 261 } 262 } 263 if (Class.forName("org.w3c.dom.Node").isInstance( varObject)) { 264 newXObject = new XNodeSetForDOM ( new JSTLNodeList( (Node )varObject ),xctxt ); 265 } else if ( Class.forName("java.lang.String").isInstance( varObject)){ 266 newXObject = new XString ( (String )varObject ); 267 } else if ( Class.forName("java.lang.Boolean").isInstance( varObject) ) { 268 newXObject = new XBoolean ( (Boolean )varObject ); 269 } else if ( Class.forName("java.lang.Number").isInstance( varObject) ) { 270 newXObject = new XNumber ( (Number )varObject ); 271 } 272 273 return newXObject; 274 } catch ( ClassNotFoundException cnfe ) { 276 System.out.println("CLASS NOT FOUND EXCEPTION :" + cnfe ); 278 } 279 return null ; 281 } 282 283 287 public Object getVariableValue( 288 String namespace, 289 String prefix, 290 String localName) 291 throws UnresolvableException 292 { 293 if (prefix == null || prefix.equals("")) { 298 return notNull( 299 pageContext.findAttribute(localName), 300 prefix, 301 localName); 302 } else if (prefix.equals(PAGE_P)) { 303 return notNull( 304 pageContext.getAttribute(localName,PageContext.PAGE_SCOPE), 305 prefix, 306 localName); 307 } else if (prefix.equals(REQUEST_P)) { 308 return notNull( 309 pageContext.getAttribute(localName, 310 PageContext.REQUEST_SCOPE), 311 prefix, 312 localName); 313 } else if (prefix.equals(SESSION_P)) { 314 return notNull( 315 pageContext.getAttribute(localName, 316 PageContext.SESSION_SCOPE), 317 prefix, 318 localName); 319 } else if (prefix.equals(APP_P)) { 320 return notNull( 321 pageContext.getAttribute(localName, 322 PageContext.APPLICATION_SCOPE), 323 prefix, 324 localName); 325 } else if (prefix.equals(PARAM_P)) { 326 return notNull( 327 pageContext.getRequest().getParameter(localName), 328 prefix, 329 localName); 330 } else if (prefix.equals(INITPARAM_P)) { 331 return notNull( 332 pageContext.getServletContext(). 333 getInitParameter(localName), 334 prefix, 335 localName); 336 } else if (prefix.equals(HEADER_P)) { 337 HttpServletRequest hsr = 338 (HttpServletRequest ) pageContext.getRequest(); 339 return notNull( 340 hsr.getHeader(localName), 341 prefix, 342 localName); 343 } else if (prefix.equals(COOKIE_P)) { 344 HttpServletRequest hsr = 345 (HttpServletRequest ) pageContext.getRequest(); 346 Cookie [] c = hsr.getCookies(); 347 for (int i = 0; i < c.length; i++) 348 if (c[i].getName().equals(localName)) 349 return c[i].getValue(); 350 throw new UnresolvableException("$" + prefix + ":" + localName); 351 } else { 352 throw new UnresolvableException("$" + prefix + ":" + localName); 353 } 354 } 355 356 360 private Object notNull(Object o, String prefix, String localName) 361 throws UnresolvableException { 362 if (o == null) { 363 throw new UnresolvableException("$" + (prefix==null?"":prefix+":") + localName); 364 } 365 return o; 367 } 368 } 369 370 373 private PageContext pageContext; 374 private static HashMap exprCache; 375 private static JSTLPrefixResolver jstlPrefixResolver = null; 376 377 378 private synchronized static void staticInit() { 379 if (jstlPrefixResolver == null) { 380 jstlPrefixResolver = new JSTLPrefixResolver(); 382 jstlPrefixResolver.addNamespace("pageScope", PAGE_NS_URL); 383 jstlPrefixResolver.addNamespace("requestScope", REQUEST_NS_URL); 384 jstlPrefixResolver.addNamespace("sessionScope", SESSION_NS_URL); 385 jstlPrefixResolver.addNamespace("applicationScope", APP_NS_URL); 386 jstlPrefixResolver.addNamespace("param", PARAM_NS_URL); 387 jstlPrefixResolver.addNamespace("initParam", INITPARAM_NS_URL); 388 jstlPrefixResolver.addNamespace("header", HEADER_NS_URL); 389 jstlPrefixResolver.addNamespace("cookie", COOKIE_NS_URL); 390 391 392 exprCache = new HashMap (); 394 } 395 } 396 397 static DocumentBuilderFactory dbf = null; 398 static DocumentBuilder db = null; 399 static Document d = null; 400 401 static Document getDummyDocument( ) { 402 try { 403 if ( dbf == null ) { 404 dbf = DocumentBuilderFactory.newInstance(); 405 dbf.setNamespaceAware( true ); 406 dbf.setValidating( false ); 407 } 408 db = dbf.newDocumentBuilder(); 409 410 DOMImplementation dim = db.getDOMImplementation(); 411 d = dim.createDocument("http://java.sun.com/jstl", "dummyroot", null); 412 return d; 414 } catch ( Exception e ) { 415 e.printStackTrace(); 416 } 417 return null; 418 } 419 420 static Document getDummyDocumentWithoutRoot( ) { 421 try { 422 if ( dbf == null ) { 423 dbf = DocumentBuilderFactory.newInstance(); 424 dbf.setNamespaceAware( true ); 425 dbf.setValidating( false ); 426 } 427 db = dbf.newDocumentBuilder(); 428 429 d = db.newDocument(); 430 return d; 431 } catch ( Exception e ) { 432 e.printStackTrace(); 433 } 434 return null; 435 } 436 437 private static Document getDocumentForNode(Node node) { 438 Document doc = getDummyDocumentWithoutRoot(); 439 Node importedNode = doc.importNode(node, true); 440 doc.appendChild(importedNode); 441 return doc; 442 } 443 444 String modifiedXPath = null; 448 449 450 451 452 453 456 public String valueOf(Node n, String xpath) throws JspTagException { 457 staticInit(); 459 JstlVariableContext vs = new JstlVariableContext(); 461 XPathContext xpathSupport = new XPathContext(); 462 xpathSupport.setVarStack( vs); 463 464 Vector varVector = fillVarStack(vs, xpathSupport); 465 466 Node contextNode = adaptParamsForXalan( vs, n, xpath.trim() ); 467 468 xpath = modifiedXPath; 469 470 472 XObject result = JSTLXPathAPI.eval( contextNode, xpath, 473 jstlPrefixResolver,xpathSupport, varVector); 474 475 476 478 String resultString = result.str(); 479 481 return resultString; 482 483 } 484 485 488 public boolean booleanValueOf(Node n, String xpath) 489 throws JspTagException { 490 491 staticInit(); 492 JstlVariableContext vs = new JstlVariableContext(); 493 XPathContext xpathSupport = new XPathContext(); 494 xpathSupport.setVarStack( vs); 495 496 Vector varVector = fillVarStack(vs, xpathSupport); 497 498 Node contextNode = adaptParamsForXalan( vs, n, xpath.trim() ); 499 xpath = modifiedXPath; 500 501 XObject result = JSTLXPathAPI.eval( contextNode, xpath, 502 jstlPrefixResolver, xpathSupport, varVector); 503 504 try { 505 return result.bool(); 506 } catch (TransformerException ex) { 507 throw new JspTagException ( 508 Resources.getMessage("XPATH_ERROR_XOBJECT", ex.toString()), ex); 509 } 510 } 511 512 515 public List selectNodes(Node n, String xpath) throws JspTagException { 516 517 staticInit(); 518 JstlVariableContext vs = new JstlVariableContext(); 519 XPathContext xpathSupport = new XPathContext(); 520 xpathSupport.setVarStack( vs); 521 522 Vector varVector = fillVarStack(vs, xpathSupport); 523 524 Node contextNode = adaptParamsForXalan( vs, n, xpath.trim() ); 525 xpath = modifiedXPath; 526 527 XObject result = JSTLXPathAPI.eval( contextNode, xpath, 528 jstlPrefixResolver,xpathSupport, varVector); 529 try { 530 NodeList nl= JSTLXPathAPI.getNodeList(result); 531 return new JSTLNodeList( nl ); 532 } catch ( JspTagException e ) { 533 try { 534 538 Vector vector = new Vector (); 540 Object resultObject = null; 541 if ( result.getType()== XObject.CLASS_BOOLEAN ) { 542 resultObject = new Boolean ( result.bool()); 543 } else if ( result.getType()== XObject.CLASS_NUMBER ) { 544 resultObject = new Double ( result.num()); 545 } else if ( result.getType()== XObject.CLASS_STRING ) { 546 resultObject = result.str(); 547 } 548 549 vector.add( resultObject ); 550 return new JSTLNodeList ( vector ); 551 } catch ( TransformerException te ) { 552 throw new JspTagException (te.toString(), te); 553 } 554 } 555 556 557 558 } 559 560 563 public Node selectSingleNode(Node n, String xpath) 564 throws JspTagException { 565 568 staticInit(); 569 JstlVariableContext vs = new JstlVariableContext(); 570 XPathContext xpathSupport = new XPathContext(); 571 xpathSupport.setVarStack( vs); 572 573 Vector varVector = fillVarStack(vs, xpathSupport); 574 575 Node contextNode = adaptParamsForXalan( vs, n, xpath.trim() ); 576 xpath = modifiedXPath; 577 578 return (Node ) JSTLXPathAPI.selectSingleNode( contextNode, xpath, 579 jstlPrefixResolver,xpathSupport ); 580 } 581 582 583 private VariableStack getLocalContext() { 584 VariableStack vc = new JstlVariableContext(); 586 return vc; 587 } 588 589 592 627 protected Node adaptParamsForXalan( JstlVariableContext jvc, Node n, 628 String xpath ) { 629 Node boundDocument = null; 630 631 modifiedXPath = xpath; 632 String origXPath = xpath ; 633 boolean whetherOrigXPath = true; 634 635 if ( n != null ) { 637 return n; 638 } 639 640 if ( xpath.startsWith("$") ) { 641 643 String varQName= xpath.substring( xpath.indexOf("$")+1); 644 if ( varQName.indexOf("/") > 0 ) { 645 varQName = varQName.substring( 0, varQName.indexOf("/")); 646 } 647 String varPrefix = null; 648 String varLocalName = varQName; 649 if ( varQName.indexOf( ":") >= 0 ) { 650 varPrefix = varQName.substring( 0, varQName.indexOf(":") ); 651 varLocalName = varQName.substring( varQName.indexOf(":")+1 ); 652 } 653 654 if ( xpath.indexOf("/") > 0 ) { 655 xpath = xpath.substring( xpath.indexOf("/")); 656 } else { 657 xpath = "/*"; 658 whetherOrigXPath = false; 659 } 660 661 662 try { 663 Object varObject=jvc.getVariableValue( null,varPrefix, 664 varLocalName); 665 668 if ( Class.forName("org.w3c.dom.Document").isInstance( 669 varObject ) ) { 670 boundDocument = ((Document )varObject); 672 } else { 673 674 677 if ( Class.forName("org.apache.taglibs.standard.tag.common.xml.JSTLNodeList").isInstance( varObject ) ) { 678 Document newDocument = getDummyDocument(); 679 680 JSTLNodeList jstlNodeList = (JSTLNodeList)varObject; 681 if ( jstlNodeList.getLength() == 1 ) { 682 if ( Class.forName("org.w3c.dom.Node").isInstance( 683 jstlNodeList.elementAt(0) ) ) { 684 Node node = (Node )jstlNodeList.elementAt(0); 685 boundDocument = getDocumentForNode(node); 686 if ( whetherOrigXPath ) { 687 xpath="/*" + xpath; 688 } 689 690 } else { 691 692 Object myObject = jstlNodeList.elementAt(0); 694 695 698 xpath = myObject.toString(); 699 700 boundDocument = newDocument; 702 } 703 704 } else { 705 706 Element dummyroot = newDocument.getDocumentElement(); 707 for ( int i=0; i< jstlNodeList.getLength(); i++ ) { 708 Node currNode = (Node )jstlNodeList.item(i); 709 710 Node importedNode = newDocument.importNode( 711 currNode, true ); 712 713 715 dummyroot.appendChild( importedNode ); 716 717 } 720 boundDocument = newDocument; 721 726 xpath = "/*" + xpath; 727 } 728 } else if ( Class.forName("org.w3c.dom.Node").isInstance( 729 varObject ) ) { 730 boundDocument = getDocumentForNode((Node )varObject); 731 if (whetherOrigXPath) { 732 xpath = "/*" + xpath; 733 } 734 } else { 735 boundDocument = getDummyDocument(); 736 xpath = origXPath; 737 } 738 739 740 } 741 } catch ( UnresolvableException ue ) { 742 System.out.println("Variable Unresolvable :" + ue.getMessage()); 744 ue.printStackTrace(); 745 } catch ( ClassNotFoundException cnf ) { 746 } 748 } else { 749 boundDocument = getDummyDocument(); 752 } 753 754 modifiedXPath = xpath; 755 758 return boundDocument; 759 } 760 761 762 765 769 private Vector fillVarStack(JstlVariableContext vs, XPathContext xpathSupport) 770 throws JspTagException { 771 org.apache.xpath.VariableStack myvs = xpathSupport.getVarStack(); 772 Vector varVector = getVariableQNames(); 773 for ( int i=0; i<varVector.size(); i++ ) { 774 775 QName varQName = (QName)varVector.elementAt(i); 776 777 try { 778 XObject variableValue = vs.getVariableOrParam( xpathSupport, varQName ); 779 myvs.setGlobalVariable( i, variableValue ); 782 783 } catch ( TransformerException te ) { 784 throw new JspTagException (te.toString(), te); 785 } 786 787 } 788 return varVector; 789 } 790 791 792 793 794 795 798 public static Node getContext(Tag t) throws JspTagException { 799 ForEachTag xt = 800 (ForEachTag) TagSupport.findAncestorWithClass( 801 t, ForEachTag.class); 802 if (xt == null) 803 return null; 804 else 805 return (xt.getContext()); 806 } 807 808 811 private static void p(String s) { 812 System.out.println("[XPathUtil] " + s); 813 } 814 815 public static void printDetails(Node n) { 816 System.out.println("\n\nDetails of Node = > " + n ) ; 817 System.out.println("Name:Type:Node Value = > " + n.getNodeName() + 818 ":" + n.getNodeType() + ":" + n.getNodeValue() ) ; 819 System.out.println("Namespace URI : Prefix : localName = > " + 820 n.getNamespaceURI() + ":" +n.getPrefix() + ":" + n.getLocalName()); 821 System.out.println("\n Node has children => " + n.hasChildNodes() ); 822 if ( n.hasChildNodes() ) { 823 NodeList nl = n.getChildNodes(); 824 System.out.println("Number of Children => " + nl.getLength() ); 825 for ( int i=0; i<nl.getLength(); i++ ) { 826 Node childNode = nl.item(i); 827 printDetails( childNode ); 828 } 829 } 830 } 831 } 832 833 class JSTLNodeList extends Vector implements NodeList { 834 835 Vector nodeVector; 836 837 public JSTLNodeList ( Vector nodeVector ) { 838 this.nodeVector = nodeVector; 839 } 840 841 public JSTLNodeList ( NodeList nl ) { 842 nodeVector = new Vector (); 843 for ( int i=0; i<nl.getLength(); i++ ) { 845 Node currNode = nl.item(i); 846 nodeVector.add(i, nl.item(i) ); 848 } 849 } 850 851 public JSTLNodeList ( Node n ) { 852 nodeVector = new Vector (); 853 nodeVector.addElement( n ); 854 } 855 856 857 public Node item ( int index ) { 858 return (Node )nodeVector.elementAt( index ); 859 } 860 861 public Object elementAt ( int index ) { 862 return nodeVector.elementAt( index ); 863 } 864 865 public Object get ( int index ) { 866 return nodeVector.get( index ); 867 } 868 869 public int getLength ( ) { 870 return nodeVector.size( ); 871 } 872 873 public int size ( ) { 874 return nodeVector.size( ); 876 } 877 878 883 } 884 885 886 887 888 | Popular Tags |