View Javadoc

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