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 }