Clover Coverage Report - magnolia-module-templating 4.4.5
Coverage timestamp: Mon Sep 12 2011 16:32:30 CEST
../../../../img/srcFileCovDistChart0.png 54% of files have more coverage
66   231   24   8.25
28   121   0.36   8
8     3  
1    
 
  ModelExecutionFilter       Line # 70 66 0% 24 102 0% 0.0
 
No Tests
 
1    /**
2    * This file Copyright (c) 2010-2011 Magnolia International
3    * Ltd. (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10    * This file is distributed in the hope that it will be
11    * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12    * implied warranty of MERCHANTABILITY or FITNESS FOR A
13    * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14    * Redistribution, except as permitted by whichever of the GPL
15    * or MNA you select, is prohibited.
16    *
17    * 1. For the GPL license (GPL), you can redistribute and/or
18    * modify this file under the terms of the GNU General
19    * Public License, Version 3, as published by the Free Software
20    * Foundation. You should have received a copy of the GNU
21    * General Public License, Version 3 along with this program;
22    * if not, write to the Free Software Foundation, Inc., 51
23    * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24    *
25    * 2. For the Magnolia Network Agreement (MNA), this file
26    * and the accompanying materials are made available under the
27    * terms of the MNA which accompanies this distribution, and
28    * is available at http://www.magnolia-cms.com/mna.html
29    *
30    * Any modifications to this file must keep this entire header
31    * intact.
32    *
33    */
34    package info.magnolia.module.templating;
35   
36    import java.io.IOException;
37    import javax.jcr.RepositoryException;
38    import javax.servlet.FilterChain;
39    import javax.servlet.ServletException;
40    import javax.servlet.http.HttpServletRequest;
41    import javax.servlet.http.HttpServletResponse;
42   
43    import org.apache.commons.lang.StringUtils;
44   
45    import info.magnolia.cms.core.AggregationState;
46    import info.magnolia.cms.core.Content;
47    import info.magnolia.cms.core.HierarchyManager;
48    import info.magnolia.cms.filters.OncePerRequestAbstractMgnlFilter;
49    import info.magnolia.cms.util.RequestDispatchUtil;
50    import info.magnolia.context.MgnlContext;
51   
52    /**
53    * Filter that executes the model for a paragraph before template rendering. Looks for a request parameter containing
54    * the UUID of the paragraph to execute. The model can decide to send output by itself in which case page rendering
55    * is skipped. The model can also return a URI prefixed by "redirect:", "permanent:" or "forward:" to trigger either
56    * a temporary redirect, a permanent redirect or a forward respectively. For redirects the URI can be absolute or
57    * relative within the web application (the context path is added automatically).
58    * <p/>
59    * By implementing the {@link EarlyExecutionAware} interface the callback will instead be made to a dedicated method
60    * making it easier to separate functionality for the two scenarios.
61    * <p/>
62    * To provide proper semantics this class mirrors functionality in RenderingEngine and AbstractRender, specifically in
63    * how it sets up the current content in aggregation state and creation and execution of the model.
64    *
65    * @author tmattsson
66    * @see info.magnolia.module.templating.AbstractRenderer
67    * @see info.magnolia.cms.util.RequestDispatchUtil
68    * @see EarlyExecutionAware
69    */
 
