View Javadoc

1   /*
2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3    *
4    * This software is open source.
5    * See the bottom of this file for the licence.
6    */
7   
8   package org.dom4j;
9   
10  import org.dom4j.tree.AbstractNode;
11  import org.dom4j.tree.DefaultNamespace;
12  import org.dom4j.tree.NamespaceCache;
13  
14  /**
15   * <p>
16   * <code>Namespace</code> is a Flyweight Namespace that can be shared amongst
17   * nodes.
18   * </p>
19   * 
20   * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
21   * @version $Revision: 1.22 $
22   */
23  public class Namespace extends AbstractNode {
24      /** Cache of Namespace instances */
25      protected static final NamespaceCache CACHE = new NamespaceCache();
26  
27      /** XML Namespace */
28      public static final Namespace XML_NAMESPACE = CACHE.get("xml",
29              "http://www.w3.org/XML/1998/namespace");
30  
31      /** No Namespace present */
32      public static final Namespace NO_NAMESPACE = CACHE.get("", "");
33  
34      /** The prefix mapped to this namespace */
35      private String prefix;
36  
37      /** The URI for this namespace */
38      private String uri;
39  
40      /** A cached version of the hashcode for efficiency */
41      private int hashCode;
42  
43      /**
44       * DOCUMENT ME!
45       * 
46       * @param prefix
47       *            is the prefix for this namespace
48       * @param uri
49       *            is the URI for this namespace
50       */
51      public Namespace(String prefix, String uri) {
52          this.prefix = (prefix != null) ? prefix : "";
53          this.uri = (uri != null) ? uri : "";
54      }
55  
56      /**
57       * A helper method to return the Namespace instance for the given prefix and
58       * URI
59       * 
60       * @param prefix
61       *            DOCUMENT ME!
62       * @param uri
63       *            DOCUMENT ME!
64       * 
65       * @return an interned Namespace object
66       */
67      public static Namespace get(String prefix, String uri) {
68          return CACHE.get(prefix, uri);
69      }
70  
71      /**
72       * A helper method to return the Namespace instance for no prefix and the
73       * URI
74       * 
75       * @param uri
76       *            DOCUMENT ME!
77       * 
78       * @return an interned Namespace object
79       */
80      public static Namespace get(String uri) {
81          return CACHE.get(uri);
82      }
83  
84      @Override
85      public NodeType getNodeTypeEnum() {
86          return NodeType.NAMESPACE_NODE;
87      }
88  
89      /**
90       * DOCUMENT ME!
91       * 
92       * @return the hash code based on the qualified name and the URI of the
93       *         namespace.
94       */
95      @Override
96      public int hashCode() {
97          if (hashCode == 0) {
98              hashCode = createHashCode();
99          }
100 
101         return hashCode;
102     }
103 
104     /**
105      * Factory method to create the hashcode allowing derived classes to change
106      * the behaviour
107      * 
108      * @return DOCUMENT ME!
109      */
110     protected int createHashCode() {
111         int result = uri.hashCode() ^ prefix.hashCode();
112 
113         if (result == 0) {
114             result = 0xbabe;
115         }
116 
117         return result;
118     }
119 
120     /**
121      * Checks whether this Namespace equals the given Namespace. Two Namespaces
122      * are equals if their URI and prefix are equal.
123      * 
124      * @param object
125      *            DOCUMENT ME!
126      * 
127      * @return DOCUMENT ME!
128      */
129     @Override
130     public boolean equals(Object object) {
131         if (this == object) {
132             return true;
133         } else if (object instanceof Namespace) {
134             Namespace that = (Namespace) object;
135 
136             // we cache hash codes so this should be quick
137             if (hashCode() == that.hashCode()) {
138                 return uri.equals(that.getURI())
139                         && prefix.equals(that.getPrefix());
140             }
141         }
142 
143         return false;
144     }
145 
146     @Override
147     public String getText() {
148         return uri;
149     }
150 
151     @Override
152     public String getStringValue() {
153         return uri;
154     }
155 
156     /**
157      * DOCUMENT ME!
158      * 
159      * @return the prefix for this <code>Namespace</code>.
160      */
161     public String getPrefix() {
162         return prefix;
163     }
164 
165     /**
166      * DOCUMENT ME!
167      * 
168      * @return the URI for this <code>Namespace</code>.
169      */
170     public String getURI() {
171         return uri;
172     }
173 
174     public String getXPathNameStep() {
175         if ((prefix != null) && !"".equals(prefix)) {
176             return "namespace::" + prefix;
177         }
178 
179         return "namespace::*[name()='']";
180     }
181 
182     public String getPath(Element context) {
183         StringBuffer path = new StringBuffer(10);
184         Element parent = getParent();
185 
186         if ((parent != null) && (parent != context)) {
187             path.append(parent.getPath(context));
188             path.append('/');
189         }
190 
191         path.append(getXPathNameStep());
192 
193         return path.toString();
194     }
195 
196     public String getUniquePath(Element context) {
197         StringBuffer path = new StringBuffer(10);
198         Element parent = getParent();
199 
200         if ((parent != null) && (parent != context)) {
201             path.append(parent.getUniquePath(context));
202             path.append('/');
203         }
204 
205         path.append(getXPathNameStep());
206 
207         return path.toString();
208     }
209 
210     @Override
211     public String toString() {
212         return super.toString() + " [Namespace: prefix " + getPrefix()
213                 + " mapped to URI \"" + getURI() + "\"]";
214     }
215 
216     public String asXML() {
217         StringBuffer asxml = new StringBuffer(10);
218         String pref = getPrefix();
219 
220         if ((pref != null) && (pref.length() > 0)) {
221             asxml.append("xmlns:");
222             asxml.append(pref);
223             asxml.append("=\"");
224         } else {
225             asxml.append("xmlns=\"");
226         }
227 
228         asxml.append(getURI());
229         asxml.append("\"");
230 
231         return asxml.toString();
232     }
233 
234     public void accept(Visitor visitor) {
235         visitor.visit(this);
236     }
237 
238     @Override
239     protected Node createXPathResult(Element parent) {
240         return new DefaultNamespace(parent, getPrefix(), getURI());
241     }
242 }
243 
244 /*
245  * Redistribution and use of this software and associated documentation
246  * ("Software"), with or without modification, are permitted provided that the
247  * following conditions are met:
248  * 
249  * 1. Redistributions of source code must retain copyright statements and
250  * notices. Redistributions must also contain a copy of this document.
251  * 
252  * 2. Redistributions in binary form must reproduce the above copyright notice,
253  * this list of conditions and the following disclaimer in the documentation
254  * and/or other materials provided with the distribution.
255  * 
256  * 3. The name "DOM4J" must not be used to endorse or promote products derived
257  * from this Software without prior written permission of MetaStuff, Ltd. For
258  * written permission, please contact dom4j-info@metastuff.com.
259  * 
260  * 4. Products derived from this Software may not be called "DOM4J" nor may
261  * "DOM4J" appear in their names without prior written permission of MetaStuff,
262  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
263  * 
264  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
265  * 
266  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
267  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
268  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
269  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
270  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
271  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
273  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
274  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
275  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
276  * POSSIBILITY OF SUCH DAMAGE.
277  * 
278  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
279  */