001
014
015 package com.liferay.portal.template;
016
017 import com.liferay.portal.deploy.sandbox.SandboxHandler;
018 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
019 import com.liferay.portal.kernel.cache.PortalCache;
020 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
021 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
022 import com.liferay.portal.kernel.template.StringTemplateResource;
023 import com.liferay.portal.kernel.template.Template;
024 import com.liferay.portal.kernel.template.TemplateConstants;
025 import com.liferay.portal.kernel.template.TemplateException;
026 import com.liferay.portal.kernel.template.TemplateResource;
027 import com.liferay.portal.kernel.template.TemplateResourceLoader;
028 import com.liferay.portal.kernel.template.URLTemplateResource;
029 import com.liferay.portal.kernel.util.StringBundler;
030 import com.liferay.portal.kernel.util.StringPool;
031
032 import java.io.Serializable;
033 import java.io.Writer;
034
035 import java.util.Collection;
036 import java.util.HashMap;
037 import java.util.Map;
038 import java.util.Set;
039
040 import javax.servlet.http.HttpServletRequest;
041
042
045 public abstract class AbstractTemplate implements Template {
046
047 public AbstractTemplate(
048 TemplateResource templateResource,
049 TemplateResource errorTemplateResource, Map<String, Object> context,
050 TemplateContextHelper templateContextHelper, String templateManagerName,
051 long interval) {
052
053 if (templateResource == null) {
054 throw new IllegalArgumentException("Template resource is null");
055 }
056
057 if (templateContextHelper == null) {
058 throw new IllegalArgumentException(
059 "Template context helper is null");
060 }
061
062 if (templateManagerName == null) {
063 throw new IllegalArgumentException("Template manager name is null");
064 }
065
066 this.templateResource = templateResource;
067 this.errorTemplateResource = errorTemplateResource;
068
069 this.context = new HashMap<>();
070
071 if (context != null) {
072 for (Map.Entry<String, Object> entry : context.entrySet()) {
073 put(entry.getKey(), entry.getValue());
074 }
075 }
076
077 _templateContextHelper = templateContextHelper;
078
079 if (interval != 0) {
080 _cacheTemplateResource(templateManagerName);
081 }
082 }
083
084 @Override
085 public void clear() {
086 context.clear();
087 }
088
089 @Override
090 public boolean containsKey(Object key) {
091 return context.containsKey(key);
092 }
093
094 @Override
095 public boolean containsValue(Object value) {
096 return context.containsValue(value);
097 }
098
099 @Override
100 public void doProcessTemplate(Writer writer) throws Exception {
101 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
102
103 put(TemplateConstants.WRITER, unsyncStringWriter);
104
105 processTemplate(templateResource, unsyncStringWriter);
106
107 StringBundler sb = unsyncStringWriter.getStringBundler();
108
109 sb.writeTo(writer);
110 }
111
112 @Override
113 public Set<Entry<String, Object>> entrySet() {
114 return context.entrySet();
115 }
116
117 @Override
118 public Object get(Object key) {
119 if (key == null) {
120 return null;
121 }
122
123 return context.get(key);
124 }
125
126 @Override
127 public Object get(String key) {
128 if (key == null) {
129 return null;
130 }
131
132 return context.get(key);
133 }
134
135 @Override
136 public String[] getKeys() {
137 Set<String> keys = context.keySet();
138
139 return keys.toArray(new String[keys.size()]);
140 }
141
142 @Override
143 public boolean isEmpty() {
144 return context.isEmpty();
145 }
146
147 @Override
148 public Set<String> keySet() {
149 return context.keySet();
150 }
151
152 @Override
153 public void prepare(HttpServletRequest request) {
154 _templateContextHelper.prepare(this, request);
155 }
156
157 @Override
158 public void processTemplate(Writer writer) throws TemplateException {
159 if (errorTemplateResource == null) {
160 try {
161 processTemplate(templateResource, writer);
162
163 return;
164 }
165 catch (Exception e) {
166 throw new TemplateException(
167 "Unable to process template " +
168 templateResource.getTemplateId(),
169 e);
170 }
171 }
172
173 Writer oldWriter = (Writer)get(TemplateConstants.WRITER);
174
175 try {
176 doProcessTemplate(writer);
177 }
178 catch (Exception e) {
179 put(TemplateConstants.WRITER, writer);
180
181 handleException(e, writer);
182 }
183 finally {
184 put(TemplateConstants.WRITER, oldWriter);
185 }
186 }
187
188 @Override
189 public Object put(String key, Object value) {
190 if ((key == null) || (value == null)) {
191 return null;
192 }
193
194 return context.put(key, value);
195 }
196
197 @Override
198 public void putAll(Map<? extends String, ? extends Object> map) {
199 context.putAll(map);
200 }
201
202 @Override
203 public Object remove(Object key) {
204 return context.remove(key);
205 }
206
207 @Override
208 public int size() {
209 return context.size();
210 }
211
212 @Override
213 public Collection<Object> values() {
214 return context.values();
215 }
216
217 protected String getTemplateResourceUUID(
218 TemplateResource templateResource) {
219
220 return TemplateConstants.TEMPLATE_RESOURCE_UUID_PREFIX.concat(
221 StringPool.POUND).concat(templateResource.getTemplateId());
222 }
223
224 protected abstract void handleException(Exception exception, Writer writer)
225 throws TemplateException;
226
227 protected abstract void processTemplate(
228 TemplateResource templateResource, Writer writer)
229 throws Exception;
230
231 protected Map<String, Object> context;
232 protected TemplateResource errorTemplateResource;
233 protected TemplateResource templateResource;
234
235 private void _cacheTemplateResource(String templateManagerName) {
236 String templateId = templateResource.getTemplateId();
237
238 if (templateManagerName.equals(TemplateConstants.LANG_TYPE_VM) &&
239 templateId.contains(SandboxHandler.SANDBOX_MARKER)) {
240
241 return;
242 }
243
244 if (!(templateResource instanceof CacheTemplateResource) &&
245 !(templateResource instanceof StringTemplateResource)) {
246
247 templateResource = new CacheTemplateResource(templateResource);
248 }
249
250 String portalCacheName = TemplateResourceLoader.class.getName();
251
252 portalCacheName = portalCacheName.concat(StringPool.PERIOD).concat(
253 templateManagerName);
254
255 PortalCache<String, Serializable> portalCache = _getPortalCache(
256 templateResource, portalCacheName);
257
258 Object object = portalCache.get(templateResource.getTemplateId());
259
260 if ((object == null) || !templateResource.equals(object)) {
261 portalCache.put(templateResource.getTemplateId(), templateResource);
262 }
263
264 if (errorTemplateResource == null) {
265 return;
266 }
267
268 String errorTemplateId = errorTemplateResource.getTemplateId();
269
270 if (templateManagerName.equals(TemplateConstants.LANG_TYPE_VM) &&
271 errorTemplateId.contains(SandboxHandler.SANDBOX_MARKER)) {
272
273 return;
274 }
275
276 if (!(errorTemplateResource instanceof CacheTemplateResource) &&
277 !(errorTemplateResource instanceof StringTemplateResource)) {
278
279 errorTemplateResource = new CacheTemplateResource(
280 errorTemplateResource);
281 }
282
283 portalCache = _getPortalCache(errorTemplateResource, portalCacheName);
284
285 object = portalCache.get(errorTemplateResource.getTemplateId());
286
287 if ((object == null) || !errorTemplateResource.equals(object)) {
288 portalCache.put(
289 errorTemplateResource.getTemplateId(), errorTemplateResource);
290 }
291 }
292
293 private PortalCache<String, Serializable> _getPortalCache(
294 TemplateResource templateResource, String portalCacheName) {
295
296 if (!(templateResource instanceof CacheTemplateResource)) {
297 return MultiVMPoolUtil.getCache(portalCacheName);
298 }
299
300 CacheTemplateResource cacheTemplateResource =
301 (CacheTemplateResource)templateResource;
302
303 TemplateResource innerTemplateResource =
304 cacheTemplateResource.getInnerTemplateResource();
305
306 if (innerTemplateResource instanceof URLTemplateResource) {
307 return SingleVMPoolUtil.getCache(portalCacheName);
308 }
309
310 return MultiVMPoolUtil.getCache(portalCacheName);
311 }
312
313 private final TemplateContextHelper _templateContextHelper;
314
315 }