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.TemplateManager;
020 import com.liferay.portal.kernel.template.TemplateResource;
021 import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
022 import com.liferay.portal.kernel.util.ReflectionUtil;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.template.TemplateResourceThreadLocal;
025 import com.liferay.portal.util.PropsValues;
026
027 import java.io.IOException;
028 import java.io.Reader;
029
030 import java.lang.reflect.Field;
031
032 import org.apache.commons.collections.ExtendedProperties;
033 import org.apache.velocity.Template;
034 import org.apache.velocity.exception.ParseErrorException;
035 import org.apache.velocity.exception.ResourceNotFoundException;
036 import org.apache.velocity.runtime.RuntimeInstance;
037 import org.apache.velocity.runtime.RuntimeServices;
038 import org.apache.velocity.runtime.resource.Resource;
039 import org.apache.velocity.runtime.resource.ResourceManager;
040 import org.apache.velocity.runtime.resource.ResourceManagerImpl;
041
042
046 public class LiferayResourceManager extends ResourceManagerImpl {
047
048 public LiferayResourceManager() {
049 String cacheName = TemplateResource.class.getName();
050
051 cacheName = cacheName.concat(StringPool.POUND).concat(
052 TemplateManager.VELOCITY);
053
054 _portalCache = SingleVMPoolUtil.getCache(cacheName);
055 }
056
057 @Override
058 public String getLoaderNameForResource(String source) {
059
060
061
062
063 if ((globalCache.get(ResourceManager.RESOURCE_CONTENT + source) !=
064 null) ||
065 (globalCache.get(ResourceManager.RESOURCE_TEMPLATE + source) !=
066 null)) {
067
068 return LiferayResourceLoader.class.getName();
069 }
070 else {
071 return super.getLoaderNameForResource(source);
072 }
073 }
074
075 @Override
076 public Resource getResource(
077 final String resourceName, final int resourceType,
078 final String encoding)
079 throws Exception, ParseErrorException, ResourceNotFoundException {
080
081 if (resourceType != ResourceManager.RESOURCE_TEMPLATE) {
082 return super.getResource(resourceName, resourceType, encoding);
083 }
084
085 TemplateResource templateResource = null;
086
087 if (resourceName.startsWith(
088 TemplateResource.TEMPLATE_RESOURCE_UUID_PREFIX)) {
089
090 templateResource = TemplateResourceThreadLocal.getTemplateResource(
091 TemplateManager.VELOCITY);
092 }
093 else {
094 templateResource = TemplateResourceLoaderUtil.getTemplateResource(
095 TemplateManager.VELOCITY, resourceName);
096 }
097
098 if (templateResource == null) {
099 throw new ResourceNotFoundException(
100 "Unable to find Velocity template with ID " + resourceName);
101 }
102
103 Object object = _portalCache.get(templateResource);
104
105 if ((object != null) && (object instanceof Template)) {
106 return (Template)object;
107 }
108
109 Template template = _createTemplate(templateResource);
110
111 if (PropsValues.VELOCITY_ENGINE_RESOURCE_MODIFICATION_CHECK_INTERVAL !=
112 0) {
113
114 _portalCache.put(templateResource, template);
115 }
116
117 return template;
118 }
119
120 @Override
121 public synchronized void initialize(RuntimeServices runtimeServices)
122 throws Exception {
123
124 ExtendedProperties extendedProperties =
125 runtimeServices.getConfiguration();
126
127 Field field = ReflectionUtil.getDeclaredField(
128 RuntimeInstance.class, "configuration");
129
130 field.set(
131 runtimeServices, new FastExtendedProperties(extendedProperties));
132
133 super.initialize(runtimeServices);
134 }
135
136 private Template _createTemplate(TemplateResource templateResource)
137 throws IOException {
138
139 Template template = new LiferayTemplate(templateResource.getReader());
140
141 template.setEncoding(TemplateResource.DEFAUT_ENCODING);
142 template.setName(templateResource.getTemplateId());
143 template.setResourceLoader(new LiferayResourceLoader());
144 template.setRuntimeServices(rsvc);
145
146 template.process();
147
148 return template;
149 }
150
151 private PortalCache<TemplateResource, Object> _portalCache;
152
153 private class LiferayTemplate extends Template {
154
155 public LiferayTemplate(Reader reader) {
156 _reader = reader;
157 }
158
159 @Override
160 public boolean process() throws IOException, ParseErrorException {
161 data = null;
162
163 try {
164 data = rsvc.parse(_reader, name);
165
166 initDocument();
167
168 return true;
169 }
170 catch (Exception e) {
171 throw new ParseErrorException(
172 "Unable to parse Velocity template");
173 }
174 finally {
175 if (_reader != null) {
176 _reader.close();
177 }
178 }
179 }
180
181 private Reader _reader;
182
183 }
184
185 }