offline building of site deploy to improve performance.
[utils] / support / general / src / main / java / org / wamblee / xml / SimpleNamespaceContext.java
1 /*
2  * Copyright 2005-2011 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.wamblee.xml;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.xml.XMLConstants;
26 import javax.xml.namespace.NamespaceContext;
27
28 /**
29  * Implementation of {@link NamespaceContext} for binding namespace prefixes to 
30  * namespaces. This class implements the full contract as defined by that interface. 
31  * 
32  * It provides a fluent interface style. In its simplest use, it can be constructed
33  * empty or with a single prefix using a constructor. In addition, the methods
34  * {@link #addPrefix(String, String)} and {@link #defaultNamespace(String)} can be used
35  * to add prefixes and to define the default namespace respectively. 
36  * 
37  * @author Erik Brakkee
38  */
39 public class SimpleNamespaceContext implements NamespaceContext {
40
41     private String defaultNs;
42     private Map<String, String> prefixMap;
43
44     /**
45      * Constructs an empty context without prefixes. 
46      */
47     public SimpleNamespaceContext() {
48         defaultNs = null;
49         prefixMap = new HashMap<String, String>();
50     }
51     
52     /**
53      * Creation of the namespace context for use with static imports.
54      * @return Empty namespace context. 
55      */
56     public static SimpleNamespaceContext namespaces() { 
57         return new SimpleNamespaceContext();
58     }
59
60     /**
61      * Constructs a context with a single prefix. 
62      * @param aPrefix Prefix. 
63      * @param aNamespace Namespace. 
64      */
65     public SimpleNamespaceContext(String aPrefix, String aNamespace) {
66         this();
67         addPrefix(aPrefix, aNamespace);
68     }
69
70     /**
71      * Constructs empty context (for use with static imports).
72      * @return Namespace context. 
73      */
74     public static SimpleNamespaceContext namespaceContext() {
75         return new SimpleNamespaceContext();
76     }
77
78     /**
79      * Constructs a context with a single prefix (for use with static imports).  
80      * @param aPrefix Prefix
81      * @param aNamespace Namespace. 
82      * @return
83      */
84     public static SimpleNamespaceContext namespaceContext(String aPrefix,
85         String aNamespace) {
86         return new SimpleNamespaceContext(aPrefix, aNamespace);
87     }
88
89     /**
90      * Sets the default namespace. 
91      * @param aDefaultNs Default namespace. 
92      * @return Current object for method chaining. 
93      */
94     public SimpleNamespaceContext defaultNamespace(String aDefaultNs) {
95         defaultNs = aDefaultNs;
96         return this;
97     }
98
99     /**
100      * Adds a prefix. 
101      * @param aPrefix Prefix to add. 
102      * @param aNamespace Namespace to bind prefix to. 
103      * @return Current object for method chaining. 
104      */
105     public SimpleNamespaceContext addPrefix(String aPrefix, String aNamespace) {
106         if (aPrefix == null) {
107             throw new IllegalArgumentException("prefix is null");
108         }
109         if (aNamespace == null) {
110             throw new IllegalArgumentException("namespace is null");
111         }
112         prefixMap.put(aPrefix, aNamespace);
113         return this;
114     }
115
116     @Override
117     public String getNamespaceURI(String aPrefix) {
118         if (XMLConstants.DEFAULT_NS_PREFIX.equals(aPrefix)) {
119             if (defaultNs == null) {
120                 return XMLConstants.NULL_NS_URI;
121             }
122             return defaultNs;
123         }
124         if (XMLConstants.XML_NS_PREFIX.equals(aPrefix)) {
125             return XMLConstants.XML_NS_URI;
126         }
127         if (XMLConstants.XMLNS_ATTRIBUTE.equals(aPrefix)) {
128             return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
129         }
130         String ns = prefixMap.get(aPrefix);
131         if (ns == null) {
132             return XMLConstants.NULL_NS_URI;
133         }
134         return ns;
135     }
136
137     @Override
138     public String getPrefix(String aNamespaceURI) {
139          List<String> prefixes = getPrefixList(aNamespaceURI);
140          if (prefixes.isEmpty()) { 
141              return null; 
142          }
143          return prefixes.get(0);
144     }
145
146     @Override
147     public Iterator getPrefixes(String aNamespaceURI) {
148         return Collections.unmodifiableList(getPrefixList(aNamespaceURI)).iterator();
149     }
150     
151     public List<String> getPrefixList(String aNamespaceURI) {
152         List<String> result = new ArrayList<String>(); 
153         
154         if ((aNamespaceURI == null && defaultNs == null) ||
155             (defaultNs != null && defaultNs.equals(aNamespaceURI))) {
156             result.add(XMLConstants.DEFAULT_NS_PREFIX);
157             return result; // make sure not more prefixes added.
158         }
159         if (XMLConstants.XML_NS_URI.equals(aNamespaceURI)) {
160             result.add(XMLConstants.XML_NS_PREFIX);
161             return result; // make sure no more prefixes added. 
162         }
163         if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(aNamespaceURI)) {
164             result.add(XMLConstants.XMLNS_ATTRIBUTE);
165             return result; 
166         }
167         for (Map.Entry<String,String> entry: prefixMap.entrySet()) {
168             if (entry.getValue().equals(aNamespaceURI)) { 
169                 result.add(entry.getKey());
170             }
171         }
172         return result; 
173     }
174
175 }