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