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