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