1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.commons.resourcehandler.resource;
20
21 import java.util.Collections;
22 import java.util.LinkedHashMap;
23 import java.util.Map;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import javax.faces.application.ProjectStage;
28 import javax.faces.context.ExternalContext;
29 import javax.faces.context.FacesContext;
30
31 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
32 import org.apache.myfaces.commons.util.WebConfigParamUtils;
33
34 public class ResourceHandlerCache
35 {
36 private static final Logger log = Logger
37 .getLogger(ResourceHandlerCache.class.getName());
38
39 private Boolean _resourceCacheEnabled = null;
40 private Map<ResourceKey, ResourceValue> _resourceCacheMap = null;
41
42 @JSFWebConfigParam(defaultValue = "500", since = "2.0.2")
43 private static final String RESOURCE_HANDLER_CACHE_SIZE_ATTRIBUTE = "org.apache.myfaces.RESOURCE_HANDLER_CACHE_SIZE";
44 private static final int RESOURCE_HANDLER_CACHE_DEFAULT_SIZE = 500;
45
46 @JSFWebConfigParam(defaultValue = "true", since = "2.0.2")
47 private static final String RESOURCE_HANDLER_CACHE_ENABLED_ATTRIBUTE = "org.apache.myfaces.RESOURCE_HANDLER_CACHE_ENABLED";
48 private static final boolean RESOURCE_HANDLER_CACHE_ENABLED_DEFAULT = true;
49
50 public ResourceValue getResource(String resourceName, String libraryName,
51 String contentType, String localePrefix)
52 {
53 if (!isResourceCachingEnabled() || _resourceCacheMap == null)
54 return null;
55
56 if (log.isLoggable(Level.FINE))
57 log.log(Level.FINE, "Attemping to get resource from cache for "
58 + resourceName);
59
60 ResourceKey key = new ResourceKey(resourceName, libraryName, contentType, localePrefix);
61
62 return _resourceCacheMap.get(key);
63 }
64
65 public boolean containsResource(String resourceName, String libraryName, String contentType, String localePrefix)
66 {
67 if (!isResourceCachingEnabled() || _resourceCacheMap == null)
68 return false;
69
70 ResourceKey key = new ResourceKey(resourceName, libraryName, contentType, localePrefix);
71 return _resourceCacheMap.containsKey(key);
72 }
73
74 public void putResource(String resourceName, String libraryName,
75 String contentType, String localePrefix, ResourceMeta resource, ResourceLoader loader)
76 {
77 if (!isResourceCachingEnabled())
78 return;
79
80 if (log.isLoggable(Level.FINE))
81 log.log(Level.FINE, "Attemping to put resource to cache for "
82 + resourceName);
83
84 if (_resourceCacheMap == null)
85 {
86 if (log.isLoggable(Level.FINE))
87 log.log(Level.FINE, "Initializing resource cache map");
88 _resourceCacheMap = Collections
89 .synchronizedMap(new _ResourceMap<ResourceKey, ResourceValue>(
90 getMaxSize()));
91 }
92
93 _resourceCacheMap.put(new ResourceKey(resourceName, libraryName,
94 contentType, localePrefix), new ResourceValue(resource, loader));
95 }
96
97 private boolean isResourceCachingEnabled()
98 {
99 if (_resourceCacheEnabled == null)
100 {
101 FacesContext facesContext = FacesContext.getCurrentInstance();
102
103
104 if (!facesContext.isProjectStage(ProjectStage.Production))
105 {
106 return _resourceCacheEnabled = Boolean.FALSE;
107 }
108
109 ExternalContext externalContext = facesContext.getExternalContext();
110 if (externalContext == null)
111 return false;
112
113
114 _resourceCacheEnabled = WebConfigParamUtils.getBooleanInitParameter(externalContext,
115 ResourceHandlerCache.RESOURCE_HANDLER_CACHE_ENABLED_ATTRIBUTE,
116 ResourceHandlerCache.RESOURCE_HANDLER_CACHE_ENABLED_DEFAULT);
117
118 if (log.isLoggable(Level.FINE))
119 {
120 log.log(Level.FINE, "MyFaces Resource Caching Enabled="
121 + _resourceCacheEnabled);
122 }
123 }
124 return _resourceCacheEnabled;
125 }
126
127 private int getMaxSize()
128 {
129
130 ExternalContext externalContext = FacesContext.getCurrentInstance()
131 .getExternalContext();
132 return WebConfigParamUtils.getIntegerInitParameter(externalContext,
133 RESOURCE_HANDLER_CACHE_SIZE_ATTRIBUTE, RESOURCE_HANDLER_CACHE_DEFAULT_SIZE);
134 }
135
136 public static class ResourceKey
137 {
138 private String resourceName;
139 private String libraryName;
140 private String contentType;
141 private String localePrefix;
142
143 public ResourceKey(String resourceName, String libraryName,
144 String contentType, String localePrefix)
145 {
146 this.resourceName = resourceName;
147 this.libraryName = libraryName;
148 this.contentType = contentType;
149 this.localePrefix = localePrefix;
150 }
151
152 @Override
153 public boolean equals(Object o)
154 {
155 if (this == o)
156 {
157 return true;
158 }
159 if (o == null || getClass() != o.getClass())
160 {
161 return false;
162 }
163
164 ResourceKey that = (ResourceKey) o;
165
166 if (contentType != null ? !contentType.equals(that.contentType) : that.contentType != null)
167 {
168 return false;
169 }
170 if (libraryName != null ? !libraryName.equals(that.libraryName) : that.libraryName != null)
171 {
172 return false;
173 }
174 if (localePrefix != null ? !localePrefix.equals(that.localePrefix) : that.localePrefix != null)
175 {
176 return false;
177 }
178 if (resourceName != null ? !resourceName.equals(that.resourceName) : that.resourceName != null)
179 {
180 return false;
181 }
182
183 return true;
184 }
185
186 @Override
187 public int hashCode()
188 {
189 int result = resourceName != null ? resourceName.hashCode() : 0;
190 result = 31 * result + (libraryName != null ? libraryName.hashCode() : 0);
191 result = 31 * result + (contentType != null ? contentType.hashCode() : 0);
192 result = 31 * result + (localePrefix != null ? localePrefix.hashCode() : 0);
193 return result;
194 }
195 }
196
197 public static class ResourceValue
198 {
199 private ResourceMeta resourceMeta;
200
201 private ResourceLoader resourceLoader;
202
203 public ResourceValue(ResourceMeta resourceMeta,
204 ResourceLoader resourceLoader)
205 {
206 super();
207 this.resourceMeta = resourceMeta;
208 this.resourceLoader = resourceLoader;
209 }
210
211 public ResourceMeta getResourceMeta()
212 {
213 return resourceMeta;
214 }
215
216 public ResourceLoader getResourceLoader()
217 {
218 return resourceLoader;
219 }
220 }
221
222 private static class _ResourceMap<K, V> extends LinkedHashMap<K, V>
223 {
224 private static final long serialVersionUID = 1L;
225 private int maxCapacity;
226
227 public _ResourceMap(int cacheSize)
228 {
229
230 super(cacheSize + 1, 1.1f, true);
231 maxCapacity = cacheSize;
232 }
233
234 @Override
235 protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
236 {
237 return size() > maxCapacity;
238 }
239 }
240 }