001
014
015 package com.liferay.portal.velocity;
016
017 import com.liferay.portal.kernel.cache.PortalCache;
018 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
019 import com.liferay.portal.kernel.template.TemplateConstants;
020 import com.liferay.portal.kernel.template.TemplateResource;
021 import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
022 import com.liferay.portal.kernel.util.PropsKeys;
023 import com.liferay.portal.kernel.util.ReflectionUtil;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.template.TemplateResourceThreadLocal;
026 import com.liferay.portal.util.PropsUtil;
027 import com.liferay.portal.util.PropsValues;
028
029 import java.io.IOException;
030 import java.io.Reader;
031
032 import java.lang.reflect.Field;
033
034 import java.security.AccessController;
035 import java.security.PrivilegedActionException;
036 import java.security.PrivilegedExceptionAction;
037
038 import org.apache.commons.collections.ExtendedProperties;
039 import org.apache.velocity.Template;
040 import org.apache.velocity.exception.ParseErrorException;
041 import org.apache.velocity.exception.ResourceNotFoundException;
042 import org.apache.velocity.runtime.RuntimeInstance;
043 import org.apache.velocity.runtime.RuntimeServices;
044 import org.apache.velocity.runtime.resource.Resource;
045 import org.apache.velocity.runtime.resource.ResourceManager;
046 import org.apache.velocity.runtime.resource.ResourceManagerImpl;
047
048
052 public class LiferayResourceManager extends ResourceManagerImpl {
053
054 public LiferayResourceManager() {
055 String cacheName = TemplateResource.class.getName();
056
057 cacheName = cacheName.concat(StringPool.POUND).concat(
058 TemplateConstants.LANG_TYPE_VM);
059
060 _portalCache = SingleVMPoolUtil.getCache(cacheName);
061 }
062
063 @Override
064 public String getLoaderNameForResource(String source) {
065
066
067
068
069 if ((globalCache.get(ResourceManager.RESOURCE_CONTENT + source) !=
070 null) ||
071 (globalCache.get(ResourceManager.RESOURCE_TEMPLATE + source) !=
072 null)) {
073
074 return LiferayResourceLoader.class.getName();
075 }
076 else {
077 return super.getLoaderNameForResource(source);
078 }
079 }
080
081 @Override
082 public Resource getResource(
083 final String resourceName, final int resourceType,
084 final String encoding)
085 throws Exception, ParseErrorException, ResourceNotFoundException {
086
087 String[] macroTemplateIds = PropsUtil.getArray(
088 PropsKeys.VELOCITY_ENGINE_VELOCIMACRO_LIBRARY);
089
090 for (String macroTemplateId : macroTemplateIds) {
091 if (resourceName.equals(macroTemplateId)) {
092
093
094
095
096 try {
097 return AccessController.doPrivileged(
098 new ResourcePrivilegedExceptionAction(
099 resourceName, resourceType, encoding));
100 }
101 catch (PrivilegedActionException pae) {
102 throw (IOException)pae.getException();
103 }
104 }
105 }
106
107 return doGetResource(resourceName, resourceType, encoding);
108 }
109
110 @Override
111 public synchronized void initialize(RuntimeServices runtimeServices)
112 throws Exception {
113
114 ExtendedProperties extendedProperties =
115 runtimeServices.getConfiguration();
116
117 Field field = ReflectionUtil.getDeclaredField(
118 RuntimeInstance.class, "configuration");
119
120 field.set(
121 runtimeServices, new FastExtendedProperties(extendedProperties));
122
123 super.initialize(runtimeServices);
124 }
125
126 private Template _createTemplate(TemplateResource templateResource)
127 throws IOException {
128
129 Template template = new LiferayTemplate(templateResource.getReader());
130
131 template.setEncoding(TemplateConstants.DEFAUT_ENCODING);
132 template.setName(templateResource.getTemplateId());
133 template.setResourceLoader(new LiferayResourceLoader());
134 template.setRuntimeServices(rsvc);
135
136 template.process();
137
138 return template;
139 }
140
141 private Resource doGetResource(
142 final String resourceName, final int resourceType,
143 final String encoding)
144 throws Exception, ParseErrorException, ResourceNotFoundException {
145
146 if (resourceType != ResourceManager.RESOURCE_TEMPLATE) {
147 return super.getResource(resourceName, resourceType, encoding);
148 }
149
150 TemplateResource templateResource = null;
151
152 if (resourceName.startsWith(
153 TemplateConstants.TEMPLATE_RESOURCE_UUID_PREFIX)) {
154
155 templateResource = TemplateResourceThreadLocal.getTemplateResource(
156 TemplateConstants.LANG_TYPE_VM);
157 }
158 else {
159 templateResource = TemplateResourceLoaderUtil.getTemplateResource(
160 TemplateConstants.LANG_TYPE_VM, resourceName);
161 }
162
163 if (templateResource == null) {
164 throw new ResourceNotFoundException(
165 "Unable to find Velocity template with ID " + resourceName);
166 }
167
168 Object object = _portalCache.get(templateResource);
169
170 if ((object != null) && (object instanceof Template)) {
171 return (Template)object;
172 }
173
174 Template template = _createTemplate(templateResource);
175
176 if (PropsValues.VELOCITY_ENGINE_RESOURCE_MODIFICATION_CHECK_INTERVAL !=
177 0) {
178
179 _portalCache.put(templateResource, template);
180 }
181
182 return template;
183 }
184
185 private PortalCache<TemplateResource, Object> _portalCache;
186
187 private class LiferayTemplate extends Template {
188
189 public LiferayTemplate(Reader reader) {
190 _reader = reader;
191 }
192
193 @Override
194 public boolean process() throws IOException, ParseErrorException {
195 data = null;
196
197 try {
198 data = rsvc.parse(_reader, name);
199
200 initDocument();
201
202 return true;
203 }
204 catch (Exception e) {
205 throw new ParseErrorException(
206 "Unable to parse Velocity template");
207 }
208 finally {
209 if (_reader != null) {
210 _reader.close();
211 }
212 }
213 }
214
215 private Reader _reader;
216
217 }
218
219 private class ResourcePrivilegedExceptionAction
220 implements PrivilegedExceptionAction<Resource> {
221
222 public ResourcePrivilegedExceptionAction(
223 String resourceName, int resourceType, String encoding) {
224
225 _resourceName = resourceName;
226 _resourceType = resourceType;
227 _encoding = encoding;
228 }
229
230 @Override
231 public Resource run() throws Exception {
232 return doGetResource(_resourceName, _resourceType, _encoding);
233 }
234
235 private String _encoding;
236 private String _resourceName;
237 private int _resourceType;
238
239 }
240
241 }