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