KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > Filter


1 package com.icl.saxon;
2 import com.icl.saxon.tree.TreeBuilder;
3 import com.icl.saxon.om.NamePool;
4 import com.icl.saxon.om.DocumentInfo;
5 import com.icl.saxon.output.ContentHandlerProxy;
6
7 import javax.xml.parsers.SAXParserFactory JavaDoc;
8 import javax.xml.transform.*;
9 import javax.xml.transform.sax.*;
10 import java.util.Properties JavaDoc;
11
12 import org.xml.sax.*;
13 import org.xml.sax.helpers.*;
14 import org.xml.sax.ext.*;
15
16 import java.io.IOException JavaDoc;
17
18
19
20 /**
21   * <B>Filter</B> is an XMLFilter (a SAX2 filter) that performs a transformation
22   * taking a SAX stream as input and producing a SAX stream as output.
23   * @author Michael H. Kay (mhkay@iclway.co.uk)
24   */

25   
26 public class Filter implements XMLFilter {
27
28     Controller controller;
29     XMLReader parser;
30     ContentHandler contentHandler; // destination for output of this filter
31
LexicalHandler lexicalHandler; // destination for output of this filter
32

33
34     
35     /**
36     * Create a Filter and initialise variables. The constructor is protected, because
37     * the Filter should be created using newXMLFilter() in the SAXTransformerFactory
38     * class
39     */

40
41     protected Filter(Controller controller) {
42         this.controller = controller;
43     }
44
45
46     //////////////////////////////////////////////////////////////////
47
// Implement XMLFilter interface methods
48
//////////////////////////////////////////////////////////////////
49

50     /**
51     * Set the parent reader.
52     *
53     * <p>This method allows the application to link the filter to
54     * a parent reader (which may be another filter). The argument
55     * may not be null.</p>
56     *
57     * @param parent The parent reader (the supplier of SAX events).
58     */

59     
60     public void setParent (XMLReader parent) {
61         parser = parent;
62     }
63
64     /**
65     * Get the parent reader.
66     *
67     * <p>This method allows the application to query the parent
68     * reader (which may be another filter). It is generally a
69     * bad idea to perform any operations on the parent reader
70     * directly: they should all pass through this filter.</p>
71     *
72     * @return The parent filter, or null if none has been set.
73     */

74     
75     public XMLReader getParent() {
76         return parser;
77     }
78
79     ///////////////////////////////////////////////////////////////////
80
// implement XMLReader interface methods
81
///////////////////////////////////////////////////////////////////
82

83     /**
84      * Look up the value of a feature.
85      *
86      * <p>The feature name is any fully-qualified URI. It is
87      * possible for an XMLReader to recognize a feature name but
88      * to be unable to return its value; this is especially true
89      * in the case of an adapter for a SAX1 Parser, which has
90      * no way of knowing whether the underlying parser is
91      * performing validation or expanding external entities.</p>
92      *
93      * <p>All XMLReaders are required to recognize the
94      * http://xml.org/sax/features/namespaces and the
95      * http://xml.org/sax/features/namespace-prefixes feature names.</p>
96      *
97      * @param name The feature name, which is a fully-qualified URI.
98      * @return The current state of the feature (true or false).
99      * @exception org.xml.sax.SAXNotRecognizedException When the
100      * XMLReader does not recognize the feature name.
101      * @exception org.xml.sax.SAXNotSupportedException When the
102      * XMLReader recognizes the feature name but
103      * cannot determine its value at this time.
104      * @see #setFeature
105      */

106      
107     public boolean getFeature (String JavaDoc name)
108         throws SAXNotRecognizedException, SAXNotSupportedException {
109         if (name.equals("http://xml.org/sax/features/namespaces")) {
110             return true;
111         } else if (name.equals("http://xml.org/sax/features/namespace-prefixes")) {
112             return false;
113         } else {
114             throw new SAXNotRecognizedException(name);
115         }
116     }
117
118
119     /**
120      * Set the state of a feature.
121      *
122      * <p>The feature name is any fully-qualified URI. It is
123      * possible for an XMLReader to recognize a feature name but
124      * to be unable to set its value; this is especially true
125      * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser Parser},
126      * which has no way of affecting whether the underlying parser is
127      * validating, for example.</p>
128      *
129      * <p>All XMLReaders are required to support setting
130      * http://xml.org/sax/features/namespaces to true and
131      * http://xml.org/sax/features/namespace-prefixes to false.</p>
132      *
133      * <p>Some feature values may be immutable or mutable only
134      * in specific contexts, such as before, during, or after
135      * a parse.</p>
136      *
137      * @param name The feature name, which is a fully-qualified URI.
138      * @param state The requested state of the feature (true or false).
139      * @exception org.xml.sax.SAXNotRecognizedException When the
140      * XMLReader does not recognize the feature name.
141      * @exception org.xml.sax.SAXNotSupportedException When the
142      * XMLReader recognizes the feature name but
143      * cannot set the requested value.
144      * @see #getFeature
145      */

146      
147     public void setFeature (String JavaDoc name, boolean value)
148     throws SAXNotRecognizedException, SAXNotSupportedException {
149         if (name.equals("http://xml.org/sax/features/namespaces")) {
150             if (!value) {
151                 throw new SAXNotSupportedException(name);
152             }
153         } else if (name.equals("http://xml.org/sax/features/namespace-prefixes")) {
154             if (value) {
155                 throw new SAXNotSupportedException(name);
156             }
157         } else {
158             throw new SAXNotRecognizedException(name);
159         }
160     }
161
162     /**
163      * Look up the value of a property.
164      *
165      * <p>The property name is any fully-qualified URI. It is
166      * possible for an XMLReader to recognize a property name but
167      * to be unable to return its state; this is especially true
168      * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
169      * Parser}.</p>
170      *
171      * <p>XMLReaders are not required to recognize any specific
172      * property names, though an initial core set is documented for
173      * SAX2.</p>
174      *
175      * <p>Some property values may be available only in specific
176      * contexts, such as before, during, or after a parse.</p>
177      *
178      * <p>Implementors are free (and encouraged) to invent their own properties,
179      * using names built on their own URIs.</p>
180      *
181      * @param name The property name, which is a fully-qualified URI.
182      * @return The current value of the property.
183      * @exception org.xml.sax.SAXNotRecognizedException When the
184      * XMLReader does not recognize the property name.
185      * @exception org.xml.sax.SAXNotSupportedException When the
186      * XMLReader recognizes the property name but
187      * cannot determine its value at this time.
188      * @see #setProperty
189      */

190      
191     public Object JavaDoc getProperty (String JavaDoc name)
192     throws SAXNotRecognizedException, SAXNotSupportedException {
193         if (name.equals("http://xml.org/sax/properties/lexical-handler")) {
194             return lexicalHandler;
195         } else {
196             throw new SAXNotRecognizedException(name);
197         }
198     }
199
200
201     /**
202      * Set the value of a property.
203      *
204      * <p>The property name is any fully-qualified URI. It is
205      * possible for an XMLReader to recognize a property name but
206      * to be unable to set its value; this is especially true
207      * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
208      * Parser}.</p>
209      *
210      * <p>XMLReaders are not required to recognize setting
211      * any specific property names, though a core set is provided with
212      * SAX2.</p>
213      *
214      * <p>Some property values may be immutable or mutable only
215      * in specific contexts, such as before, during, or after
216      * a parse.</p>
217      *
218      * <p>This method is also the standard mechanism for setting
219      * extended handlers.</p>
220      *
221      * @param name The property name, which is a fully-qualified URI.
222      * @param state The requested value for the property.
223      * @exception org.xml.sax.SAXNotRecognizedException When the
224      * XMLReader does not recognize the property name.
225      * @exception org.xml.sax.SAXNotSupportedException When the
226      * XMLReader recognizes the property name but
227      * cannot set the requested value.
228      */

229      
230     public void setProperty (String JavaDoc name, Object JavaDoc value)
231     throws SAXNotRecognizedException, SAXNotSupportedException {
232         if (name.equals("http://xml.org/sax/properties/lexical-handler")) {
233             if (value instanceof LexicalHandler) {
234                 lexicalHandler = (LexicalHandler)value;
235             } else {
236                 throw new SAXNotSupportedException(
237                     "Lexical Handler must be instance of org.xml.sax.ext.LexicalHandler");
238             }
239         } else {
240             throw new SAXNotRecognizedException(name);
241         }
242     }
243     
244     /**
245     * Register a content handler to receive the output of the transformation
246     * filter. If the content handler is also a LexicalHandler, and if no LexicalHandler
247     * is separately registered, the ContentHandler will also act as the LexicalHandler
248     */

249     
250     public void setContentHandler(ContentHandler handler) {
251         contentHandler = handler;
252         if (handler instanceof LexicalHandler && lexicalHandler==null) {
253             lexicalHandler = (LexicalHandler)handler;
254         }
255     }
256     
257     /**
258     * Get the ContentHandler registered using setContentHandler()
259     */

260     
261     public ContentHandler getContentHandler() {
262         return contentHandler;
263     }
264     
265
266     /**
267      * Allow an application to register an entity resolver.
268      *
269      * <p>If the application does not register an entity resolver,
270      * the XMLReader will perform its own default resolution.</p>
271      *
272      * <p>Applications may register a new or different resolver in the
273      * middle of a parse, and the SAX parser must begin using the new
274      * resolver immediately.</p>
275      *
276      * @param resolver The entity resolver.
277      * @exception java.lang.NullPointerException If the resolver
278      * argument is null.
279      * @see #getEntityResolver
280      */

281      
282     public void setEntityResolver (EntityResolver resolver) {
283         // XSLT output does not use entities, so the resolver is never used
284
}
285
286
287     /**
288      * Return the current entity resolver.
289      *
290      * @return Always null, since no entity resolver is used even if one
291      * is supplied.
292      * @see #setEntityResolver
293      */

294
295     public EntityResolver getEntityResolver () {
296         return null;
297     }
298
299
300     /**
301      * Allow an application to register a DTD event handler.
302      *
303      * <p>If the application does not register a DTD handler, all DTD
304      * events reported by the SAX parser will be silently ignored.</p>
305      *
306      * <p>Applications may register a new or different handler in the
307      * middle of a parse, and the SAX parser must begin using the new
308      * handler immediately.</p>
309      *
310      * @param handler The DTD handler.
311      * @exception java.lang.NullPointerException If the handler
312      * argument is null.
313      * @see #getDTDHandler
314      */

315      
316     public void setDTDHandler (DTDHandler handler) {
317         // XSLT output does not include a DTD
318
}
319
320
321     /**
322      * Return the current DTD handler.
323      *
324      * @return Always null, since no DTD handler is used even if one has been
325      * supplied.
326      * @see #setDTDHandler
327      */

328      
329     public DTDHandler getDTDHandler () {
330         return null;
331     }
332
333
334
335     /**
336      * Allow an application to register an error event handler.
337      *
338      * <p>If the application does not register an error handler, all
339      * error events reported by the SAX parser will be silently
340      * ignored; however, normal processing may not continue. It is
341      * highly recommended that all SAX applications implement an
342      * error handler to avoid unexpected bugs.</p>
343      *
344      * <p>Applications may register a new or different handler in the
345      * middle of a parse, and the SAX parser must begin using the new
346      * handler immediately.</p>
347      *
348      * @param handler The error handler.
349      * @exception java.lang.NullPointerException If the handler
350      * argument is null.
351      * @see #getErrorHandler
352      */

353      
354     public void setErrorHandler (ErrorHandler handler) {
355         // No effect
356
}
357
358     /**
359      * Return the current error handler.
360      *
361      * @return The current error handler, or null if none
362      * has been registered.
363      * @see #setErrorHandler
364      */

365     public ErrorHandler getErrorHandler () {
366         return null;
367     }
368
369     /**
370      * "Parse an XML document." In the context of a Transformer, this means
371      * perform a transformation. The method is equivalent to transform().
372      *
373      * @param source The input source (the XML document to be transformed)
374      * @exception org.xml.sax.SAXException Any SAX exception, possibly
375      * wrapping another exception.
376      * @exception java.io.IOException An IO exception from the parser,
377      * possibly from a byte stream or character stream
378      * supplied by the application.
379      * @see org.xml.sax.InputSource
380      * @see #parse(java.lang.String)
381      * @see #setEntityResolver
382      * @see #setDTDHandler
383      * @see #setContentHandler
384      * @see #setErrorHandler
385      */

386      
387     public void parse (InputSource input) throws IOException JavaDoc, SAXException {
388         if (parser==null) {
389             try {
390                 parser = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
391             } catch (Exception JavaDoc err) {
392                 throw new SAXException(err);
393             }
394         }
395         SAXSource source = new SAXSource();
396         source.setInputSource(input);
397         source.setXMLReader(parser);
398         ContentHandlerProxy result = new ContentHandlerProxy();
399         result.setUnderlyingContentHandler(contentHandler);
400         if (lexicalHandler!=null) {
401             result.setLexicalHandler(lexicalHandler);
402         }
403         try {
404             controller.transform(source, result);
405         } catch (TransformerException err) {
406             Throwable JavaDoc cause = err.getException();
407             if (cause != null && cause instanceof SAXException) {
408                 throw (SAXException)cause;
409             } else if (cause != null && cause instanceof IOException JavaDoc) {
410                 throw (IOException JavaDoc)cause;
411             } else {
412                 throw new SAXException(err);
413             }
414         }
415                 
416             
417     }
418
419     /**
420      * Parse (i.e. transform) an XML document from a system identifier (URI).
421      *
422      * <p>This method is a shortcut for the common case of reading a
423      * document from a system identifier. It is the exact
424      * equivalent of the following:</p>
425      *
426      * <pre>
427      * parse(new InputSource(systemId));
428      * </pre>
429      *
430      * <p>If the system identifier is a URL, it must be fully resolved
431      * by the application before it is passed to the parser.</p>
432      *
433      * @param systemId The system identifier (URI).
434      * @exception org.xml.sax.SAXException Any SAX exception, possibly
435      * wrapping another exception.
436      * @exception java.io.IOException An IO exception from the parser,
437      * possibly from a byte stream or character stream
438      * supplied by the application.
439      * @see #parse(org.xml.sax.InputSource)
440      */

441      
442     public void parse (String JavaDoc systemId) throws IOException JavaDoc, SAXException {
443         InputSource input = new InputSource(systemId);
444         parse(input);
445     }
446
447
448
449 }
450
451 //
452
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
453
// you may not use this file except in compliance with the License. You may obtain a copy of the
454
// License at http://www.mozilla.org/MPL/
455
//
456
// Software distributed under the License is distributed on an "AS IS" basis,
457
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
458
// See the License for the specific language governing rights and limitations under the License.
459
//
460
// The Original Code is: all this file.
461
//
462
// The Initial Developer of the Original Code is
463
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
464
//
465
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
466
//
467
// Contributor(s): None
468
//
469
Popular Tags