001
014
015 package com.liferay.portal.freemarker;
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.StringPool;
024 import com.liferay.portal.template.TemplateResourceThreadLocal;
025 import com.liferay.portal.util.PropsUtil;
026 import com.liferay.portal.util.PropsValues;
027
028 import freemarker.cache.TemplateCache;
029
030 import freemarker.template.Configuration;
031 import freemarker.template.Template;
032
033 import java.io.IOException;
034
035 import java.security.AccessController;
036 import java.security.PrivilegedActionException;
037 import java.security.PrivilegedExceptionAction;
038
039 import java.util.Locale;
040
041
044 public class LiferayTemplateCache extends TemplateCache {
045
046 public LiferayTemplateCache(Configuration configuration) {
047 _configuration = configuration;
048
049 String cacheName = TemplateResource.class.getName();
050
051 cacheName = cacheName.concat(StringPool.POUND).concat(
052 TemplateConstants.LANG_TYPE_FTL);
053
054 _portalCache = SingleVMPoolUtil.getCache(cacheName);
055 }
056
057 @Override
058 public Template getTemplate(
059 String templateId, Locale locale, String encoding, boolean parse)
060 throws IOException {
061
062 String[] macroTemplateIds = PropsUtil.getArray(
063 PropsKeys.FREEMARKER_ENGINE_MACRO_LIBRARY);
064
065 for (String macroTemplateId : macroTemplateIds) {
066 int pos = macroTemplateId.indexOf(" as ");
067
068 if (pos != -1) {
069 macroTemplateId = macroTemplateId.substring(0, pos);
070 }
071
072 if (templateId.equals(macroTemplateId)) {
073
074
075
076
077 try {
078 return AccessController.doPrivileged(
079 new TemplatePrivilegedExceptionAction(
080 macroTemplateId, locale, encoding, parse));
081 }
082 catch (PrivilegedActionException pae) {
083 throw (IOException)pae.getException();
084 }
085 }
086 }
087
088 return doGetTemplate(templateId, locale, encoding, parse);
089 }
090
091 private Template doGetTemplate(
092 String templateId, Locale locale, String encoding, boolean parse)
093 throws IOException {
094
095 if (templateId == null) {
096 throw new IllegalArgumentException("Argument \"name\" is null");
097 }
098
099 if (locale == null) {
100 throw new IllegalArgumentException("Argument \"locale\" is null");
101 }
102
103 if (encoding == null) {
104 throw new IllegalArgumentException("Argument \"encoding\" is null");
105 }
106
107 TemplateResource templateResource = null;
108
109 if (templateId.startsWith(
110 TemplateConstants.TEMPLATE_RESOURCE_UUID_PREFIX)) {
111
112 templateResource = TemplateResourceThreadLocal.getTemplateResource(
113 TemplateConstants.LANG_TYPE_FTL);
114 }
115 else {
116 try {
117 templateResource =
118 TemplateResourceLoaderUtil.getTemplateResource(
119 TemplateConstants.LANG_TYPE_FTL, templateId);
120 }
121 catch (Exception e) {
122 templateResource = null;
123 }
124 }
125
126 if (templateResource == null) {
127 throw new IOException(
128 "Unable to find FreeMarker template with ID " + templateId);
129 }
130
131 Object object = _portalCache.get(templateResource);
132
133 if ((object != null) && (object instanceof Template)) {
134 return (Template)object;
135 }
136
137 Template template = new Template(
138 templateResource.getTemplateId(), templateResource.getReader(),
139 _configuration, TemplateConstants.DEFAUT_ENCODING);
140
141 if (PropsValues.
142 FREEMARKER_ENGINE_RESOURCE_MODIFICATION_CHECK_INTERVAL != 0) {
143
144 _portalCache.put(templateResource, template);
145 }
146
147 return template;
148 }
149
150 private Configuration _configuration;
151 private PortalCache<TemplateResource, Object> _portalCache;
152
153 private class TemplatePrivilegedExceptionAction
154 implements PrivilegedExceptionAction<Template> {
155
156 public TemplatePrivilegedExceptionAction(
157 String templateId, Locale locale, String encoding, boolean parse) {
158
159 _templateId = templateId;
160 _locale = locale;
161 _encoding = encoding;
162 _parse = parse;
163 }
164
165 @Override
166 public Template run() throws Exception {
167 return doGetTemplate(_templateId, _locale, _encoding, _parse);
168 }
169
170 private String _encoding;
171 private Locale _locale;
172 private boolean _parse;
173 private String _templateId;
174
175 }
176
177 }