View Javadoc

1   package org.portletbridge.xsl;
2   
3   import java.io.IOException;
4   import java.util.Iterator;
5   import java.util.Map;
6   
7   import javax.xml.transform.ErrorListener;
8   import javax.xml.transform.Templates;
9   import javax.xml.transform.TransformerConfigurationException;
10  import javax.xml.transform.TransformerFactory;
11  import javax.xml.transform.sax.SAXResult;
12  import javax.xml.transform.sax.SAXSource;
13  import javax.xml.transform.sax.SAXTransformerFactory;
14  import javax.xml.transform.sax.TransformerHandler;
15  
16  import org.xml.sax.ContentHandler;
17  import org.xml.sax.DTDHandler;
18  import org.xml.sax.EntityResolver;
19  import org.xml.sax.InputSource;
20  import org.xml.sax.XMLReader;
21  import org.xml.sax.helpers.XMLFilterImpl;
22  import org.xml.sax.helpers.XMLReaderFactory;
23  
24  public class XslFilter extends XMLFilterImpl {
25  
26      private Templates templates;
27  
28      private TransformerHandler transformerHandler;
29  
30      private Map context = null;
31  
32      /***
33       * Construct an empty XML filter, with no parent.
34       * 
35       * <p>
36       * This filter will have no parent: you must assign a parent before you
37       * start a parse or do any configuration with setFeature or setProperty.
38       * </p>
39       * 
40       * @see org.xml.sax.XMLReader#setFeature
41       * @see org.xml.sax.XMLReader#setProperty
42       */
43      public XslFilter(Templates templates)
44              throws TransformerConfigurationException {
45          this.templates = templates;
46          // Use JAXP1.1 ( if possible )
47          try {
48              TransformerFactory tfactory = TransformerFactory.newInstance();
49              // Does this factory support SAX features?
50              if (tfactory.getFeature(SAXSource.FEATURE)) {
51                  // If so, we can safely cast.
52                  SAXTransformerFactory stfactory = ((SAXTransformerFactory) tfactory);
53                  transformerHandler = stfactory.newTransformerHandler(templates);
54              } else {
55                  throw new TransformerConfigurationException(
56                          "Can't do ChainedXslFilter because tfactory is not a SAXTransformerFactory");
57              }
58          } catch (javax.xml.parsers.FactoryConfigurationError ex1) {
59              throw new TransformerConfigurationException(ex1.toString());
60          }
61      }
62  
63      /***
64       * Set the parent reader.
65       * 
66       * <p>
67       * This is the {@link org.xml.sax.XMLReader XMLReader}from which this
68       * filter will obtain its events and to which it will pass its configuration
69       * requests. The parent may itself be another filter.
70       * </p>
71       * 
72       * <p>
73       * If there is no parent reader set, any attempt to parse or to set or get a
74       * feature or property will fail.
75       * </p>
76       * 
77       * @param parent
78       *            The parent XML reader.
79       * @throws java.lang.NullPointerException
80       *             If the parent is null.
81       */
82      public void setParent(XMLReader parent) {
83          super.setParent(parent);
84  
85          if (null != parent.getContentHandler())
86              this.setContentHandler(parent.getContentHandler());
87  
88          // Not really sure if we should do this here, but
89          // it seems safer in case someone calls parse() on
90          // the parent.
91          setupParse();
92      }
93  
94      /***
95       * Parse a document.
96       * 
97       * @param input
98       *            The input source for the document entity.
99       * @throws org.xml.sax.SAXException
100      *             Any SAX exception, possibly wrapping another exception.
101      * @throws java.io.IOException
102      *             An IO exception from the parser, possibly from a byte stream
103      *             or character stream supplied by the application.
104      * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
105      */
106     public void parse(InputSource input) throws org.xml.sax.SAXException,
107             IOException {
108         if (null == getParent()) {
109             XMLReader reader = null;
110 
111             // Use JAXP1.1 ( if possible )
112             try {
113                 javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory
114                         .newInstance();
115                 factory.setNamespaceAware(true);
116                 javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();
117                 reader = jaxpParser.getXMLReader();
118 
119             } catch (javax.xml.parsers.ParserConfigurationException ex) {
120                 throw new org.xml.sax.SAXException(ex);
121             } catch (javax.xml.parsers.FactoryConfigurationError ex1) {
122                 throw new org.xml.sax.SAXException(ex1.toString());
123             } catch (NoSuchMethodError ex2) {
124             } catch (AbstractMethodError ame) {
125             }
126 
127             XMLReader parent;
128             if (reader == null)
129                 parent = XMLReaderFactory.createXMLReader();
130             else
131                 parent = reader;
132             try {
133                 parent.setFeature(
134                         "http://xml.org/sax/features/namespace-prefixes", true);
135             } catch (org.xml.sax.SAXException se) {
136             }
137             // setParent calls setupParse...
138             setParent(parent);
139         } else {
140             // Make sure everything is set up.
141             setupParse();
142         }
143 
144         if (context != null) {
145             for (Iterator iter = context.entrySet().iterator(); iter.hasNext();) {
146                 Map.Entry entry = (Map.Entry) iter.next();
147                 transformerHandler.getTransformer().setParameter(
148                         (String) entry.getKey(), entry.getValue());
149             }
150         }
151 
152         //    final ErrorListener errorListener =
153         // transformerHandler.getTransformer().getErrorListener();
154         //    transformerHandler.getTransformer().setErrorListener(new
155         // ErrorListener() {
156         //        public void error(TransformerException exception)
157         //                throws TransformerException {
158         //            if(errorListener != null) {
159         //                errorListener.error(exception);
160         //            }
161         //        }
162         //
163         //        public void fatalError(TransformerException exception)
164         //                throws TransformerException {
165         //            if(errorListener != null) {
166         //                errorListener.fatalError(exception);
167         //            }
168         //        }
169         //
170         //        public void warning(TransformerException exception)
171         //                throws TransformerException {
172         //            if(errorListener != null) {
173         //                errorListener.warning(exception);
174         //            }
175         //        }
176         //    });
177 
178         getParent().parse(input);
179 
180         //    Exception e =
181         // transformerHandler.getTransformer().getExceptionThrown();
182         //    if(null != e)
183         //    {
184         //      if(e instanceof org.xml.sax.SAXException)
185         //        throw (org.xml.sax.SAXException)e;
186         //      else
187         //        throw new org.xml.sax.SAXException(e);
188         //    }
189 
190     }
191 
192     /***
193      * Parse a document.
194      * 
195      * @param systemId
196      *            The system identifier as a fully-qualified URI.
197      * @throws org.xml.sax.SAXException
198      *             Any SAX exception, possibly wrapping another exception.
199      * @throws java.io.IOException
200      *             An IO exception from the parser, possibly from a byte stream
201      *             or character stream supplied by the application.
202      * @see org.xml.sax.XMLReader#parse(java.lang.String)
203      */
204     public void parse(String systemId) throws org.xml.sax.SAXException,
205             IOException {
206         parse(new InputSource(systemId));
207     }
208 
209     /***
210      * Set up before a parse.
211      * 
212      * <p>
213      * Before every parse, check whether the parent is non-null, and re-register
214      * the filter for all of the events.
215      * </p>
216      */
217     private void setupParse() {
218         XMLReader p = getParent();
219         if (p == null) {
220             throw new NullPointerException("No parent for filter");
221         }
222 
223         ContentHandler ch = transformerHandler;
224         //    if(ch instanceof SourceTreeHandler)
225         //      ((SourceTreeHandler)ch).setUseMultiThreading(true);
226         p.setContentHandler(ch);
227 
228         if (ch instanceof EntityResolver)
229             p.setEntityResolver((EntityResolver) ch);
230         else
231             p.setEntityResolver(this);
232 
233         if (ch instanceof DTDHandler)
234             p.setDTDHandler((DTDHandler) ch);
235         else
236             p.setDTDHandler(this);
237 
238         ErrorListener elistener = transformerHandler.getTransformer()
239                 .getErrorListener();
240         if ((null != elistener)
241                 && (elistener instanceof org.xml.sax.ErrorHandler))
242             p.setErrorHandler((org.xml.sax.ErrorHandler) elistener);
243         else
244             p.setErrorHandler(this);
245     }
246 
247     /***
248      * Set the content event handler.
249      * 
250      * @param resolver
251      *            The new content handler.
252      * @throws java.lang.NullPointerException
253      *             If the handler is null.
254      * @see org.xml.sax.XMLReader#setContentHandler
255      */
256     public void setContentHandler(ContentHandler handler) {
257         transformerHandler.setResult(new SAXResult(handler));
258     }
259 
260     public void setErrorListener(ErrorListener handler) {
261         transformerHandler.getTransformer().setErrorListener(handler);
262     }
263 
264     public Map getContext() {
265         return context;
266     }
267 
268     public void setContext(Map context) {
269         this.context = context;
270     }
271 }