1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.blossom.view;
35
36 import java.lang.reflect.Constructor;
37 import java.lang.reflect.InvocationTargetException;
38 import java.util.Map;
39 import javax.jcr.Node;
40 import javax.servlet.ServletContext;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43
44 import info.magnolia.context.MgnlContext;
45 import info.magnolia.module.blossom.render.RenderContext;
46 import info.magnolia.rendering.context.RenderingContext;
47 import info.magnolia.rendering.engine.RenderException;
48 import info.magnolia.rendering.model.RenderingModel;
49 import info.magnolia.rendering.renderer.FreemarkerRenderer;
50 import info.magnolia.rendering.template.RenderableDefinition;
51
52 import org.springframework.util.ClassUtils;
53 import org.springframework.web.servlet.support.RequestContext;
54 import org.springframework.web.servlet.view.AbstractTemplateView;
55
56
57
58
59
60
61 public class FreemarkerTemplateViewRenderer extends FreemarkerRenderer {
62
63
64 private boolean exposeModelAsRequestAttributes = true;
65 private boolean exposeSpringMacroHelpers = true;
66
67 public boolean isExposeModelAsRequestAttributes() {
68 return exposeModelAsRequestAttributes;
69 }
70
71 public void setExposeModelAsRequestAttributes(boolean exposeModelAsRequestAttributes) {
72 this.exposeModelAsRequestAttributes = exposeModelAsRequestAttributes;
73 }
74
75 public boolean isExposeSpringMacroHelpers() {
76 return exposeSpringMacroHelpers;
77 }
78
79 public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
80 this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
81 }
82
83 @Override
84 protected void setupContext(Map<String, Object> ctx, Node content, RenderableDefinition definition, RenderingModel<?> model, Object actionResult) {
85 super.setupContext(ctx, content, definition, model, actionResult);
86 ctx.putAll(RenderContext.get().getModel());
87 }
88
89 @Override
90 protected String resolveTemplateScript(Node content, RenderableDefinition definition, RenderingModel<?> model, String actionResult) {
91 return RenderContext.get().getTemplateScript();
92 }
93
94 @Override
95 protected void onRender(Node content, RenderableDefinition definition, RenderingContext renderingCtx, Map<String, Object> ctx, String templateScript) throws RenderException {
96
97 if (MgnlContext.isWebContext()) {
98
99 @SuppressWarnings("unchecked")
100 Map<String, Object> model = ctx;
101
102
103
104 if (this.exposeSpringMacroHelpers) {
105 model.put(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE, createRequestContext(model));
106 }
107
108
109
110
111 if (this.exposeModelAsRequestAttributes) {
112 HttpServletRequest request = MgnlContext.getWebContext().getRequest();
113 for (Map.Entry<String, Object> entry : model.entrySet()) {
114 String modelName = entry.getKey();
115 Object modelValue = entry.getValue();
116 if (modelValue != null) {
117 request.setAttribute(modelName, modelValue);
118 } else {
119 request.removeAttribute(modelName);
120 }
121 }
122 }
123 }
124
125 super.onRender(content, definition, renderingCtx, ctx, templateScript);
126 }
127
128 private static final Constructor<RequestContext> spring30RequestContextConstructor = ClassUtils.getConstructorIfAvailable(RequestContext.class, new Class[] {HttpServletRequest.class, HttpServletResponse.class, ServletContext.class, Map.class});
129 private static final Constructor<RequestContext> spring25RequestContextConstructor = ClassUtils.getConstructorIfAvailable(RequestContext.class, new Class[] {HttpServletRequest.class, ServletContext.class, Map.class});
130
131
132
133
134
135 private RequestContext createRequestContext(Map<String, Object> model) throws RenderException {
136 try {
137
138
139 if (spring30RequestContextConstructor != null) {
140 return spring30RequestContextConstructor.newInstance(
141 MgnlContext.getWebContext().getRequest(),
142 MgnlContext.getWebContext().getResponse(),
143 MgnlContext.getWebContext().getServletContext(),
144 model);
145 }
146
147
148 if (spring25RequestContextConstructor != null) {
149 return spring25RequestContextConstructor.newInstance(
150 MgnlContext.getWebContext().getRequest(),
151 MgnlContext.getWebContext().getServletContext(),
152 model);
153 }
154
155 throw new RenderException("Could not create RequestContext");
156
157 } catch (InstantiationException e) {
158 throw new RenderException("Could not create RequestContext", e);
159 } catch (IllegalAccessException e) {
160 throw new RenderException("Could not create RequestContext", e);
161 } catch (InvocationTargetException e) {
162 throw new RenderException("Could not create RequestContext", e);
163 }
164 }
165 }