001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020:
021: // NamespaceSupport.java - generic Namespace support for SAX.
022: // http://www.saxproject.org
023: // Written by David Megginson
024: // This class is in the Public Domain. NO WARRANTY!
025: // $Id: NamespaceSupport.java,v 1.2 2005/09/10 19:10:42 kohsuke Exp $
026: package com.sun.xml.txw2;
027:
028: import java.util.EmptyStackException;
029: import java.util.Enumeration;
030: import java.util.Hashtable;
031: import java.util.Vector;
032:
033: /**
034: * Encapsulate Namespace logic for use by applications using SAX,
035: * or internally by SAX drivers.
036: *
037: * <blockquote>
038: * <em>This module, both source code and documentation, is in the
039: * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
040: * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
041: * for further information.
042: * </blockquote>
043: *
044: * <p>This class encapsulates the logic of Namespace processing: it
045: * tracks the declarations currently in force for each context and
046: * automatically processes qualified XML names into their Namespace
047: * parts; it can also be used in reverse for generating XML qnames
048: * from Namespaces.</p>
049: *
050: * <p>Namespace support objects are reusable, but the reset method
051: * must be invoked between each session.</p>
052: *
053: * <p>Here is a simple session:</p>
054: *
055: * <pre>
056: * String parts[] = new String[3];
057: * NamespaceSupport support = new NamespaceSupport();
058: *
059: * support.pushContext();
060: * support.declarePrefix("", "http://www.w3.org/1999/xhtml");
061: * support.declarePrefix("dc", "http://www.purl.org/dc#");
062: *
063: * parts = support.processName("p", parts, false);
064: * System.out.println("Namespace URI: " + parts[0]);
065: * System.out.println("Local name: " + parts[1]);
066: * System.out.println("Raw name: " + parts[2]);
067: *
068: * parts = support.processName("dc:title", parts, false);
069: * System.out.println("Namespace URI: " + parts[0]);
070: * System.out.println("Local name: " + parts[1]);
071: * System.out.println("Raw name: " + parts[2]);
072: *
073: * support.popContext();
074: * </pre>
075: *
076: * <p>Note that this class is optimized for the use case where most
077: * elements do not contain Namespace declarations: if the same
078: * prefix/URI mapping is repeated for each context (for example), this
079: * class will be somewhat less efficient.</p>
080: *
081: * <p>Although SAX drivers (parsers) may choose to use this class to
082: * implement namespace handling, they are not required to do so.
083: * Applications must track namespace information themselves if they
084: * want to use namespace information.
085: *
086: * @since SAX 2.0
087: * @author David Megginson
088: * @version 2.0.1 (sax2r2)
089: */
090: final class NamespaceSupport {
091:
092: ////////////////////////////////////////////////////////////////////
093: // Constants.
094: ////////////////////////////////////////////////////////////////////
095:
096: /**
097: * The XML Namespace URI as a constant.
098: * The value is <code>http://www.w3.org/XML/1998/namespace</code>
099: * as defined in the "Namespaces in XML" * recommendation.
100: *
101: * <p>This is the Namespace URI that is automatically mapped
102: * to the "xml" prefix.</p>
103: */
104: public final static String XMLNS = "http://www.w3.org/XML/1998/namespace";
105:
106: /**
107: * The namespace declaration URI as a constant.
108: * The value is <code>http://www.w3.org/xmlns/2000/</code>, as defined
109: * in a backwards-incompatible erratum to the "Namespaces in XML"
110: * recommendation. Because that erratum postdated SAX2, SAX2 defaults
111: * to the original recommendation, and does not normally use this URI.
112: *
113: *
114: * <p>This is the Namespace URI that is optionally applied to
115: * <em>xmlns</em> and <em>xmlns:*</em> attributes, which are used to
116: * declare namespaces. </p>
117: *
118: * @since SAX 2.1alpha
119: * @see #setNamespaceDeclUris
120: * @see #isNamespaceDeclUris
121: */
122: public final static String NSDECL = "http://www.w3.org/xmlns/2000/";
123:
124: /**
125: * An empty enumeration.
126: */
127: private final static Enumeration EMPTY_ENUMERATION = new Vector()
128: .elements();
129:
130: ////////////////////////////////////////////////////////////////////
131: // Constructor.
132: ////////////////////////////////////////////////////////////////////
133:
134: /**
135: * Create a new Namespace support object.
136: */
137: public NamespaceSupport() {
138: reset();
139: }
140:
141: ////////////////////////////////////////////////////////////////////
142: // Context management.
143: ////////////////////////////////////////////////////////////////////
144:
145: /**
146: * Reset this Namespace support object for reuse.
147: *
148: * <p>It is necessary to invoke this method before reusing the
149: * Namespace support object for a new session. If namespace
150: * declaration URIs are to be supported, that flag must also
151: * be set to a non-default value.
152: * </p>
153: *
154: * @see #setNamespaceDeclUris
155: */
156: public void reset() {
157: contexts = new Context[32];
158: namespaceDeclUris = false;
159: contextPos = 0;
160: contexts[contextPos] = currentContext = new Context();
161: currentContext.declarePrefix("xml", XMLNS);
162: }
163:
164: /**
165: * Start a new Namespace context.
166: * The new context will automatically inherit
167: * the declarations of its parent context, but it will also keep
168: * track of which declarations were made within this context.
169: *
170: * <p>Event callback code should start a new context once per element.
171: * This means being ready to call this in either of two places.
172: * For elements that don't include namespace declarations, the
173: * <em>ContentHandler.startElement()</em> callback is the right place.
174: * For elements with such a declaration, it'd done in the first
175: * <em>ContentHandler.startPrefixMapping()</em> callback.
176: * A boolean flag can be used to
177: * track whether a context has been started yet. When either of
178: * those methods is called, it checks the flag to see if a new context
179: * needs to be started. If so, it starts the context and sets the
180: * flag. After <em>ContentHandler.startElement()</em>
181: * does that, it always clears the flag.
182: *
183: * <p>Normally, SAX drivers would push a new context at the beginning
184: * of each XML element. Then they perform a first pass over the
185: * attributes to process all namespace declarations, making
186: * <em>ContentHandler.startPrefixMapping()</em> callbacks.
187: * Then a second pass is made, to determine the namespace-qualified
188: * names for all attributes and for the element name.
189: * Finally all the information for the
190: * <em>ContentHandler.startElement()</em> callback is available,
191: * so it can then be made.
192: *
193: * <p>The Namespace support object always starts with a base context
194: * already in force: in this context, only the "xml" prefix is
195: * declared.</p>
196: *
197: * @see org.xml.sax.ContentHandler
198: * @see #popContext
199: */
200: public void pushContext() {
201: int max = contexts.length;
202:
203: contextPos++;
204:
205: // Extend the array if necessary
206: if (contextPos >= max) {
207: Context newContexts[] = new Context[max * 2];
208: System.arraycopy(contexts, 0, newContexts, 0, max);
209: max *= 2;
210: contexts = newContexts;
211: }
212:
213: // Allocate the context if necessary.
214: currentContext = contexts[contextPos];
215: if (currentContext == null) {
216: contexts[contextPos] = currentContext = new Context();
217: }
218:
219: // Set the parent, if any.
220: if (contextPos > 0) {
221: currentContext.setParent(contexts[contextPos - 1]);
222: }
223: }
224:
225: /**
226: * Revert to the previous Namespace context.
227: *
228: * <p>Normally, you should pop the context at the end of each
229: * XML element. After popping the context, all Namespace prefix
230: * mappings that were previously in force are restored.</p>
231: *
232: * <p>You must not attempt to declare additional Namespace
233: * prefixes after popping a context, unless you push another
234: * context first.</p>
235: *
236: * @see #pushContext
237: */
238: public void popContext() {
239: contexts[contextPos].clear();
240: contextPos--;
241: if (contextPos < 0) {
242: throw new EmptyStackException();
243: }
244: currentContext = contexts[contextPos];
245: }
246:
247: ////////////////////////////////////////////////////////////////////
248: // Operations within a context.
249: ////////////////////////////////////////////////////////////////////
250:
251: /**
252: * Declare a Namespace prefix. All prefixes must be declared
253: * before they are referenced. For example, a SAX driver (parser)
254: * would scan an element's attributes
255: * in two passes: first for namespace declarations,
256: * then a second pass using {@link #processName processName()} to
257: * interpret prefixes against (potentially redefined) prefixes.
258: *
259: * <p>This method declares a prefix in the current Namespace
260: * context; the prefix will remain in force until this context
261: * is popped, unless it is shadowed in a descendant context.</p>
262: *
263: * <p>To declare the default element Namespace, use the empty string as
264: * the prefix.</p>
265: *
266: * <p>Note that there is an asymmetry in this library: {@link
267: * #getPrefix getPrefix} will not return the "" prefix,
268: * even if you have declared a default element namespace.
269: * To check for a default namespace,
270: * you have to look it up explicitly using {@link #getURI getURI}.
271: * This asymmetry exists to make it easier to look up prefixes
272: * for attribute names, where the default prefix is not allowed.</p>
273: *
274: * @param prefix The prefix to declare, or the empty string to
275: * indicate the default element namespace. This may never have
276: * the value "xml" or "xmlns".
277: * @param uri The Namespace URI to associate with the prefix.
278: * @return true if the prefix was legal, false otherwise
279: *
280: * @see #processName
281: * @see #getURI
282: * @see #getPrefix
283: */
284: public boolean declarePrefix(String prefix, String uri) {
285: if (prefix.equals("xml") || prefix.equals("xmlns")) {
286: return false;
287: } else {
288: currentContext.declarePrefix(prefix, uri);
289: return true;
290: }
291: }
292:
293: /**
294: * Process a raw XML qualified name, after all declarations in the
295: * current context have been handled by {@link #declarePrefix
296: * declarePrefix()}.
297: *
298: * <p>This method processes a raw XML qualified name in the
299: * current context by removing the prefix and looking it up among
300: * the prefixes currently declared. The return value will be the
301: * array supplied by the caller, filled in as follows:</p>
302: *
303: * <dl>
304: * <dt>parts[0]</dt>
305: * <dd>The Namespace URI, or an empty string if none is
306: * in use.</dd>
307: * <dt>parts[1]</dt>
308: * <dd>The local name (without prefix).</dd>
309: * <dt>parts[2]</dt>
310: * <dd>The original raw name.</dd>
311: * </dl>
312: *
313: * <p>All of the strings in the array will be internalized. If
314: * the raw name has a prefix that has not been declared, then
315: * the return value will be null.</p>
316: *
317: * <p>Note that attribute names are processed differently than
318: * element names: an unprefixed element name will receive the
319: * default Namespace (if any), while an unprefixed attribute name
320: * will not.</p>
321: *
322: * @param qName The XML qualified name to be processed.
323: * @param parts An array supplied by the caller, capable of
324: * holding at least three members.
325: * @param isAttribute A flag indicating whether this is an
326: * attribute name (true) or an element name (false).
327: * @return The supplied array holding three internalized strings
328: * representing the Namespace URI (or empty string), the
329: * local name, and the XML qualified name; or null if there
330: * is an undeclared prefix.
331: * @see #declarePrefix
332: * @see java.lang.String#intern */
333: public String[] processName(String qName, String parts[],
334: boolean isAttribute) {
335: String myParts[] = currentContext.processName(qName,
336: isAttribute);
337: if (myParts == null) {
338: return null;
339: } else {
340: parts[0] = myParts[0];
341: parts[1] = myParts[1];
342: parts[2] = myParts[2];
343: return parts;
344: }
345: }
346:
347: /**
348: * Look up a prefix and get the currently-mapped Namespace URI.
349: *
350: * <p>This method looks up the prefix in the current context.
351: * Use the empty string ("") for the default Namespace.</p>
352: *
353: * @param prefix The prefix to look up.
354: * @return The associated Namespace URI, or null if the prefix
355: * is undeclared in this context.
356: * @see #getPrefix
357: * @see #getPrefixes
358: */
359: public String getURI(String prefix) {
360: return currentContext.getURI(prefix);
361: }
362:
363: /**
364: * Return an enumeration of all prefixes whose declarations are
365: * active in the current context.
366: * This includes declarations from parent contexts that have
367: * not been overridden.
368: *
369: * <p><strong>Note:</strong> if there is a default prefix, it will not be
370: * returned in this enumeration; check for the default prefix
371: * using the {@link #getURI getURI} with an argument of "".</p>
372: *
373: * @return An enumeration of prefixes (never empty).
374: * @see #getDeclaredPrefixes
375: * @see #getURI
376: */
377: public Enumeration getPrefixes() {
378: return currentContext.getPrefixes();
379: }
380:
381: /**
382: * Return one of the prefixes mapped to a Namespace URI.
383: *
384: * <p>If more than one prefix is currently mapped to the same
385: * URI, this method will make an arbitrary selection; if you
386: * want all of the prefixes, use the {@link #getPrefixes}
387: * method instead.</p>
388: *
389: * <p><strong>Note:</strong> this will never return the empty (default) prefix;
390: * to check for a default prefix, use the {@link #getURI getURI}
391: * method with an argument of "".</p>
392: *
393: * @param uri the namespace URI
394: * @return one of the prefixes currently mapped to the URI supplied,
395: * or null if none is mapped or if the URI is assigned to
396: * the default namespace
397: * @see #getPrefixes(java.lang.String)
398: * @see #getURI
399: */
400: public String getPrefix(String uri) {
401: return currentContext.getPrefix(uri);
402: }
403:
404: /**
405: * Return an enumeration of all prefixes for a given URI whose
406: * declarations are active in the current context.
407: * This includes declarations from parent contexts that have
408: * not been overridden.
409: *
410: * <p>This method returns prefixes mapped to a specific Namespace
411: * URI. The xml: prefix will be included. If you want only one
412: * prefix that's mapped to the Namespace URI, and you don't care
413: * which one you get, use the {@link #getPrefix getPrefix}
414: * method instead.</p>
415: *
416: * <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included
417: * in this enumeration; to check for the presence of a default
418: * Namespace, use the {@link #getURI getURI} method with an
419: * argument of "".</p>
420: *
421: * @param uri The Namespace URI.
422: * @return An enumeration of prefixes (never empty).
423: * @see #getPrefix
424: * @see #getDeclaredPrefixes
425: * @see #getURI
426: */
427: public Enumeration getPrefixes(String uri) {
428: Vector prefixes = new Vector();
429: Enumeration allPrefixes = getPrefixes();
430: while (allPrefixes.hasMoreElements()) {
431: String prefix = (String) allPrefixes.nextElement();
432: if (uri.equals(getURI(prefix))) {
433: prefixes.addElement(prefix);
434: }
435: }
436: return prefixes.elements();
437: }
438:
439: /**
440: * Return an enumeration of all prefixes declared in this context.
441: *
442: * <p>The empty (default) prefix will be included in this
443: * enumeration; note that this behaviour differs from that of
444: * {@link #getPrefix} and {@link #getPrefixes}.</p>
445: *
446: * @return An enumeration of all prefixes declared in this
447: * context.
448: * @see #getPrefixes
449: * @see #getURI
450: */
451: public Enumeration getDeclaredPrefixes() {
452: return currentContext.getDeclaredPrefixes();
453: }
454:
455: /**
456: * Controls whether namespace declaration attributes are placed
457: * into the {@link #NSDECL NSDECL} namespace
458: * by {@link #processName processName()}. This may only be
459: * changed before any contexts have been pushed.
460: *
461: * @since SAX 2.1alpha
462: *
463: * @exception IllegalStateException when attempting to set this
464: * after any context has been pushed.
465: */
466: public void setNamespaceDeclUris(boolean value) {
467: if (contextPos != 0)
468: throw new IllegalStateException();
469: if (value == namespaceDeclUris)
470: return;
471: namespaceDeclUris = value;
472: if (value)
473: currentContext.declarePrefix("xmlns", NSDECL);
474: else {
475: contexts[contextPos] = currentContext = new Context();
476: currentContext.declarePrefix("xml", XMLNS);
477: }
478: }
479:
480: /**
481: * Returns true if namespace declaration attributes are placed into
482: * a namespace. This behavior is not the default.
483: *
484: * @since SAX 2.1alpha
485: */
486: public boolean isNamespaceDeclUris() {
487: return namespaceDeclUris;
488: }
489:
490: ////////////////////////////////////////////////////////////////////
491: // Internal state.
492: ////////////////////////////////////////////////////////////////////
493:
494: private Context contexts[];
495: private Context currentContext;
496: private int contextPos;
497: private boolean namespaceDeclUris;
498:
499: ////////////////////////////////////////////////////////////////////
500: // Internal classes.
501: ////////////////////////////////////////////////////////////////////
502:
503: /**
504: * Internal class for a single Namespace context.
505: *
506: * <p>This module caches and reuses Namespace contexts,
507: * so the number allocated
508: * will be equal to the element depth of the document, not to the total
509: * number of elements (i.e. 5-10 rather than tens of thousands).
510: * Also, data structures used to represent contexts are shared when
511: * possible (child contexts without declarations) to further reduce
512: * the amount of memory that's consumed.
513: * </p>
514: */
515: final class Context {
516:
517: /**
518: * Create the root-level Namespace context.
519: */
520: Context() {
521: copyTables();
522: }
523:
524: /**
525: * (Re)set the parent of this Namespace context.
526: * The context must either have been freshly constructed,
527: * or must have been cleared.
528: *
529: * @param context The parent Namespace context object.
530: */
531: void setParent(Context parent) {
532: this .parent = parent;
533: declarations = null;
534: prefixTable = parent.prefixTable;
535: uriTable = parent.uriTable;
536: elementNameTable = parent.elementNameTable;
537: attributeNameTable = parent.attributeNameTable;
538: defaultNS = parent.defaultNS;
539: declSeen = false;
540: }
541:
542: /**
543: * Makes associated state become collectible,
544: * invalidating this context.
545: * {@link #setParent} must be called before
546: * this context may be used again.
547: */
548: void clear() {
549: parent = null;
550: prefixTable = null;
551: uriTable = null;
552: elementNameTable = null;
553: attributeNameTable = null;
554: defaultNS = "";
555: }
556:
557: /**
558: * Declare a Namespace prefix for this context.
559: *
560: * @param prefix The prefix to declare.
561: * @param uri The associated Namespace URI.
562: * @see org.xml.sax.helpers.NamespaceSupport#declarePrefix
563: */
564: void declarePrefix(String prefix, String uri) {
565: // Lazy processing...
566: // if (!declsOK)
567: // throw new IllegalStateException (
568: // "can't declare any more prefixes in this context");
569: if (!declSeen) {
570: copyTables();
571: }
572: if (declarations == null) {
573: declarations = new Vector();
574: }
575:
576: prefix = prefix.intern();
577: uri = uri.intern();
578: if ("".equals(prefix)) {
579: defaultNS = uri;
580: } else {
581: prefixTable.put(prefix, uri);
582: uriTable.put(uri, prefix); // may wipe out another prefix
583: }
584: declarations.addElement(prefix);
585: }
586:
587: /**
588: * Process an XML qualified name in this context.
589: *
590: * @param qName The XML qualified name.
591: * @param isAttribute true if this is an attribute name.
592: * @return An array of three strings containing the
593: * URI part (or empty string), the local part,
594: * and the raw name, all internalized, or null
595: * if there is an undeclared prefix.
596: * @see org.xml.sax.helpers.NamespaceSupport#processName
597: */
598: String[] processName(String qName, boolean isAttribute) {
599: String name[];
600: Hashtable table;
601:
602: // Select the appropriate table.
603: if (isAttribute) {
604: table = attributeNameTable;
605: } else {
606: table = elementNameTable;
607: }
608:
609: // Start by looking in the cache, and
610: // return immediately if the name
611: // is already known in this content
612: name = (String[]) table.get(qName);
613: if (name != null) {
614: return name;
615: }
616:
617: // We haven't seen this name in this
618: // context before. Maybe in the parent
619: // context, but we can't assume prefix
620: // bindings are the same.
621: name = new String[3];
622: name[2] = qName.intern();
623: int index = qName.indexOf(':');
624:
625: // No prefix.
626: if (index == -1) {
627: if (isAttribute) {
628: if (qName == "xmlns" && namespaceDeclUris)
629: name[0] = NSDECL;
630: else
631: name[0] = "";
632: } else {
633: name[0] = defaultNS;
634: }
635: name[1] = name[2];
636: }
637:
638: // Prefix
639: else {
640: String prefix = qName.substring(0, index);
641: String local = qName.substring(index + 1);
642: String uri;
643: if ("".equals(prefix)) {
644: uri = defaultNS;
645: } else {
646: uri = (String) prefixTable.get(prefix);
647: }
648: if (uri == null
649: || (!isAttribute && "xmlns".equals(prefix))) {
650: return null;
651: }
652: name[0] = uri;
653: name[1] = local.intern();
654: }
655:
656: // Save in the cache for future use.
657: // (Could be shared with parent context...)
658: table.put(name[2], name);
659: return name;
660: }
661:
662: /**
663: * Look up the URI associated with a prefix in this context.
664: *
665: * @param prefix The prefix to look up.
666: * @return The associated Namespace URI, or null if none is
667: * declared.
668: * @see org.xml.sax.helpers.NamespaceSupport#getURI
669: */
670: String getURI(String prefix) {
671: if ("".equals(prefix)) {
672: return defaultNS;
673: } else if (prefixTable == null) {
674: return null;
675: } else {
676: return (String) prefixTable.get(prefix);
677: }
678: }
679:
680: /**
681: * Look up one of the prefixes associated with a URI in this context.
682: *
683: * <p>Since many prefixes may be mapped to the same URI,
684: * the return value may be unreliable.</p>
685: *
686: * @param uri The URI to look up.
687: * @return The associated prefix, or null if none is declared.
688: * @see org.xml.sax.helpers.NamespaceSupport#getPrefix
689: */
690: String getPrefix(String uri) {
691: if (uriTable == null) {
692: return null;
693: } else {
694: return (String) uriTable.get(uri);
695: }
696: }
697:
698: /**
699: * Return an enumeration of prefixes declared in this context.
700: *
701: * @return An enumeration of prefixes (possibly empty).
702: * @see org.xml.sax.helpers.NamespaceSupport#getDeclaredPrefixes
703: */
704: Enumeration getDeclaredPrefixes() {
705: if (declarations == null) {
706: return EMPTY_ENUMERATION;
707: } else {
708: return declarations.elements();
709: }
710: }
711:
712: /**
713: * Return an enumeration of all prefixes currently in force.
714: *
715: * <p>The default prefix, if in force, is <em>not</em>
716: * returned, and will have to be checked for separately.</p>
717: *
718: * @return An enumeration of prefixes (never empty).
719: * @see org.xml.sax.helpers.NamespaceSupport#getPrefixes
720: */
721: Enumeration getPrefixes() {
722: if (prefixTable == null) {
723: return EMPTY_ENUMERATION;
724: } else {
725: return prefixTable.keys();
726: }
727: }
728:
729: ////////////////////////////////////////////////////////////////
730: // Internal methods.
731: ////////////////////////////////////////////////////////////////
732:
733: /**
734: * Copy on write for the internal tables in this context.
735: *
736: * <p>This class is optimized for the normal case where most
737: * elements do not contain Namespace declarations.</p>
738: */
739: private void copyTables() {
740: if (prefixTable != null) {
741: prefixTable = (Hashtable) prefixTable.clone();
742: } else {
743: prefixTable = new Hashtable();
744: }
745: if (uriTable != null) {
746: uriTable = (Hashtable) uriTable.clone();
747: } else {
748: uriTable = new Hashtable();
749: }
750: elementNameTable = new Hashtable();
751: attributeNameTable = new Hashtable();
752: declSeen = true;
753: }
754:
755: ////////////////////////////////////////////////////////////////
756: // Protected state.
757: ////////////////////////////////////////////////////////////////
758:
759: Hashtable prefixTable;
760: Hashtable uriTable;
761: Hashtable elementNameTable;
762: Hashtable attributeNameTable;
763: String defaultNS = "";
764:
765: ////////////////////////////////////////////////////////////////
766: // Internal state.
767: ////////////////////////////////////////////////////////////////
768:
769: private Vector declarations = null;
770: private boolean declSeen = false;
771: private Context parent = null;
772: }
773: }
774:
775: // end of NamespaceSupport.java
|