70    public class ModelExecutionFilter extends OncePerRequestAbstractMgnlFilter {
71   
72    public static final String MODEL_ATTRIBUTE_PREFIX = ModelExecutionFilter.class.getName() + "-model-";
73    public static final String ACTION_RESULT_ATTRIBUTE_PREFIX = ModelExecutionFilter.class.getName() + "-actionResult-";
74    public static final String DEFAULT_MODEL_EXECUTION_ATTRIBUTE_NAME = "mgnlModelExecutionUUID";
75   
76    private String attributeName = DEFAULT_MODEL_EXECUTION_ATTRIBUTE_NAME;
77   
 
78  0 toggle public void setAttributeName(String attributeName) {
79  0 this.attributeName = attributeName;
80    }
81   
 
82  0 toggle @Override
83    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
84   
85  0 String paragraphUuid = getUuidOfParagraphToExecute();
86   
87  0 if (paragraphUuid == null) {
88  0 chain.doFilter(request, response);
89  0 return;
90    }
91   
92  0 Content content = getContent(paragraphUuid);
93   
94  0 Content orgMainContent = null;
95  0 Content orgCurrentContent = null;
96   
97  0 AggregationState state = getAggregationStateSafely();
98  0 if (state != null) {
99  0 orgMainContent = state.getMainContent();
100  0 orgCurrentContent = state.getCurrentContent();
101   
102  0 state.setCurrentContent(content);
103    // if not yet set the passed content is the entry point of the rendering
104  0 if (orgMainContent == null) {
105  0 state.setMainContent(content);
106    }
107    }
108  0 try {
109   
110  0 Paragraph paragraph = getParagraph(content);
111   
112  0 RenderingModelBasedRenderer renderingModelBasedRenderer = getRenderingModelBasedRenderer(paragraph);
113   
114  0 RenderingModel renderingModel;
115  0 try {
116  0 renderingModel = renderingModelBasedRenderer.newModel(content, paragraph, null);
117    }
118    catch (RenderException e) {
119  0 throw new ServletException(e.getMessage(), e);
120    }
121   
122  0 String actionResult;
123  0 if (renderingModel instanceof EarlyExecutionAware) {
124  0 actionResult = ((EarlyExecutionAware)renderingModel).executeEarly();
125    } else {
126  0 actionResult = renderingModel.execute();
127    }
128   
129    // If the model rendered something on its own or sent a redirect we will not proceed with rendering.
130  0 if (response.isCommitted())
131  0 return;
132   
133  0 if (handleActionResult(actionResult, request, response))
134  0 return;
135   
136    // Proceed with page rendering, the model will be reused later when the paragraph is rendered.
137  0 MgnlContext.setAttribute(MODEL_ATTRIBUTE_PREFIX + paragraphUuid, renderingModel);
138  0 MgnlContext.setAttribute(ACTION_RESULT_ATTRIBUTE_PREFIX + paragraphUuid, actionResult);
139  0 try {
140  0 chain.doFilter(request, response);
141    } finally {
142  0 MgnlContext.removeAttribute(MODEL_ATTRIBUTE_PREFIX + paragraphUuid);
143  0 MgnlContext.removeAttribute(ACTION_RESULT_ATTRIBUTE_PREFIX + paragraphUuid);
144    }
145   
146    } finally {
147  0 if (state != null) {
148  0 state.setMainContent(orgMainContent);
149  0 state.setCurrentContent(orgCurrentContent);
150    }
151    }
152    }
153   
 
154  0 toggle protected static AggregationState getAggregationStateSafely() {
155  0 if (MgnlContext.isWebContext()) {
156  0 return MgnlContext.getAggregationState();
157    }
158  0 return null;
159    }
160   
 
161  0 toggle protected String getUuidOfParagraphToExecute() {
162  0 return (String) MgnlContext.getInstance().getAttribute(attributeName);
163    }
164   
165    /**
166    * Returns the Content node for the supplied uuid. Never returns null.
167    */
 
168  0 toggle protected Content getContent(String uuid) throws ServletException {
169   
170  0 String repository = MgnlContext.getAggregationState().getRepository();
171  0 HierarchyManager hm = MgnlContext.getHierarchyManager(repository);
172   
173  0 try {
174  0 return hm.getContentByUUID(uuid);
175    } catch (RepositoryException e) {
176  0 throw new ServletException("Can't read content for paragraph: " + uuid, e);
177    }
178    }
179   
180    /**
181    * Returns the Paragraph for the supplied Content. Never returns null.
182    */
 
183  0 toggle protected Paragraph getParagraph(Content content) throws ServletException {
184   
185  0 String templateName = content.getMetaData().getTemplate();
186   
187  0 if (StringUtils.isEmpty(templateName)) {
188  0 throw new ServletException("No paragraph name set for paragraph with UUID: " + content.getUUID());
189    }
190   
191  0 Paragraph paragraph = ParagraphManager.getInstance().getParagraphDefinition(templateName);
192   
193  0 if (paragraph == null) {
194  0 throw new ServletException("Paragraph does not exist: " + templateName);
195    }
196   
197  0 return paragraph;
198    }
199   
200    /**
201    * Returns the ParagraphRenderer for the supplied Paragraph if it supports RenderingModel. Never returns null.
202    * @throws IllegalArgumentException if there is no renderer registered for the paragraph
203    * @throws ServletException if the renderer does not support RenderingModel
204    */
 
205  0 toggle protected RenderingModelBasedRenderer getRenderingModelBasedRenderer(Paragraph paragraph) throws ServletException {
206   
207  0 ParagraphRenderer renderer = ParagraphRendererManager.getInstance().getRenderer(paragraph.getType());
208   
209  0 if (!(renderer instanceof RenderingModelBasedRenderer))
210  0 throw new ServletException("Renderer [" + paragraph.getName() + "] does not support RenderingModel");
211   
212  0 return (RenderingModelBasedRenderer) renderer;
213    }
214   
215    /**
216    * Returns true if special handling was performed.
217    */
 
218  0 toggle protected boolean handleActionResult(String actionResult, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
219   
220  0 if (actionResult == null)
221  0 return false;
222   
223  0 if (actionResult.equals(RenderingModel.SKIP_RENDERING))
224  0 return true;
225   
226  0 if (RequestDispatchUtil.dispatch(actionResult, request, response))
227  0 return true;
228   
229  0 return false;
230    }
231    }