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.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.template.TemplateException;
025 import com.liferay.portal.kernel.template.TemplateManager;
026 import com.liferay.portal.kernel.template.TemplateResource;
027 import com.liferay.portal.kernel.template.TemplateResourceLoader;
028 import com.liferay.portal.kernel.util.InstanceFactory;
029 import com.liferay.portal.kernel.util.StringPool;
030 import com.liferay.portal.kernel.util.Validator;
031
032 import java.io.IOException;
033 import java.io.ObjectInput;
034 import java.io.ObjectOutput;
035 import java.io.Reader;
036
037 import java.util.HashSet;
038 import java.util.Set;
039
040
043 public class DefaultTemplateResourceLoader implements TemplateResourceLoader {
044
045 public DefaultTemplateResourceLoader(
046 String name, String[] templateResourceParserClassNames,
047 long modificationCheckInterval) {
048
049 if (Validator.isNull(name)) {
050 throw new IllegalArgumentException(
051 "Template resource loader name is null");
052 }
053
054 if (templateResourceParserClassNames == null) {
055 throw new IllegalArgumentException(
056 "Template resource parser class names is null");
057 }
058
059 _name = name;
060
061 for (String templateResourceParserClassName :
062 templateResourceParserClassNames) {
063
064 try {
065 TemplateResourceParser templateResourceParser =
066 (TemplateResourceParser)InstanceFactory.newInstance(
067 templateResourceParserClassName);
068
069 _templateResourceParsers.add(templateResourceParser);
070 }
071 catch (Exception e) {
072 _log.error(e, e);
073 }
074 }
075
076 _modificationCheckInterval = modificationCheckInterval;
077
078 String cacheName = TemplateResourceLoader.class.getName();
079
080 cacheName = cacheName.concat(StringPool.PERIOD).concat(name);
081
082 _portalCache = MultiVMPoolUtil.getCache(cacheName);
083
084 CacheListener<String, TemplateResource> cacheListener =
085 new TemplateResourceCacheListener(name);
086
087 _portalCache.registerCacheListener(
088 cacheListener, CacheListenerScope.ALL);
089 }
090
091 public void clearCache() {
092 _portalCache.removeAll();
093 }
094
095 public void clearCache(String templateId) {
096 _portalCache.remove(templateId);
097 }
098
099 public void destroy() {
100 _portalCache.destroy();
101
102 _templateResourceParsers.clear();
103 }
104
105 public String getName() {
106 return _name;
107 }
108
109 public TemplateResource getTemplateResource(String templateId) {
110 TemplateResource templateResource = _loadFromCache(templateId);
111
112 if (templateResource != null) {
113 if (templateResource instanceof NullHolderTemplateResource) {
114 return null;
115 }
116
117 return templateResource;
118 }
119
120 templateResource = _loadFromParser(templateId);
121
122 if (_modificationCheckInterval != 0) {
123 if (templateResource == null) {
124 _portalCache.put(templateId, new NullHolderTemplateResource());
125 }
126 else {
127 _portalCache.put(templateId, templateResource);
128 }
129 }
130
131 return templateResource;
132 }
133
134 public boolean hasTemplateResource(String templateId) {
135 TemplateResource templateResource = getTemplateResource(templateId);
136
137 if (templateResource != null) {
138 return true;
139 }
140
141 return false;
142 }
143
144 private TemplateResource _loadFromCache(String templateId) {
145 if (_modificationCheckInterval == 0) {
146 return null;
147 }
148
149 Object object = _portalCache.get(templateId);
150
151 if (object == null) {
152 return null;
153 }
154
155 if (!(object instanceof TemplateResource)) {
156 _portalCache.remove(templateId);
157
158 if (_log.isWarnEnabled()) {
159 _log.warn(
160 "Remove template " + templateId +
161 " because it is not a template resource");
162 }
163
164 return null;
165 }
166
167 TemplateResource templateResource = (TemplateResource)object;
168
169 if (_modificationCheckInterval > 0) {
170 long expireTime =
171 templateResource.getLastModified() + _modificationCheckInterval;
172
173 if (System.currentTimeMillis() > expireTime) {
174 _portalCache.remove(templateId);
175
176 templateResource = null;
177
178 if (_log.isDebugEnabled()) {
179 _log.debug(
180 "Remove expired template resource " + templateId);
181 }
182 }
183 }
184
185 return templateResource;
186 }
187
188 private TemplateResource _loadFromParser(String templateId) {
189 for (TemplateResourceParser templateResourceParser :
190 _templateResourceParsers) {
191
192 try {
193 TemplateResource templateResource =
194 templateResourceParser.getTemplateResource(templateId);
195
196 if (templateResource != null) {
197 if ((_modificationCheckInterval != 0) &&
198 (!_name.equals(TemplateManager.VELOCITY) ||
199 !templateId.contains(
200 SandboxHandler.SANDBOX_MARKER))) {
201
202 templateResource = new CacheTemplateResource(
203 templateResource);
204 }
205
206 return templateResource;
207 }
208 }
209 catch (TemplateException te) {
210 _log.warn(
211 "Unable to parse template " + templateId + " with parser " +
212 templateResourceParser,
213 te);
214 }
215 }
216
217 return null;
218 }
219
220 private static Log _log = LogFactoryUtil.getLog(
221 DefaultTemplateResourceLoader.class);
222
223 private long _modificationCheckInterval;
224 private String _name;
225 private PortalCache<String, TemplateResource> _portalCache;
226 private Set<TemplateResourceParser> _templateResourceParsers =
227 new HashSet<TemplateResourceParser>();
228
229 private static class NullHolderTemplateResource
230 implements TemplateResource {
231
232
236 public NullHolderTemplateResource() {
237 }
238
239 public long getLastModified() {
240 return _lastModified;
241 }
242
243 public Reader getReader() {
244 return null;
245 }
246
247 public String getTemplateId() {
248 return null;
249 }
250
251 public void readExternal(ObjectInput objectInput) throws IOException {
252 _lastModified = objectInput.readLong();
253 }
254
255 public void writeExternal(ObjectOutput objectOutput)
256 throws IOException {
257
258 objectOutput.writeLong(_lastModified);
259 }
260
261 private long _lastModified = System.currentTimeMillis();
262
263 }
264
265 }