KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > taglibs > standard > tag > common > xml > ParseSupport


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.taglibs.standard.tag.common.xml;
18
19 import java.io.FileNotFoundException JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.Reader JavaDoc;
23 import java.io.StringReader JavaDoc;
24
25 import javax.servlet.http.HttpServletRequest JavaDoc;
26 import javax.servlet.jsp.JspException JavaDoc;
27 import javax.servlet.jsp.JspTagException JavaDoc;
28 import javax.servlet.jsp.PageContext JavaDoc;
29 import javax.servlet.jsp.tagext.BodyTagSupport JavaDoc;
30 import javax.xml.parsers.DocumentBuilder JavaDoc;
31 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
32 import javax.xml.parsers.ParserConfigurationException JavaDoc;
33 import javax.xml.transform.TransformerConfigurationException JavaDoc;
34 import javax.xml.transform.TransformerFactory JavaDoc;
35 import javax.xml.transform.dom.DOMResult JavaDoc;
36 import javax.xml.transform.sax.SAXTransformerFactory JavaDoc;
37 import javax.xml.transform.sax.TransformerHandler JavaDoc;
38
39 import org.apache.taglibs.standard.resources.Resources;
40 import org.apache.taglibs.standard.tag.common.core.ImportSupport;
41 import org.apache.taglibs.standard.tag.common.core.Util;
42 import org.w3c.dom.Document JavaDoc;
43 import org.xml.sax.EntityResolver JavaDoc;
44 import org.xml.sax.InputSource JavaDoc;
45 import org.xml.sax.SAXException JavaDoc;
46 import org.xml.sax.XMLFilter JavaDoc;
47 import org.xml.sax.XMLReader JavaDoc;
48 import org.xml.sax.helpers.XMLReaderFactory JavaDoc;
49
50 /**
51  * <p>Support for tag handlers for &lt;parse&gt;, the XML parsing tag.</p>
52  *
53  * @author Shawn Bayern
54  */

