KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > website > template > PushUpTemplateController


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2007
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * Felix Gnass [fgnass at neteye dot de]
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.website.template;
25
26 import java.io.IOException JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31
32 import javax.servlet.ServletException JavaDoc;
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34 import javax.servlet.http.HttpServletResponse JavaDoc;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.riotfamily.common.web.util.ServletUtils;
39 import org.riotfamily.website.interceptor.pushup.DeferredRenderingResponseWrapper;
40 import org.springframework.util.Assert;
41 import org.springframework.web.servlet.ModelAndView;
42
43 /**
44  * TemplateController that allows slots to be processed before others while
45  * still being rendered at the original position within the template.
46  * <p>
47  * These 'pushed-up' controllers can expose request attributes which can then
48  * be read by other controllers that would usually be processed before.
49  * A common usecase is when a controller that renders the page content also
50  * wants to control the document's title tag.
51  * </p>
52  * @author Felix Gnass [fgnass at neteye dot de]
53  * @since 6.5
54  */

55 public class PushUpTemplateController extends TemplateController {
56
57     private static final Log log = LogFactory.getLog(
58             PushUpTemplateController.class);
59
60     private static final String JavaDoc RESPONSE_WRAPPERS_ATTRIBUTE =
61             PushUpTemplateController.class.getName() + ".responseWrappers";
62
63     protected static final String JavaDoc SLOT_TO_RENDER_PARAMETER = "slotToRender";
64
65     private List JavaDoc pushUpSlots;
66
67     public void setPushUpSlots(List JavaDoc pushUpSlots) {
68         this.pushUpSlots = pushUpSlots;
69     }
70
71     protected ModelAndView handleRequestInternal(HttpServletRequest JavaDoc request,
72             HttpServletResponse JavaDoc response) throws Exception JavaDoc {
73
74         String JavaDoc slotToRender = request.getParameter(SLOT_TO_RENDER_PARAMETER);
75         if (slotToRender != null) {
76             renderCapturedSlot(request, response, slotToRender);
77             return null;
78         }
79         handlePushUps(request, response);
80         return super.handleRequestInternal(request, response);
81     }
82
83     protected void handlePushUps(HttpServletRequest JavaDoc request,
84             HttpServletResponse JavaDoc response)
85             throws ServletException JavaDoc, IOException JavaDoc {
86
87         if (pushUpSlots != null && !pushUpSlots.isEmpty()) {
88             //REVISIT Perhaps we should a check whether this is a top-level request ...
89
HashMap JavaDoc config = new HashMap JavaDoc();
90             request.setAttribute(SLOTS_CONFIGURATION_ATTRIBUTE, config);
91             Iterator JavaDoc it = pushUpSlots.iterator();
92             while (it.hasNext()) {
93                 String JavaDoc slot = (String JavaDoc) it.next();
94                 config.put(slot, getDeferredRenderingUrl(request, slot));
95                 handlePushUp(request, response, slot);
96             }
97         }
98     }
99
100     /**
101      * Returns an URL that can be requested in order to render a captured
102      * slot. The URL is constructed from the current servletPath by appending
103      * a parameter that contains the given slot path.
104      */

105     protected String JavaDoc getDeferredRenderingUrl(HttpServletRequest JavaDoc request,
106             String JavaDoc slot) {
107
108         StringBuffer JavaDoc url = new StringBuffer JavaDoc()
109                 .append(ServletUtils.getPathWithinApplication(request))
110                 .append('?').append(SLOT_TO_RENDER_PARAMETER).append('=')
111                 .append(slot);
112
113         return url.toString();
114     }
115
116     protected final Map JavaDoc getResponseWrappers(HttpServletRequest JavaDoc request) {
117         Map JavaDoc wrappers = (Map JavaDoc) request.getAttribute(RESPONSE_WRAPPERS_ATTRIBUTE);
118         if (wrappers == null) {
119             wrappers = new HashMap JavaDoc();
120             request.setAttribute(RESPONSE_WRAPPERS_ATTRIBUTE, wrappers);
121         }
122         return wrappers;
123     }
124
125     protected void handlePushUp(HttpServletRequest JavaDoc request,
126             HttpServletResponse JavaDoc response, String JavaDoc slot)
127             throws ServletException JavaDoc, IOException JavaDoc {
128
129         DeferredRenderingResponseWrapper responseWrapper =
130             new DeferredRenderingResponseWrapper(response);
131
132         getResponseWrappers(request).put(slot, responseWrapper);
133         request.setAttribute(SLOT_PATH_ATTRIBUTE, slot);
134
135         String JavaDoc url = (String JavaDoc) getMergedConfiguration().get(slot);
136
137         log.debug("Capturing pushed-up slot " + slot + " [" + url + "]");
138         request.getRequestDispatcher(url).forward(
139                 request, responseWrapper);
140     }
141
142     /**
143      * Renders a previously captured response for the given slot.
144      */

145     protected void renderCapturedSlot(HttpServletRequest JavaDoc request,
146             HttpServletResponse JavaDoc response, String JavaDoc slot) throws IOException JavaDoc {
147
148         log.debug("Rendering captured slot: " + slot);
149         DeferredRenderingResponseWrapper responseWrapper =
150                 (DeferredRenderingResponseWrapper)
151                 getResponseWrappers(request).get(slot);
152
153         Assert.notNull(responseWrapper,
154                 "No wrapped response found for slot: " + slot);
155
156         responseWrapper.renderResponse(response);
157     }
158 }
159
Popular Tags