001 //
002 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.1-05/30/2003 05:06 AM(java_re)-fcs
003 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
004 // Any modifications to this file will be lost upon recompilation of the source schema.
005 // Generated on: 2004.10.11 at 12:13:34 EDT
006 //
007
008 /*
009 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
010 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
011 */
012
013 package astronomy.data.spectra.impl.runtime;
014
015 import java.util.Enumeration;
016 import java.util.HashMap;
017 import java.util.HashSet;
018 import java.util.Iterator;
019 import java.util.Map;
020 import java.util.Set;
021
022 import javax.xml.XMLConstants;
023
024 import org.xml.sax.SAXException;
025
026 import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
027 import com.sun.xml.bind.marshaller.NamespaceSupport;
028
029 /**
030 * Implementation of the NamespaceContext2.
031 *
032 * This class also provides several utility methods for
033 * XMLSerializer-derived classes.
034 *
035 * The startElement method and the endElement method need to be called
036 * appropriately when used. See javadoc for those methods for details.
037 */
038 public class NamespaceContextImpl implements NamespaceContext2
039 {
040 /**
041 * Sequence generator. Used as the last resort to generate
042 * unique prefix.
043 */
044 private int iota = 1;
045
046 /**
047 * Used to maintain association between prefixes and URIs.
048 */
049 private final NamespaceSupport nss = new NamespaceSupport();
050
051 /**
052 * A flag that indicates the current mode of this object.
053 */
054 private boolean inCollectingMode;
055
056 /** Assigns prefixes to URIs. Can be null. */
057 private final NamespacePrefixMapper prefixMapper;
058
059 /**
060 * Used during the collecting mode to sort out the namespace
061 * URIs we need for this element.
062 *
063 * A map from prefixes to namespace URIs.
064 */
065 private final Map decls = new HashMap();
066
067 private final Map reverseDecls = new HashMap();
068
069
070 public NamespaceContextImpl(NamespacePrefixMapper _prefixMapper) {
071 this.prefixMapper = _prefixMapper;
072 // declare the default namespace binding
073 // which are effective because of the way XML1.0 is made
074 nss.declarePrefix("","");
075 nss.declarePrefix( "xmlns", XMLConstants.XMLNS_ATTRIBUTE_NS_URI );
076 // this one is taken care of by the NamespaceSupport class by default.
077 // nss.declarePrefix( "xml", XMLConstants.XML_NS_URI );
078 }
079
080 //
081 //
082 // public methods of MarshallingContext
083 //
084 //
085 /**
086 * @param requirePrefix
087 * true if this is called for attribute name. false otherwise.
088 */
089 public String declareNamespace( String namespaceUri, String preferedPrefix, boolean requirePrefix ) {
090 if( !inCollectingMode ) {
091 if( !requirePrefix && nss.getURI("").equals(namespaceUri) )
092 return ""; // can use the default prefix. use it whenever we can
093
094 // find a valid prefix for this namespace URI
095 // ASSERTION: the result is always non-null,
096 // since we require all the namespace URIs to be declared while
097 // this object is in collection mode.
098 return nss.getPrefix(namespaceUri);
099 } else {
100 if( requirePrefix && namespaceUri.length()==0 )
101 return "";
102
103 // collect this new namespace URI
104 String prefix = (String)reverseDecls.get(namespaceUri);
105 if( prefix!=null ) {
106 if( !requirePrefix || prefix.length()!=0 ) {
107 // this namespace URI is already taken care of,
108 // and it satisfies the "requirePrefix" requirement.
109 return prefix;
110 } else {
111 // the prefix was already allocated but it's "",
112 // and we specifically need non-empty prefix.
113
114 // erase the current binding
115 decls.remove(prefix);
116 reverseDecls.remove(namespaceUri);
117 }
118 }
119
120
121 if( namespaceUri.length()==0 ) {
122 // the empty namespace URI needs to be bound to the default prefix.
123 prefix = "";
124 } else {
125 // see if this namespace URI is already in-scope
126 prefix = nss.getPrefix(namespaceUri);
127 if( prefix==null )
128 prefix = (String)reverseDecls.get(namespaceUri);
129
130 if( prefix==null ) {
131 // if not, try to allocate a new one.
132
133 // use prefixMapper if specified. If so, just let the
134 // prefixMapper decide if it wants to use the suggested prefix.
135 // otherwise our best bet is the suggested prefix.
136 if( prefixMapper!=null )
137 prefix = prefixMapper.getPreferredPrefix(
138 namespaceUri,preferedPrefix,requirePrefix);
139 else
140 prefix = preferedPrefix;
141
142 if( prefix==null )
143 // if the user don't care, generate one
144 prefix = "ns"+(iota++);
145 }
146 }
147
148 // ASSERT: prefix!=null
149
150 if( requirePrefix && prefix.length()==0 )
151 // we can't map it to the default prefix. generate one.
152 prefix = "ns"+(iota++);
153
154
155 while(true) {
156 String existingUri = (String)decls.get(prefix);
157
158 if( existingUri==null ) {
159 // this prefix is unoccupied. use it
160 decls.put( prefix, namespaceUri );
161 reverseDecls.put( namespaceUri, prefix );
162 return prefix;
163 }
164
165 if( existingUri.length()==0 ) {
166 // we have to remap the new namespace URI to a different
167 // prefix because the current association of ""->"" cannot
168 // be changed
169 ;
170 } else {
171 // the new one takes precedence. this is necessary
172 // because we might first assign "uri1"->"" and then
173 // later find that ""->"" needs to be added.
174
175 // so change the existing one
176 decls.put( prefix, namespaceUri );
177 reverseDecls.put( namespaceUri, prefix );
178
179 namespaceUri = existingUri;
180 }
181
182 // we need to find a new prefix for URI "namespaceUri"
183 // generate a machine-made prefix
184 prefix = "ns"+(iota++);
185
186 // go back to the loop and reassign
187 }
188 }
189 }
190
191
192 public String getPrefix( String namespaceUri ) {
193 // even through the method name is "getPrefix", we
194 // use this method to declare prefixes if necessary.
195
196 // the only time a prefix is required is when we print
197 // attribute names, and in those cases we will call
198 // declareNamespace method directly. So it's safe to
199 // assume that we don't require a prefix in this case.
200 return declareNamespace(namespaceUri,null,false);
201 }
202
203 /**
204 * Obtains the namespace URI currently associated to the given prefix.
205 * If no namespace URI is associated, return null.
206 */
207 public String getNamespaceURI( String prefix ) {
208 String uri = (String)decls.get(prefix);
209 if(uri!=null) return uri;
210
211 return nss.getURI(prefix);
212 }
213
214 public Iterator getPrefixes( String namespaceUri ) {
215 // not particularly efficient implementation.
216 Set s = new HashSet();
217
218 String prefix = (String)reverseDecls.get(namespaceUri);
219 if(prefix!=null) s.add(prefix);
220
221 if( nss.getURI("").equals(namespaceUri) )
222 s.add("");
223
224 for( Enumeration e=nss.getPrefixes(namespaceUri); e.hasMoreElements(); )
225 s.add(e.nextElement());
226
227 return s.iterator();
228 }
229
230 /**
231 * Sets the current bindings aside and starts a new element context.
232 *
233 * This method should be called at the beginning of the startElement method
234 * of the Serializer implementation.
235 */
236 public void startElement() {
237 nss.pushContext();
238 inCollectingMode = true;
239 }
240
241 /**
242 * Reconciles the namespace URI/prefix mapping requests since the
243 * last startElement method invocation and finalizes them.
244 *
245 * This method must be called after all the necessary namespace URIs
246 * for this element is reported through the declareNamespace method
247 * or the getPrefix method.
248 */
249 public void endNamespaceDecls() {
250 for( Iterator itr=decls.entrySet().iterator(); itr.hasNext(); ) {
251 Map.Entry e = (Map.Entry)itr.next();
252 String prefix = (String)e.getKey();
253 String uri = (String)e.getValue();
254 if(!uri.equals(nss.getURI(prefix))) // avoid redundant decls.
255 nss.declarePrefix( prefix, uri );
256 }
257 decls.clear();
258 reverseDecls.clear();
259 inCollectingMode = false;
260 }
261
262 /**
263 * Ends the current element context and gets back to the parent context.
264 *
265 * This method should be called at the end of the endElement method
266 * of derived classes.
267 */
268 public void endElement() {
269 nss.popContext();
270 }
271
272
273
274 /** Iterates all newly declared namespace prefixes for this element. */
275 public void iterateDeclaredPrefixes( PrefixCallback callback ) throws SAXException {
276 for( Enumeration e=nss.getDeclaredPrefixes(); e.hasMoreElements(); ) {
277 String p = (String)e.nextElement();
278 String uri = nss.getURI(p);
279
280 callback.onPrefixMapping( p, uri );
281 }
282 }
283
284
285 }