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.el;
20
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.regex.Pattern;
24
25 import javax.faces.component.UIComponent;
26 import javax.faces.context.FacesContext;
27 import javax.faces.view.Location;
28
29
30
31
32
33
34
35 public final class CompositeComponentELUtils
36 {
37
38
39
40
41
42
43
44
45
46
47
48 public static final String CURRENT_COMPOSITE_COMPONENT_KEY = "org.apache.myfaces.compositecomponent.current";
49
50
51
52
53
54 public static final String LOCATION_KEY = "org.apache.myfaces.compositecomponent.location";
55
56
57
58
59
60 public static final String LEVEL_KEY = "oam.cc.ccLevel";
61
62
63
64
65 public static final Pattern CC_EXPRESSION_REGEX = Pattern.compile(".*[^\\w\\.]cc[^\\w].*");
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public static final Pattern CC_ATTRS_METHOD_EXPRESSION_REGEX
81 = Pattern.compile("[^\\(]*[^\\w\\.\\(]cc\\.attrs\\.[^\\.]*(\\(.*)?");
82
83 private static final String CC = "cc";
84
85 private static final String CC_ATTRS = "cc.attrs";
86
87 public static final String CC_FIND_COMPONENT_EXPRESSION = "oam.CC_FIND_COMPONENT_EXPRESSION";
88
89
90
91
92 private CompositeComponentELUtils()
93 {
94
95 }
96
97
98
99
100
101
102
103
104
105 public static UIComponent getCompositeComponentBasedOnLocation(final FacesContext facesContext,
106 final Location location)
107 {
108
109 UIComponent currentCompositeComponent = UIComponent.getCurrentCompositeComponent(facesContext);
110
111
112 if (currentCompositeComponent != null)
113 {
114 Location componentLocation = (Location) currentCompositeComponent.getAttributes().get(LOCATION_KEY);
115 if (componentLocation != null
116 && componentLocation.getPath().equals(location.getPath()))
117 {
118 return currentCompositeComponent;
119 }
120 }
121
122 UIComponent currentComponent = UIComponent.getCurrentComponent(facesContext);
123
124 if (currentComponent == null)
125 {
126
127 return null;
128 }
129
130
131 UIComponent matchingCompositeComponent
132 = lookForCompositeComponentOnStack(facesContext, location, currentComponent);
133
134 if (matchingCompositeComponent != null)
135 {
136 return matchingCompositeComponent;
137 }
138
139
140
141
142 if (currentCompositeComponent != null)
143 {
144 currentComponent = currentCompositeComponent;
145 }
146 else
147 {
148
149
150
151 boolean found = false;
152 while (currentComponent != null && !found)
153 {
154 String findComponentExpr = (String) currentComponent.getAttributes().get(CC_FIND_COMPONENT_EXPRESSION);
155 if (findComponentExpr != null)
156 {
157 UIComponent foundComponent = facesContext.getViewRoot().findComponent(findComponentExpr);
158 if (foundComponent != null)
159 {
160 Location foundComponentLocation = (Location) currentComponent.getAttributes().get(LOCATION_KEY);
161 if (foundComponentLocation != null
162 && foundComponentLocation.getPath().equals(location.getPath()))
163 {
164 return foundComponent;
165 }
166 else
167 {
168 while (foundComponent != null)
169 {
170 Location componentLocation
171 = (Location) foundComponent.getAttributes().get(LOCATION_KEY);
172 if (componentLocation != null
173 && componentLocation.getPath().equals(location.getPath()))
174 {
175 return foundComponent;
176 }
177
178 foundComponent = UIComponent.getCompositeComponentParent(foundComponent);
179 }
180 }
181 }
182 }
183
184 if (UIComponent.isCompositeComponent(currentComponent))
185 {
186 found = true;
187 }
188 else
189 {
190 currentComponent = currentComponent.getParent();
191 }
192 }
193 }
194
195
196
197 while (currentComponent != null)
198 {
199 Location componentLocation = (Location) currentComponent.getAttributes().get(LOCATION_KEY);
200 if (componentLocation != null
201 && componentLocation.getPath().equals(location.getPath()))
202 {
203 return currentComponent;
204 }
205
206 currentComponent = UIComponent.getCompositeComponentParent(currentComponent);
207 }
208
209
210 return null;
211 }
212
213 private static UIComponent lookForCompositeComponentOnStack(final FacesContext facesContext,
214 final Location location,
215 UIComponent currentComponent)
216 {
217 if (UIComponent.isCompositeComponent(currentComponent))
218 {
219 Location componentLocation = (Location) currentComponent.getAttributes().get(LOCATION_KEY);
220 if (componentLocation != null
221 && componentLocation.getPath().equals(location.getPath()))
222 {
223 return currentComponent;
224 }
225 }
226 currentComponent.popComponentFromEL(facesContext);
227 try
228 {
229 UIComponent c = UIComponent.getCurrentComponent(facesContext);
230 if (c != null)
231 {
232 return lookForCompositeComponentOnStack( facesContext, location, c);
233 }
234 else
235 {
236 return null;
237 }
238 }
239 finally
240 {
241 currentComponent.pushComponentToEL(facesContext, currentComponent);
242 }
243 }
244
245 private static int getCCLevel(UIComponent component)
246 {
247 Integer ccLevel = (Integer) component.getAttributes().get(LEVEL_KEY);
248 if (ccLevel == null)
249 {
250 return 0;
251 }
252 return ccLevel.intValue();
253 }
254
255 public static UIComponent getCompositeComponentBasedOnLocation(final FacesContext facesContext,
256 UIComponent baseComponent, final Location location)
257 {
258 UIComponent currentComponent = baseComponent;
259 while (currentComponent != null)
260 {
261 Location componentLocation = (Location) currentComponent.getAttributes().get(
262 LOCATION_KEY);
263 if (componentLocation != null
264 && componentLocation.getPath().equals(location.getPath()))
265 {
266 return currentComponent;
267 }
268
269 currentComponent = UIComponent.getCompositeComponentParent(currentComponent);
270 }
271 return null;
272 }
273
274
275
276
277
278
279
280
281
282
283
284 public static UIComponent getCompositeComponentBasedOnLocation(final FacesContext facesContext,
285 final Location location, int ccLevel)
286 {
287
288 UIComponent currentCompositeComponent = UIComponent.getCurrentCompositeComponent(facesContext);
289
290
291 if (currentCompositeComponent != null)
292 {
293 Location componentLocation = (Location) currentCompositeComponent.getAttributes().get(LOCATION_KEY);
294 if (componentLocation != null
295 && componentLocation.getPath().equals(location.getPath()) &&
296 (ccLevel == getCCLevel(currentCompositeComponent)) )
297 {
298 return currentCompositeComponent;
299 }
300 }
301
302 UIComponent currentComponent = UIComponent.getCurrentComponent(facesContext);
303
304 if (currentComponent == null)
305 {
306
307 return null;
308 }
309
310
311 UIComponent matchingCompositeComponent
312 = lookForCompositeComponentOnStack(facesContext, location, ccLevel, currentComponent);
313
314 if (matchingCompositeComponent != null)
315 {
316 return matchingCompositeComponent;
317 }
318
319
320
321
322 if (currentCompositeComponent != null)
323 {
324 currentComponent = currentCompositeComponent;
325 }
326 else
327 {
328
329
330
331 boolean found = false;
332 while (currentComponent != null && !found)
333 {
334 String findComponentExpr = (String) currentComponent.getAttributes().get(CC_FIND_COMPONENT_EXPRESSION);
335 if (findComponentExpr != null)
336 {
337 UIComponent foundComponent = facesContext.getViewRoot().findComponent(findComponentExpr);
338 if (foundComponent != null)
339 {
340 Location foundComponentLocation = (Location) currentComponent.getAttributes().get(LOCATION_KEY);
341 if (foundComponentLocation != null
342 && foundComponentLocation.getPath().equals(location.getPath()) &&
343 ccLevel == getCCLevel(foundComponent))
344 {
345 return foundComponent;
346 }
347 else
348 {
349 while (foundComponent != null)
350 {
351 Location componentLocation
352 = (Location) foundComponent.getAttributes().get(LOCATION_KEY);
353 if (componentLocation != null
354 && componentLocation.getPath().equals(location.getPath()) &&
355 ccLevel == getCCLevel(foundComponent))
356 {
357 return foundComponent;
358 }
359
360 foundComponent = UIComponent.getCompositeComponentParent(foundComponent);
361 }
362 }
363 }
364 }
365
366 if (UIComponent.isCompositeComponent(currentComponent))
367 {
368 found = true;
369 }
370 else
371 {
372 currentComponent = currentComponent.getParent();
373 }
374 }
375 }
376
377
378
379 while (currentComponent != null)
380 {
381 Location componentLocation = (Location) currentComponent.getAttributes().get(LOCATION_KEY);
382 if (componentLocation != null
383 && componentLocation.getPath().equals(location.getPath()) &&
384 ccLevel == getCCLevel(currentComponent))
385 {
386 return currentComponent;
387 }
388
389 currentComponent = UIComponent.getCompositeComponentParent(currentComponent);
390 }
391
392
393 return null;
394 }
395
396 private static UIComponent lookForCompositeComponentOnStack(final FacesContext facesContext,
397 final Location location, int ccLevel,
398 UIComponent currentComponent)
399 {
400 if (UIComponent.isCompositeComponent(currentComponent))
401 {
402 Location componentLocation = (Location) currentComponent.getAttributes().get(LOCATION_KEY);
403 if (componentLocation != null
404 && componentLocation.getPath().equals(location.getPath()) &&
405 (ccLevel == getCCLevel(currentComponent)) )
406 {
407 return currentComponent;
408 }
409 }
410 currentComponent.popComponentFromEL(facesContext);
411 try
412 {
413 UIComponent c = UIComponent.getCurrentComponent(facesContext);
414 if (c != null)
415 {
416 return lookForCompositeComponentOnStack( facesContext, location, ccLevel, c);
417 }
418 else
419 {
420 return null;
421 }
422 }
423 finally
424 {
425 currentComponent.pushComponentToEL(facesContext, currentComponent);
426 }
427 }
428
429
430
431
432
433
434
435
436 public static void saveCompositeComponentForResolver(FacesContext facesContext, Location location, int ccLevel)
437 {
438 UIComponent cc = ccLevel > 0 ? getCompositeComponentBasedOnLocation(facesContext, location, ccLevel)
439 : getCompositeComponentBasedOnLocation(facesContext, location);
440 List<UIComponent> list = (List<UIComponent>) facesContext.getAttributes().get(CURRENT_COMPOSITE_COMPONENT_KEY);
441 if (list == null)
442 {
443 list = new ArrayList<UIComponent>();
444 facesContext.getAttributes().put(CURRENT_COMPOSITE_COMPONENT_KEY, list);
445 }
446 list.add(cc);
447 }
448
449
450
451
452
453 public static void removeCompositeComponentForResolver(FacesContext facesContext)
454 {
455 List<UIComponent> list = (List<UIComponent>) facesContext.getAttributes().get(CURRENT_COMPOSITE_COMPONENT_KEY);
456 if (list != null)
457 {
458 list.remove(list.size()-1);
459 }
460 }
461
462
463
464
465
466 public static boolean isCompositeComponentExpression(String expression)
467 {
468 if (expression.contains(CC))
469 {
470 return CC_EXPRESSION_REGEX.matcher(expression).matches();
471 }
472 else
473 {
474 return false;
475 }
476 }
477
478
479
480
481
482
483
484
485
486 public static boolean isCompositeComponentAttrsMethodExpression(String expression)
487 {
488 if (expression.contains(CC_ATTRS))
489 {
490 return CC_ATTRS_METHOD_EXPRESSION_REGEX.matcher(expression).matches();
491 }
492 else
493 {
494 return false;
495 }
496 }
497
498 }