KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdom > Namespace


1 /*--
2
3  $Id: Namespace.java,v 1.42 2004/12/11 00:46:02 jhunter Exp $
4
5  Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
6  All rights reserved.
7  
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11  
12  1. Redistributions of source code must retain the above copyright
13     notice, this list of conditions, and the following disclaimer.
14  
15  2. Redistributions in binary form must reproduce the above copyright
16     notice, this list of conditions, and the disclaimer that follows
17     these conditions in the documentation and/or other materials
18     provided with the distribution.
19
20  3. The name "JDOM" must not be used to endorse or promote products
21     derived from this software without prior written permission. For
22     written permission, please contact <request_AT_jdom_DOT_org>.
23  
24  4. Products derived from this software may not be called "JDOM", nor
25     may "JDOM" appear in their name, without prior written permission
26     from the JDOM Project Management <request_AT_jdom_DOT_org>.
27  
28  In addition, we request (but do not require) that you include in the
29  end-user documentation provided with the redistribution and/or in the
30  software itself an acknowledgement equivalent to the following:
31      "This product includes software developed by the
32       JDOM Project (http://www.jdom.org/)."
33  Alternatively, the acknowledgment may be graphical using the logos
34  available at http://www.jdom.org/images/logos.
35
36  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  SUCH DAMAGE.
48
49  This software consists of voluntary contributions made by many
50  individuals on behalf of the JDOM Project and was originally
51  created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52  Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
53  on the JDOM Project, please see <http://www.jdom.org/>.
54  
55  */

56
57 package org.jdom;
58
59 import java.util.*;
60
61 /**
62  * An XML namespace representation, as well as a factory for creating XML
63  * namespace objects. Namespaces are not Serializable, however objects that use
64  * namespaces have special logic to handle serialization manually. These classes
65  * call the getNamespace() method on deserialization to ensure there is one
66  * unique Namespace object for any unique prefix/uri pair.
67  *
68  * @version $Revision: 1.42 $, $Date: 2004/12/11 00:46:02 $
69  * @author Brett McLaughlin
70  * @author Elliotte Rusty Harold
71  * @author Jason Hunter
72  * @author Wesley Biggs
73  */

