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