added Jelly
[org.ibex.jetty.git] / src / org / ibex / jetty / Jelly.java
1 /*\r
2  * Copyright 2002,2004 The Apache Software Foundation.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package org.ibex.jetty;\r
18 \r
19 import org.apache.commons.jelly.JellyContext;\r
20 import javax.servlet.ServletContext;\r
21 import java.io.*;\r
22 import java.net.*;\r
23 \r
24 import java.io.IOException;\r
25 import java.io.PrintWriter;\r
26 import java.io.StringWriter;\r
27 import java.io.UnsupportedEncodingException;\r
28 import java.net.MalformedURLException;\r
29 import java.net.URL;\r
30 \r
31 import javax.servlet.ServletException;\r
32 import javax.servlet.ServletOutputStream;\r
33 import javax.servlet.http.HttpServlet;\r
34 import javax.servlet.http.HttpServletRequest;\r
35 import javax.servlet.http.HttpServletResponse;\r
36 \r
37 import org.apache.commons.jelly.JellyContext;\r
38 import org.apache.commons.jelly.JellyException;\r
39 import org.apache.commons.jelly.XMLOutput;\r
40 \r
41 /**\r
42  * Servlet for handling display of Jelly-fied XML files. Modelled after VelocityServlet.\r
43  *\r
44  * @author Kelvin Tan\r
45  * @version $Revision: 1.7 $\r
46  */\r
47 public class Jelly extends HttpServlet {\r
48     /**\r
49      * The HTTP request object context key.\r
50      */\r
51     public static final String REQUEST = "request";\r
52 \r
53     /**\r
54      * The HTTP response object context key.\r
55      */\r
56     public static final String RESPONSE = "response";\r
57 \r
58     protected void doGet(\r
59         HttpServletRequest request,\r
60         HttpServletResponse response)\r
61         throws ServletException, IOException {\r
62 \r
63         doRequest(request, response);\r
64     }\r
65 \r
66     protected void doPost(\r
67         HttpServletRequest request,\r
68         HttpServletResponse response)\r
69         throws ServletException, IOException {\r
70 \r
71         doRequest(request, response);\r
72     }\r
73 \r
74     /**\r
75      * Handles all requests\r
76      * @param req HttpServletRequest object containing client request\r
77      * @param res HttpServletResponse object for the response\r
78      * @throws ServletException\r
79      * @throws IOException\r
80      */\r
81     protected void doRequest(HttpServletRequest req, HttpServletResponse res)\r
82         throws ServletException, IOException {\r
83 \r
84         JellyContext context = createContext(req, res);\r
85         try {\r
86             URL script = getScript(req);\r
87             runScript(script, context, req, res);\r
88         }\r
89         catch (Exception e) {\r
90             error(req, res, e);\r
91         }\r
92     }\r
93 \r
94     /**\r
95      * @see org.apache.velocity.servlet.VelocityServlet#createContext\r
96      * @param req\r
97      * @param res\r
98      * @return\r
99      */\r
100     protected JellyContext createContext(\r
101         HttpServletRequest req,\r
102         HttpServletResponse res) {\r
103 \r
104         JellyContext ctx = new JellyServletContext(getServletContext());\r
105         ctx.setVariable(REQUEST, req);\r
106         ctx.setVariable(RESPONSE, res);\r
107         return ctx;\r
108     }\r
109 \r
110     /**\r
111      * <p>\r
112      * Either use the query parameter "script", or the URI itself\r
113      * to denote the script to run.\r
114      * </p>\r
115      * <p>\r
116      * Example: script=index.jelly or http://localhost:8080/foo/index.jelly.\r
117      * </p>\r
118      *\r
119      * @see org.apache.velocity.servlet.VelocityServlet#getTemplate\r
120      * @param req\r
121      * @return\r
122      * @throws MalformedURLException\r
123      */\r
124     protected URL getScript(HttpServletRequest req) throws MalformedURLException {\r
125         return new URL("file:" + new File(getServletContext().getRealPath(req.getServletPath())).getAbsolutePath());\r
126     }\r
127 \r
128     /**\r
129      * @see org.apache.velocity.servlet.VelocityServlet#mergeTemplate\r
130      * @param script\r
131      * @param context\r
132      * @param req\r
133      * @param res\r
134      * @throws IOException\r
135      * @throws UnsupportedEncodingException\r
136      * @throws JellyException\r
137      */\r
138     protected void runScript(\r
139         URL script,\r
140         JellyContext context,\r
141         HttpServletRequest req,\r
142         HttpServletResponse res)\r
143         throws IOException, UnsupportedEncodingException, JellyException {\r
144 \r
145         ServletOutputStream output = res.getOutputStream();\r
146         XMLOutput xmlOutput = XMLOutput.createXMLOutput(output);\r
147         context.runScript(script, xmlOutput);\r
148         xmlOutput.flush();\r
149         xmlOutput.close();\r
150         output.flush();\r
151     }\r
152 \r
153     /**\r
154      * Invoked when there is an error thrown in any part of doRequest() processing.\r
155      * <br><br>\r
156      * Default will send a simple HTML response indicating there was a problem.\r
157      *<br><br>\r
158      * Ripped from VelocityServlet.\r
159      *\r
160      * @param request original HttpServletRequest from servlet container.\r
161      * @param response HttpServletResponse object from servlet container.\r
162      * @param cause  Exception that was thrown by some other part of process.\r
163      */\r
164     protected void error(\r
165         HttpServletRequest request,\r
166         HttpServletResponse response,\r
167         Exception cause)\r
168         throws ServletException, IOException {\r
169 \r
170         StringBuffer html = new StringBuffer();\r
171         html.append("<html>");\r
172         html.append("<title>Error</title>");\r
173         html.append("<body bgcolor=\"#ffffff\">");\r
174         html.append("<h2>JellyServlet : Error processing the script</h2>");\r
175         html.append("<pre>");\r
176         String why = cause.getMessage();\r
177         if (why != null && why.trim().length() > 0) {\r
178             html.append(why);\r
179             html.append("<br>");\r
180         }\r
181 \r
182         StringWriter sw = new StringWriter();\r
183         cause.printStackTrace(new PrintWriter(sw));\r
184 \r
185         html.append(sw.toString());\r
186         html.append("</pre>");\r
187         html.append("</body>");\r
188         html.append("</html>");\r
189         response.getOutputStream().print(html.toString());\r
190     }\r
191 \r
192 \r
193 /**\r
194  *\r
195  * @author <a href="mailto:kelvint@apache.org">Kelvin Tan</a>\r
196  * @version 1.1\r
197  */\r
198 public static class JellyServletContext extends JellyContext {\r
199 \r
200     private ServletContext ctx;\r
201 \r
202     public JellyServletContext() {\r
203         init();\r
204     }\r
205 \r
206     public JellyServletContext(ServletContext ctx) {\r
207         super();\r
208         this.ctx = ctx;\r
209         init();\r
210     }\r
211 \r
212     public JellyServletContext(JellyContext parent, ServletContext ctx) {\r
213         super(parent);\r
214         this.ctx = ctx;\r
215         init();\r
216     }\r
217 \r
218     private void init() {\r
219         registerTagLibrary("jelly:core", "org.apache.commons.jelly.tags.core.CoreTagLibrary");\r
220     }\r
221 \r
222     /**\r
223      * Allow access of relative URIs when performing &lt;j:include&gt;.\r
224      * @param s\r
225      * @return\r
226      * @throws MalformedURLException\r
227      */\r
228     public URL getResource(String s) throws MalformedURLException {\r
229         System.err.println("getResource(s)");\r
230         return ctx.getResource(s);\r
231     }\r
232 \r
233     /**\r
234      * Allow access of relative URIs when performing &lt;j:include&gt;.\r
235      * @param s\r
236      * @return\r
237      */\r
238     public InputStream getResourceAsStream(String s) {\r
239         return ctx.getResourceAsStream(s);\r
240     }\r
241 \r
242     protected JellyContext createChildContext()\r
243     {\r
244         return new JellyServletContext(this, ctx);\r
245     }\r
246 }\r
247 \r
248 }\r