001: //
002: // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.5-b16-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: 2005.12.17 at 09:43:27 AM GMT+07:00
006: //
007:
008: package com.mvnforum.jaxb.db.impl.runtime;
009:
010: import java.util.Enumeration;
011: import java.util.HashMap;
012: import java.util.HashSet;
013: import java.util.Iterator;
014: import java.util.Map;
015: import java.util.Set;
016:
017: import javax.xml.XMLConstants;
018:
019: import org.xml.sax.SAXException;
020:
021: import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
022: import 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: */
033: public class NamespaceContextImpl implements NamespaceContext2 {
034: /**
035: * Sequence generator. Used as the last resort to generate
036: * unique prefix.
037: */
038: private int iota = 1;
039:
040: /**
041: * Used to maintain association between prefixes and URIs.
042: */
043: private final NamespaceSupport nss = new NamespaceSupport();
044:
045: /**
046: * A flag that indicates the current mode of this object.
047: */
048: private boolean inCollectingMode;
049:
050: /** Assigns prefixes to URIs. Can be null. */
051: private final NamespacePrefixMapper prefixMapper;
052:
053: /**
054: * Used during the collecting mode to sort out the namespace
055: * URIs we need for this element.
056: *
057: * A map from prefixes to namespace URIs.
058: */
059: private final Map decls = new HashMap();
060:
061: private final Map reverseDecls = new HashMap();
062:
063: public NamespaceContextImpl(NamespacePrefixMapper _prefixMapper) {
064: this .prefixMapper = _prefixMapper;
065: // declare the default namespace binding
066: // which are effective because of the way XML1.0 is made
067: nss.declarePrefix("", "");
068: nss.declarePrefix("xmlns", XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
069: // this one is taken care of by the NamespaceSupport class by default.
070: // nss.declarePrefix( "xml", XMLConstants.XML_NS_URI );
071: }
072:
073: public final NamespacePrefixMapper getNamespacePrefixMapper() {
074: return prefixMapper;
075: }
076:
077: //
078: //
079: // public methods of MarshallingContext
080: //
081: //
082: /**
083: * @param requirePrefix
084: * true if this is called for attribute name. false otherwise.
085: */
086: public String declareNamespace(String namespaceUri,
087: String preferedPrefix, boolean requirePrefix) {
088: if (!inCollectingMode) {
089: if (!requirePrefix && nss.getURI("").equals(namespaceUri))
090: return ""; // can use the default prefix. use it whenever we can
091:
092: // find a valid prefix for this namespace URI
093: // ASSERTION: the result is always non-null,
094: // since we require all the namespace URIs to be declared while
095: // this object is in collection mode.
096: if (requirePrefix)
097: return nss.getPrefix2(namespaceUri);
098: else
099: return nss.getPrefix(namespaceUri);
100: } else {
101: if (requirePrefix && namespaceUri.length() == 0)
102: return "";
103:
104: // collect this new namespace URI
105: String prefix = (String) reverseDecls.get(namespaceUri);
106: if (prefix != null) {
107: if (!requirePrefix || prefix.length() != 0) {
108: // this namespace URI is already taken care of,
109: // and it satisfies the "requirePrefix" requirement.
110: return prefix;
111: } else {
112: // the prefix was already allocated but it's "",
113: // and we specifically need non-empty prefix.
114:
115: // erase the current binding
116: decls.remove(prefix);
117: reverseDecls.remove(namespaceUri);
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,
139: requirePrefix);
140: else
141: prefix = preferedPrefix;
142:
143: if (prefix == null)
144: // if the user don't care, generate one
145: prefix = "ns" + (iota++);
146: }
147: }
148:
149: // ASSERT: prefix!=null
150:
151: if (requirePrefix && prefix.length() == 0)
152: // we can't map it to the default prefix. generate one.
153: prefix = "ns" + (iota++);
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: public String getPrefix(String namespaceUri) {
192: // even through the method name is "getPrefix", we
193: // use this method to declare prefixes if necessary.
194:
195: // the only time a prefix is required is when we print
196: // attribute names, and in those cases we will call
197: // declareNamespace method directly. So it's safe to
198: // assume that we don't require a prefix in this case.
199: return declareNamespace(namespaceUri, null, false);
200: }
201:
202: /**
203: * Obtains the namespace URI currently associated to the given prefix.
204: * If no namespace URI is associated, return null.
205: */
206: public String getNamespaceURI(String prefix) {
207: String uri = (String) decls.get(prefix);
208: if (uri != null)
209: 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)
220: s.add(prefix);
221:
222: if (nss.getURI("").equals(namespaceUri))
223: s.add("");
224:
225: for (Enumeration e = nss.getPrefixes(namespaceUri); e
226: .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
255: .hasNext();) {
256: Map.Entry e = (Map.Entry) itr.next();
257: String prefix = (String) e.getKey();
258: String uri = (String) e.getValue();
259: if (!uri.equals(nss.getURI(prefix))) // avoid redundant decls.
260: nss.declarePrefix(prefix, uri);
261: }
262: decls.clear();
263: reverseDecls.clear();
264: }
265: inCollectingMode = false;
266: }
267:
268: /**
269: * Ends the current element context and gets back to the parent context.
270: *
271: * This method should be called at the end of the endElement method
272: * of derived classes.
273: */
274: public void endElement() {
275: nss.popContext();
276: }
277:
278: /** Iterates all newly declared namespace prefixes for this element. */
279: public void iterateDeclaredPrefixes(PrefixCallback callback)
280: throws SAXException {
281: for (Enumeration e = nss.getDeclaredPrefixes(); e
282: .hasMoreElements();) {
283: String p = (String) e.nextElement();
284: String uri = nss.getURI(p);
285:
286: callback.onPrefixMapping(p, uri);
287: }
288: }
289:
290: }
|