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. import java.util.HashMap;
  18. import java.util.Iterator;
  19. import java.util.Map;
  20. import org.apache.commons.jxpath.Pointer;
  21. import org.apache.commons.jxpath.ri.model.NodeIterator;
  22. import org.apache.commons.jxpath.ri.model.NodePointer;
  23. /**
  24. * The reference implementation of JXPathContext.
  25. *
  26. * @author Dmitri Plotnikov
  27. * @version $Revision: 1.2 $ $Date: 2004/06/29 22:57:20 $
  28. */
  29. public class NamespaceResolver implements Cloneable {
  30. protected HashMap namespaceMap = new HashMap();
  31. protected HashMap reverseMap;
  32. protected NodePointer pointer;
  33. private boolean sealed;
  34. /**
  35. * Registers a namespace prefix.
  36. *
  37. * @param prefix A namespace prefix
  38. * @param namespaceURI A URI for that prefix
  39. */
  40. public void registerNamespace(String prefix, String namespaceURI) {
  41. namespaceMap.put(prefix, namespaceURI);
  42. reverseMap = null;
  43. }
  44. /**
  45. * Register a namespace for the expression context.
  46. */
  47. public void setNamespaceContextPointer(NodePointer pointer) {
  48. this.pointer = pointer;
  49. }
  50. public Pointer getNamespaceContextPointer() {
  51. return pointer;
  52. }
  53. /**
  54. * Given a prefix, returns a registered namespace URI. If the requested
  55. * prefix was not defined explicitly using the registerNamespace method,
  56. * JXPathContext will then check the context node to see if the prefix is
  57. * defined there. See
  58. * {@link #setNamespaceContextPointer(Pointer) setNamespaceContextPointer}.
  59. *
  60. * @param prefix The namespace prefix to look up
  61. * @return namespace URI or null if the prefix is undefined.
  62. */
  63. public String getNamespaceURI(String prefix) {
  64. String uri = (String) namespaceMap.get(prefix);
  65. if (uri == null && pointer != null) {
  66. uri = pointer.getNamespaceURI(prefix);
  67. }
  68. // System.err.println("For prefix " + prefix + " URI=" + uri);
  69. return uri;
  70. }
  71. public String getPrefix(String namespaceURI) {
  72. if (reverseMap == null) {
  73. reverseMap = new HashMap();
  74. NodeIterator ni = pointer.namespaceIterator();
  75. if (ni != null) {
  76. for (int position = 1; ni.setPosition(position); position++) {
  77. NodePointer nsPointer = ni.getNodePointer();
  78. QName qname = nsPointer.getName();
  79. reverseMap.put(qname.getPrefix(), qname.getName());
  80. }
  81. }
  82. Iterator it = namespaceMap.entrySet().iterator();
  83. while (it.hasNext()) {
  84. Map.Entry entry = (Map.Entry) it.next();
  85. reverseMap.put(entry.getValue(), entry.getKey());
  86. }
  87. }
  88. String prefix = (String) reverseMap.get(namespaceURI);
  89. return prefix;
  90. }
  91. public boolean isSealed() {
  92. return sealed;
  93. }
  94. public void seal() {
  95. sealed = true;
  96. }
  97. public Object clone() {
  98. try {
  99. return super.clone();
  100. }
  101. catch (CloneNotSupportedException e) {
  102. // Of course, it's supported.
  103. e.printStackTrace();
  104. return null;
  105. }
  106. }
  107. }