001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    // $Id: JAXPPrefixResolver.java 468655 2006-10-28 07:12:06Z minchau $
019    
020    package org.apache.xpath.jaxp;
021    
022    import org.w3c.dom.Node;
023    import org.w3c.dom.NamedNodeMap;
024    import org.apache.xml.utils.PrefixResolver;
025    
026    import javax.xml.namespace.NamespaceContext;
027    
028    /**
029     * <meta name="usage" content="general"/>
030     * This class implements a Default PrefixResolver which
031     * can be used to perform prefix-to-namespace lookup
032     * for the XPath object.
033     * This class delegates the resolution to the passed NamespaceContext
034     */
035    public class JAXPPrefixResolver implements PrefixResolver
036    {
037    
038        private NamespaceContext namespaceContext;
039        
040    
041        public JAXPPrefixResolver ( NamespaceContext nsContext ) {
042            this.namespaceContext = nsContext;
043        } 
044    
045    
046        public String getNamespaceForPrefix( String prefix ) {
047            return namespaceContext.getNamespaceURI( prefix );
048        }
049    
050        /**
051         * Return the base identifier.
052         *
053         * @return null
054         */
055        public String getBaseIdentifier() {
056            return null;
057        }
058    
059        /**
060         * @see PrefixResolver#handlesNullPrefixes() 
061         */
062        public boolean handlesNullPrefixes() {
063            return false;
064        }
065    
066    
067        /**
068         * The URI for the XML namespace.
069         * (Duplicate of that found in org.apache.xpath.XPathContext). 
070         */
071         
072        public static final String S_XMLNAMESPACEURI =
073            "http://www.w3.org/XML/1998/namespace";
074    
075    
076        /**
077         * Given a prefix and a Context Node, get the corresponding namespace.
078         * Warning: This will not work correctly if namespaceContext
079         * is an attribute node.
080         * @param prefix Prefix to resolve.
081         * @param namespaceContext Node from which to start searching for a
082         * xmlns attribute that binds a prefix to a namespace.
083         * @return Namespace that prefix resolves to, or null if prefix
084         * is not bound.
085         */
086        public String getNamespaceForPrefix(String prefix,
087                                          org.w3c.dom.Node namespaceContext) {
088            Node parent = namespaceContext;
089            String namespace = null;
090    
091            if (prefix.equals("xml")) {
092                namespace = S_XMLNAMESPACEURI;
093            } else {
094                int type;
095    
096                while ((null != parent) && (null == namespace)
097                    && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
098                        || (type == Node.ENTITY_REFERENCE_NODE))) {
099    
100                    if (type == Node.ELEMENT_NODE) {
101                        NamedNodeMap nnm = parent.getAttributes();
102    
103                        for (int i = 0; i < nnm.getLength(); i++) {
104                            Node attr = nnm.item(i);
105                            String aname = attr.getNodeName();
106                            boolean isPrefix = aname.startsWith("xmlns:");
107    
108                            if (isPrefix || aname.equals("xmlns")) {
109                                int index = aname.indexOf(':');
110                                String p =isPrefix ?aname.substring(index + 1) :"";
111    
112                                if (p.equals(prefix)) {
113                                    namespace = attr.getNodeValue();
114                                    break;
115                                }
116                            }
117                        }
118                    }
119    
120                    parent = parent.getParentNode();
121                }
122            }
123            return namespace;
124        }
125    
126    }
127