View Javadoc
1   /**
2    * This file Copyright (c) 2010-2018 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.blossom.view;
35  
36  import info.magnolia.context.MgnlContext;
37  import info.magnolia.freemarker.FreemarkerHelper;
38  import info.magnolia.module.blossom.render.RenderContext;
39  import info.magnolia.objectfactory.Components;
40  import info.magnolia.rendering.context.RenderingContext;
41  import info.magnolia.rendering.engine.RenderException;
42  import info.magnolia.rendering.engine.RenderingEngine;
43  import info.magnolia.rendering.model.RenderingModel;
44  import info.magnolia.rendering.renderer.ContextAttributeConfiguration;
45  import info.magnolia.rendering.renderer.FreemarkerRenderer;
46  import info.magnolia.rendering.template.RenderableDefinition;
47  
48  import java.util.Map;
49  
50  import javax.inject.Inject;
51  import javax.jcr.Node;
52  import javax.servlet.http.HttpServletRequest;
53  
54  import org.springframework.web.servlet.support.RequestContext;
55  import org.springframework.web.servlet.view.AbstractTemplateView;
56  
57  /**
58   * Renders templates using the {@link FreemarkerRenderer}.
59   *
60   * <p>This is typically used in combination with the {@link info.magnolia.module.site.renderer.SiteAwareRendererWrapper SiteAwareRendererWrapper}
61   * provided by the site module, enabling use of the template prototype configured on the site.
62   * To construct this object use {@link SiteAwareFreemarkerTemplateViewRendererFactoryBean}.
63   *
64   * @see FreemarkerTemplateViewRenderer
65   * @see info.magnolia.module.site.renderer.SiteAwareRendererWrapper
66   * @see SiteAwareFreemarkerTemplateViewRendererFactoryBean
67   * @since 1.0
68   */
69  public class FreemarkerTemplateViewRenderer extends FreemarkerRenderer {
70  
71      private boolean exposeModelAsRequestAttributes = true;
72      private boolean exposeSpringMacroHelpers = true;
73  
74      @Inject
75      public FreemarkerTemplateViewRenderer(FreemarkerHelper freemarkerHelper, RenderingEngine renderingEngine) {
76          super(freemarkerHelper, renderingEngine);
77      }
78  
79      /**
80       * @deprecated since 3.3.2, use managed components and {@link #FreemarkerTemplateViewRenderer(FreemarkerHelper, RenderingEngine)}.
81       */
82      @Deprecated
83      public FreemarkerTemplateViewRenderer() {
84          this(Components.getComponent(FreemarkerHelper.class), Components.getComponent(RenderingEngine.class));
85      }
86  
87      public boolean isExposeModelAsRequestAttributes() {
88          return exposeModelAsRequestAttributes;
89      }
90  
91      public void setExposeModelAsRequestAttributes(boolean exposeModelAsRequestAttributes) {
92          this.exposeModelAsRequestAttributes = exposeModelAsRequestAttributes;
93      }
94  
95      public boolean isExposeSpringMacroHelpers() {
96          return exposeSpringMacroHelpers;
97      }
98  
99      public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
100         this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
101     }
102 
103     public void addContextAttribute(String name, Class<?> componentClass) {
104         ContextAttributeConfiguration attributeConfiguration = new ContextAttributeConfiguration();
105         attributeConfiguration.setName(name);
106         attributeConfiguration.setComponentClass(componentClass);
107         addContextAttribute(name, attributeConfiguration);
108     }
109 
110     @Override
111     protected void setupContext(Map<String, Object> ctx, Node content, RenderableDefinition definition, RenderingModel<?> model, Object actionResult) {
112         super.setupContext(ctx, content, definition, model, actionResult);
113         ctx.putAll(RenderContext.get().getModel());
114     }
115 
116     @Override
117     protected String resolveTemplateScript(Node content, RenderableDefinition definition, RenderingModel<?> model, String actionResult) {
118         return RenderContext.get().getTemplateScript();
119     }
120 
121     @Override
122     protected void onRender(Node content, RenderableDefinition definition, RenderingContext renderingCtx, Map<String, Object> ctx, String templateScript) throws RenderException {
123 
124         if (MgnlContext.isWebContext()) {
125 
126             @SuppressWarnings("unchecked")
127             Map<String, Object> model = ctx;
128 
129             // Expose RequestContext instance for Spring macros.
130             // See org.springframework.web.servlet.view.AbstractTemplateView#setExposeSpringMacroHelpers
131             if (this.exposeSpringMacroHelpers) {
132                 model.put(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE,
133                         new RequestContext(
134                                 MgnlContext.getWebContext().getRequest(),
135                                 MgnlContext.getWebContext().getResponse(),
136                                 MgnlContext.getWebContext().getServletContext(),
137                                 model));
138             }
139 
140             // Expose the model objects in the given map as request attributes.
141             // Necessary to let JSP tags access them, especially the spring form taglib.
142             // See org.springframework.web.servlet.view.AbstractView#exposeModelAsRequestAttributes
143             if (this.exposeModelAsRequestAttributes) {
144                 HttpServletRequest request = MgnlContext.getWebContext().getRequest();
145                 for (Map.Entry<String, Object> entry : model.entrySet()) {
146                     String modelName = entry.getKey();
147                     Object modelValue = entry.getValue();
148                     if (modelValue != null) {
149                         request.setAttribute(modelName, modelValue);
150                     } else {
151                         request.removeAttribute(modelName);
152                     }
153                 }
154             }
155         }
156 
157         super.onRender(content, definition, renderingCtx, ctx, templateScript);
158     }
159 }