001
014
015 package com.liferay.portal.template;
016
017 import com.liferay.portal.deploy.sandbox.SandboxHandler;
018 import com.liferay.portal.kernel.cache.CacheListener;
019 import com.liferay.portal.kernel.cache.CacheListenerScope;
020 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
021 import com.liferay.portal.kernel.cache.PortalCache;
022 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
026 import com.liferay.portal.kernel.template.TemplateConstants;
027 import com.liferay.portal.kernel.template.TemplateException;
028 import com.liferay.portal.kernel.template.TemplateResource;
029 import com.liferay.portal.kernel.template.TemplateResourceLoader;
030 import com.liferay.portal.kernel.template.URLTemplateResource;
031 import com.liferay.portal.kernel.util.InstanceFactory;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.portal.kernel.util.Validator;
034
035 import java.io.IOException;
036 import java.io.ObjectInput;
037 import java.io.ObjectOutput;
038 import java.io.Reader;
039
040 import java.util.HashSet;
041 import java.util.Set;
042
043
046 @DoPrivileged
047 public class DefaultTemplateResourceLoader implements TemplateResourceLoader {
048
049 public DefaultTemplateResourceLoader(
050 String name, String[] templateResourceParserClassNames,
051 long modificationCheckInterval) {
052
053 if (Validator.isNull(name)) {
054 throw new IllegalArgumentException(
055 "Template resource loader name is null");
056 }
057
058 if (templateResourceParserClassNames == null) {
059 throw new IllegalArgumentException(
060 "Template resource parser class names is null");
061 }
062
063 _name = name;
064
065 for (String templateResourceParserClassName :
066 templateResourceParserClassNames) {
067
068 try {
069 TemplateResourceParser templateResourceParser =
070 (TemplateResourceParser)InstanceFactory.newInstance(
071 templateResourceParserClassName);
072
073 _templateResourceParsers.add(templateResourceParser);
074 }
075 catch (Exception e) {
076 _log.error(e, e);
077 }
078 }
079
080 _modificationCheckInterval = modificationCheckInterval;
081
082 String cacheName = TemplateResourceLoader.class.getName();
083
084 cacheName = cacheName.concat(StringPool.PERIOD).concat(name);
085
086 _multiVMPortalCache = MultiVMPoolUtil.getCache(cacheName);
087
088 CacheListener<String, TemplateResource> cacheListener =
089 new TemplateResourceCacheListener(name);
090
091 _multiVMPortalCache.registerCacheListener(
092 cacheListener, CacheListenerScope.ALL);
093
094 _singleVMPortalCache = SingleVMPoolUtil.getCache(cacheName);
095
096 _singleVMPortalCache.registerCacheListener(
097 cacheListener, CacheListenerScope.ALL);
098 }
099
100 @Override
101 public void clearCache() {
102 _multiVMPortalCache.removeAll();
103 _singleVMPortalCache.removeAll();
104 }
105
106 @Override
107 public void clearCache(String templateId) {
108 _multiVMPortalCache.remove(templateId);
109 _singleVMPortalCache.remove(templateId);
110 }
111
112 @Override
113 public void destroy() {
114 _multiVMPortalCache.destroy();
115 _singleVMPortalCache.destroy();
116
117 _templateResourceParsers.clear();
118 }
119
120 @Override
121 public String getName() {
122 return _name;
123 }
124
125 @Override
126 public TemplateResource getTemplateResource(String templateId) {
127 if (_modificationCheckInterval == 0) {
128 return _loadFromParser(templateId);
129 }
130
131 TemplateResource templateResource = _loadFromCache(templateId);
132
133 if (templateResource != null) {
134 if (templateResource instanceof NullHolderTemplateResource) {
135 return null;
136 }
137
138 return templateResource;
139 }
140
141 templateResource = _loadFromParser(templateId);
142
143 _updateCache(templateId, templateResource);
144
145 return templateResource;
146 }
147
148 @Override
149 public boolean hasTemplateResource(String templateId) {
150 TemplateResource templateResource = getTemplateResource(templateId);
151
152 if (templateResource != null) {
153 return true;
154 }
155
156 return false;
157 }
158
159 private TemplateResource _loadFromCache(
160 PortalCache<String, TemplateResource> portalCache, String templateId) {
161
162 Object object = portalCache.get(templateId);
163
164 if (object == null) {
165 return null;
166 }
167
168 if (!(object instanceof TemplateResource)) {
169 portalCache.remove(templateId);
170
171 if (_log.isWarnEnabled()) {
172 _log.warn(
173 "Remove template " + templateId +
174 " because it is not a template resource");
175 }
176
177 return null;
178 }
179
180 TemplateResource templateResource = (TemplateResource)object;
181
182 if (_modificationCheckInterval > 0) {
183 long expireTime =
184 templateResource.getLastModified() + _modificationCheckInterval;
185
186 if (System.currentTimeMillis() > expireTime) {
187 portalCache.remove(templateId);
188
189 templateResource = _nullHolderTemplateResource;
190
191 if (_log.isDebugEnabled()) {
192 _log.debug(
193 "Remove expired template resource " + templateId);
194 }
195 }
196 }
197
198 return templateResource;
199 }
200
201 private TemplateResource _loadFromCache(String templateId) {
202 TemplateResource templateResource = _loadFromCache(
203 _singleVMPortalCache, templateId);
204
205 if (templateResource != null) {
206 if (templateResource == _nullHolderTemplateResource) {
207 return null;
208 }
209
210 return templateResource;
211 }
212
213 templateResource = _loadFromCache(_multiVMPortalCache, templateId);
214
215 if ((templateResource == null) ||
216 (templateResource == _nullHolderTemplateResource)) {
217
218 return null;
219 }
220
221 return templateResource;
222 }
223
224 private TemplateResource _loadFromParser(String templateId) {
225 for (TemplateResourceParser templateResourceParser :
226 _templateResourceParsers) {
227
228 try {
229 if (!templateResourceParser.isTemplateResourceValid(
230 templateId, getName())) {
231
232 continue;
233 }
234
235 TemplateResource templateResource =
236 templateResourceParser.getTemplateResource(templateId);
237
238 if (templateResource != null) {
239 if ((_modificationCheckInterval != 0) &&
240 (!_name.equals(TemplateConstants.LANG_TYPE_VM) ||
241 !templateId.contains(
242 SandboxHandler.SANDBOX_MARKER))) {
243
244 templateResource = new CacheTemplateResource(
245 templateResource);
246 }
247
248 return templateResource;
249 }
250 }
251 catch (TemplateException te) {
252 if (_log.isWarnEnabled()) {
253 _log.warn(
254 "Unable to parse template " + templateId +
255 " with parser " + templateResourceParser,
256 te);
257 }
258 }
259 }
260
261 return null;
262 }
263
264 private void _updateCache(
265 String templateId, TemplateResource templateResource) {
266
267 if (templateResource == null) {
268 _singleVMPortalCache.put(
269 templateId, new NullHolderTemplateResource());
270
271 return;
272 }
273
274 CacheTemplateResource cacheTemplateResource =
275 (CacheTemplateResource)templateResource;
276
277 TemplateResource innerTemplateResource =
278 cacheTemplateResource.getInnerTemplateResource();
279
280 if (innerTemplateResource instanceof URLTemplateResource) {
281 _singleVMPortalCache.put(templateId, templateResource);
282
283 return;
284 }
285
286 _multiVMPortalCache.put(templateId, templateResource);
287 }
288
289 private static Log _log = LogFactoryUtil.getLog(
290 DefaultTemplateResourceLoader.class);
291
292 private static NullHolderTemplateResource _nullHolderTemplateResource =
293 new NullHolderTemplateResource();
294
295 private long _modificationCheckInterval;
296 private PortalCache<String, TemplateResource> _multiVMPortalCache;
297 private String _name;
298 private PortalCache<String, TemplateResource> _singleVMPortalCache;
299 private Set<TemplateResourceParser> _templateResourceParsers =
300 new HashSet<TemplateResourceParser>();
301
302 private static class NullHolderTemplateResource
303 implements TemplateResource {
304
305
309 public NullHolderTemplateResource() {
310 }
311
312 @Override
313 public long getLastModified() {
314 return _lastModified;
315 }
316
317 @Override
318 public Reader getReader() {
319 return null;
320 }
321
322 @Override
323 public String getTemplateId() {
324 return null;
325 }
326
327 @Override
328 public void readExternal(ObjectInput objectInput) throws IOException {
329 _lastModified = objectInput.readLong();
330 }
331
332 @Override
333 public void writeExternal(ObjectOutput objectOutput)
334 throws IOException {
335
336 objectOutput.writeLong(_lastModified);
337 }
338
339 private long _lastModified = System.currentTimeMillis();
340
341 }
342
343 }