GRAILS-1019: Allowing expressions to be used with the 'disabled' attribute for g...
[grails.git] / src / web / org / codehaus / groovy / grails / web / servlet / view / GroovyPageView.java
blob98713461b0086f8fbf0ab5d1294d19f10af13443
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;
35 import java.util.Map;
37 import grails.util.GrailsUtil;
39 /**
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.
48 * @see #getUrl()
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
54 * @since 0.4
56 * <p/>
57 * Created: Feb 27, 2007
58 * Time: 8:25:10 AM
60 public class GroovyPageView extends AbstractUrlBasedView {
62 private static final Log LOG = LogFactory.getLog(GroovyPageView.class);
63 /**
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";
72 /**
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);
91 /**
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);
106 Writer out = null;
107 try {
108 out = createResponseWriter(response);
109 w.writeTo(out);
111 catch(Exception e) {
112 // create fresh response writer
113 out = createResponseWriter(response);
114 handleException(e, out, templateEngine, request);
116 finally {
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);
132 try {
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);
141 w.writeTo(out);
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);
160 return out;