1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.dom4j.io.aelfred;
32
33 import java.io.IOException;
34 import java.io.InputStreamReader;
35 import java.util.ArrayList;
36 import java.util.Enumeration;
37 import java.util.HashMap;
38 import java.util.Iterator;
39 import java.util.Locale;
40
41 import org.xml.sax.AttributeList;
42 import org.xml.sax.Attributes;
43 import org.xml.sax.ContentHandler;
44 import org.xml.sax.DTDHandler;
45 import org.xml.sax.DocumentHandler;
46 import org.xml.sax.EntityResolver;
47 import org.xml.sax.ErrorHandler;
48 import org.xml.sax.InputSource;
49 import org.xml.sax.Locator;
50 import org.xml.sax.Parser;
51 import org.xml.sax.SAXException;
52 import org.xml.sax.SAXNotRecognizedException;
53 import org.xml.sax.SAXNotSupportedException;
54 import org.xml.sax.SAXParseException;
55 import org.xml.sax.XMLReader;
56 import org.xml.sax.ext.DeclHandler;
57 import org.xml.sax.ext.LexicalHandler;
58 import org.xml.sax.helpers.NamespaceSupport;
59
60
61
62
63 /***
64 * An enhanced SAX2 version of Microstar's Ælfred XML parser.
65 * The enhancements primarily relate to significant improvements in
66 * conformance to the XML specification, and SAX2 support. Performance
67 * has been improved. However, the Ælfred proprietary APIs are
68 * no longer public. See the package level documentation for more
69 * information.
70 *
71 * <table border="1" width='100%' cellpadding='3' cellspacing='0'>
72 * <tr bgcolor='#ccccff'>
73 * <th><font size='+1'>Name</font></th>
74 * <th><font size='+1'>Notes</font></th></tr>
75 *
76 * <tr><td colspan=2><center><em>Features ... URL prefix is
77 * <b>http://xml.org/sax/features/</b></em></center></td></tr>
78 *
79 * <tr><td>(URL)/external-general-entities</td>
80 * <td>Value is fixed at <em>true</em></td></tr>
81 * <tr><td>(URL)/external-parameter-entities</td>
82 * <td>Value is fixed at <em>true</em></td></tr>
83 * <tr><td>(URL)/namespace-prefixes</td>
84 * <td>Value defaults to <em>false</em> (but XML 1.0 names are
85 * always reported)</td></tr>
86 * <tr><td>(URL)/namespaces</td>
87 * <td>Value defaults to <em>true</em></td></tr>
88 * <tr><td>(URL)/string-interning</td>
89 * <td>Value is fixed at <em>true</em></td></tr>
90 * <tr><td>(URL)/validation</td>
91 * <td>Value is fixed at <em>false</em></td></tr>
92 *
93 * <tr><td colspan=2><center><em>Handler Properties ... URL prefix is
94 * <b>http://xml.org/sax/properties/</b></em></center></td></tr>
95 *
96 * <tr><td>(URL)/declaration-handler</td>
97 * <td>A declaration handler may be provided. Declaration of general
98 * entities is exposed, but not parameter entities; none of the entity
99 * names reported here will begin with "%". </td></tr>
100 * <tr><td>(URL)/lexical-handler</td>
101 * <td>A lexical handler may be provided. Entity boundaries and
102 * comments are not exposed; only CDATA sections and the start/end of
103 * the DTD (the internal subset is not detectible). </td></tr>
104 * </table>
105 *
106 * <p> Note that the declaration handler doesn't suffice for showing all
107 * the logical structure
108 * of the DTD; it doesn't expose the name of the root element, or the values
109 * that are permitted in a NOTATIONS attribute. (The former is exposed as
110 * lexical data, and SAX2 beta doesn't expose the latter.)
111 *
112 * <p> Although support for several features and properties is "built in"
113 * to this parser, it support all others by storing the assigned values
114 * and returning them.
115 *
116 * <p>This parser currently implements the SAX1 Parser API, but
117 * it may not continue to do so in the future.
118 *
119 * @author Written by David Megginson <dmeggins@microstar.com>
120 * (version 1.2a from Microstar)
121 * @author Updated by David Brownell <david-b@pacbell.net>
122 * @version $Date: 2002/05/24 14:41:55 $
123 * @see org.xml.sax.Parser
124 * @deprecated Use Aelfred2 instead! THIS CLASS WILL BE REMOVED IN dom4j-1.6 !!
125 */
126 final public class SAXDriver
127 implements Locator, Attributes, XMLReader, Parser, AttributeList
128 {
129 private final DefaultHandler base = new DefaultHandler ();
130 private XmlParser parser;
131
132 private EntityResolver entityResolver = base;
133 private ContentHandler contentHandler = base;
134 private DTDHandler dtdHandler = base;
135 private ErrorHandler errorHandler = base;
136 private DeclHandler declHandler = base;
137 private LexicalHandler lexicalHandler = base;
138
139 private String elementName = null;
140 private ArrayList entityStack = new ArrayList ();
141
142 private ArrayList attributeNames = new ArrayList ();
143 private ArrayList attributeNamespaces = new ArrayList ();
144 private ArrayList attributeLocalNames = new ArrayList ();
145 private ArrayList attributeValues = new ArrayList ();
146
147 private boolean namespaces = true;
148 private boolean xmlNames = false;
149 private boolean nspending = false;
150
151
152 private int attributeCount = 0;
153 private String nsTemp [] = new String [3];
154 private NamespaceSupport prefixStack = new NamespaceSupport ();
155
156 private HashMap features;
157 private HashMap properties;
158
159
160
161
162
163
164 /*** Constructs a SAX Parser. */
165 public SAXDriver () {}
166
167
168
169
170
171
172 /***
173 * <b>SAX1</b>: Sets the locale used for diagnostics; currently,
174 * only locales using the English language are supported.
175 * @param locale The locale for which diagnostics will be generated
176 */
177 public void setLocale (Locale locale)
178 throws SAXException
179 {
180 if ("en".equals (locale.getLanguage ()))
181 return ;
182
183 throw new SAXException ("AElfred only supports English locales.");
184 }
185
186
187 /***
188 * <b>SAX2</b>: Returns the object used when resolving external
189 * entities during parsing (both general and parameter entities).
190 */
191 public EntityResolver getEntityResolver ()
192 {
193 return entityResolver;
194 }
195
196 /***
197 * <b>SAX1, SAX2</b>: Set the entity resolver for this parser.
198 * @param handler The object to receive entity events.
199 */
200 public void setEntityResolver (EntityResolver resolver)
201 {
202 if (resolver == null)
203 resolver = base;
204 this.entityResolver = resolver;
205 }
206
207
208 /***
209 * <b>SAX2</b>: Returns the object used to process declarations related
210 * to notations and unparsed entities.
211 */
212 public DTDHandler getDTDHandler ()
213 {
214 return dtdHandler;
215 }
216
217 /***
218 * <b>SAX1, SAX2</b>: Set the DTD handler for this parser.
219 * @param handler The object to receive DTD events.
220 */
221 public void setDTDHandler (DTDHandler handler)
222 {
223 if (handler == null)
224 handler = base;
225 this.dtdHandler = handler;
226 }
227
228
229 /***
230 * <b>SAX1</b>: Set the document handler for this parser. If a
231 * content handler was set, this document handler will supplant it.
232 * The parser is set to report all XML 1.0 names rather than to
233 * filter out "xmlns" attributes (the "namespace-prefixes" feature
234 * is set to true).
235 *
236 * @deprecated SAX2 programs should use the XMLReader interface
237 * and a ContentHandler.
238 *
239 * @param handler The object to receive document events.
240 */
241 public void setDocumentHandler (DocumentHandler handler)
242 {
243 contentHandler = new Adapter (handler);
244 xmlNames = true;
245 }
246
247 /***
248 * <b>SAX2</b>: Returns the object used to report the logical
249 * content of an XML document.
250 */
251 public ContentHandler getContentHandler ()
252 {
253 return contentHandler;
254 }
255
256 /***
257 * <b>SAX2</b>: Assigns the object used to report the logical
258 * content of an XML document. If a document handler was set,
259 * this content handler will supplant it (but XML 1.0 style name
260 * reporting may remain enabled).
261 */
262 public void setContentHandler (ContentHandler handler)
263 {
264 if (handler == null)
265 handler = base;
266 contentHandler = handler;
267 }
268
269 /***
270 * <b>SAX1, SAX2</b>: Set the error handler for this parser.
271 * @param handler The object to receive error events.
272 */
273 public void setErrorHandler (ErrorHandler handler)
274 {
275 if (handler == null)
276 handler = base;
277 this.errorHandler = handler;
278 }
279
280 /***
281 * <b>SAX2</b>: Returns the object used to receive callbacks for XML
282 * errors of all levels (fatal, nonfatal, warning); this is never null;
283 */
284 public ErrorHandler getErrorHandler ()
285 {
286 return errorHandler;
287 }
288
289
290 /***
291 * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly
292 * when no URI is available.
293 * If you want anything useful to happen, you should set
294 * at least one type of handler.
295 * @param source The XML input source. Don't set 'encoding' unless
296 * you know for a fact that it's correct.
297 * @see #setEntityResolver
298 * @see #setDTDHandler
299 * @see #setContentHandler
300 * @see #setErrorHandler
301 * @exception SAXException The handlers may throw any SAXException,
302 * and the parser normally throws SAXParseException objects.
303 * @exception IOException IOExceptions are normally through through
304 * the parser if there are problems reading the source document.
305 */
306
307 public void parse (InputSource source) throws SAXException, IOException
308 {
309 synchronized (base) {
310 parser = new XmlParser ();
311 parser.setHandler (this);
312
313 try {
314 String systemId = source.getSystemId ();
315
316
317
318
319
320 if (systemId != null)
321 entityStack.add (systemId);
322 else
323 entityStack.add ("illegal:unknown system ID");
324
325 parser.doParse (systemId,
326 source.getPublicId (),
327 source.getCharacterStream (),
328 source.getByteStream (),
329 source.getEncoding ());
330 } catch (SAXException e) {
331 throw e;
332 } catch (IOException e) {
333 throw e;
334 } catch (RuntimeException e) {
335 throw e;
336 } catch (Exception e) {
337 throw new SAXException (e.getMessage (), e);
338 } finally {
339 contentHandler.endDocument ();
340 entityStack.clear ();
341 }
342 }
343 }
344
345
346 /***
347 * <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a
348 * system identifier (URI).
349 */
350
351 public void parse (String systemId) throws SAXException, IOException
352 {
353 parse (new InputSource (systemId));
354 }
355
356
357
358
359 static final String FEATURE = "http://xml.org/sax/features/";
360 static final String HANDLER = "http://xml.org/sax/properties/";
361
362 /***
363 * <b>SAX2</b>: Tells the value of the specified feature flag.
364 *
365 * @exception SAXNotRecognizedException thrown if the feature flag
366 * is neither built in, nor yet assigned.
367 */
368 public boolean getFeature (String featureId)
369 throws SAXNotRecognizedException
370 {
371 if ((FEATURE + "validation").equals (featureId))
372 return false;
373
374
375 if ((FEATURE + "external-general-entities").equals (featureId)
376 || (FEATURE + "external-parameter-entities")
377 .equals (featureId))
378 return true;
379
380
381 if ((FEATURE + "namespace-prefixes").equals (featureId))
382 return xmlNames;
383
384
385 if ((FEATURE + "namespaces").equals (featureId))
386 return namespaces;
387
388
389
390
391 if ((FEATURE + "string-interning").equals (featureId))
392 return true;
393
394 if (features != null && features.containsKey (featureId))
395 return ((Boolean)features.get (featureId)).booleanValue ();
396
397 throw new SAXNotRecognizedException (featureId);
398 }
399
400 /***
401 * <b>SAX2</b>: Returns the specified property.
402 *
403 * @exception SAXNotRecognizedException thrown if the property value
404 * is neither built in, nor yet stored.
405 */
406 public Object getProperty (String propertyId)
407 throws SAXNotRecognizedException
408 {
409 if ((HANDLER + "declaration-handler").equals (propertyId))
410 return declHandler;
411
412 if ((HANDLER + "lexical-handler").equals (propertyId))
413 return lexicalHandler;
414
415 if (properties != null && properties.containsKey (propertyId))
416 return properties.get (propertyId);
417
418
419 throw new SAXNotRecognizedException (propertyId);
420 }
421
422 /***
423 * <b>SAX2</b>: Sets the state of feature flags in this parser. Some
424 * built-in feature flags are mutable; all flags not built-in are
425 * motable.
426 */
427 public void setFeature (String featureId, boolean state)
428 throws SAXNotRecognizedException, SAXNotSupportedException
429 {
430 boolean value;
431
432 try {
433
434 value = getFeature (featureId);
435
436 if (state == value)
437 return;
438
439 if ((FEATURE + "namespace-prefixes").equals (featureId)) {
440
441 xmlNames = state;
442 return;
443 }
444
445 if ((FEATURE + "namespaces").equals (featureId)) {
446
447 if (true) {
448 namespaces = state;
449 return;
450 }
451
452 }
453
454
455 if (features == null || !features.containsKey (featureId))
456 throw new SAXNotSupportedException (featureId);
457
458 } catch (SAXNotRecognizedException e) {
459
460 if (features == null)
461 features = new HashMap (5);
462 }
463
464
465 features.put (featureId,
466 state
467 ? Boolean.TRUE
468 : Boolean.FALSE);
469 }
470
471 /***
472 * <b>SAX2</b>: Assigns the specified property. Like SAX1 handlers,
473 * these may be changed at any time.
474 */
475 public void setProperty (String propertyId, Object property)
476 throws SAXNotRecognizedException, SAXNotSupportedException
477 {
478 Object value;
479
480 try {
481
482 value = getProperty (propertyId);
483
484 if ((HANDLER + "declaration-handler").equals (propertyId)) {
485 if (property == null)
486 declHandler = base;
487 else if (! (property instanceof DeclHandler))
488 throw new SAXNotSupportedException (propertyId);
489 else
490 declHandler = (DeclHandler) property;
491 return ;
492 }
493
494 if ((HANDLER + "lexical-handler").equals (propertyId)) {
495 if (property == null)
496 lexicalHandler = base;
497 else if (! (property instanceof LexicalHandler))
498 throw new SAXNotSupportedException (propertyId);
499 else
500 lexicalHandler = (LexicalHandler) property;
501 return ;
502 }
503
504
505 if (properties == null || !properties.containsKey (propertyId))
506 throw new SAXNotSupportedException (propertyId);
507
508 } catch (SAXNotRecognizedException e) {
509
510 if (properties == null)
511 properties = new HashMap (5);
512 }
513
514
515 properties.put (propertyId, property);
516 }
517
518
519
520
521
522
523
524
525
526
527
528
529 void startDocument () throws SAXException
530 {
531 contentHandler.setDocumentLocator (this);
532 contentHandler.startDocument ();
533 attributeNames.clear ();
534 attributeValues.clear ();
535 }
536
537 void endDocument () throws SAXException
538 {
539
540
541 }
542
543 Object resolveEntity (String publicId, String systemId)
544 throws SAXException, IOException
545 {
546 InputSource source = entityResolver.resolveEntity (publicId,
547 systemId);
548
549 if (source == null) {
550 return null;
551 } else if (source.getCharacterStream () != null) {
552 return source.getCharacterStream ();
553 } else if (source.getByteStream () != null) {
554 if (source.getEncoding () == null)
555 return source.getByteStream ();
556 else try {
557 return new InputStreamReader (
558 source.getByteStream (),
559 source.getEncoding ()
560 );
561 } catch (IOException e) {
562 return source.getByteStream ();
563 }
564 } else {
565 return source.getSystemId ();
566 }
567
568
569
570 }
571
572
573 void startExternalEntity (String systemId)
574 throws SAXException
575 {
576 entityStack.add (systemId);
577 }
578
579 void endExternalEntity (String systemId)
580 throws SAXException
581 {
582 entityStack.remove ( entityStack.size() - 1 );
583 }
584
585 void doctypeDecl (String name, String publicId, String systemId)
586 throws SAXException
587 {
588 lexicalHandler.startDTD (name, publicId, systemId);
589
590
591
592
593
594
595
596 }
597
598 void endDoctype () throws SAXException
599 {
600
601
602
603
604
605 deliverDTDEvents ();
606 lexicalHandler.endDTD ();
607 }
608
609
610 void attribute (String aname, String value, boolean isSpecified)
611 throws SAXException
612 {
613 if (attributeCount++ == 0) {
614 if (namespaces)
615 prefixStack.pushContext ();
616 }
617
618
619
620 if (value != null) {
621 if (namespaces) {
622 int index = aname.indexOf (':');
623
624
625 if (index > 0) {
626
627 if (index == 5 && aname.startsWith ("xmlns")) {
628 String prefix = aname.substring (index + 1);
629
630 if (value.length () == 0) {
631 errorHandler.error (new SAXParseException (
632 "missing URI in namespace decl attribute: "
633 + aname,
634 this));
635 } else {
636 prefixStack.declarePrefix (prefix, value);
637 contentHandler.startPrefixMapping (prefix, value);
638 }
639 if (!xmlNames)
640 return;
641 nsTemp [0] = "";
642 nsTemp [1] = aname;
643
644
645 } else {
646 if (prefixStack.processName (aname, nsTemp, true)
647 == null) {
648
649 nsTemp[0] = "";
650 nsTemp[1] = aname;
651 nspending = true;
652
653
654
655
656
657
658
659 }
660 }
661
662
663 } else {
664
665 if ("xmlns".equals (aname)) {
666 prefixStack.declarePrefix ("", value);
667 contentHandler.startPrefixMapping ("", value);
668 if (!xmlNames)
669 return;
670 }
671 nsTemp [0] = "";
672 nsTemp [1] = aname;
673 }
674 } else
675 nsTemp [0] = nsTemp [1] = "";
676
677 attributeNamespaces.add (nsTemp [0]);
678 attributeLocalNames.add (nsTemp [1]);
679 attributeNames.add (aname);
680
681 attributeValues.add (value);
682 }
683 }
684
685 void startElement (String elname)
686 throws SAXException
687 {
688 ContentHandler handler = contentHandler;
689
690
691
692
693
694
695
696
697
698
699
700
701
702 if (attributeCount == 0)
703 prefixStack.pushContext ();
704
705
706 elementName = elname;
707 if (namespaces) {
708
709
710 if (attributeCount > 0 && nspending) {
711 for (int i=0; i<attributeLocalNames.size(); i++) {
712 String aname = (String)attributeLocalNames.get(i);
713 if (aname.indexOf(':')>0) {
714
715 if (prefixStack.processName (aname, nsTemp, true) == null) {
716 errorHandler.error (new SAXParseException (
717 "undeclared name prefix in: " + aname,
718 this));
719 } else {
720 attributeNamespaces.set(i, nsTemp[0]);
721 attributeLocalNames.set(i, nsTemp[1]);
722 }
723 }
724 }
725 }
726
727
728 if (prefixStack.processName (elname, nsTemp, false) == null) {
729 errorHandler.error (new SAXParseException (
730 "undeclared name prefix in: " + elname,
731 this));
732 nsTemp [0] = nsTemp [1] = "";
733 }
734
735 handler.startElement (nsTemp [0], nsTemp [1], elname, this);
736 } else
737 handler.startElement ("", "", elname, this);
738
739
740
741 if (attributeCount != 0) {
742 attributeNames.clear ();
743 attributeNamespaces.clear ();
744 attributeLocalNames.clear ();
745 attributeValues.clear ();
746 attributeCount = 0;
747 }
748 nspending = false;
749 }
750
751 void endElement (String elname)
752 throws SAXException
753 {
754 ContentHandler handler = contentHandler;
755
756 handler.endElement ("", "", elname);
757
758 if (!namespaces)
759 return;
760
761 Enumeration prefixes = prefixStack.getDeclaredPrefixes ();
762
763 while (prefixes.hasMoreElements ())
764 handler.endPrefixMapping ((String) prefixes.nextElement ());
765 prefixStack.popContext ();
766 }
767
768 void startCDATA ()
769 throws SAXException
770 {
771 lexicalHandler.startCDATA ();
772 }
773
774 void charData (char ch[], int start, int length)
775 throws SAXException
776 {
777 contentHandler.characters (ch, start, length);
778 }
779
780 void endCDATA ()
781 throws SAXException
782 {
783 lexicalHandler.endCDATA ();
784 }
785
786 void ignorableWhitespace (char ch[], int start, int length)
787 throws SAXException
788 {
789 contentHandler.ignorableWhitespace (ch, start, length);
790 }
791
792 void processingInstruction (String target, String data)
793 throws SAXException
794 {
795
796
797
798
799 contentHandler.processingInstruction (target, data);
800 }
801
802 void comment (char ch[], int start, int length)
803 throws SAXException
804 {
805
806
807
808
809 if (lexicalHandler != base)
810 lexicalHandler.comment (ch, start, length);
811 }
812
813
814 void error (String message, String url, int line, int column)
815 throws SAXException
816 {
817 SAXParseException fatal;
818
819 fatal = new SAXParseException (message, null, url, line, column);
820 errorHandler.fatalError (fatal);
821
822
823 throw fatal;
824 }
825
826
827
828
829
830 private void deliverDTDEvents ()
831 throws SAXException
832 {
833 String ename;
834 String nname;
835 String publicId;
836 String systemId;
837
838
839 if (dtdHandler != base) {
840 Iterator notationNames = parser.declaredNotations ();
841
842 while (notationNames.hasNext ()) {
843 nname = (String) notationNames.next ();
844 publicId = parser.getNotationPublicId (nname);
845 systemId = parser.getNotationSystemId (nname);
846 dtdHandler.notationDecl (nname, publicId, systemId);
847 }
848 }
849
850
851 if (dtdHandler != base || declHandler != base) {
852 Iterator entityNames = parser.declaredEntities ();
853 int type;
854
855 while (entityNames.hasNext ()) {
856 ename = (String) entityNames.next ();
857 type = parser.getEntityType (ename);
858
859 if (ename.charAt (0) == '%')
860 continue;
861
862
863 if (type == XmlParser.ENTITY_NDATA) {
864 publicId = parser.getEntityPublicId (ename);
865 systemId = parser.getEntitySystemId (ename);
866 nname = parser.getEntityNotationName (ename);
867 dtdHandler.unparsedEntityDecl (ename,
868 publicId, systemId, nname);
869
870
871 }
872 else if (type == XmlParser.ENTITY_TEXT) {
873 publicId = parser.getEntityPublicId (ename);
874 systemId = parser.getEntitySystemId (ename);
875 declHandler.externalEntityDecl (ename,
876 publicId, systemId);
877
878
879 }
880 else if (type == XmlParser.ENTITY_INTERNAL) {
881
882
883 if ("lt".equals (ename) || "gt".equals (ename)
884 || "quot".equals (ename)
885 || "apos".equals (ename)
886 || "amp".equals (ename))
887 continue;
888 declHandler.internalEntityDecl (ename,
889 parser.getEntityValue (ename));
890 }
891 }
892 }
893
894
895 if (declHandler != base) {
896 Iterator elementNames = parser.declaredElements ();
897 Iterator attNames;
898
899 while (elementNames.hasNext ()) {
900 String model = null;
901
902 ename = (String) elementNames.next ();
903 switch (parser.getElementContentType (ename)) {
904 case XmlParser.CONTENT_ANY:
905 model = "ANY";
906 break;
907 case XmlParser.CONTENT_EMPTY:
908 model = "EMPTY";
909 break;
910 case XmlParser.CONTENT_MIXED:
911 case XmlParser.CONTENT_ELEMENTS:
912 model = parser.getElementContentModel (ename);
913 break;
914 case XmlParser.CONTENT_UNDECLARED:
915 default:
916 model = null;
917 break;
918 }
919 if (model != null)
920 declHandler.elementDecl (ename, model);
921
922 attNames = parser.declaredAttributes (ename);
923 while (attNames != null && attNames.hasNext ()) {
924 String aname = (String) attNames.next ();
925 String type;
926 String valueDefault;
927 String value;
928
929 switch (parser.getAttributeType (ename, aname)) {
930 case XmlParser.ATTRIBUTE_CDATA:
931 type = "CDATA";
932 break;
933 case XmlParser.ATTRIBUTE_ENTITY:
934 type = "ENTITY";
935 break;
936 case XmlParser.ATTRIBUTE_ENTITIES:
937 type = "ENTITIES";
938 break;
939 case XmlParser.ATTRIBUTE_ENUMERATED:
940 type = parser.getAttributeIterator (ename, aname);
941 break;
942 case XmlParser.ATTRIBUTE_ID:
943 type = "ID";
944 break;
945 case XmlParser.ATTRIBUTE_IDREF:
946 type = "IDREF";
947 break;
948 case XmlParser.ATTRIBUTE_IDREFS:
949 type = "IDREFS";
950 break;
951 case XmlParser.ATTRIBUTE_NMTOKEN:
952 type = "NMTOKEN";
953 break;
954 case XmlParser.ATTRIBUTE_NMTOKENS:
955 type = "NMTOKENS";
956 break;
957
958
959
960
961
962 case XmlParser.ATTRIBUTE_NOTATION:
963 type = "NOTATION";
964 break;
965
966 default:
967 errorHandler.fatalError (new SAXParseException (
968 "internal error, att type", this));
969 type = null;
970 }
971
972 switch (parser.getAttributeDefaultValueType (
973 ename, aname)) {
974 case XmlParser.ATTRIBUTE_DEFAULT_IMPLIED:
975 valueDefault = "#IMPLIED";
976 break;
977 case XmlParser.ATTRIBUTE_DEFAULT_REQUIRED:
978 valueDefault = "#REQUIRED";
979 break;
980 case XmlParser.ATTRIBUTE_DEFAULT_FIXED:
981 valueDefault = "#FIXED";
982 break;
983 case XmlParser.ATTRIBUTE_DEFAULT_SPECIFIED:
984 valueDefault = null;
985 break;
986
987 default:
988 errorHandler.fatalError (new SAXParseException (
989 "internal error, att default", this));
990 valueDefault = null;
991 }
992
993 value = parser.getAttributeDefaultValue (ename, aname);
994
995 declHandler.attributeDecl (ename, aname,
996 type, valueDefault, value);
997 }
998 }
999 }
1000 }
1001
1002
1003
1004
1005
1006
1007 /***
1008 * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1009 * (don't invoke on parser);
1010 */
1011 public int getLength ()
1012 {
1013 return attributeNames.size ();
1014 }
1015
1016 /***
1017 * <b>SAX2 Attributes</b> method (don't invoke on parser);
1018 */
1019 public String getURI (int index)
1020 {
1021 return (String) (attributeNamespaces.get (index));
1022 }
1023
1024 /***
1025 * <b>SAX2 Attributes</b> method (don't invoke on parser);
1026 */
1027 public String getLocalName (int index)
1028 {
1029 return (String) (attributeLocalNames.get (index));
1030 }
1031
1032 /***
1033 * <b>SAX2 Attributes</b> method (don't invoke on parser);
1034 */
1035 public String getQName (int i)
1036 {
1037 return (String) (attributeNames.get (i));
1038 }
1039
1040 /***
1041 * <b>SAX1 AttributeList</b> method (don't invoke on parser);
1042 */
1043 public String getName (int i)
1044 {
1045 return (String) (attributeNames.get (i));
1046 }
1047
1048 /***
1049 * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1050 * (don't invoke on parser);
1051 */
1052 public String getType (int i)
1053 {
1054 switch (parser.getAttributeType (elementName, getQName (i))) {
1055
1056 case XmlParser.ATTRIBUTE_UNDECLARED:
1057 case XmlParser.ATTRIBUTE_CDATA:
1058 return "CDATA";
1059 case XmlParser.ATTRIBUTE_ID:
1060 return "ID";
1061 case XmlParser.ATTRIBUTE_IDREF:
1062 return "IDREF";
1063 case XmlParser.ATTRIBUTE_IDREFS:
1064 return "IDREFS";
1065 case XmlParser.ATTRIBUTE_ENTITY:
1066 return "ENTITY";
1067 case XmlParser.ATTRIBUTE_ENTITIES:
1068 return "ENTITIES";
1069 case XmlParser.ATTRIBUTE_ENUMERATED:
1070
1071
1072 case XmlParser.ATTRIBUTE_NMTOKEN:
1073 return "NMTOKEN";
1074 case XmlParser.ATTRIBUTE_NMTOKENS:
1075 return "NMTOKENS";
1076 case XmlParser.ATTRIBUTE_NOTATION:
1077
1078
1079 return "NOTATION";
1080
1081 }
1082
1083 return null;
1084 }
1085
1086
1087 /***
1088 * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1089 * (don't invoke on parser);
1090 */
1091 public String getValue (int i)
1092 {
1093 return (String) (attributeValues.get (i));
1094 }
1095
1096
1097 /***
1098 * <b>SAX2 Attributes</b> method (don't invoke on parser);
1099 */
1100 public int getIndex (String uri, String local)
1101 {
1102 int length = getLength ();
1103
1104 for (int i = 0; i < length; i++) {
1105 if (!getURI (i).equals (uri))
1106 continue;
1107 if (getLocalName (i).equals (local))
1108 return i;
1109 }
1110 return -1;
1111 }
1112
1113
1114 /***
1115 * <b>SAX2 Attributes</b> method (don't invoke on parser);
1116 */
1117 public int getIndex (String xmlName)
1118 {
1119 int length = getLength ();
1120
1121 for (int i = 0; i < length; i++) {
1122 if (getQName (i).equals (xmlName))
1123 return i;
1124 }
1125 return -1;
1126 }
1127
1128
1129 /***
1130 * <b>SAX2 Attributes</b> method (don't invoke on parser);
1131 */
1132 public String getType (String uri, String local)
1133 {
1134 int index = getIndex (uri, local);
1135
1136 if (index < 0)
1137 return null;
1138 return getType (index);
1139 }
1140
1141
1142 /***
1143 * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1144 * (don't invoke on parser);
1145 */
1146 public String getType (String xmlName)
1147 {
1148 int index = getIndex (xmlName);
1149
1150 if (index < 0)
1151 return null;
1152 return getType (index);
1153 }
1154
1155
1156 /***
1157 * <b>SAX Attributes</b> method (don't invoke on parser);
1158 */
1159 public String getValue (String uri, String local)
1160 {
1161 int index = getIndex (uri, local);
1162
1163 if (index < 0)
1164 return null;
1165 return getValue (index);
1166 }
1167
1168
1169 /***
1170 * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1171 * (don't invoke on parser);
1172 */
1173 public String getValue (String xmlName)
1174 {
1175 int index = getIndex (xmlName);
1176
1177 if (index < 0)
1178 return null;
1179 return getValue (index);
1180 }
1181
1182
1183
1184
1185
1186
1187 /***
1188 * <b>SAX Locator</b> method (don't invoke on parser);
1189 */
1190 public String getPublicId ()
1191 {
1192 return null;
1193 }
1194
1195 /***
1196 * <b>SAX Locator</b> method (don't invoke on parser);
1197 */
1198 public String getSystemId ()
1199 {
1200 return (String) entityStack.get ( entityStack.size() - 1 );
1201 }
1202
1203 /***
1204 * <b>SAX Locator</b> method (don't invoke on parser);
1205 */
1206 public int getLineNumber ()
1207 {
1208 return parser.getLineNumber ();
1209 }
1210
1211 /***
1212 * <b>SAX Locator</b> method (don't invoke on parser);
1213 */
1214 public int getColumnNumber ()
1215 {
1216 return parser.getColumnNumber ();
1217 }
1218
1219
1220
1221 private static class Adapter implements ContentHandler
1222 {
1223 private DocumentHandler docHandler;
1224
1225 Adapter (DocumentHandler dh)
1226 { docHandler = dh; }
1227
1228
1229 public void setDocumentLocator (Locator l)
1230 { docHandler.setDocumentLocator (l); }
1231
1232 public void startDocument () throws SAXException
1233 { docHandler.startDocument (); }
1234
1235 public void processingInstruction (String target, String data)
1236 throws SAXException
1237 { docHandler.processingInstruction (target, data); }
1238
1239 public void startPrefixMapping (String prefix, String uri)
1240 {
1241
1242 public void startElement (
1243 String namespace,
1244 String local,
1245 String name,
1246 Attributes attrs ) throws SAXException
1247 {
1248 docHandler.startElement (name, (AttributeList) attrs);
1249 }
1250
1251 public void characters (char buf [], int offset, int len)
1252 throws SAXException
1253 {
1254 docHandler.characters (buf, offset, len);
1255 }
1256
1257 public void ignorableWhitespace (char buf [], int offset, int len)
1258 throws SAXException
1259 {
1260 docHandler.ignorableWhitespace (buf, offset, len);
1261 }
1262
1263 public void skippedEntity (String name)
1264 {
1265
1266 public void endElement (String u, String l, String name)
1267 throws SAXException
1268 { docHandler.endElement (name); }
1269
1270 public void endPrefixMapping (String prefix)
1271 {
1272
1273 public void endDocument () throws SAXException
1274 { docHandler.endDocument (); }
1275 }
1276 }
1277