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 public void clearCache() {
094 _portalCache.removeAll();
095 }
096
097 public void clearCache(String templateId) {
098 _portalCache.remove(templateId);
099 }
100
101 public void destroy() {
102 _portalCache.destroy();
103
104 _templateResourceParsers.clear();
105 }
106
107 public String getName() {
108 return _name;
109 }
110
111 public TemplateResource getTemplateResource(String templateId) {
112 TemplateResource templateResource = _loadFromCache(templateId);
113
114 if (templateResource != null) {
115 if (templateResource instanceof NullHolderTemplateResource) {
116 return null;
117 }
118
119 return templateResource;
120 }
121
122 templateResource = _loadFromParser(templateId);
123
124 if (_modificationCheckInterval != 0) {
125 if (templateResource == null) {
126 _portalCache.put(templateId, new NullHolderTemplateResource());
127 }
128 else {
129 _portalCache.put(templateId, templateResource);
130 }
131 }
132
133 return templateResource;
134 }
135
136 public boolean hasTemplateResource(String templateId) {
137 TemplateResource templateResource = getTemplateResource(templateId);
138
139 if (templateResource != null) {
140 return true;
141 }
142
143 return false;
144 }
145
146 private TemplateResource _loadFromCache(String templateId) {
147 if (_modificationCheckInterval == 0) {
148 return null;
149 }
150
151 Object object = _portalCache.get(templateId);
152
153 if (object == null) {
154 return null;
155 }
156
157 if (!(object instanceof TemplateResource)) {
158 _portalCache.remove(templateId);
159
160 if (_log.isWarnEnabled()) {
161 _log.warn(
162 "Remove template " + templateId +
163 " because it is not a template resource");
164 }
165
166 return null;
167 }
168
169 TemplateResource templateResource = (TemplateResource)object;
170
171 if (_modificationCheckInterval > 0) {
172 long expireTime =
173 templateResource.getLastModified() + _modificationCheckInterval;
174
175 if (System.currentTimeMillis() > expireTime) {
176 _portalCache.remove(templateId);
177
178 templateResource = null;
179
180 if (_log.isDebugEnabled()) {
181 _log.debug(
182 "Remove expired template resource " + templateId);
183 }
184 }
185 }
186
187 return templateResource;
188 }
189
190 private TemplateResource _loadFromParser(String templateId) {
191 for (TemplateResourceParser templateResourceParser :
192 _templateResourceParsers) {
193
194 try {
195 TemplateResource templateResource =
196 templateResourceParser.getTemplateResource(templateId);
197
198 if (templateResource != null) {
199 if ((_modificationCheckInterval != 0) &&
200 (!_name.equals(TemplateConstants.LANG_TYPE_VM) ||
201 !templateId.contains(
202 SandboxHandler.SANDBOX_MARKER))) {
203
204 templateResource = new CacheTemplateResource(
205 templateResource);
206 }
207
208 return templateResource;
209 }
210 }
211 catch (TemplateException te) {
212 _log.warn(
213 "Unable to parse template " + templateId + " with parser " +
214 templateResourceParser,
215 te);
216 }
217 }
218
219 return null;
220 }
221
222 private static Log _log = LogFactoryUtil.getLog(
223 DefaultTemplateResourceLoader.class);
224
225 private long _modificationCheckInterval;
226 private String _name;
227 private PortalCache<String, TemplateResource> _portalCache;
228 private Set<TemplateResourceParser> _templateResourceParsers =
229 new HashSet<TemplateResourceParser>();
230
231 private static class NullHolderTemplateResource
232 implements TemplateResource {
233
234
238 public NullHolderTemplateResource() {
239 }
240
241 public long getLastModified() {
242 return _lastModified;
243 }
244
245 public Reader getReader() {
246 return null;
247 }
248
249 public String getTemplateId() {
250 return null;
251 }
252
253 public void readExternal(ObjectInput objectInput) throws IOException {
254 _lastModified = objectInput.readLong();
255 }
256
257 public void writeExternal(ObjectOutput objectOutput)
258 throws IOException {
259
260 objectOutput.writeLong(_lastModified);
261 }
262
263 private long _lastModified = System.currentTimeMillis();
264
265 }
266
267 }