KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > xml > NamespaceBinding


1 // Copyright (c) 2003, 2006 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.xml;
5 import java.io.*;
6
7 /** A "namespace node" as a link in a linked list.
8  *
9  * The list may contain duplicates - i.e. multiple namespace bindings
10  * for the same prefix but (usually) different uris. In that case the
11  * first binding "wins". One reason for allowing duplicates it to allow
12  * sharing of the lists between a child and its parent element.
13  */

14
15 public final class NamespaceBinding implements Externalizable
16 {
17   /** Namespace prefix. An interned String.
18    * A default namespace declaration is represented using null. */

19   public final String JavaDoc getPrefix () { return prefix; }
20   public final void setPrefix (String JavaDoc prefix) { this.prefix = prefix; }
21   String JavaDoc prefix;
22
23   /** Namespace uri. An interned String.
24    * The value null "undeclares" any following namespaces; it corresponds
25    * to an empty uri as in the XML Namespaces 1.1 Candidate Recommendation. */

26   public final String JavaDoc getUri () { return uri; }
27   public final void setUri (String JavaDoc uri) { this.uri = uri; }
28   String JavaDoc uri;
29
30   NamespaceBinding next;
31
32   int depth;
33
34   public final NamespaceBinding getNext () { return next; }
35   public final void setNext (NamespaceBinding next)
36   {
37     this.next = next;
38     this.depth = next == null ? 0 : next.depth + 1;
39   }
40
41   /** Chain the first list in front of the second list.
42    * (The name {@code nconc} comes from Common Lisp.)
43    */

44   public final static NamespaceBinding
45   nconc (NamespaceBinding list1, NamespaceBinding list2)
46   {
47     if (list1 == null)
48       return list2;
49     list1.setNext(nconc(list1.next, list2));
50     return list1;
51   }
52
53   // public NamespaceBinding () { }
54

55   public NamespaceBinding (String JavaDoc prefix, String JavaDoc uri, NamespaceBinding next)
56   {
57     this.prefix = prefix;
58     this.uri = uri;
59     setNext(next);
60   }
61
62   public static final String JavaDoc XML_NAMESPACE
63   = "http://www.w3.org/XML/1998/namespace";
64
65   public static final NamespaceBinding predefinedXML
66   = new NamespaceBinding("xml", XML_NAMESPACE, null);
67
68   /** Resolve a prefix.
69    * @param prefix an interned namespace prefix to search for.
70    * @return a uri or null if not bound
71    */

72   public String JavaDoc resolve (String JavaDoc prefix)
73   {
74     for (NamespaceBinding ns = this; ns != null; ns = ns.next)
75       {
76     if (ns.prefix == prefix)
77       return ns.uri;
78       }
79     return null;
80   }
81
82   /** Resolve a prefix, in the initial part of this list.
83    * @param prefix an interned namespace prefix to search for.
84    * @param fencePost only search this list until then.
85    * @return a uri or null if not bound
86    */

87   public String JavaDoc resolve (String JavaDoc prefix, NamespaceBinding fencePost)
88   {
89     for (NamespaceBinding ns = this; ns != fencePost; ns = ns.next)
90       {
91     if (ns.prefix == prefix)
92       return ns.uri;
93       }
94     return null;
95   }
96
97   public static NamespaceBinding commonAncestor (NamespaceBinding ns1,
98                          NamespaceBinding ns2)
99   {
100     if (ns1.depth > ns2.depth)
101       {
102     NamespaceBinding tmp = ns1;
103     ns1 = ns2;
104     ns2 = tmp;
105       }
106     while (ns2.depth > ns1.depth)
107       ns2 = ns2.next;
108     while (ns1 != ns2)
109       {
110     ns1 = ns1.next;
111     ns2 = ns2.next;
112       }
113     return ns1;
114   }
115
116   /* For debugging:
117   void check ()
118   {
119     NamespaceBinding ns = this;
120     int d = depth;
121     for (;;)
122       {
123     if (ns == null)
124       throw new Error("null ns");
125     if (ns.depth != d)
126       throw new Error("bad depth "+ns.depth+" shoudl be "+d);
127     ns = ns.next;
128     if (ns == null && d == 0)
129       return;
130     d--;
131       }
132   }
133   */

134
135   /** Reverse the chain, until a fencePost. */
136   public NamespaceBinding reversePrefix (NamespaceBinding fencePost)
137   {
138     NamespaceBinding prev = fencePost;
139     NamespaceBinding t = this;
140     int depth = fencePost == null ? -1 : fencePost.depth;
141     while (t != fencePost)
142       {
143     NamespaceBinding next = t.next;
144     t.next = prev;
145     prev = t;
146     t.depth = ++depth;
147     t = next;
148       }
149     return prev;
150   }
151
152   /** Return the number of bindings before the <code>fencePost</code>. */
153   public int count (NamespaceBinding fencePost)
154   {
155     int count = 0;
156     for (NamespaceBinding ns = this; ns != fencePost; ns = ns.next)
157       count++;
158     return count;
159   }
160
161   /** Append a new NamespaceBinding if not redundant. */
162   public static NamespaceBinding maybeAdd(String JavaDoc prefix, String JavaDoc uri,
163                       NamespaceBinding bindings)
164   {
165     if (bindings == null)
166       {
167     if (uri == null)
168       return bindings;
169     bindings = predefinedXML;
170       }
171     String JavaDoc found = bindings.resolve(prefix);
172     if (found == null ? uri == null : found.equals(uri))
173       return bindings;
174     return new NamespaceBinding(prefix, uri, bindings);
175   }
176
177   /** Return a String showing just a single namespace binding. */
178   public String JavaDoc toString()
179   {
180     return "Namespace{"+prefix+"="+uri+", depth:"+depth+"}";
181   }
182
183   /** Return a String showing the full namespace binding list. */
184   public String JavaDoc toStringAll()
185   {
186     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc("Namespaces{");
187     for (NamespaceBinding ns = this; ns != null; ns = ns.next)
188       {
189     sbuf.append(ns.prefix);
190     sbuf.append("=\"");
191     sbuf.append(ns.uri);
192     sbuf.append(ns == null ? "\"" : "\", ");
193       }
194     sbuf.append('}');
195     return sbuf.toString();
196   }
197
198   public void writeExternal(ObjectOutput out) throws IOException
199   {
200     out.writeUTF(prefix);
201     out.writeUTF(uri);
202     out.writeObject(next);
203   }
204
205   public void readExternal(ObjectInput in)
206     throws IOException, ClassNotFoundException JavaDoc
207   {
208     prefix = in.readUTF();
209     uri = in.readUTF();
210     next = (NamespaceBinding) in.readObject();
211   }
212
213 }
214
Popular Tags