001 /*
002 * This file is part of the Echo Point Project. This project is a collection
003 * of Components that have extended the Echo Web Application Framework.
004 *
005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006 *
007 * The contents of this file are subject to the Mozilla Public License Version
008 * 1.1 (the "License"); you may not use this file except in compliance with
009 * the License. You may obtain a copy of the License at
010 * http://www.mozilla.org/MPL/
011 *
012 * Software distributed under the License is distributed on an "AS IS" basis,
013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014 * for the specific language governing rights and limitations under the
015 * License.
016 *
017 * Alternatively, the contents of this file may be used under the terms of
018 * either the GNU General Public License Version 2 or later (the "GPL"), or
019 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020 * in which case the provisions of the GPL or the LGPL are applicable instead
021 * of those above. If you wish to allow use of your version of this file only
022 * under the terms of either the GPL or the LGPL, and not to allow others to
023 * use your version of this file under the terms of the MPL, indicate your
024 * decision by deleting the provisions above and replace them with the notice
025 * and other provisions required by the GPL or the LGPL. If you do not delete
026 * the provisions above, a recipient may use your version of this file under
027 * the terms of any one of the MPL, the GPL or the LGPL.
028 */
029 package echopoint.template.ui;
030
031 import java.io.*;
032
033 import javax.servlet.Servlet;
034 import javax.servlet.ServletException;
035 import javax.servlet.http.HttpServletRequest;
036 import javax.servlet.http.HttpServletResponse;
037 import javax.servlet.jsp.JspFactory;
038 import javax.servlet.jsp.JspWriter;
039 import javax.servlet.jsp.PageContext;
040
041 import nextapp.echo.webcontainer.Connection;
042
043 import org.w3c.dom.Element;
044
045 import echopoint.template.JspTemplateDataSource;
046 import echopoint.template.TemplateDataSource;
047 import echopoint.util.io.CapturedHttpServletResponse;
048 import echopoint.util.throwable.ThrowableKit;
049
050 /**
051 * <code>JspXHTMLTemplateCompiler</code> can compile
052 * XHTML source template data from JSP page
053 * into a XHTML DO Element.
054 */
055
056 public class JspXHTMLTemplateCompiler extends XHTMLTemplateCompiler {
057
058 /**
059 * @see echopoint.template.ui.TemplateCompiler#compileTemplateDataIntoXHTML(nextapp.echo.webcontainer.Connection, echopoint.template.TemplateDataSource)
060 */
061 public Element compileTemplateDataIntoXHTML(Connection c, TemplateDataSource tds) throws Exception {
062 // we dont use the TDS input stream because it does know
063 // where to get the stream
064 InputStream inputStream = jspExecute(c,(JspTemplateDataSource) tds);
065 return compileXHTML(inputStream,tds);
066 }
067
068 public String templateDataAsString(Connection c, TemplateDataSource tds) throws Exception {
069 InputStream inputStream = jspExecute(c,(JspTemplateDataSource) tds);
070 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
071 StringBuilder sb = new StringBuilder();
072
073 String line = null;
074 try {
075 while ((line = reader.readLine()) != null) {
076 sb.append(line + "\n");
077 }
078 } finally {
079 inputStream.close();
080 }
081
082 return sb.toString();
083
084 }
085
086 /**
087 * Executes a JSP page for a given JspTemplateDataSource. The content
088 * of the JSP page is captured and is ready for XHTML parsing afterwards
089 *
090 * @param c - connection
091 * @param jspTemplateDataSource - datasource
092 * @return an InputStream of the captured JSP output
093 */
094 private InputStream jspExecute(Connection c, JspTemplateDataSource jspTemplateDataSource) {
095 String jspPath = jspTemplateDataSource.getJspPath();
096 Servlet servlet = c.getServlet();
097 HttpServletRequest request = c.getRequest();
098 HttpServletResponse wrappedResponse = c.getResponse();
099 CapturedHttpServletResponse response = new CapturedHttpServletResponse(wrappedResponse,jspTemplateDataSource.getCharacterEncoding());
100
101 String requestAttributes[] = jspTemplateDataSource.getAttributeNames();
102 try {
103 //
104 // setup Request variables from the JspTemplateDataSource
105 for (int i = 0; i < requestAttributes.length; i++) {
106 String name = requestAttributes[i];
107 request.setAttribute(name,jspTemplateDataSource.getAttribute(name));
108 }
109 //
110 // and get the content into out captured response
111 jspInclude(true,jspPath,servlet,request,response);
112 } finally {
113 //
114 // tear down Request variables
115 for (int i = 0; i < requestAttributes.length; i++) {
116 String name = requestAttributes[i];
117 request.removeAttribute(name);
118 }
119 }
120
121 //
122 // now we have captured the JSP output, we need to reverse that
123 // and return it as an InputStream.
124 return response.getCapturedInputStream();
125 }
126
127 /**
128 * Include the JSP template content by using the PageContext.include mechanism
129 */
130 private void jspInclude(boolean isLoudErrorsUsed, String jspPath, Servlet servlet, HttpServletRequest request, HttpServletResponse response) {
131 JspFactory factory = null;
132 PageContext pc = null;
133 PrintWriter out = null;
134 try {
135 out = response.getWriter();
136 factory = JspFactory.getDefaultFactory();
137
138 pc = factory.getPageContext(servlet, request, response, null, true, JspWriter.NO_BUFFER, true);
139
140 if (pc != null) {
141 ///////////////////////////////////////////////
142 // include the page
143 ///////////////////////////////////////////////
144 pc.include(jspPath);
145
146 factory.releasePageContext(pc);
147 pc = null;
148
149 } else {
150 ///////////////////////////////////////////////
151 // we have no page context, it cant be output
152 ///////////////////////////////////////////////
153 throw new ServletException("Unable to obtain JSP PageContext object");
154 }
155 } catch (ServletException e) {
156 if (isLoudErrorsUsed) {
157 out.println("<div style=\"background:red;color:white;font-size:12;border-width:1; border-style:solid; border-color:black; padding:4; margin:4\" >");
158 out.println("<blink><b>");
159 out.println("<p>JSP Exception : '<em>" + e + "</em>'</p>");
160 out.println("</b></blink></div>");
161 } else {
162 out.println("<!-- ");
163 out.println("JSP Exception : '" + e + "'");
164 out.println(" -->");
165 }
166 } catch (IOException e) {
167 throw ThrowableKit.makeRuntimeException(e);
168 } finally {
169 // cleanup the factory and page context
170 if (factory != null && pc != null)
171 factory.releasePageContext(pc);
172 }
173 }
174
175
176 }