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
097 @Override
098 public void clearCache() {
099 _multiVMPortalCache.removeAll();
100 _singleVMPortalCache.removeAll();
101 }
102
103 @Override
104 public void clearCache(String templateId) {
105 _multiVMPortalCache.remove(templateId);
106 _singleVMPortalCache.remove(templateId);
107 }
108
109 @Override
110 public void destroy() {
111 _multiVMPortalCache.destroy();
112 _singleVMPortalCache.destroy();
113
114 _templateResourceParsers.clear();
115 }
116
117 @Override
118 public String getName() {
119 return _name;
120 }
121
122 @Override
123 public TemplateResource getTemplateResource(String templateId) {
124 if (_modificationCheckInterval == 0) {
125 return _loadFromParser(templateId);
126 }
127
128 TemplateResource templateResource = _loadFromCache(templateId);
129
130 if (templateResource != null) {
131 if (templateResource instanceof NullHolderTemplateResource) {
132 return null;
133 }
134
135 return templateResource;
136 }
137
138 templateResource = _loadFromParser(templateId);
139
140 _updateCache(templateId, templateResource);
141
142 return templateResource;
143 }
144
145 @Override
146 public boolean hasTemplateResource(String templateId) {
147 TemplateResource templateResource = getTemplateResource(templateId);
148
149 if (templateResource != null) {
150 return true;
151 }
152
153 return false;
154 }
155
156 private TemplateResource _loadFromCache(
157 PortalCache<String, TemplateResource> portalCache, String templateId) {
158
159 Object object = portalCache.get(templateId);
160
161 if (object == null) {
162 return null;
163 }
164
165 if (!(object instanceof TemplateResource)) {
166 portalCache.remove(templateId);
167
168 if (_log.isWarnEnabled()) {
169 _log.warn(
170 "Remove template " + templateId +
171 " because it is not a template resource");
172 }
173
174 return null;
175 }
176
177 TemplateResource templateResource = (TemplateResource)object;
178
179 if (_modificationCheckInterval > 0) {
180 long expireTime =
181 templateResource.getLastModified() + _modificationCheckInterval;
182
183 if (System.currentTimeMillis() > expireTime) {
184 portalCache.remove(templateId);
185
186 templateResource = _nullHolderTemplateResource;
187
188 if (_log.isDebugEnabled()) {
189 _log.debug(
190 "Remove expired template resource " + templateId);
191 }
192 }
193 }
194
195 return templateResource;
196 }
197
198 private TemplateResource _loadFromCache(String templateId) {
199 TemplateResource templateResource = _loadFromCache(
200 _singleVMPortalCache, templateId);
201
202 if (templateResource != null) {
203 if (templateResource == _nullHolderTemplateResource) {
204 return null;
205 }
206
207 return templateResource;
208 }
209
210 templateResource = _loadFromCache(_multiVMPortalCache, templateId);
211
212 if ((templateResource == null) ||
213 (templateResource == _nullHolderTemplateResource)) {
214
215 return null;
216 }
217
218 return templateResource;
219 }
220
221 private TemplateResource _loadFromParser(String templateId) {
222 for (TemplateResourceParser templateResourceParser :
223 _templateResourceParsers) {
224
225 try {
226 TemplateResource templateResource =
227 templateResourceParser.getTemplateResource(templateId);
228
229 if (templateResource != null) {
230 if ((_modificationCheckInterval != 0) &&
231 (!_name.equals(TemplateConstants.LANG_TYPE_VM) ||
232 !templateId.contains(
233 SandboxHandler.SANDBOX_MARKER))) {
234
235 templateResource = new CacheTemplateResource(
236 templateResource);
237 }
238
239 return templateResource;
240 }
241 }
242 catch (TemplateException te) {
243 if (_log.isWarnEnabled()) {
244 _log.warn(
245 "Unable to parse template " + templateId +
246 " with parser " + templateResourceParser,
247 te);
248 }
249 }
250 }
251
252 return null;
253 }
254
255 private void _updateCache(
256 String templateId, TemplateResource templateResource) {
257
258 if (templateResource == null) {
259 _singleVMPortalCache.put(
260 templateId, new NullHolderTemplateResource());
261
262 return;
263 }
264
265 CacheTemplateResource cacheTemplateResource =
266 (CacheTemplateResource)templateResource;
267
268 TemplateResource innerTemplateResource =
269 cacheTemplateResource.getInnerTemplateResource();
270
271 if (innerTemplateResource instanceof URLTemplateResource) {
272 _singleVMPortalCache.put(templateId, templateResource);
273
274 return;
275 }
276
277 _multiVMPortalCache.put(templateId, templateResource);
278 }
279
280 private static Log _log = LogFactoryUtil.getLog(
281 DefaultTemplateResourceLoader.class);
282
283 private static NullHolderTemplateResource _nullHolderTemplateResource =
284 new NullHolderTemplateResource();
285
286 private long _modificationCheckInterval;
287 private PortalCache<String, TemplateResource> _multiVMPortalCache;
288 private String _name;
289 private PortalCache<String, TemplateResource> _singleVMPortalCache;
290 private Set<TemplateResourceParser> _templateResourceParsers =
291 new HashSet<TemplateResourceParser>();
292
293 private static class NullHolderTemplateResource
294 implements TemplateResource {
295
296
300 public NullHolderTemplateResource() {
301 }
302
303 @Override
304 public long getLastModified() {
305 return _lastModified;
306 }
307
308 @Override
309 public Reader getReader() {
310 return null;
311 }
312
313 @Override
314 public String getTemplateId() {
315 return null;
316 }
317
318 @Override
319 public void readExternal(ObjectInput objectInput) throws IOException {
320 _lastModified = objectInput.readLong();
321 }
322
323 @Override
324 public void writeExternal(ObjectOutput objectOutput)
325 throws IOException {
326
327 objectOutput.writeLong(_lastModified);
328 }
329
330 private long _lastModified = System.currentTimeMillis();
331
332 }
333
334 }