74 public final class Namespace {
75
76     // XXX May want to use weak references to keep the maps from growing
77
// large with extended use
78

79     // XXX We may need to make the namespaces HashMap synchronized with
80
// reader/writer locks or perhaps make Namespace no longer a flyweight.
81
// As written, multiple put() calls may happen from different threads
82
// concurrently and cause a ConcurrentModificationException. See
83
// http://lists.denveronline.net/lists/jdom-interest/2000-September/003009.html.
84
// No one has ever reported this over the many years, so don't worry yet.
85

86     private static final String JavaDoc CVS_ID =
87       "@(#) $RCSfile: Namespace.java,v $ $Revision: 1.42 $ $Date: 2004/12/11 00:46:02 $ $Name: $";
88
89     /**
90      * Factory list of namespaces.
91      * Keys are <i>prefix</i>&amp;<i>URI</i>.
92      * Values are Namespace objects
93      */

94     private static HashMap namespaces;
95
96     /** Define a <code>Namespace</code> for when <i>not</i> in a namespace */
97     public static final Namespace NO_NAMESPACE = new Namespace("", "");
98
99     /** Define a <code>Namespace</code> for the standard xml prefix. */
100     public static final Namespace XML_NAMESPACE =
101         new Namespace("xml", "http://www.w3.org/XML/1998/namespace");
102
103     /** The prefix mapped to this namespace */
104     private String JavaDoc prefix;
105
106     /** The URI for this namespace */
107     private String JavaDoc uri;
108
109     /**
110      * This static initializer acts as a factory contructor.
111      * It sets up storage and required initial values.
112      */

113     static {
114         namespaces = new HashMap(16);
115
116         // Add the "empty" namespace
117
namespaces.put(new NamespaceKey(NO_NAMESPACE), NO_NAMESPACE);
118         namespaces.put(new NamespaceKey(XML_NAMESPACE), XML_NAMESPACE);
119     }
120
121     /**
122      * This will retrieve (if in existence) or create (if not) a
123      * <code>Namespace</code> for the supplied prefix and URI.
124      *
125      * @param prefix <code>String</code> prefix to map to
126      * <code>Namespace</code>.
127      * @param uri <code>String</code> URI of new <code>Namespace</code>.
128      * @return <code>Namespace</code> - ready to use namespace.
129      * @throws IllegalNameException if the given prefix and uri make up
130      * an illegal namespace name.
131      */

132     public static Namespace getNamespace(String JavaDoc prefix, String JavaDoc uri) {
133         // Sanity checking
134
if ((prefix == null) || (prefix.trim().equals(""))) {
135             // Short-cut out for common case of no namespace
136
if ((uri == null) || (uri.trim().equals(""))) {
137                 return NO_NAMESPACE;
138             }
139             prefix = "";
140         }
141         else if ((uri == null) || (uri.trim().equals(""))) {
142             uri = "";
143         }
144
145         // Return existing namespace if found. The preexisting namespaces
146
// should all be legal. In other words, an illegal namespace won't
147
// have been placed in this. Thus we can do this test before
148
// verifying the URI and prefix.
149
NamespaceKey lookup = new NamespaceKey(prefix, uri);
150         Namespace preexisting = (Namespace) namespaces.get(lookup);
151         if (preexisting != null) {
152             return preexisting;
153         }
154
155         // Ensure proper naming
156
String JavaDoc reason;
157         if ((reason = Verifier.checkNamespacePrefix(prefix)) != null) {
158             throw new IllegalNameException(prefix, "Namespace prefix", reason);
159         }
160         if ((reason = Verifier.checkNamespaceURI(uri)) != null) {
161             throw new IllegalNameException(uri, "Namespace URI", reason);
162         }
163
164         // Unless the "empty" Namespace (no prefix and no URI), require a URI
165
if ((!prefix.equals("")) && (uri.equals(""))) {
166             throw new IllegalNameException("", "namespace",
167                 "Namespace URIs must be non-null and non-empty Strings");
168         }
169
170         // Handle XML namespace mislabels. If the user requested the correct
171
// namespace and prefix -- xml, http://www.w3.org/XML/1998/namespace
172
// -- then it was already returned from the preexisting namespaces.
173
// Thus any use of the xml prefix or the
174
// http://www.w3.org/XML/1998/namespace URI at this point must be
175
// incorrect.
176
if (prefix.equals("xml")) {
177             throw new IllegalNameException(prefix, "Namespace prefix",
178              "The xml prefix can only be bound to " +
179              "http://www.w3.org/XML/1998/namespace");
180         }
181
182         // The erratum to Namespaces in XML 1.0 that suggests this
183
// next check is controversial. Not everyone accepts it.
184
if (uri.equals("http://www.w3.org/XML/1998/namespace")) {
185             throw new IllegalNameException(uri, "Namespace URI",
186              "The http://www.w3.org/XML/1998/namespace must be bound to " +
187              "the xml prefix.");
188         }
189
190         // Finally, store and return
191
Namespace ns = new Namespace(prefix, uri);
192         namespaces.put(lookup, ns);
193         return ns;
194     }
195
196     /**
197      * This will retrieve (if in existence) or create (if not) a
198      * <code>Namespace</code> for the supplied URI, and make it usable
199      * as a default namespace, as no prefix is supplied.
200      *
201      * @param uri <code>String</code> URI of new <code>Namespace</code>.
202      * @return <code>Namespace</code> - ready to use namespace.
203      */

204     public static Namespace getNamespace(String JavaDoc uri) {
205         return getNamespace("", uri);
206     }
207
208     /**
209      * This constructor handles creation of a <code>Namespace</code> object
210      * with a prefix and URI; it is intentionally left <code>private</code>
211      * so that it cannot be invoked by external programs/code.
212      *
213      * @param prefix <code>String</code> prefix to map to this namespace.
214      * @param uri <code>String</code> URI for namespace.
215      */

216     private Namespace(String JavaDoc prefix, String JavaDoc uri) {
217         this.prefix = prefix;
218         this.uri = uri;
219     }
220
221     /**
222      * This returns the prefix mapped to this <code>Namespace</code>.
223      *
224      * @return <code>String</code> - prefix for this <code>Namespace</code>.
225      */

226     public String JavaDoc getPrefix() {
227         return prefix;
228     }
229
230     /**
231      * This returns the namespace URI for this <code>Namespace</code>.
232      *
233      * @return <code>String</code> - URI for this <code>Namespace</code>.
234      */

235     public String JavaDoc getURI() {
236         return uri;
237     }
238
239     /**
240      * This tests for equality - Two <code>Namespaces</code>
241      * are equal if and only if their URIs are byte-for-byte equals.
242      *
243      * @param ob <code>Object</code> to compare to this <code>Namespace</code>.
244      * @return <code>boolean</code> - whether the supplied object is equal to
245      * this <code>Namespace</code>.
246      */

247     public boolean equals(Object JavaDoc ob) {
248         if (this == ob) {
249             return true;
250         }
251         if (ob instanceof Namespace) { // instanceof returns false if null
252
return uri.equals(((Namespace)ob).uri);
253         }
254         return false;
255     }
256
257     /**
258      * This returns a <code>String</code> representation of this
259      * <code>Namespace</code>, suitable for use in debugging.
260      *
261      * @return <code>String</code> - information about this instance.
262      */

263     public String JavaDoc toString() {
264         return "[Namespace: prefix \"" + prefix + "\" is mapped to URI \"" +
265                uri + "\"]";
266     }
267
268     /**
269      * This returns a probably unique hash code for the <code>Namespace</code>.
270      * If two namespaces have the same URI, they are equal and have the same
271      * hash code, even if they have different prefixes.
272      *
273      * @return <code>int</code> - hash code for this <code>Namespace</code>.
274      */

275     public int hashCode() {
276         return uri.hashCode();
277     }
278 }
279
Popular Tags