KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > xml > dom4j > o3impl > NamespaceStack


1 /*
2  * Copyright 2001 (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  * $Id: NamespaceStack.java,v 1.1 2003/11/02 18:10:03 per_nyfelt Exp $
8  */

9
10 package org.ozoneDB.xml.dom4j.o3impl;
11
12 import org.dom4j.*;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Map JavaDoc;
17
18 /** NamespaceStack implements a stack of namespaces and optionally
19  * maintains a cache of all the fully qualified names (<code>QName</code>)
20  * which are in scope. This is useful when building or navigating a <i>dom4j</i>
21  * document.
22  *
23  * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
24  * @version $Revision: 1.1 $
25  */

26 public class NamespaceStack {
27
28     /** The factory used to create new <code>AbstractNamespace</code> instances */
29     private NodeFactory nodeFactory;
30
31     /** The Stack of namespaces */
32     private ArrayList JavaDoc namespaceStack = new ArrayList JavaDoc();
33
34     /** The cache of qualifiedNames to QNames per namespace context */
35     private ArrayList JavaDoc namespaceCacheList = new ArrayList JavaDoc();
36
37     /** A cache of current namespace context cache of mapping from qualifiedName to QName */
38     private Map JavaDoc currentNamespaceCache;
39
40     /** A cache of mapping from qualifiedName to QName before any namespaces are declared */
41     private Map JavaDoc rootNamespaceCache = new HashMap JavaDoc();
42
43
44     /** Caches the default namespace defined via xmlns="" */
45     private Namespace defaultNamespace;
46
47
48 // public NamespaceStack() {
49
// this.nodeFactory = DocumentFactory.getInstance();
50
// }
51

52     /**
53      * @deprecated Use NamespaceStack(NodeFactory) instead.
54      */

55     public NamespaceStack(DocumentFactory documentFactory) {
56         this.nodeFactory = documentFactory;
57     }
58
59     public NamespaceStack(NodeFactory nodeFactory) {
60         this.nodeFactory = nodeFactory;
61     }
62
63     /** Pushes the given namespace onto the stack so that its prefix
64      * becomes available.
65      *
66      * @param namespace is the <code>AbstractNamespace</code> to add to the stack.
67      */

68     public void push(Namespace namespace) {
69         namespaceStack.add(namespace);
70         namespaceCacheList.add(null);
71         currentNamespaceCache = null;
72         String JavaDoc prefix = namespace.getPrefix();
73         if (prefix == null || prefix.length() == 0) {
74             defaultNamespace = namespace;
75         }
76     }
77
78     /** Pops the most recently used <code>AbstractNamespace</code> from
79      * the stack
80      *
81      * @return AbstractNamespace popped from the stack
82      */

83     public Namespace pop() {
84         return remove(namespaceStack.size() - 1);
85     }
86
87     /** @return the number of namespaces on the stackce stack.
88      */

89     public int size() {
90         return namespaceStack.size();
91     }
92
93     /** Clears the stack
94      */

95     public void clear() {
96         namespaceStack.clear();
97         namespaceCacheList.clear();
98         rootNamespaceCache.clear();
99         currentNamespaceCache = null;
100     }
101
102     /** @return the namespace at the specified index on the stack
103      */

104     public AbstractNamespace getNamespace(int index) {
105         return (AbstractNamespace) namespaceStack.get(index);
106     }
107
108     /** @return the namespace for the given prefix or null
109      * if it could not be found.
110      */

111     public Namespace getNamespaceForPrefix(String JavaDoc prefix) {
112         if (prefix == null) {
113             prefix = "";
114         }
115         for (int i = namespaceStack.size() - 1; i >= 0; i--) {
116             Namespace namespace = (Namespace) namespaceStack.get(i);
117             if (prefix.equals(namespace.getPrefix())) {
118                 return namespace;
119             }
120         }
121         return null;
122     }
123
124     /** @return the URI for the given prefix or null if it
125      * could not be found.
126      */

127     public String JavaDoc getURI(String JavaDoc prefix) {
128         Namespace namespace = getNamespaceForPrefix(prefix);
129         return (namespace != null) ? namespace.getURI() : null;
130     }
131
132     /** @return true if the given prefix is in the stack.
133      */

134     public boolean contains(Namespace namespace) {
135         String JavaDoc prefix = namespace.getPrefix();
136         Namespace current = null;
137         if (prefix == null || prefix.length() == 0) {
138             current = getDefaultNamespace();
139         } else {
140             current = getNamespaceForPrefix(prefix);
141         }
142         if (current == null) {
143             return false;
144         }
145         if (current == namespace) {
146             return true;
147         }
148         return namespace.getURI().equals(current.getURI());
149     }
150
151     public QName getQName(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qualifiedName) {
152         if (localName == null) {
153             localName = qualifiedName;
154         } else if (qualifiedName == null) {
155             qualifiedName = localName;
156         }
157         if (namespaceURI == null) {
158             namespaceURI = "";
159         }
160         String JavaDoc prefix = "";
161         int index = qualifiedName.indexOf(":");
162         if (index > 0) {
163             prefix = qualifiedName.substring(0, index);
164             if (localName.trim().length() == 0) {
165                 localName = qualifiedName.substring(index + 1);
166             }
167         } else if (localName.trim().length() == 0) {
168             localName = qualifiedName;
169         }
170         Namespace namespace = createNamespace(prefix, namespaceURI);
171         return pushQName(localName, qualifiedName, namespace, prefix);
172     }
173
174     public QName getAttributeQName(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qualifiedName) {
175         if (qualifiedName == null) {
176             qualifiedName = localName;
177         }
178         Map JavaDoc map = getNamespaceCache();
179         QName answer = (QName) map.get(qualifiedName);
180         if (answer != null) {
181             return answer;
182         }
183         if (localName == null) {
184             localName = qualifiedName;
185         }
186         if (namespaceURI == null) {
187             namespaceURI = "";
188         }
189         Namespace namespace = null;
190         String JavaDoc prefix = "";
191         int index = qualifiedName.indexOf(":");
192         if (index > 0) {
193             prefix = qualifiedName.substring(0, index);
194             namespace = createNamespace(prefix, namespaceURI);
195             if (localName.trim().length() == 0) {
196                 localName = qualifiedName.substring(index + 1);
197             }
198         } else {
199             // attributes with no prefix have no namespace
200
namespace = nodeFactory.getNoNamespace();
201             //AbstractNamespace.NO_NAMESPACE;
202
if (localName.trim().length() == 0) {
203                 localName = qualifiedName;
204             }
205         }
206         answer = pushQName(localName, qualifiedName, namespace, prefix);
207         map.put(qualifiedName, answer);
208         return answer;
209     }
210
211     /** Adds a namepace to the stack with the given prefix and URI */
212     public void push(String JavaDoc prefix, String JavaDoc uri) {
213         if (uri == null) {
214             uri = "";
215         }
216         Namespace namespace = createNamespace(prefix, uri);
217         push(namespace);
218     }
219
220     /** Adds a new namespace to the stack */
221     public Namespace addNamespace(String JavaDoc prefix, String JavaDoc uri) {
222         Namespace namespace = createNamespace(prefix, uri);
223         push(namespace);
224         return namespace;
225     }
226
227     /** Pops a namepace from the stack with the given prefix and URI */
228     public Namespace pop(String JavaDoc prefix) {
229         if (prefix == null) {
230             prefix = "";
231         }
232         Namespace namespace = null;
233         for (int i = namespaceStack.size() - 1; i >= 0; i--) {
234             Namespace ns = (Namespace) namespaceStack.get(i);
235             if (prefix.equals(ns.getPrefix())) {
236                 remove(i);
237                 namespace = ns;
238                 break;
239             }
240         }
241         if (namespace == null) {
242             System.out.println("Warning: missing namespace prefix ignored: " + prefix);
243         }
244         return namespace;
245     }
246
247     public String JavaDoc toString() {
248         return super.toString() + " Stack: " + namespaceStack.toString();
249     }
250
251     /**
252      * @deprecated Use getNodeFactory() instead
253      */

254     public DocumentFactory getDocumentFactory() {
255         if (getNodeFactory() instanceof XPathFactory) {
256             return new DelegateDocumentFactory(getNodeFactory(), (XPathFactory) getNodeFactory());
257         } else {
258             return new DelegateDocumentFactory(getNodeFactory(), DocumentFactory.getInstance());
259         }
260     }
261
262     /**
263      * @deprecated Use setNodeFactory(NodeFactory) instead
264      */

265     public void setDocumentFactory(DocumentFactory documentFactory) {
266         this.nodeFactory = documentFactory;
267     }
268
269     public NodeFactory getNodeFactory() {
270         return nodeFactory;
271     }
272
273     public void setNodeFactory(NodeFactory nodeFactory) {
274         this.nodeFactory = nodeFactory;
275     }
276
277     public Namespace getDefaultNamespace() {
278         if (defaultNamespace == null) {
279             defaultNamespace = findDefaultNamespace();
280         }
281         return defaultNamespace;
282     }
283
284     // Implementation methods
285
//-------------------------------------------------------------------------
286

287     /** Adds the QName to the stack of available QNames
288      */

289     protected QName pushQName(String JavaDoc localName, String JavaDoc qualifiedName, Namespace namespace, String JavaDoc prefix) {
290         if (prefix == null || prefix.length() == 0) {
291             this.defaultNamespace = null;
292         }
293         return createQName(localName, qualifiedName, namespace);
294     }
295
296     /** Factory method to creeate new QName instances. By default this method
297      * interns the QName
298      */

299     protected QName createQName(String JavaDoc localName, String JavaDoc qualifiedName, Namespace namespace) {
300         return getNodeFactory().createQName(localName, namespace);
301     }
302
303     /** Factory method to creeate new AbstractNamespace instances. By default this method
304      * interns the AbstractNamespace
305      */

306     protected Namespace createNamespace(String JavaDoc prefix, String JavaDoc namespaceURI) {
307         return getNodeFactory().createNamespace(prefix, namespaceURI);
308     }
309
310     /** Attempts to find the current default namespace on the stack right now or returns null if one
311      * could not be found
312      */

313     protected Namespace findDefaultNamespace() {
314         for (int i = namespaceStack.size() - 1; i >= 0; i--) {
315             Namespace namespace = (Namespace) namespaceStack.get(i);
316             if (namespace != null) {
317                 String JavaDoc prefix = namespace.getPrefix();
318                 if (prefix == null || namespace.getPrefix().length() == 0) {
319                     return namespace;
320                 }
321             }
322         }
323         return null;
324     }
325
326     /** Removes the namespace at the given index of the stack */
327     protected Namespace remove(int index) {
328         Namespace namespace = (Namespace) namespaceStack.remove(index);
329         namespaceCacheList.remove(index);
330         defaultNamespace = null;
331         currentNamespaceCache = null;
332         return namespace;
333     }
334
335     protected Map JavaDoc getNamespaceCache() {
336         if (currentNamespaceCache == null) {
337             int index = namespaceStack.size() - 1;
338             if (index < 0) {
339                 currentNamespaceCache = rootNamespaceCache;
340             } else {
341                 currentNamespaceCache = (Map JavaDoc) namespaceCacheList.get(index);
342                 if (currentNamespaceCache == null) {
343                     currentNamespaceCache = new HashMap JavaDoc();
344                     namespaceCacheList.set(index, currentNamespaceCache);
345                 }
346             }
347         }
348         return currentNamespaceCache;
349     }
350 }
351
352
353 /*
354  * Redistribution and use of this software and associated documentation
355  * ("Software"), with or without modification, are permitted provided
356  * that the following conditions are met:
357  *
358  * 1. Redistributions of source code must retain copyright
359  * statements and notices. Redistributions must also contain a
360  * copy of this document.
361  *
362  * 2. Redistributions in binary form must reproduce the
363  * above copyright notice, this list of conditions and the
364  * following disclaimer in the documentation and/or other
365  * materials provided with the distribution.
366  *
367  * 3. The name "DOM4J" must not be used to endorse or promote
368  * products derived from this Software without prior written
369  * permission of MetaStuff, Ltd. For written permission,
370  * please contact dom4j-info@metastuff.com.
371  *
372  * 4. Products derived from this Software may not be called "DOM4J"
373  * nor may "DOM4J" appear in their names without prior written
374  * permission of MetaStuff, Ltd. DOM4J is a registered
375  * trademark of MetaStuff, Ltd.
376  *
377  * 5. Due credit should be given to the DOM4J Project
378  * (http://dom4j.org/).
379  *
380  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
381  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
382  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
383  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
384  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
385  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
386  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
387  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
388  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
389  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
390  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
391  * OF THE POSSIBILITY OF SUCH DAMAGE.
392  *
393  * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
394  *
395  * $Id: NamespaceStack.java,v 1.1 2003/11/02 18:10:03 per_nyfelt Exp $
396  */

397
Popular Tags