View Javadoc

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