55 public abstract class ParseSupport extends BodyTagSupport JavaDoc {
56
57     //*********************************************************************
58
// Protected state
59

60     protected Object JavaDoc xml; // 'xml' attribute
61
protected String JavaDoc systemId; // 'systemId' attribute
62
protected XMLFilter JavaDoc filter; // 'filter' attribute
63

64     //*********************************************************************
65
// Private state
66

67     private String JavaDoc var; // 'var' attribute
68
private String JavaDoc varDom; // 'varDom' attribute
69
private int scope; // processed 'scope' attr
70
private int scopeDom; // processed 'scopeDom' attr
71

72     // state in support of XML parsing...
73
private DocumentBuilderFactory JavaDoc dbf;
74     private DocumentBuilder JavaDoc db;
75     private TransformerFactory JavaDoc tf;
76     private TransformerHandler JavaDoc th;
77
78
79     //*********************************************************************
80
// Constructor and initialization
81

82     public ParseSupport() {
83     super();
84     init();
85     }
86
87     private void init() {
88     var = varDom = null;
89     xml = null;
90     systemId = null;
91     filter = null;
92     dbf = null;
93     db = null;
94     tf = null;
95     th = null;
96     scope = PageContext.PAGE_SCOPE;
97     scopeDom = PageContext.PAGE_SCOPE;
98     }
99
100
101     //*********************************************************************
102
// Tag logic
103

104     // parse 'source' or body, storing result in 'var'
105
public int doEndTag() throws JspException JavaDoc {
106       try {
107     
108     // set up our DocumentBuilder
109
if (dbf == null) {
110             dbf = DocumentBuilderFactory.newInstance();
111             dbf.setNamespaceAware(true);
112             dbf.setValidating(false);
113         }
114         db = dbf.newDocumentBuilder();
115
116     // if we've gotten a filter, set up a transformer to support it
117
if (filter != null) {
118             if (tf == null)
119                 tf = TransformerFactory.newInstance();
120             if (!tf.getFeature(SAXTransformerFactory.FEATURE))
121                 throw new JspTagException JavaDoc(
122             Resources.getMessage("PARSE_NO_SAXTRANSFORMER"));
123             SAXTransformerFactory JavaDoc stf = (SAXTransformerFactory JavaDoc) tf;
124             th = stf.newTransformerHandler();
125     }
126
127     // produce a Document by parsing whatever the attributes tell us to use
128
Document JavaDoc d;
129     Object JavaDoc xmlText = this.xml;
130     if (xmlText == null) {
131         // if the attribute was specified, use the body as 'xml'
132
if (bodyContent != null && bodyContent.getString() != null)
133         xmlText = bodyContent.getString().trim();
134         else
135         xmlText = "";
136     }
137     if (xmlText instanceof String JavaDoc)
138         d = parseStringWithFilter((String JavaDoc) xmlText, filter);
139     else if (xmlText instanceof Reader JavaDoc)
140         d = parseReaderWithFilter((Reader JavaDoc) xmlText, filter);
141     else
142         throw new JspTagException JavaDoc(
143             Resources.getMessage("PARSE_INVALID_SOURCE"));
144
145     // we've got a Document object; store it out as appropriate
146
// (let any exclusivity or other constraints be enforced by TEI/TLV)
147
if (var != null)
148         pageContext.setAttribute(var, d, scope);
149     if (varDom != null)
150         pageContext.setAttribute(varDom, d, scopeDom);
151
152     return EVAL_PAGE;
153       } catch (SAXException JavaDoc ex) {
154     throw new JspException JavaDoc(ex);
155       } catch (IOException JavaDoc ex) {
156     throw new JspException JavaDoc(ex);
157       } catch (ParserConfigurationException JavaDoc ex) {
158     throw new JspException JavaDoc(ex);
159       } catch (TransformerConfigurationException JavaDoc ex) {
160     throw new JspException JavaDoc(ex);
161       }
162     }
163
164     // Releases any resources we may have (or inherit)
165
public void release() {
166     init();
167     }
168
169
170     //*********************************************************************
171
// Private utility methods
172

173     /** Parses the given InputSource after, applying the given XMLFilter. */
174     private Document JavaDoc parseInputSourceWithFilter(InputSource JavaDoc s, XMLFilter JavaDoc f)
175             throws SAXException JavaDoc, IOException JavaDoc {
176     if (f != null) {
177             // prepare an output Document
178
Document JavaDoc o = db.newDocument();
179
180             // use TrAX to adapt SAX events to a Document object
181
th.setResult(new DOMResult JavaDoc(o));
182             XMLReader JavaDoc xr = XMLReaderFactory.createXMLReader();
183         xr.setEntityResolver(new JstlEntityResolver(pageContext));
184             // (note that we overwrite the filter's parent. this seems
185
// to be expected usage. we could cache and reset the old
186
// parent, but you can't setParent(null), so this wouldn't
187
// be perfect.)
188
f.setParent(xr);
189             f.setContentHandler(th);
190             f.parse(s);
191             return o;
192     } else
193         return parseInputSource(s);
194     }
195
196     /** Parses the given Reader after applying the given XMLFilter. */
197     private Document JavaDoc parseReaderWithFilter(Reader JavaDoc r, XMLFilter JavaDoc f)
198             throws SAXException JavaDoc, IOException JavaDoc {
199     return parseInputSourceWithFilter(new InputSource JavaDoc(r), f);
200     }
201
202     /** Parses the given String after applying the given XMLFilter. */
203     private Document JavaDoc parseStringWithFilter(String JavaDoc s, XMLFilter JavaDoc f)
204             throws SAXException JavaDoc, IOException JavaDoc {
205         StringReader JavaDoc r = new StringReader JavaDoc(s);
206         return parseReaderWithFilter(r, f);
207     }
208
209     /** Parses the given Reader after applying the given XMLFilter. */
210     private Document JavaDoc parseURLWithFilter(String JavaDoc url, XMLFilter JavaDoc f)
211             throws SAXException JavaDoc, IOException JavaDoc {
212     return parseInputSourceWithFilter(new InputSource JavaDoc(url), f);
213     }
214
215     /** Parses the given InputSource into a Document. */
216     private Document JavaDoc parseInputSource(InputSource JavaDoc s)
217         throws SAXException JavaDoc, IOException JavaDoc {
218     db.setEntityResolver(new JstlEntityResolver(pageContext));
219
220         // normalize URIs so they can be processed consistently by resolver
221
if (systemId == null)
222             s.setSystemId("jstl:");
223     else if (ImportSupport.isAbsoluteUrl(systemId))
224             s.setSystemId(systemId);
225         else
226             s.setSystemId("jstl:" + systemId);
227     return db.parse(s);
228     }
229
230     /** Parses the given Reader into a Document. */
231     private Document JavaDoc parseReader(Reader JavaDoc r) throws SAXException JavaDoc, IOException JavaDoc {
232         return parseInputSource(new InputSource JavaDoc(r));
233     }
234
235     /** Parses the given String into a Document. */
236     private Document JavaDoc parseString(String JavaDoc s) throws SAXException JavaDoc, IOException JavaDoc {
237         StringReader JavaDoc r = new StringReader JavaDoc(s);
238         return parseReader(r);
239     }
240
241     /** Parses the URL (passed as a String) into a Document. */
242     private Document JavaDoc parseURL(String JavaDoc url) throws SAXException JavaDoc, IOException JavaDoc {
243     return parseInputSource(new InputSource JavaDoc(url));
244     }
245
246     //*********************************************************************
247
// JSTL-specific EntityResolver class
248

249     /** Lets us resolve relative external entities. */
250     public static class JstlEntityResolver implements EntityResolver JavaDoc {
251     private final PageContext JavaDoc ctx;
252         public JstlEntityResolver(PageContext JavaDoc ctx) {
253             this.ctx = ctx;
254         }
255         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
256             throws FileNotFoundException JavaDoc {
257
258         // pass if we don't have a systemId
259
if (systemId == null)
260         return null;
261
262         // strip leading "jstl:" off URL if applicable
263
if (systemId.startsWith("jstl:"))
264         systemId = systemId.substring(5);
265
266         // we're only concerned with relative URLs
267
if (ImportSupport.isAbsoluteUrl(systemId))
268         return null;
269
270         // for relative URLs, load and wrap the resource.
271
// don't bother checking for 'null' since we specifically want
272
// the parser to fail if the resource doesn't exist
273
InputStream JavaDoc s;
274         if (systemId.startsWith("/")) {
275             s = ctx.getServletContext().getResourceAsStream(systemId);
276             if (s == null)
277             throw new FileNotFoundException JavaDoc(
278             Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
279              systemId));
280         } else {
281         String JavaDoc pagePath =
282             ((HttpServletRequest JavaDoc) ctx.getRequest()).getServletPath();
283         String JavaDoc basePath =
284             pagePath.substring(0, pagePath.lastIndexOf("/"));
285         s = ctx.getServletContext().getResourceAsStream(
286               basePath + "/" + systemId);
287             if (s == null)
288             throw new FileNotFoundException JavaDoc(
289             Resources.getMessage("UNABLE_TO_RESOLVE_ENTITY",
290              systemId));
291         }
292         return new InputSource JavaDoc(s);
293         }
294     }
295
296     //*********************************************************************
297
// Tag attributes
298

299     public void setVar(String JavaDoc var) {
300     this.var = var;
301     }
302
303     public void setVarDom(String JavaDoc varDom) {
304     this.varDom = varDom;
305     }
306
307     public void setScope(String JavaDoc scope) {
308     this.scope = Util.getScope(scope);
309     }
310
311     public void setScopeDom(String JavaDoc scopeDom) {
312     this.scopeDom = Util.getScope(scopeDom);
313     }
314 }
315
Popular Tags