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.resources.renderers;
35
36 import info.magnolia.cms.beans.config.MIMEMapping;
37 import info.magnolia.context.MgnlContext;
38 import info.magnolia.freemarker.FreemarkerHelper;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.jcr.util.PropertyUtil;
41 import info.magnolia.jcr.wrapper.HTMLEscapingNodeWrapper;
42 import info.magnolia.module.resources.ResourcesModule;
43 import info.magnolia.module.resources.loaders.ResourceLoader;
44 import info.magnolia.module.resources.templates.ResourceTemplate;
45 import info.magnolia.objectfactory.Classes;
46 import info.magnolia.objectfactory.guice.GuiceUtils;
47 import info.magnolia.rendering.context.RenderingContext;
48 import info.magnolia.rendering.engine.RenderException;
49 import info.magnolia.rendering.engine.RenderingEngine;
50 import info.magnolia.rendering.model.RenderingModel;
51 import info.magnolia.rendering.renderer.FreemarkerRenderer;
52 import info.magnolia.rendering.template.RenderableDefinition;
53 import info.magnolia.rendering.util.AppendableWriter;
54
55 import java.io.IOException;
56 import java.io.InputStream;
57 import java.io.Reader;
58 import java.io.StringReader;
59 import java.util.List;
60 import java.util.Map;
61
62 import javax.inject.Inject;
63 import javax.inject.Provider;
64 import javax.jcr.Node;
65 import javax.jcr.RepositoryException;
66 import javax.servlet.http.HttpServletResponse;
67
68 import org.apache.commons.io.IOUtils;
69 import org.apache.commons.lang3.StringUtils;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73 import freemarker.template.TemplateException;
74
75
76
77
78
79
80
81
82
83
84 public class ResourcesTextTemplateRenderer extends FreemarkerRenderer {
85
86 private static final Logger log = LoggerFactory.getLogger(ResourcesTextTemplateRenderer.class);
87 private final Provider<ResourcesModule> resourcesModule;
88
89
90
91
92 @Deprecated
93 public ResourcesTextTemplateRenderer(FreemarkerHelper fmRenderer, RenderingEngine renderingEngine) {
94 this(fmRenderer, renderingEngine, GuiceUtils.providerForInstance(ResourcesModule.getInstance()));
95 }
96
97 @Inject
98 public ResourcesTextTemplateRenderer(FreemarkerHelper fmRenderer, RenderingEngine renderingEngine, Provider<ResourcesModule> resourcesModule) {
99 super(fmRenderer, renderingEngine);
100 this.resourcesModule = resourcesModule;
101 }
102
103 @Override
104 protected void onRender(Node content, RenderableDefinition definition, RenderingContext renderingCtx, Map<String, Object> ctx, String templateScript) throws RenderException {
105
106 ResourceTemplate resourceTemplate = (ResourceTemplate) definition;
107
108 final HttpServletResponse response = MgnlContext.getWebContext().getResponse();
109 final String contentType = resourceTemplate.getContentType();
110 final boolean processed = resourceTemplate.isProcessed();
111
112 response.setContentType(contentType);
113
114 content = NodeUtil.deepUnwrap(content, HTMLEscapingNodeWrapper.class);
115
116 StringBuffer text;
117 if (shouldBypass(content)) {
118
119
120 if (processed) {
121 super.onRender(content, definition, renderingCtx, ctx, templateScript);
122 return;
123 }
124
125 InputStream in = null;
126 List<ResourceLoader> loaders = resourcesModule.get().getResourceLoaders();
127
128 for (ResourceLoader loader : loaders) {
129 try {
130 in = loader.getStream(templateScript);
131 if (in != null) {
132 break;
133 }
134 } catch (IOException e) {
135 log.debug("Can't load resource '{}' with ResourceLoader '{}'", templateScript, loader.getClass());
136 }
137 }
138
139 if (in == null) {
140 throw new RenderException(String.format("Template '%s' not found.", templateScript));
141 }
142
143 try {
144 text = new StringBuffer();
145 text.append(IOUtils.toString(in));
146 } catch (IOException e) {
147 throw new RenderException(String.format("Can't render resource '%s'.", templateScript), e);
148 } finally {
149 IOUtils.closeQuietly(in);
150 }
151
152 } else {
153 text = new StringBuffer();
154 text.append(PropertyUtil.getString(content, "text"));
155 }
156
157 try {
158
159 AppendableWriter out = renderingCtx.getAppendable();
160
161 if (processed) {
162 Reader reader = new StringReader(text.toString());
163 try {
164 this.getFmHelper().render(reader, ctx, out);
165 } catch (TemplateException e) {
166 throw new RenderException(e);
167 }
168 } else {
169 out.write(text.toString());
170 }
171 } catch (IOException e) {
172 throw new RenderException("Can't render resource", e);
173 }
174 }
175
176
177
178
179
180 @Override
181 protected String resolveTemplateScript(Node content, RenderableDefinition definition, RenderingModel<?> model, final String actionResult) {
182 if (shouldBypass(content)) {
183 try {
184 String path;
185 if (StringUtils.isNotBlank(MIMEMapping.getMIMEType(StringUtils.substringAfterLast(content.getPath(), ".")))) {
186 return content.getPath();
187 }
188 String extension = PropertyUtil.getString(content, "extension");
189 path = content.getPath();
190 if (extension != null) {
191 path += "." + extension;
192 }
193 return path;
194 } catch (RepositoryException re) {
195 log.error("Not able to determineTemplatePath ", re);
196 }
197 }
198
199
200
201
202 return "";
203 }
204
205
206
207
208 @Override
209 public RenderingModel<?> newModel(Node content, RenderableDefinition definition, RenderingModel<?> parentModel) throws RenderException {
210
211 String modelClass = PropertyUtil.getString(content, "modelClass");
212
213 if (StringUtils.isEmpty(modelClass)) {
214 return super.newModel(content, definition, parentModel);
215 }
216
217 Class<? extends RenderingModel<?>> clazz;
218 try {
219 clazz = Classes.getClassFactory().forName(modelClass);
220 } catch (ClassNotFoundException e) {
221 throw new RenderException("Could not create model.", e);
222 }
223
224 return super.newModel(clazz, content, definition, parentModel);
225 }
226
227 protected boolean shouldBypass(Node content) {
228 return PropertyUtil.getBoolean(content, "bypass", false);
229 }
230
231 }