    1   /*
    2    * Copyright 1999-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri;
    17
    18
    19  import java.util.HashMap;
    20  import java.util.Iterator;
    21  import java.util.Map;
    22
    23  import org.apache.commons.jxpath.Pointer;
    24  import org.apache.commons.jxpath.ri.model.NodeIterator;
    25  import org.apache.commons.jxpath.ri.model.NodePointer;
    26
    27  /***
    28   * The reference implementation of JXPathContext.
    29   *
    30   * @author Dmitri Plotnikov
    31   * @version $Revision: 1.2 $ $Date: 2004/06/29 22:57:20 $
    32   */
    33  public class NamespaceResolver implements Cloneable {
    34
    35      protected HashMap namespaceMap = new HashMap();
    36      protected HashMap reverseMap;
    37      protected NodePointer pointer;
    38      private boolean sealed;
    39
    40      /***
    41       * Registers a namespace prefix.
    42       *
    43       * @param prefix A namespace prefix
    44       * @param namespaceURI A URI for that prefix
    45       */
    46      public void registerNamespace(String prefix, String namespaceURI) {
    47          namespaceMap.put(prefix, namespaceURI);
    48          reverseMap = null;
    49      }
    50
    51      /***
    52       * Register a namespace for the expression context.
    53       */
    54      public void setNamespaceContextPointer(NodePointer pointer) {
    55          this.pointer = pointer;
    56      }
    57
    58      public Pointer getNamespaceContextPointer() {
    59          return pointer;
    60      }
    61
    62      /***
    63       * Given a prefix, returns a registered namespace URI. If the requested
    64       * prefix was not defined explicitly using the registerNamespace method,
    65       * JXPathContext will then check the context node to see if the prefix is
    66       * defined there. See
    67       * {@link #setNamespaceContextPointer(Pointer) setNamespaceContextPointer}.
    68       *
    69       * @param prefix The namespace prefix to look up
    70       * @return namespace URI or null if the prefix is undefined.
    71       */
    72      public String getNamespaceURI(String prefix) {
    73          String uri = (String) namespaceMap.get(prefix);
    74          if (uri == null && pointer != null) {
    75              uri = pointer.getNamespaceURI(prefix);
    76          }
    77  //        System.err.println("For prefix " + prefix + " URI=" + uri);
    78          return uri;
    79      }
    80
    81      public String getPrefix(String namespaceURI) {
    82          if (reverseMap == null) {
    83              reverseMap = new HashMap();
    84              NodeIterator ni = pointer.namespaceIterator();
    85              if (ni != null) {
    86                  for (int position = 1; ni.setPosition(position); position++) {
    87                      NodePointer nsPointer = ni.getNodePointer();
    88                      QName qname = nsPointer.getName();
    89                      reverseMap.put(qname.getPrefix(), qname.getName());
    90                  }
    91              }
    92              Iterator it = namespaceMap.entrySet().iterator();
    93              while (it.hasNext()) {
    94                  Map.Entry entry = (Map.Entry) it.next();
    95                  reverseMap.put(entry.getValue(), entry.getKey());
    96              }
    97          }
    98          String prefix = (String) reverseMap.get(namespaceURI);
    99          return prefix;
    100     }
    101
    102     public boolean isSealed() {
    103         return sealed;
    104     }
    105
    106     public void seal() {
    107         sealed = true;
    108     }
    109
    110     public Object clone() {
    111         try {
    112             return super.clone();
    113         }
    114         catch (CloneNotSupportedException e) {
    115             // Of course, it's supported.
    116             e.printStackTrace();
    117             return null;
    118         }
    119     }
    120 }