001
014
015 package com.liferay.util.freemarker;
016
017 import com.liferay.portal.kernel.cache.CacheRegistryItem;
018 import com.liferay.portal.kernel.cache.CacheRegistryUtil;
019 import com.liferay.portal.kernel.memory.FinalizeAction;
020 import com.liferay.portal.kernel.memory.FinalizeManager;
021 import com.liferay.portal.kernel.util.ContextPathUtil;
022 import com.liferay.portal.kernel.util.StringPool;
023
024 import freemarker.ext.jsp.TaglibFactory;
025
026 import freemarker.template.TemplateHashModel;
027 import freemarker.template.TemplateModel;
028 import freemarker.template.TemplateModelException;
029
030 import java.lang.ref.Reference;
031
032 import java.util.Map;
033 import java.util.concurrent.ConcurrentHashMap;
034
035 import javax.servlet.ServletContext;
036
037
040 public class FreeMarkerTaglibFactoryUtil implements CacheRegistryItem {
041
042 public static TemplateHashModel createTaglibFactory(
043 ServletContext servletContext) {
044
045 return new TaglibFactoryCacheWrapper(servletContext);
046 }
047
048 @Override
049 public String getRegistryName() {
050 return _registryName;
051 }
052
053 @Override
054 public void invalidate() {
055 _templateModels.clear();
056 }
057
058 private static FreeMarkerTaglibFactoryUtil _getInstance(
059 ServletContext servletContext) {
060
061 if (_instance != null) {
062 return _instance;
063 }
064
065 synchronized(FreeMarkerTaglibFactoryUtil.class) {
066 if (_instance == null) {
067 String contextPath = ContextPathUtil.getContextPath(
068 servletContext);
069
070
071
072 _instance = new FreeMarkerTaglibFactoryUtil(contextPath);
073
074
075
076
077 CacheRegistryUtil.unregister(_instance._registryName);
078
079
080
081 CacheRegistryUtil.register(_instance);
082
083
084
085
086 final String name = _instance._registryName;
087
088
089
090
091 FinalizeManager.register(
092 servletContext,
093 new FinalizeAction() {
094
095 @Override
096 public void doFinalize(Reference<?> reference) {
097 CacheRegistryUtil.unregister(name);
098 }
099
100 }, FinalizeManager.PHANTOM_REFERENCE_FACTORY);
101 }
102 }
103
104 return _instance;
105 }
106
107 private FreeMarkerTaglibFactoryUtil(String contextPath) {
108 _contextPath = contextPath;
109 _registryName = FreeMarkerTaglibFactoryUtil.class.getName().concat(
110 StringPool.AT).concat(_contextPath);
111 }
112
113 private static volatile FreeMarkerTaglibFactoryUtil _instance;
114
115 private final String _contextPath;
116 private final String _registryName;
117 private Map<String, TemplateModel> _templateModels =
118 new ConcurrentHashMap<String, TemplateModel>();
119
120 private static class TaglibFactoryCacheWrapper
121 implements TemplateHashModel {
122
123 public TaglibFactoryCacheWrapper(ServletContext servletContext) {
124 FreeMarkerTaglibFactoryUtil freeMarkerTaglibFactoryUtil =
125 _getInstance(servletContext);
126
127 _templateModels = freeMarkerTaglibFactoryUtil._templateModels;
128 _taglibFactory = new TaglibFactory(servletContext);
129 }
130
131 @Override
132 public TemplateModel get(String uri) throws TemplateModelException {
133 TemplateModel templateModel = _templateModels.get(uri);
134
135 if (templateModel == null) {
136 templateModel = _taglibFactory.get(uri);
137
138 _templateModels.put(uri, templateModel);
139 }
140
141 return templateModel;
142 }
143
144 @Override
145 public boolean isEmpty() {
146 return false;
147 }
148
149 private final TaglibFactory _taglibFactory;
150 private final Map<String, TemplateModel> _templateModels;
151
152 }
153
154 }