1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.xpath.internal.jaxp;
23
24import org.w3c.dom.Node;
25import org.w3c.dom.NamedNodeMap;
26import com.sun.org.apache.xml.internal.utils.PrefixResolver;
27
28import javax.xml.namespace.NamespaceContext;
29
30/**
31 * <meta name="usage" content="general"/>
32 * This class implements a Default PrefixResolver which
33 * can be used to perform prefix-to-namespace lookup
34 * for the XPath object.
35 * This class delegates the resolution to the passed NamespaceContext
36 */
37public class JAXPPrefixResolver implements PrefixResolver
38{
39
40    private NamespaceContext namespaceContext;
41
42
43    public JAXPPrefixResolver ( NamespaceContext nsContext ) {
44        this.namespaceContext = nsContext;
45    }
46
47
48    public String getNamespaceForPrefix( String prefix ) {
49        return namespaceContext.getNamespaceURI( prefix );
50    }
51
52    /**
53     * Return the base identifier.
54     *
55     * @return null
56     */
57    public String getBaseIdentifier() {
58        return null;
59    }
60
61    /**
62     * @see PrefixResolver#handlesNullPrefixes()
63     */
64    public boolean handlesNullPrefixes() {
65        return false;
66    }
67
68
69    /**
70     * The URI for the XML namespace.
71     * (Duplicate of that found in com.sun.org.apache.xpath.internal.XPathContext).
72     */
73
74    public static final String S_XMLNAMESPACEURI =
75        "http://www.w3.org/XML/1998/namespace";
76
77
78    /**
79     * Given a prefix and a Context Node, get the corresponding namespace.
80     * Warning: This will not work correctly if namespaceContext
81     * is an attribute node.
82     * @param prefix Prefix to resolve.
83     * @param namespaceContext Node from which to start searching for a
84     * xmlns attribute that binds a prefix to a namespace.
85     * @return Namespace that prefix resolves to, or null if prefix
86     * is not bound.
87     */
88    public String getNamespaceForPrefix(String prefix,
89                                      org.w3c.dom.Node namespaceContext) {
90        Node parent = namespaceContext;
91        String namespace = null;
92
93        if (prefix.equals("xml")) {
94            namespace = S_XMLNAMESPACEURI;
95        } else {
96            int type;
97
98            while ((null != parent) && (null == namespace)
99                && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
100                    || (type == Node.ENTITY_REFERENCE_NODE))) {
101
102                if (type == Node.ELEMENT_NODE) {
103                    NamedNodeMap nnm = parent.getAttributes();
104
105                    for (int i = 0; i < nnm.getLength(); i++) {
106                        Node attr = nnm.item(i);
107                        String aname = attr.getNodeName();
108                        boolean isPrefix = aname.startsWith("xmlns:");
109
110                        if (isPrefix || aname.equals("xmlns")) {
111                            int index = aname.indexOf(':');
112                            String p =isPrefix ?aname.substring(index + 1) :"";
113
114                            if (p.equals(prefix)) {
115                                namespace = attr.getNodeValue();
116                                break;
117                            }
118                        }
119                    }
120                }
121
122                parent = parent.getParentNode();
123            }
124        }
125        return namespace;
126    }
127
128}
129