1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.impl;
20
21 import java.io.IOException;
22 import java.net.URL;
23 import java.net.URLConnection;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.concurrent.ConcurrentHashMap;
29
30 import javax.faces.view.facelets.FaceletContext;
31 import javax.faces.view.facelets.FaceletException;
32
33 import org.apache.myfaces.shared.resource.ResourceLoaderUtils;
34 import org.apache.myfaces.view.facelets.AbstractFaceletCache;
35 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
36 import org.apache.myfaces.view.facelets.util.ParameterCheck;
37
38
39
40
41
42
43
44
45
46 class CacheELFaceletCacheImpl extends AbstractFaceletCache<DefaultFacelet>
47 {
48
49 private static final long INFINITE_DELAY = -1;
50 private static final long NO_CACHE_DELAY = 0;
51
52
53
54
55
56
57
58
59 private Map<String, FaceletNode> _facelets;
60
61 private Map<String, DefaultFacelet> _viewMetadataFacelets;
62
63 private Map<String, DefaultFacelet> _compositeComponentMetadataFacelets;
64
65 private long _refreshPeriod;
66
67 CacheELFaceletCacheImpl(long refreshPeriod)
68 {
69 _refreshPeriod = refreshPeriod < 0 ? INFINITE_DELAY : refreshPeriod * 1000;
70
71 _facelets = new ConcurrentHashMap<String, FaceletNode>();
72
73 _viewMetadataFacelets = new ConcurrentHashMap<String, DefaultFacelet>();
74
75 _compositeComponentMetadataFacelets = new ConcurrentHashMap<String, DefaultFacelet>();
76 }
77
78 @Override
79 public DefaultFacelet getFacelet(URL url) throws IOException
80 {
81 ParameterCheck.notNull("url", url);
82
83 String key = url.toString();
84
85 FaceletNode node = _facelets.get(key);
86 DefaultFacelet f = node != null ? node.getFacelet() : null;
87
88 if (f == null || this.needsToBeRefreshed(f))
89 {
90
91 Set<String> paramsSet = null;
92 if (node != null)
93 {
94 paramsSet = node.getParams();
95 }
96 f = getMemberFactory().newInstance(url);
97 if (_refreshPeriod != NO_CACHE_DELAY)
98 {
99
100
101
102
103 _facelets.put(key, (paramsSet != null && !paramsSet.isEmpty()) ?
104 new FaceletNode(f, paramsSet) : new FaceletNode(f) );
105 }
106 }
107
108 return f;
109 }
110
111 @Override
112 public DefaultFacelet getFacelet(FaceletContext ctx, URL url) throws IOException
113 {
114 String key = url.toString();
115
116
117
118
119
120
121
122
123 FaceletNode node = _facelets.get(key);
124 DefaultFacelet f = (node != null) ? node.getFacelet() : null;
125
126 Set<String> paramsSet = Collections.emptySet();
127 paramsSet = (node != null) ? node.getParams() : paramsSet;
128
129 AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
130 Set<String> knownParameters = actx.getTemplateContext().isKnownParametersEmpty() ?
131 (Set) Collections.emptySet() : actx.getTemplateContext().getKnownParameters();
132
133 boolean create = false;
134 for (String paramKey : knownParameters)
135 {
136 if (!paramsSet.contains(paramKey))
137 {
138 create = true;
139 break;
140 }
141 }
142
143 if (f == null || this.needsToBeRefreshed(f) || create)
144 {
145
146 f = getMemberFactory().newInstance(url);
147 if (_refreshPeriod != NO_CACHE_DELAY)
148 {
149
150 if (!paramsSet.isEmpty()|| !knownParameters.isEmpty() )
151 {
152 paramsSet = new HashSet(paramsSet);
153 paramsSet.addAll(knownParameters);
154
155 _facelets.put(key, new FaceletNode(f, paramsSet));
156 }
157 else
158 {
159
160 _facelets.put(key, new FaceletNode(f));
161 }
162
163 }
164 }
165
166 if (!paramsSet.isEmpty())
167 {
168
169 for (String param : paramsSet)
170 {
171 if (!actx.getTemplateContext().containsKnownParameter(param))
172 {
173 actx.getTemplateContext().addKnownParameters(param);
174 }
175 }
176 }
177
178 return f;
179 }
180
181 @Override
182 public boolean isFaceletCached(URL url)
183 {
184 return _facelets.containsKey(url.toString());
185 }
186
187 @Override
188 public DefaultFacelet getViewMetadataFacelet(URL url) throws IOException
189 {
190 ParameterCheck.notNull("url", url);
191
192 String key = url.toString();
193
194 DefaultFacelet f = _viewMetadataFacelets.get(key);
195
196 if (f == null || this.needsToBeRefreshed(f))
197 {
198
199 f = getMetadataMemberFactory().newInstance(url);
200 if (_refreshPeriod != NO_CACHE_DELAY)
201 {
202
203
204
205 _viewMetadataFacelets.put(key, f);
206 }
207 }
208
209 return f;
210 }
211
212 @Override
213 public boolean isViewMetadataFaceletCached(URL url)
214 {
215 return _viewMetadataFacelets.containsKey(url.toString());
216 }
217
218
219
220
221
222
223
224
225 protected boolean needsToBeRefreshed(DefaultFacelet facelet)
226 {
227
228 if (_refreshPeriod == NO_CACHE_DELAY)
229 {
230 return true;
231 }
232
233
234 if (_refreshPeriod == INFINITE_DELAY)
235 {
236 return false;
237 }
238
239 long target = facelet.getCreateTime() + _refreshPeriod;
240 if (System.currentTimeMillis() > target)
241 {
242
243
244 try
245 {
246 URLConnection conn = facelet.getSource().openConnection();
247 long lastModified = ResourceLoaderUtils.getResourceLastModified(conn);
248
249 return lastModified == 0 || lastModified > target;
250 }
251 catch (IOException e)
252 {
253 throw new FaceletException("Error Checking Last Modified for " + facelet.getAlias(), e);
254 }
255 }
256
257 return false;
258 }
259
260 @Override
261 public DefaultFacelet getCompositeComponentMetadataFacelet(URL url) throws IOException
262 {
263 ParameterCheck.notNull("url", url);
264
265 String key = url.toString();
266
267 DefaultFacelet f = _compositeComponentMetadataFacelets.get(key);
268
269 if (f == null || this.needsToBeRefreshed(f))
270 {
271 f = getCompositeComponentMetadataMemberFactory().newInstance(url);
272 if (_refreshPeriod != NO_CACHE_DELAY)
273 {
274
275
276
277
278 _compositeComponentMetadataFacelets.put(key, f);
279 }
280 }
281 return f;
282 }
283
284 @Override
285 public boolean isCompositeComponentMetadataFaceletCached(URL url)
286 {
287 return _compositeComponentMetadataFacelets.containsKey(url.toString());
288 }
289
290 private static class FaceletNode
291 {
292 private DefaultFacelet facelet;
293 private Set<String> params;
294
295 public FaceletNode(DefaultFacelet facelet)
296 {
297 this.facelet = facelet;
298 this.params = Collections.emptySet();
299 }
300
301 public FaceletNode(DefaultFacelet facelet, Set<String> params)
302 {
303 this.facelet = facelet;
304 this.params = params;
305 }
306
307
308
309
310 public DefaultFacelet getFacelet()
311 {
312 return facelet;
313 }
314
315
316
317
318 public void setFacelet(DefaultFacelet facelet)
319 {
320 this.facelet = facelet;
321 }
322
323
324
325
326 public Set<String> getParams()
327 {
328 return params;
329 }
330
331
332
333
334 public void setParams(Set<String> params)
335 {
336 this.params = params;
337 }
338
339 }
340 }