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    /*
019     * $Id: PrefixResolverDefault.java 468655 2006-10-28 07:12:06Z minchau $
020     */
021    package org.apache.xml.utils;
022    
023    import org.w3c.dom.NamedNodeMap;
024    import org.w3c.dom.Node;
025    
026    /**
027     * This class implements a generic PrefixResolver that
028     * can be used to perform prefix-to-namespace lookup
029     * for the XPath object.
030     * @xsl.usage general
031     */
032    public class PrefixResolverDefault implements PrefixResolver
033    {
034    
035      /**
036       * The context to resolve the prefix from, if the context
037       * is not given.
038       */
039      Node m_context;
040    
041      /**
042       * Construct a PrefixResolverDefault object.
043       * @param xpathExpressionContext The context from
044       * which XPath expression prefixes will be resolved.
045       * Warning: This will not work correctly if xpathExpressionContext
046       * is an attribute node.
047       */
048      public PrefixResolverDefault(Node xpathExpressionContext)
049      {
050        m_context = xpathExpressionContext;
051      }
052    
053      /**
054       * Given a namespace, get the corrisponding prefix.  This assumes that
055       * the PrevixResolver hold's it's own namespace context, or is a namespace
056       * context itself.
057       * @param prefix Prefix to resolve.
058       * @return Namespace that prefix resolves to, or null if prefix
059       * is not bound.
060       */
061      public String getNamespaceForPrefix(String prefix)
062      {
063        return getNamespaceForPrefix(prefix, m_context);
064      }
065    
066      /**
067       * Given a namespace, get the corrisponding prefix.
068       * Warning: This will not work correctly if namespaceContext
069       * is an attribute node.
070       * @param prefix Prefix to resolve.
071       * @param namespaceContext Node from which to start searching for a
072       * xmlns attribute that binds a prefix to a namespace.
073       * @return Namespace that prefix resolves to, or null if prefix
074       * is not bound.
075       */
076      public String getNamespaceForPrefix(String prefix,
077                                          org.w3c.dom.Node namespaceContext)
078      {
079    
080        Node parent = namespaceContext;
081        String namespace = null;
082    
083        if (prefix.equals("xml"))
084        {
085          namespace = Constants.S_XMLNAMESPACEURI;
086        }
087        else
088        {
089          int type;
090    
091          while ((null != parent) && (null == namespace)
092                 && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
093                     || (type == Node.ENTITY_REFERENCE_NODE)))
094          {
095            if (type == Node.ELEMENT_NODE)
096            {
097                    if (parent.getNodeName().indexOf(prefix+":") == 0) 
098                            return parent.getNamespaceURI();                
099              NamedNodeMap nnm = parent.getAttributes();
100    
101              for (int i = 0; i < nnm.getLength(); i++)
102              {
103                Node attr = nnm.item(i);
104                String aname = attr.getNodeName();
105                boolean isPrefix = aname.startsWith("xmlns:");
106    
107                if (isPrefix || aname.equals("xmlns"))
108                {
109                  int index = aname.indexOf(':');
110                  String p = isPrefix ? aname.substring(index + 1) : "";
111    
112                  if (p.equals(prefix))
113                  {
114                    namespace = attr.getNodeValue();
115    
116                    break;
117                  }
118                }
119              }
120            }
121    
122            parent = parent.getParentNode();
123          }
124        }
125    
126        return namespace;
127      }
128    
129      /**
130       * Return the base identifier.
131       *
132       * @return null
133       */
134      public String getBaseIdentifier()
135      {
136        return null;
137      }
138            /**
139             * @see PrefixResolver#handlesNullPrefixes()
140             */
141            public boolean handlesNullPrefixes() {
142                    return false;
143            }
144    
145    }