KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > soap > util > xml > NSStack


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2000 The Apache Software Foundation. All rights
6  * 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 following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "SOAP" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
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 APACHE SOFTWARE FOUNDATION OR
40  * ITS 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  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2000, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.apache.soap.util.xml;
59
60 import java.io.*;
61 import java.util.*;
62 import org.apache.soap.util.xml.* ;
63
64 /**
65  * This class implements a namespace stack for XML apps to use. If
66  * you need to keep track of namespaces in scope, then this class is
67  * for you. Every time you enter a new element and wish to add some
68  * namespace declarations that are to be visible within that
69  * element, you should call <tt>pushScope</tt> to create a new
70  * scope. Then, call <tt>addNSDeclaration</tt> any number of times to
71  * add new declarations for that scope. Scopes nest inside out; that
72  * is, any NS declaration added into a scope is visible from any
73  * scopes that are pushed later. When you want to see whether an NS
74  * declaration has already been made for a certain URI, you should
75  * call <tt>getPrefixInScopeForURI</tt> to get the prefix that has
76  * been bound to that URI. There is a covenience version of
77  * <tt>addNSDecalration</tt> which can be used if you want me to give
78  * you a not-so-random, yet unique, prefix for your namespace
79  * declaration.
80  *
81  * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
82  */

83 public class NSStack {
84   Vector nss = new Vector (); // vector holding vectors of ns decls (stack)
85
int nssCount = 0; // number of items on the stack
86
Vector tos; // the vector @ the top of the stack
87
private final static String JavaDoc nsPrefixPrefix = "ns";
88   private int nsPrefixCount = 1;
89
90   /**
91    * Enter a new scope: after calling this I'm ready to accept new
92    * declarations into that scope.
93    */

94   public void pushScope () {
95     nss.addElement (tos = new Vector ());
96     nssCount++;
97   }
98
99   /**
100    * Leave a scope: this removes any NS declarations that were added
101    * in the last scope. Note that I don't bother to validate that you
102    * don't call popScope too many times; that's your problem.
103    */

104   public void popScope () {
105     nss.removeElementAt (--nssCount);
106     tos = (nssCount != 0) ? (Vector) nss.elementAt (nssCount-1) : null;
107   }
108
109   /**
110    * Add a new declaration to the current scope. This is visible within
111    * the current scope as well as from any nested scopes.
112    *
113    * @param prefix the prefix to be used for this namespace
114    * @param URI the namespace name of this namespace.
115    */

116   synchronized public void addNSDeclaration (String JavaDoc prefix, String JavaDoc URI) {
117     tos.addElement (new NSDecl (prefix, URI));
118   }
119
120   /**
121    * Add a new declaration to the current scope using a unique prefix
122    * and return the prefix. This is useful when one just wants to add a
123    * decl and doesn't want to have to deal with creating unique prefixes.
124    * If the namespace name is already declared and in scope, then the
125    * previously declared prefix is returned.
126    *
127    * @param URI the namespace name of this namespace
128    * @return the unique prefix created or previously declared
129    * for this namespace
130    */

131   synchronized public String JavaDoc addNSDeclaration (String JavaDoc URI) {
132     String JavaDoc uniquePrefix = getPrefixFromURI (URI);
133     if (uniquePrefix == null) {
134       do {
135               uniquePrefix = nsPrefixPrefix + nsPrefixCount++;
136       } while (getURIFromPrefix (uniquePrefix) != null);
137       addNSDeclaration (uniquePrefix, URI);
138     }
139     return uniquePrefix;
140   }
141
142   /**
143    * Return the prefix associated with the given namespace name by
144    * looking thru all the namespace declarations that are in scope.
145    *
146    * @param URI the namespace name for whom a declared prefix is desired
147    * @return the prefix or null if namespace name not found
148    */

149   public String JavaDoc getPrefixFromURI (String JavaDoc URI) {
150     for (int i = nssCount-1; i >= 0; i--) {
151       Vector scope = (Vector) nss.elementAt (i);
152       for (Enumeration e = scope.elements (); e.hasMoreElements (); ) {
153         NSDecl nsd = (NSDecl) e.nextElement ();
154         if (nsd.URI.equals (URI)) {
155           return nsd.prefix;
156         }
157       }
158     }
159     return null;
160   }
161
162   /**
163    * Return the prefix associated with the given namespace name by
164    * looking thru all the namespace declarations that are in scope.
165    * If the namespace declaration is not found, create one and
166    * return the generated prefix.
167    *
168    * @param URI the namespace name for whom a declared prefix is desired
169    * @return the prefix (will never return null)
170    */

171   synchronized public String JavaDoc getPrefixFromURI (String JavaDoc namespaceURI,
172                                                Writer sink)
173     throws IOException {
174     String JavaDoc prefix = getPrefixFromURI (namespaceURI);
175
176     if (prefix == null) {
177       prefix = addNSDeclaration (namespaceURI);
178
179       sink.write (" xmlns:" + prefix + "=\"" + namespaceURI + '\"');
180     }
181
182     return prefix;
183   }
184
185   /**
186    * Return the namespace name associated with the given prefix by
187    * looking thru all the namespace declarations that are in scope.
188    *
189    * @param prefix the prefix for whom a declared namespace name is desired
190    * @return the namespace name or null if prefix not found
191    */

192   public String JavaDoc getURIFromPrefix (String JavaDoc prefix) {
193     for (int i = nssCount-1; i >= 0; i--) {
194       Vector scope = (Vector) nss.elementAt (i);
195       for (Enumeration e = scope.elements (); e.hasMoreElements (); ) {
196         NSDecl nsd = (NSDecl) e.nextElement ();
197         if (nsd.prefix.equals (prefix)) {
198           return nsd.URI;
199         }
200       }
201     }
202     return null;
203   }
204
205   // MJD - debug
206
public String JavaDoc toString()
207   {
208     return nss.toString();
209   }
210   // MJD - debug
211
}
212
213
Popular Tags