1 /* Copyright 2004-2005 Graeme Rocher
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
15 package org
.codehaus
.groovy
.grails
.web
.servlet
.view
;
17 import groovy
.lang
.Writable
;
18 import groovy
.text
.Template
;
19 import org
.apache
.commons
.logging
.Log
;
20 import org
.apache
.commons
.logging
.LogFactory
;
21 import org
.codehaus
.groovy
.grails
.web
.errors
.GrailsWrappedRuntimeException
;
22 import org
.codehaus
.groovy
.grails
.web
.pages
.GSPResponseWriter
;
23 import org
.codehaus
.groovy
.grails
.web
.pages
.GroovyPage
;
24 import org
.codehaus
.groovy
.grails
.web
.pages
.GroovyPagesTemplateEngine
;
25 import org
.codehaus
.groovy
.grails
.web
.servlet
.GrailsApplicationAttributes
;
26 import org
.codehaus
.groovy
.grails
.web
.servlet
.mvc
.GrailsWebRequest
;
27 import org
.springframework
.web
.context
.request
.RequestContextHolder
;
28 import org
.springframework
.web
.servlet
.view
.AbstractUrlBasedView
;
30 import javax
.servlet
.http
.HttpServletRequest
;
31 import javax
.servlet
.http
.HttpServletResponse
;
32 import java
.io
.IOException
;
33 import java
.io
.Writer
;
34 import java
.util
.HashMap
;
37 import grails
.util
.GrailsUtil
;
40 * A Spring View that renders Groovy Server Pages to the reponse. It requires an instance
41 * of GroovyPagesTemplateEngine to be set and will render to view returned by the getUrl()
42 * method of AbstractUrlBasedView
44 * This view also requires an instance of GrailsWebRequest to be bound to the currently
45 * executing Thread using Spring's RequestContextHolder. This can be done with by adding
46 * the GrailsWebRequestFilter.
49 * @see org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine
50 * @see org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter
51 * @see org.springframework.web.context.request.RequestContextHolder
53 * @author Graeme Rocher
57 * Created: Feb 27, 2007
60 public class GroovyPageView
extends AbstractUrlBasedView
{
62 private static final Log LOG
= LogFactory
.getLog(GroovyPageView
.class);
64 * The size of the buffer to use for the GSPReponseWriter
66 private static final int BUFFER_SIZE
= 8024;
67 private static final String ERRORS_VIEW
= GrailsApplicationAttributes
.PATH_TO_VIEWS
+"/error"+ GroovyPage
.EXTENSION
;
68 public static final String EXCEPTION_MODEL_KEY
= "exception";
73 * Delegates to renderMergedOutputModel(..)
75 * @see #renderMergedOutputModel(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
77 * @param model The view model
78 * @param request The HttpServletRequest
79 * @param response The HttpServletResponse
80 * @throws Exception When an error occurs rendering the view
82 protected final void renderMergedOutputModel(Map model
, HttpServletRequest request
, HttpServletResponse response
) throws Exception
{
83 super.exposeModelAsRequestAttributes(model
, request
);
84 // we retrieve the template engine from the context every time so that application reloading works
85 // and we don't end up with cached references
86 GroovyPagesTemplateEngine templateEngine
= (GroovyPagesTemplateEngine
) getApplicationContext().getBean(GroovyPagesTemplateEngine
.BEAN_ID
);
87 if(templateEngine
== null) throw new IllegalStateException("No GroovyPagesTemplateEngine found in ApplicationContext!");
88 renderWithTemplateEngine(templateEngine
,model
, response
, request
);
92 * Renders a page with the specified TemplateEngine, mode and response
94 * @param templateEngine The TemplateEngine to use
95 * @param model The model to use
96 * @param response The HttpServletResponse instance
97 * @param request The HttpServletRequest
99 * @throws java.io.IOException Thrown when an error occurs writing the response
101 protected void renderWithTemplateEngine(GroovyPagesTemplateEngine templateEngine
, Map model
,
102 HttpServletResponse response
, HttpServletRequest request
) throws IOException
{
103 Template t
= templateEngine
.createTemplate(getUrl());
104 Writable w
= t
.make(model
);
108 out
= createResponseWriter(response
);
112 // create fresh response writer
113 out
= createResponseWriter(response
);
114 handleException(e
, out
, templateEngine
, request
);
117 if(out
!=null)out
.close();
122 * Performs exception handling by attempting to render the Errors view
124 * @param exception The exception that occured
125 * @param out The Writer
126 * @param engine The GSP engine
128 protected void handleException(Exception exception
, Writer out
, GroovyPagesTemplateEngine engine
, HttpServletRequest request
) {
130 GrailsUtil
.deepSanitize(exception
);
131 LOG
.error("Error processing GroovyPageView: " + exception
.getMessage(), exception
);
133 // GRAILS-603 null out controller to avoid default layout being applied to error page
134 request
.setAttribute(GrailsApplicationAttributes
.CONTROLLER
, null);
135 Template t
= engine
.createTemplate(ERRORS_VIEW
);
137 Map model
= new HashMap();
138 model
.put(EXCEPTION_MODEL_KEY
,new GrailsWrappedRuntimeException(getServletContext(),exception
));
139 Writable w
= t
.make(model
);
142 } catch (Throwable t
) {
143 LOG
.error("Error attempting to render errors view : " + t
.getMessage(), t
);
144 LOG
.error("Original exception : " + exception
.getMessage(), exception
);
150 * Creates the Response Writer for the specified HttpServletResponse instance
152 * @param response The HttpServletResponse instance
153 * @return A response Writer
155 //TODO this method is dupe'd across GSP servlet, reload servlet and here...
156 protected Writer
createResponseWriter(HttpServletResponse response
) {
157 Writer out
= GSPResponseWriter
.getInstance(response
, BUFFER_SIZE
);
158 GrailsWebRequest webRequest
= (GrailsWebRequest
) RequestContextHolder
.currentRequestAttributes();
159 webRequest
.setOut(out
);