001: /*
002: * Copyright 2002,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.commons.jelly.servlet;
018:
019: import java.io.IOException;
020: import java.io.PrintWriter;
021: import java.io.StringWriter;
022: import java.io.UnsupportedEncodingException;
023: import java.net.MalformedURLException;
024: import java.net.URL;
025:
026: import javax.servlet.ServletException;
027: import javax.servlet.ServletOutputStream;
028: import javax.servlet.http.HttpServlet;
029: import javax.servlet.http.HttpServletRequest;
030: import javax.servlet.http.HttpServletResponse;
031:
032: import org.apache.commons.jelly.JellyContext;
033: import org.apache.commons.jelly.JellyException;
034: import org.apache.commons.jelly.XMLOutput;
035:
036: /**
037: * Servlet for handling display of Jelly-fied XML files. Modelled after VelocityServlet.
038: *
039: * @author Kelvin Tan
040: * @version $Revision: 155420 $
041: */
042: public class JellyServlet extends HttpServlet {
043: /**
044: * The HTTP request object context key.
045: */
046: public static final String REQUEST = "request";
047:
048: /**
049: * The HTTP response object context key.
050: */
051: public static final String RESPONSE = "response";
052:
053: protected void doGet(HttpServletRequest request,
054: HttpServletResponse response) throws ServletException,
055: IOException {
056:
057: doRequest(request, response);
058: }
059:
060: protected void doPost(HttpServletRequest request,
061: HttpServletResponse response) throws ServletException,
062: IOException {
063:
064: doRequest(request, response);
065: }
066:
067: /**
068: * Handles all requests
069: * @param req HttpServletRequest object containing client request
070: * @param res HttpServletResponse object for the response
071: * @throws ServletException
072: * @throws IOException
073: */
074: protected void doRequest(HttpServletRequest req,
075: HttpServletResponse res) throws ServletException,
076: IOException {
077:
078: JellyContext context = createContext(req, res);
079: try {
080: URL script = getScript(req);
081: runScript(script, context, req, res);
082: } catch (Exception e) {
083: error(req, res, e);
084: }
085: }
086:
087: /**
088: * @see org.apache.velocity.servlet.VelocityServlet#createContext
089: * @param req
090: * @param res
091: * @return
092: */
093: protected JellyContext createContext(HttpServletRequest req,
094: HttpServletResponse res) {
095:
096: JellyContext ctx = new JellyServletContext(getServletContext());
097: ctx.setVariable(REQUEST, req);
098: ctx.setVariable(RESPONSE, res);
099: return ctx;
100: }
101:
102: /**
103: * <p>
104: * Either use the query parameter "script", or the URI itself
105: * to denote the script to run.
106: * </p>
107: * <p>
108: * Example: script=index.jelly or http://localhost:8080/foo/index.jelly.
109: * </p>
110: *
111: * @see org.apache.velocity.servlet.VelocityServlet#getTemplate
112: * @param req
113: * @return
114: * @throws MalformedURLException
115: */
116: protected URL getScript(HttpServletRequest req)
117: throws MalformedURLException {
118:
119: String scriptUrl = req.getParameter("script");
120: if (scriptUrl == null) {
121: scriptUrl = req.getPathInfo();
122: }
123: URL url = getServletContext().getResource(scriptUrl);
124: if (url == null) {
125: throw new IllegalArgumentException("Invalid script url:"
126: + scriptUrl);
127: }
128: return url;
129: }
130:
131: /**
132: * @see org.apache.velocity.servlet.VelocityServlet#mergeTemplate
133: * @param script
134: * @param context
135: * @param req
136: * @param res
137: * @throws IOException
138: * @throws UnsupportedEncodingException
139: * @throws JellyException
140: */
141: protected void runScript(URL script, JellyContext context,
142: HttpServletRequest req, HttpServletResponse res)
143: throws IOException, UnsupportedEncodingException,
144: JellyException {
145:
146: ServletOutputStream output = res.getOutputStream();
147: XMLOutput xmlOutput = XMLOutput.createXMLOutput(output);
148: context.runScript(script, xmlOutput);
149: xmlOutput.flush();
150: xmlOutput.close();
151: output.flush();
152: }
153:
154: /**
155: * Invoked when there is an error thrown in any part of doRequest() processing.
156: * <br><br>
157: * Default will send a simple HTML response indicating there was a problem.
158: *<br><br>
159: * Ripped from VelocityServlet.
160: *
161: * @param request original HttpServletRequest from servlet container.
162: * @param response HttpServletResponse object from servlet container.
163: * @param cause Exception that was thrown by some other part of process.
164: */
165: protected void error(HttpServletRequest request,
166: HttpServletResponse response, Exception cause)
167: throws ServletException, IOException {
168:
169: StringBuffer html = new StringBuffer();
170: html.append("<html>");
171: html.append("<title>Error</title>");
172: html.append("<body bgcolor=\"#ffffff\">");
173: html
174: .append("<h2>JellyServlet : Error processing the script</h2>");
175: html.append("<pre>");
176: String why = cause.getMessage();
177: if (why != null && why.trim().length() > 0) {
178: html.append(why);
179: html.append("<br>");
180: }
181:
182: StringWriter sw = new StringWriter();
183: cause.printStackTrace(new PrintWriter(sw));
184:
185: html.append(sw.toString());
186: html.append("</pre>");
187: html.append("</body>");
188: html.append("</html>");
189: response.getOutputStream().print(html.toString());
190: }
191: }
|