xpathutil.java

来自「jakarta-taglibs」· Java 代码 · 共 888 行 · 第 1/3 页

JAVA
888
字号
/*
 * Copyright 1999-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.taglibs.standard.tag.common.xml;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerException;

import org.apache.taglibs.standard.resources.Resources;
import org.apache.xml.utils.QName;
import org.apache.xpath.VariableStack;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XNodeSetForDOM;
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XString;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * <p>Support for tag handlers that evaluate XPath expressions.</p>
 *
 * @author Shawn Bayern
 * @author Ramesh Mandava ( ramesh.mandava@sun.com )
 * @author Pierre Delisle ( pierre.delisle@sun.com )
 */
// would ideally be a base class, but some of our user handlers already
// have their own parents
public class XPathUtil {
    
    //*********************************************************************
    // Constructor
    
    /**
     * Constructs a new XPathUtil object associated with the given
     * PageContext.
     */
    public XPathUtil(PageContext pc) {
        pageContext = pc;
    }    
    
    int globalVarSize=0;
    public Vector getVariableQNames ( ) {

        globalVarSize = 0;
        Vector variableVector = new Vector ( );
        // Now construct attributes in different scopes
        Enumeration enum_ = pageContext.getAttributeNamesInScope( 
            PageContext.PAGE_SCOPE );
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( PAGE_NS_URL, PAGE_P, varName); 
            //Adding both namespace qualified QName and just localName
            variableVector.addElement( varQName );
            globalVarSize++;
            
            variableVector.addElement( new QName(null, varName ) );
            globalVarSize++;
        }
        enum_ = pageContext.getAttributeNamesInScope( 
            PageContext.REQUEST_SCOPE );
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( REQUEST_NS_URL,REQUEST_P, varName); 
            //Adding both namespace qualified QName and just localName
            variableVector.addElement( varQName );
            globalVarSize++;
            variableVector.addElement( new QName(null, varName ) );
            globalVarSize++;
        }
        enum_ = pageContext.getAttributeNamesInScope( 
            PageContext.SESSION_SCOPE );
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( SESSION_NS_URL, SESSION_P,varName); 
            //Adding both namespace qualified QName and just localName
            variableVector.addElement( varQName );
            globalVarSize++;
            variableVector.addElement( new QName(null, varName ) );
            globalVarSize++;
        }
        enum_ = pageContext.getAttributeNamesInScope( 
            PageContext.APPLICATION_SCOPE );
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( APP_NS_URL, APP_P,varName ); 
            //Adding both namespace qualified QName and just localName
            variableVector.addElement( varQName );
            globalVarSize++;
            variableVector.addElement( new QName(null, varName ) );
            globalVarSize++;
        }
        enum_ = pageContext.getRequest().getParameterNames();
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( PARAM_NS_URL, PARAM_P,varName ); 
            //Adding both namespace qualified QName and just localName
            variableVector.addElement( varQName );
            globalVarSize++;
        }
        enum_ = pageContext.getServletContext().getInitParameterNames();
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( INITPARAM_NS_URL, INITPARAM_P,varName ); 
            //Adding both namespace qualified QName and just localName
            variableVector.addElement( varQName );
            globalVarSize++;
        }
        enum_ = ((HttpServletRequest)pageContext.getRequest()).getHeaderNames();
        while ( enum_.hasMoreElements() ) {
            String varName = (String)enum_.nextElement();
            QName varQName = new QName ( HEADER_NS_URL, HEADER_P,varName ); 
            //Adding namespace qualified QName 
            variableVector.addElement( varQName );
            globalVarSize++;
        }
        Cookie[] c= ((HttpServletRequest)pageContext.getRequest()).getCookies();
        if ( c!= null ) {
	    for (int i = 0; i < c.length; i++) {
	        String varName = c[i].getName();
                QName varQName = new QName ( COOKIE_NS_URL, COOKIE_P,varName ); 
                //Adding namespace qualified QName 
                variableVector.addElement( varQName );
                globalVarSize++;
            }
        }

        return variableVector;
        
    }
 
    //*********************************************************************
    // Support for JSTL variable resolution
    
    // The URLs
    private static final String PAGE_NS_URL
    = "http://java.sun.com/jstl/xpath/page";
    private static final String REQUEST_NS_URL
    = "http://java.sun.com/jstl/xpath/request";
    private static final String SESSION_NS_URL
    = "http://java.sun.com/jstl/xpath/session";
    private static final String APP_NS_URL
    = "http://java.sun.com/jstl/xpath/app";
    private static final String PARAM_NS_URL
    = "http://java.sun.com/jstl/xpath/param";
    private static final String INITPARAM_NS_URL
    = "http://java.sun.com/jstl/xpath/initParam";
    private static final String COOKIE_NS_URL
    = "http://java.sun.com/jstl/xpath/cookie";
    private static final String HEADER_NS_URL
    = "http://java.sun.com/jstl/xpath/header";
    
    // The prefixes
    private static final String PAGE_P = "pageScope";
    private static final String REQUEST_P = "requestScope";
    private static final String SESSION_P = "sessionScope";
    private static final String APP_P = "applicationScope";
    private static final String PARAM_P = "param";
    private static final String INITPARAM_P = "initParam";
    private static final String COOKIE_P = "cookie";
    private static final String HEADER_P = "header";
    
    /**
     * org.apache.xpath.VariableStack defines a class to keep track of a stack 
     * for template arguments and variables. 
     * JstlVariableContext customizes it so it handles JSTL custom
     * variable-mapping rules.
     */
    protected class JstlVariableContext extends org.apache.xpath.VariableStack {
        
        public JstlVariableContext( ) {
            super();
        }
        
        /**
         * Get a variable as an XPath object based on it's qualified name.
         * We override the base class method so JSTL's custom variable-mapping 
         * rules can be applied.
         *
         * @param xctxt The XPath context. @@@ we don't use it...
         *  (from xalan: which must be passed in order to lazy evaluate variables.)
         * @param qname The qualified name of the variable.
         */
        public XObject getVariableOrParam(
        XPathContext xctxt, 
        org.apache.xml.utils.QName qname)
        throws javax.xml.transform.TransformerException, UnresolvableException
        {
            //p( "***********************************getVariableOrParam begin****");
            String namespace = qname.getNamespaceURI();
            String prefix = qname.getPrefix();
            String localName = qname.getLocalName();
            
            //p("namespace:prefix:localname=>"+ namespace
            //     + ":" + prefix +":" + localName );
            
            try {
                Object varObject = getVariableValue(namespace,prefix,localName);


                //XObject varObject = myvs.getVariableOrParam( xpathSupport, varQName);
                XObject newXObject = new XObject( varObject);

                if ( Class.forName("org.w3c.dom.Document").isInstance( varObject) ) {

                    NodeList nl= ((Document)varObject).getChildNodes();
                    // To allow non-welformed document
                    Vector nodeVector = new Vector();
                    for ( int i=0; i<nl.getLength(); i++ ) {
                        Node currNode = nl.item(i);
                        if ( currNode.getNodeType() == Node.ELEMENT_NODE ) {
                            nodeVector.addElement( currNode);
                        }
                    }
                    JSTLNodeList jstlNodeList = new JSTLNodeList( nodeVector);
                    newXObject = new XNodeSetForDOM( jstlNodeList, xctxt );
                    
                    return newXObject;
                   
                } 
                if ( Class.forName(
        "org.apache.taglibs.standard.tag.common.xml.JSTLNodeList").isInstance(
                     varObject) ) {
                    JSTLNodeList jstlNodeList = (JSTLNodeList)varObject;
                    if  ( ( jstlNodeList.getLength() == 1 ) && 
   (!Class.forName("org.w3c.dom.Node").isInstance( jstlNodeList.elementAt(0) ) ) ) { 
                        varObject = jstlNodeList.elementAt(0);
                        //Now we need to allow this primitive type to be coverted 
                        // to type which Xalan XPath understands 
                    } else {
                        return new XNodeSetForDOM (  jstlNodeList ,xctxt );
                    }
                } 
                if (Class.forName("org.w3c.dom.Node").isInstance( varObject)) {
                    newXObject = new XNodeSetForDOM ( new JSTLNodeList( (Node)varObject ),xctxt );
                } else if ( Class.forName("java.lang.String").isInstance( varObject)){
                    newXObject = new XString ( (String)varObject );
                } else if ( Class.forName("java.lang.Boolean").isInstance( varObject) ) {
                    newXObject = new XBoolean ( (Boolean)varObject );
                } else if ( Class.forName("java.lang.Number").isInstance( varObject) ) {
                    newXObject = new XNumber ( (Number)varObject );
                } 

                return newXObject;
               // myvs.setGlobalVariable( i, newXObject );
            } catch ( ClassNotFoundException cnfe ) {
                // This shouldn't happen (FIXME: LOG)
                System.out.println("CLASS NOT FOUND EXCEPTION :" + cnfe );
            } 
            //System.out.println("*****getVariableOrParam returning *null*" );
            return null ;
        }
        
        /**
         * Retrieve an XPath's variable value using JSTL's custom 
         * variable-mapping rules
         */
        public Object getVariableValue(
        String namespace, 
        String prefix,
        String localName) 
        throws UnresolvableException 
        {
            // p("resolving: ns=" + namespace + " prefix=" + prefix + " localName=" + localName);
            // We can match on namespace with Xalan but leaving as is
            // [ I 'd prefer to match on namespace, but this doesn't appear
            // to work in Jaxen]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?