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.tag;
20
21 import java.util.Arrays;
22
23 import javax.el.ELException;
24 import javax.el.ExpressionFactory;
25 import javax.el.MethodExpression;
26 import javax.el.ValueExpression;
27 import javax.faces.component.UIComponent;
28 import javax.faces.view.Location;
29 import javax.faces.view.facelets.FaceletContext;
30 import javax.faces.view.facelets.TagAttribute;
31 import javax.faces.view.facelets.TagAttributeException;
32
33 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
34 import org.apache.myfaces.view.facelets.el.CompositeComponentELUtils;
35 import org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression;
36 import org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression;
37 import org.apache.myfaces.view.facelets.el.ELText;
38 import org.apache.myfaces.view.facelets.el.LocationMethodExpression;
39 import org.apache.myfaces.view.facelets.el.LocationValueExpression;
40 import org.apache.myfaces.view.facelets.el.ResourceELUtils;
41 import org.apache.myfaces.view.facelets.el.ResourceLocationValueExpression;
42 import org.apache.myfaces.view.facelets.el.TagMethodExpression;
43 import org.apache.myfaces.view.facelets.el.TagValueExpression;
44 import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;
45
46
47
48
49
50
51
52 public final class TagAttributeImpl extends TagAttribute
53 {
54
55 private final static int EL_LITERAL = 1;
56
57 private final static int EL_CC = 2;
58
59 private final static int EL_CC_ATTR_ME = 4;
60
61 private final static int EL_RESOURCE = 8;
62
63 private final int capabilities;
64
65 private final String localName;
66
67 private final Location location;
68
69 private final String namespace;
70
71 private final String qName;
72
73 private final String value;
74
75 private String string;
76
77
78
79
80
81
82
83 private volatile Object[] cachedExpression;
84
85 public TagAttributeImpl(Location location, String ns, String localName, String qName, String value)
86 {
87 boolean literal;
88 boolean compositeComponentExpression;
89 boolean compositeComponentAttrMethodExpression;
90 boolean resourceExpression;
91 this.location = location;
92 this.namespace = ns;
93
94
95
96 this.localName = (localName == null) ? qName : ((localName.length() > 0) ? localName : qName);
97 this.qName = qName;
98 this.value = value;
99
100 try
101 {
102 literal = ELText.isLiteral(this.value);
103 }
104 catch (ELException e)
105 {
106 throw new TagAttributeException(this, e);
107 }
108
109 compositeComponentExpression = !literal ?
110 CompositeComponentELUtils.isCompositeComponentExpression(this.value) :
111 false;
112 compositeComponentAttrMethodExpression = compositeComponentExpression ?
113 CompositeComponentELUtils.isCompositeComponentAttrsMethodExpression(this.value) :
114 false;
115 resourceExpression = !literal ? ResourceELUtils.isResourceExpression(this.value) : false;
116
117 this.capabilities = (literal ? EL_LITERAL : 0) | (compositeComponentExpression ? EL_CC : 0) |
118 (compositeComponentAttrMethodExpression ? EL_CC_ATTR_ME : 0) | ( resourceExpression ? EL_RESOURCE : 0);
119 }
120
121
122
123
124
125
126
127
128
129
130
131 public boolean getBoolean(FaceletContext ctx)
132 {
133 if ((this.capabilities & EL_LITERAL) != 0)
134 {
135 return Boolean.valueOf(this.value).booleanValue();
136 }
137 else
138 {
139 return ((Boolean) this.getObject(ctx, Boolean.class)).booleanValue();
140 }
141 }
142
143
144
145
146
147
148
149
150
151
152
153 public int getInt(FaceletContext ctx)
154 {
155 if ((this.capabilities & EL_LITERAL) != 0)
156 {
157 return Integer.parseInt(this.value);
158 }
159 else
160 {
161 return ((Number) this.getObject(ctx, Integer.class)).intValue();
162 }
163 }
164
165
166
167
168
169
170 public String getLocalName()
171 {
172 return this.localName;
173 }
174
175
176
177
178
179
180 public Location getLocation()
181 {
182 return this.location;
183 }
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 public MethodExpression getMethodExpression(FaceletContext ctx, Class type, Class[] paramTypes)
200 {
201 AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
202
203
204 Object[] localCachedExpression = cachedExpression;
205
206 if (actx.isAllowCacheELExpressions() && localCachedExpression != null &&
207 (localCachedExpression.length % 3 == 0))
208 {
209
210 for (int i = 0; i < (localCachedExpression.length/3); i++)
211 {
212 if ( ((type == null && localCachedExpression[(i*3)] == null ) ||
213 (type != null && type.equals(localCachedExpression[(i*3)])) ) &&
214 (Arrays.equals(paramTypes, (Class[]) localCachedExpression[(i*3)+1])) )
215 {
216 if ((this.capabilities & EL_CC) != 0 &&
217 localCachedExpression[(i*3)+2] instanceof LocationMethodExpression)
218 {
219 UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
220 if (cc != null)
221 {
222 Location location = (Location) cc.getAttributes().get(
223 CompositeComponentELUtils.LOCATION_KEY);
224 if (location != null)
225 {
226 return ((LocationMethodExpression)localCachedExpression[(i*3)+2]).apply(
227 actx.getFaceletCompositionContext().getCompositeComponentLevel(), location);
228 }
229 }
230 return ((LocationMethodExpression)localCachedExpression[(i*3)+2]).apply(
231 actx.getFaceletCompositionContext().getCompositeComponentLevel());
232 }
233 return (MethodExpression) localCachedExpression[(i*3)+2];
234 }
235 }
236 }
237
238 actx.beforeConstructELExpression();
239 try
240 {
241 MethodExpression methodExpression = null;
242
243
244
245
246
247
248 if ((this.capabilities & EL_CC_ATTR_ME) != 0)
249 {
250
251
252
253
254
255 if (this.value.contains("("))
256 {
257
258
259
260 throw new ELException("Cannot add parameters to a MethodExpression "
261 + "pointing to cc.attrs");
262 }
263
264 ValueExpression valueExpr = this.getValueExpression(ctx, Object.class);
265 methodExpression = new ValueExpressionMethodExpression(valueExpr);
266
267 if (actx.getFaceletCompositionContext().isWrapTagExceptionsAsContextAware())
268 {
269 methodExpression = new ContextAwareTagMethodExpression(this, methodExpression);
270 }
271 else
272 {
273 methodExpression = new TagMethodExpression(this, methodExpression);
274 }
275 }
276 else
277 {
278 ExpressionFactory f = ctx.getExpressionFactory();
279 methodExpression = f.createMethodExpression(ctx, this.value, type, paramTypes);
280
281 if (actx.getFaceletCompositionContext().isWrapTagExceptionsAsContextAware())
282 {
283 methodExpression = new ContextAwareTagMethodExpression(this, methodExpression);
284 }
285 else
286 {
287 methodExpression = new TagMethodExpression(this, methodExpression);
288 }
289
290
291
292
293
294
295 if ((this.capabilities & EL_CC) != 0)
296 {
297 Location currentLocation = getLocation();
298 UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
299 if (cc != null)
300 {
301 Location ccLocation = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
302 if (ccLocation != null && !ccLocation.getPath().equals(currentLocation.getPath()))
303 {
304
305
306
307 currentLocation = ccLocation;
308 }
309 }
310 methodExpression = new LocationMethodExpression(currentLocation, methodExpression,
311 actx.getFaceletCompositionContext().getCompositeComponentLevel());
312 }
313 }
314
315
316 if (actx.isAllowCacheELExpressions() && !actx.isAnyFaceletsVariableResolved())
317 {
318 if (localCachedExpression != null && (localCachedExpression.length % 3 == 0))
319 {
320
321
322 Object[] array = new Object[localCachedExpression.length+3];
323 array[0] = type;
324 array[1] = paramTypes;
325 array[2] = methodExpression;
326 for (int i = 0; i < localCachedExpression.length; i++)
327 {
328 array[i+3] = localCachedExpression[i];
329 }
330 cachedExpression = array;
331 }
332 else
333 {
334 cachedExpression = new Object[]{type, paramTypes, methodExpression};
335 }
336 }
337
338 return methodExpression;
339 }
340 catch (Exception e)
341 {
342 throw new TagAttributeException(this, e);
343 }
344 finally
345 {
346 actx.afterConstructELExpression();
347 }
348 }
349
350
351
352
353
354
355 public String getNamespace()
356 {
357 return this.namespace;
358 }
359
360
361
362
363
364
365
366
367
368 public Object getObject(FaceletContext ctx)
369 {
370 return this.getObject(ctx, Object.class);
371 }
372
373
374
375
376
377
378 public String getQName()
379 {
380 return this.qName;
381 }
382
383
384
385
386
387
388 public String getValue()
389 {
390 return this.value;
391 }
392
393
394
395
396
397
398
399
400
401 public String getValue(FaceletContext ctx)
402 {
403 if ((this.capabilities & EL_LITERAL) != 0)
404 {
405 return this.value;
406 }
407 else
408 {
409 return (String) this.getObject(ctx, String.class);
410 }
411 }
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 public Object getObject(FaceletContext ctx, Class type)
427 {
428 if ((this.capabilities & EL_LITERAL) != 0)
429 {
430 if (String.class.equals(type))
431 {
432 return this.value;
433 }
434 else
435 {
436 try
437 {
438 return ctx.getExpressionFactory().coerceToType(this.value, type);
439 }
440 catch (Exception e)
441 {
442 throw new TagAttributeException(this, e);
443 }
444 }
445 }
446 else
447 {
448 ValueExpression ve = this.getValueExpression(ctx, type);
449 try
450 {
451 return ve.getValue(ctx);
452 }
453 catch (Exception e)
454 {
455 throw new TagAttributeException(this, e);
456 }
457 }
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471 public ValueExpression getValueExpression(FaceletContext ctx, Class type)
472 {
473 AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
474
475
476 Object[] localCachedExpression = cachedExpression;
477 if (actx.isAllowCacheELExpressions() && localCachedExpression != null && localCachedExpression.length == 2)
478 {
479
480 if (localCachedExpression[0] == null && type == null)
481 {
482
483 if ((this.capabilities & EL_CC) != 0)
484 {
485 UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
486 if (cc != null)
487 {
488 Location location = (Location) cc.getAttributes().get(
489 CompositeComponentELUtils.LOCATION_KEY);
490 if (location != null)
491 {
492 return ((LocationValueExpression)localCachedExpression[1]).apply(
493 actx.getFaceletCompositionContext().getCompositeComponentLevel(), location);
494 }
495 }
496 return ((LocationValueExpression)localCachedExpression[1]).apply(
497 actx.getFaceletCompositionContext().getCompositeComponentLevel());
498 }
499 return (ValueExpression) localCachedExpression[1];
500 }
501 else if (localCachedExpression[0] != null && localCachedExpression[0].equals(type))
502 {
503
504 if ((this.capabilities & EL_CC) != 0)
505 {
506 UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
507 if (cc != null)
508 {
509 Location location = (Location) cc.getAttributes().get(
510 CompositeComponentELUtils.LOCATION_KEY);
511 if (location != null)
512 {
513 return ((LocationValueExpression)localCachedExpression[1]).apply(
514 actx.getFaceletCompositionContext().getCompositeComponentLevel(), location);
515 }
516 }
517 return ((LocationValueExpression)localCachedExpression[1]).apply(
518 actx.getFaceletCompositionContext().getCompositeComponentLevel());
519 }
520 return (ValueExpression) localCachedExpression[1];
521 }
522 }
523
524 actx.beforeConstructELExpression();
525 try
526 {
527 ExpressionFactory f = ctx.getExpressionFactory();
528 ValueExpression valueExpression = f.createValueExpression(ctx, this.value, type);
529
530 if (actx.getFaceletCompositionContext().isWrapTagExceptionsAsContextAware())
531 {
532 valueExpression = new ContextAwareTagValueExpression(this, valueExpression);
533 }
534 else
535 {
536 valueExpression = new TagValueExpression(this, valueExpression);
537 }
538
539
540
541
542
543
544 if ((this.capabilities & EL_CC) != 0)
545 {
546
547
548
549
550 Location currentLocation = getLocation();
551 UIComponent cc = actx.getFaceletCompositionContext().getCompositeComponentFromStack();
552 if (cc != null)
553 {
554 Location ccLocation = (Location) cc.getAttributes().get(CompositeComponentELUtils.LOCATION_KEY);
555 if (ccLocation != null && !ccLocation.getPath().equals(currentLocation.getPath()))
556 {
557
558
559
560
561 currentLocation = ccLocation;
562 }
563 }
564
565 valueExpression = new LocationValueExpression(currentLocation, valueExpression,
566 actx.getFaceletCompositionContext().getCompositeComponentLevel());
567 }
568 else if ((this.capabilities & EL_RESOURCE) != 0)
569 {
570 valueExpression = new ResourceLocationValueExpression(getLocation(), valueExpression);
571 }
572
573
574 if (actx.isAllowCacheELExpressions() && !actx.isAnyFaceletsVariableResolved())
575 {
576 cachedExpression = new Object[]{type, valueExpression};
577 }
578 return valueExpression;
579 }
580 catch (Exception e)
581 {
582 throw new TagAttributeException(this, e);
583 }
584 finally
585 {
586 actx.afterConstructELExpression();
587 }
588 }
589
590
591
592
593
594
595 public boolean isLiteral()
596 {
597 return (this.capabilities & EL_LITERAL) != 0;
598 }
599
600
601
602
603
604
605 public String toString()
606 {
607 if (this.string == null)
608 {
609 this.string = this.location + " " + this.qName + "=\"" + this.value + "\"";
610 }
611 return this.string;
612 }
613
614 }