1 package net.sf.tomp.xtcl.filter;
2
3 import org.xml.sax.Attributes;
4 import org.xml.sax.ContentHandler;
5 import org.xml.sax.DTDHandler;
6 import org.xml.sax.EntityResolver;
7 import org.xml.sax.ErrorHandler;
8 import org.xml.sax.InputSource;
9 import org.xml.sax.Locator;
10 import org.xml.sax.SAXException;
11 import org.xml.sax.SAXNotRecognizedException;
12 import org.xml.sax.SAXNotSupportedException;
13 import org.xml.sax.SAXParseException;
14 import org.xml.sax.XMLReader;
15 import org.xml.sax.ext.LexicalHandler;
16
17 import java.io.IOException;
18
19 /***
20 * DOCUMENT ME!
21 *
22 * @author tomp
23 */
24 public class XTFilterImpl implements XTFilter
25 {
26
27
28
29
30 /*** DOCUMENT ME! */
31 protected XMLReader parent = null;
32
33 /*** DOCUMENT ME! */
34 protected Locator locator = null;
35
36 /*** DOCUMENT ME! */
37 protected EntityResolver entityResolver = null;
38
39 /*** DOCUMENT ME! */
40 protected DTDHandler dtdHandler = null;
41
42 /*** DOCUMENT ME! */
43 protected ContentHandler contentHandler = null;
44
45 /*** DOCUMENT ME! */
46 protected ErrorHandler errorHandler = null;
47
48 /*** DOCUMENT ME! */
49 protected LexicalHandler lexicalHandler = null;
50
51
52
53
54
55 /***
56 * Construct an empty XML filter, with no parent.
57 * <p>
58 * This filter will have no parent: you must assign a parent before you
59 * start a parse or do any configuration with setFeature or setProperty,
60 * unless you use this as a pure event consumer rather than as an {@link
61 * XMLReader}.
62 * </p>
63 *
64 * @see org.xml.sax.XMLReader#setFeature
65 * @see org.xml.sax.XMLReader#setProperty
66 * @see #setParent
67 */
68 public XTFilterImpl()
69 {
70 super();
71 }
72
73 /***
74 * Construct an XML filter with the specified parent.
75 *
76 * @param parent DOCUMENT ME!
77 * @see #setParent
78 * @see #getParent
79 */
80 public XTFilterImpl(XMLReader parent)
81 {
82 super();
83 setParent(parent);
84 }
85
86
87 public void setParameter(String k, Object v)
88 {
89
90
91 throw new UnsupportedOperationException("Cannot set parameters to "
92 + this);
93 }
94
95
96
97
98
99 /***
100 * Set the parent reader.
101 * <p>
102 * This is the {@link org.xml.sax.XMLReader XMLReader}from which this
103 * filter will obtain its events and to which it will pass its configuration
104 * requests. The parent may itself be another filter.
105 * </p>
106 * <p>
107 * If there is no parent reader set, any attempt to parse or to set or get a
108 * feature or property will fail.
109 * </p>
110 *
111 * @param parent The parent XML reader.
112 * @see #getParent
113 */
114 public void setParent(XMLReader parent)
115 {
116 this.parent = parent;
117 }
118
119 /***
120 * Get the parent reader.
121 *
122 * @return The parent XML reader, or null if none is set.
123 * @see #setParent
124 */
125 public XMLReader getParent()
126 {
127 return parent;
128 }
129
130
131
132
133
134 /***
135 * Set the value of a feature.
136 * <p>
137 * This will always fail if the parent is null.
138 * </p>
139 *
140 * @param name The feature name.
141 * @param value The requested feature value.
142 * @exception SAXNotRecognizedException If the feature value can't be
143 * assigned or retrieved from the parent.
144 * @exception SAXNotSupportedException When the parent recognizes the
145 * feature name but cannot set the requested value.
146 */
147 public void setFeature(String name, boolean value)
148 throws SAXNotRecognizedException, SAXNotSupportedException
149 {
150 if (parent != null)
151 {
152 parent.setFeature(name, value);
153 }
154 else
155 {
156 throw new SAXNotRecognizedException("Feature: " + name);
157 }
158 }
159
160 /***
161 * Look up the value of a feature.
162 * <p>
163 * This will always fail if the parent is null.
164 * </p>
165 *
166 * @param name The feature name.
167 * @return The current value of the feature.
168 * @exception SAXNotRecognizedException If the feature value can't be
169 * assigned or retrieved from the parent.
170 * @exception SAXNotSupportedException When the parent recognizes the
171 * feature name but cannot determine its value at this time.
172 */
173 public boolean getFeature(String name)
174 throws SAXNotRecognizedException, SAXNotSupportedException
175 {
176 if (parent != null)
177 {
178 return parent.getFeature(name);
179 }
180 else
181 {
182 throw new SAXNotRecognizedException("Feature: " + name);
183 }
184 }
185
186 /***
187 * Set the value of a property.
188 * <p>
189 * This will always fail if the parent is null.
190 * </p>
191 *
192 * @param name The property name.
193 * @param value The requested property value.
194 * @exception SAXNotRecognizedException If the property value can't be
195 * assigned or retrieved from the parent.
196 * @exception SAXNotSupportedException When the parent recognizes the
197 * property name but cannot set the requested value.
198 */
199 public void setProperty(String name, Object value)
200 throws SAXNotRecognizedException, SAXNotSupportedException
201 {
202 if ("http://xml.org/sax/properties/lexical-handler".equals(name))
203 {
204 setLexicalHandler((LexicalHandler) value);
205 }
206 else if (parent != null)
207 {
208 parent.setProperty(name, value);
209 }
210 else
211 {
212 throw new SAXNotRecognizedException("Property: " + name);
213 }
214 }
215
216 /***
217 * Look up the value of a property.
218 *
219 * @param name The property name.
220 * @return The current value of the property.
221 * @exception SAXNotRecognizedException If the property value can't be
222 * assigned or retrieved from the parent.
223 * @exception SAXNotSupportedException When the parent recognizes the
224 * property name but cannot determine its value at this time.
225 */
226 public Object getProperty(String name)
227 throws SAXNotRecognizedException, SAXNotSupportedException
228 {
229 if ("http://xml.org/sax/properties/lexical-handler".equals(name))
230 {
231 return getLexicalHandler();
232 }
233 else if (parent != null)
234 {
235 return parent.getProperty(name);
236 }
237 else
238 {
239 throw new SAXNotRecognizedException("Property: " + name);
240 }
241 }
242
243 /***
244 * Set the entity resolver.
245 *
246 * @param resolver The new entity resolver.
247 */
248 public void setEntityResolver(EntityResolver resolver)
249 {
250 entityResolver = resolver;
251 }
252
253 /***
254 * Get the current entity resolver.
255 *
256 * @return The current entity resolver, or null if none was set.
257 */
258 public EntityResolver getEntityResolver()
259 {
260 return entityResolver;
261 }
262
263 /***
264 * Set the DTD event handler.
265 *
266 * @param handler The new DTD handler.
267 */
268 public void setDTDHandler(DTDHandler handler)
269 {
270 dtdHandler = handler;
271 }
272
273 /***
274 * Get the current DTD event handler.
275 *
276 * @return The current DTD handler, or null if none was set.
277 */
278 public DTDHandler getDTDHandler()
279 {
280 return dtdHandler;
281 }
282
283 /***
284 * Set the content event handler.
285 *
286 * @param handler The new content handler.
287 */
288 public void setContentHandler(ContentHandler handler)
289 {
290
291 contentHandler = handler;
292 }
293
294 /***
295 * Get the content event handler.
296 *
297 * @return The current content handler, or null if none was set.
298 */
299 public ContentHandler getContentHandler()
300 {
301
302 return contentHandler;
303 }
304
305 /***
306 * Set the lexical event handler.
307 *
308 * @param handler The new lexical handler.
309 */
310 public void setLexicalHandler(LexicalHandler handler)
311 {
312
313 lexicalHandler = handler;
314 }
315
316 /***
317 * Get the lexical event handler.
318 *
319 * @return The current lexical handler, or null if none was set.
320 */
321 public LexicalHandler getLexicalHandler()
322 {
323
324 return lexicalHandler;
325 }
326
327 /***
328 * Set the error event handler.
329 *
330 * @param handler The new error handler.
331 */
332 public void setErrorHandler(ErrorHandler handler)
333 {
334 errorHandler = handler;
335 }
336
337 /***
338 * Get the current error event handler.
339 *
340 * @return The current error handler, or null if none was set.
341 */
342 public ErrorHandler getErrorHandler()
343 {
344 return errorHandler;
345 }
346
347 /***
348 * Parse a document.
349 *
350 * @param input The input source for the document entity.
351 * @exception SAXException Any SAX exception, possibly wrapping another
352 * exception.
353 * @exception IOException An IO exception from the parser, possibly from a
354 * byte stream or character stream supplied by the
355 * application.
356 */
357 public void parse(InputSource input)
358 throws SAXException, IOException
359 {
360 setupParse();
361
362
363
364 parent.parse(input);
365 }
366
367 /***
368 * Parse a document.
369 *
370 * @param systemId The system identifier as a fully-qualified URI.
371 * @exception SAXException Any SAX exception, possibly wrapping another
372 * exception.
373 * @exception IOException An IO exception from the parser, possibly from a
374 * byte stream or character stream supplied by the
375 * application.
376 */
377 public void parse(String systemId)
378 throws SAXException, IOException
379 {
380 parse(new InputSource(systemId));
381 }
382
383
384
385
386
387 /***
388 * Filter an external entity resolution.
389 *
390 * @param publicId The entity's public identifier, or null.
391 * @param systemId The entity's system identifier.
392 * @return A new InputSource or null for the default.
393 * @exception SAXException The client may throw an exception during
394 * processing.
395 * @exception IOException The client may throw an I/O-related exception
396 * while obtaining the new InputSource.
397 */
398 public InputSource resolveEntity(String publicId, String systemId)
399 throws SAXException, IOException
400 {
401 if (entityResolver != null)
402 {
403 return entityResolver.resolveEntity(publicId, systemId);
404 }
405 else
406 {
407 return null;
408 }
409 }
410
411
412
413
414
415 /***
416 * Filter a notation declaration event.
417 *
418 * @param name The notation name.
419 * @param publicId The notation's public identifier, or null.
420 * @param systemId The notation's system identifier, or null.
421 * @exception SAXException The client may throw an exception during
422 * processing.
423 */
424 public void notationDecl(String name, String publicId, String systemId)
425 throws SAXException
426 {
427 if (dtdHandler != null)
428 {
429 dtdHandler.notationDecl(name, publicId, systemId);
430 }
431 }
432
433 /***
434 * Filter an unparsed entity declaration event.
435 *
436 * @param name The entity name.
437 * @param publicId The entity's public identifier, or null.
438 * @param systemId The entity's system identifier, or null.
439 * @param notationName The name of the associated notation.
440 * @exception SAXException The client may throw an exception during
441 * processing.
442 */
443 public void unparsedEntityDecl(String name, String publicId,
444 String systemId, String notationName)
445 throws SAXException
446 {
447 if (dtdHandler != null)
448 {
449 dtdHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
450 }
451 }
452
453
454
455
456
457 /***
458 * Filter a new document locator event.
459 *
460 * @param locator The document locator.
461 */
462 public void setDocumentLocator(Locator locator)
463 {
464 if ((locator == null) || (locator.getSystemId() == null))
465 {
466
467
468 return;
469 }
470
471
472 this.locator = locator;
473
474 if (contentHandler != null)
475 {
476
477 }
478 }
479
480 public Locator getDocumentLocator()
481 {
482 return locator;
483 }
484
485 /***
486 * Filter a start document event.
487 *
488 * @exception SAXException The client may throw an exception during
489 * processing.
490 */
491 public void startDocument()
492 throws SAXException
493 {
494
495 if (contentHandler != null)
496 {
497 contentHandler.startDocument();
498 }
499 }
500
501 /***
502 * Filter an end document event.
503 *
504 * @exception SAXException The client may throw an exception during
505 * processing.
506 */
507 public void endDocument()
508 throws SAXException
509 {
510
511
512 if (contentHandler != null)
513 {
514 contentHandler.endDocument();
515 }
516 }
517
518 /***
519 * Filter a start Namespace prefix mapping event.
520 *
521 * @param prefix The Namespace prefix.
522 * @param uri The Namespace URI.
523 * @exception SAXException The client may throw an exception during
524 * processing.
525 */
526 public void startPrefixMapping(String prefix, String uri)
527 throws SAXException
528 {
529 if (contentHandler != null)
530 {
531 contentHandler.startPrefixMapping(prefix, uri);
532 }
533 }
534
535 /***
536 * Filter an end Namespace prefix mapping event.
537 *
538 * @param prefix The Namespace prefix.
539 * @exception SAXException The client may throw an exception during
540 * processing.
541 */
542 public void endPrefixMapping(String prefix)
543 throws SAXException
544 {
545 if (contentHandler != null)
546 {
547 contentHandler.endPrefixMapping(prefix);
548 }
549 }
550
551 /***
552 * Filter a start element event.
553 *
554 * @param uri The element's Namespace URI, or the empty string.
555 * @param localName The element's local name, or the empty string.
556 * @param qName The element's qualified (prefixed) name, or the empty
557 * string.
558 * @param atts The element's attributes.
559 * @exception SAXException The client may throw an exception during
560 * processing.
561 */
562 public void startElement(String uri, String localName, String qName,
563 Attributes atts) throws SAXException
564 {
565 if (contentHandler != null)
566 {
567 contentHandler.startElement(uri, localName, qName, atts);
568 }
569 }
570
571 /***
572 * Filter an end element event.
573 *
574 * @param uri The element's Namespace URI, or the empty string.
575 * @param localName The element's local name, or the empty string.
576 * @param qName The element's qualified (prefixed) name, or the empty
577 * string.
578 * @exception SAXException The client may throw an exception during
579 * processing.
580 */
581 public void endElement(String uri, String localName, String qName)
582 throws SAXException
583 {
584 if (contentHandler != null)
585 {
586 contentHandler.endElement(uri, localName, qName);
587 }
588 }
589
590 /***
591 * Filter a character data event.
592 *
593 * @param ch An array of characters.
594 * @param start The starting position in the array.
595 * @param length The number of characters to use from the array.
596 * @exception SAXException The client may throw an exception during
597 * processing.
598 */
599 public void characters(char[] ch, int start, int length)
600 throws SAXException
601 {
602 if (contentHandler != null)
603 {
604 contentHandler.characters(ch, start, length);
605 }
606 }
607
608 /***
609 * Filter an ignorable whitespace event.
610 *
611 * @param ch An array of characters.
612 * @param start The starting position in the array.
613 * @param length The number of characters to use from the array.
614 * @exception SAXException The client may throw an exception during
615 * processing.
616 */
617 public void ignorableWhitespace(char[] ch, int start, int length)
618 throws SAXException
619 {
620 if (contentHandler != null)
621 {
622 contentHandler.ignorableWhitespace(ch, start, length);
623 }
624 }
625
626 /***
627 * Filter a processing instruction event.
628 *
629 * @param target The processing instruction target.
630 * @param data The text following the target.
631 * @exception SAXException The client may throw an exception during
632 * processing.
633 */
634 public void processingInstruction(String target, String data)
635 throws SAXException
636 {
637 if (contentHandler != null)
638 {
639 contentHandler.processingInstruction(target, data);
640 }
641 }
642
643 /***
644 * Filter a skipped entity event.
645 *
646 * @param name The name of the skipped entity.
647 * @exception SAXException The client may throw an exception during
648 * processing.
649 */
650 public void skippedEntity(String name)
651 throws SAXException
652 {
653 if (contentHandler != null)
654 {
655 contentHandler.skippedEntity(name);
656 }
657 }
658
659
660
661
662
663 /***
664 * Filter a warning event.
665 *
666 * @param e The warning as an exception.
667 * @exception SAXException The client may throw an exception during
668 * processing.
669 */
670 public void warning(SAXParseException e)
671 throws SAXException
672 {
673 if (errorHandler != null)
674 {
675 errorHandler.warning(e);
676 }
677 }
678
679 /***
680 * Filter an error event.
681 *
682 * @param e The error as an exception.
683 * @exception SAXException The client may throw an exception during
684 * processing.
685 */
686 public void error(SAXParseException e)
687 throws SAXException
688 {
689 if (errorHandler != null)
690 {
691 errorHandler.error(e);
692 }
693 }
694
695 /***
696 * Filter a fatal error event.
697 *
698 * @param e The error as an exception.
699 * @exception SAXException The client may throw an exception during
700 * processing.
701 */
702 public void fatalError(SAXParseException e)
703 throws SAXException
704 {
705 if (errorHandler != null)
706 {
707 errorHandler.fatalError(e);
708 }
709 }
710
711
712
713
714
715 /***
716 * Callback interface for SAX (part of LexicalHandler interface): not for
717 * application use
718 *
719 * @param ch DOCUMENT ME!
720 * @param start DOCUMENT ME!
721 * @param length DOCUMENT ME!
722 * @throws SAXException DOCUMENT ME!
723 */
724 public void comment(char[] ch, int start, int length)
725 throws SAXException
726 {
727 if (lexicalHandler != null)
728 {
729 lexicalHandler.comment(ch, start, length);
730 }
731 }
732
733
734
735 /***
736 * Register the start of the DTD. Comments in the DTD are skipped because
737 * they are not part of the XPath data model
738 *
739 * @param name DOCUMENT ME!
740 * @param publicId DOCUMENT ME!
741 * @param systemId DOCUMENT ME!
742 * @throws SAXException DOCUMENT ME!
743 */
744 public void startDTD(String name, String publicId, String systemId)
745 throws SAXException
746 {
747 if (lexicalHandler != null)
748 {
749 lexicalHandler.startDTD(name, publicId, systemId);
750 }
751 }
752
753 /***
754 * Register the end of the DTD. Comments in the DTD are skipped because they
755 * are not part of the XPath data model
756 *
757 * @throws SAXException DOCUMENT ME!
758 */
759 public void endDTD() throws SAXException
760 {
761 if (lexicalHandler != null)
762 {
763 lexicalHandler.endDTD();
764 }
765 }
766
767 /***
768 * DOCUMENT ME!
769 *
770 * @param name DOCUMENT ME!
771 * @throws SAXException DOCUMENT ME!
772 */
773 public void startEntity(String name)
774 throws SAXException
775 {
776 if (lexicalHandler != null)
777 {
778 lexicalHandler.startEntity(name);
779 }
780 }
781
782 /***
783 * DOCUMENT ME!
784 *
785 * @param name DOCUMENT ME!
786 * @throws SAXException DOCUMENT ME!
787 */
788 public void endEntity(String name)
789 throws SAXException
790 {
791 if (lexicalHandler != null)
792 {
793 lexicalHandler.endEntity(name);
794 }
795 }
796
797 /***
798 * DOCUMENT ME!
799 *
800 * @throws SAXException DOCUMENT ME!
801 */
802 public void startCDATA() throws SAXException
803 {
804 if (lexicalHandler != null)
805 {
806 lexicalHandler.startCDATA();
807 }
808 }
809
810 /***
811 * DOCUMENT ME!
812 *
813 * @throws SAXException DOCUMENT ME!
814 */
815 public void endCDATA() throws SAXException
816 {
817 if (lexicalHandler != null)
818 {
819 lexicalHandler.endCDATA();
820 }
821 }
822
823
824
825
826
827 /***
828 * Set up before a parse.
829 * <p>
830 * Before every parse, check whether the parent is non-null, and re-register
831 * the filter for all of the events.
832 * </p>
833 *
834 * @throws SAXException DOCUMENT ME!
835 * @throws NullPointerException DOCUMENT ME!
836 */
837 protected void setupParse()
838 throws SAXException
839 {
840 if (parent == null)
841 {
842 throw new NullPointerException("No parent for filter " + this);
843 }
844
845 parent.setEntityResolver(this);
846 parent.setDTDHandler(this);
847 parent.setContentHandler(this);
848
849
850 parent.setErrorHandler(this);
851
852 try
853 {
854 parent.setProperty("http://xml.org/sax/properties/lexical-handler",
855 this);
856 }
857 catch (SAXException se)
858 {
859
860 }
861 }
862 }
863
864
865
866
867
868
869
870
871
872
873
874