1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
package org.apache.shale.tiger.faces; |
19 | |
|
20 | |
import java.util.ArrayList; |
21 | |
import java.util.HashMap; |
22 | |
import java.util.List; |
23 | |
import java.util.Map; |
24 | |
import javax.faces.context.ExternalContext; |
25 | |
import javax.faces.context.FacesContext; |
26 | |
import javax.faces.el.EvaluationException; |
27 | |
import javax.faces.el.PropertyNotFoundException; |
28 | |
import javax.faces.el.ValueBinding; |
29 | |
import javax.faces.el.VariableResolver; |
30 | |
import org.apache.commons.logging.Log; |
31 | |
import org.apache.commons.logging.LogFactory; |
32 | |
import org.apache.shale.tiger.config.FacesConfigConfig; |
33 | |
import org.apache.shale.tiger.managed.Bean; |
34 | |
import org.apache.shale.tiger.managed.Value; |
35 | |
import org.apache.shale.tiger.managed.config.ListEntriesConfig; |
36 | |
import org.apache.shale.tiger.managed.config.ListEntryConfig; |
37 | |
import org.apache.shale.tiger.managed.config.ManagedBeanConfig; |
38 | |
import org.apache.shale.tiger.managed.config.ManagedPropertyConfig; |
39 | |
import org.apache.shale.tiger.managed.config.MapEntriesConfig; |
40 | |
import org.apache.shale.tiger.managed.config.MapEntryConfig; |
41 | |
import org.apache.shale.tiger.view.faces.LifecycleListener2; |
42 | |
import org.apache.shale.util.ConverterHelper; |
43 | |
import org.apache.shale.util.Messages; |
44 | |
import org.apache.shale.util.PropertyHelper; |
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
|
60 | |
|
61 | |
|
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | |
|
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
|
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
|
82 | |
|
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
|
88 | |
|
89 | |
public class VariableResolverImpl extends VariableResolver { |
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | 18 | public VariableResolverImpl(VariableResolver original) { |
98 | |
|
99 | 18 | this.original = original; |
100 | |
|
101 | 18 | if (log().isInfoEnabled()) { |
102 | 18 | log().info(messages().getMessage("variable.resolver", |
103 | |
new Object[] { original })); |
104 | |
} |
105 | |
|
106 | 18 | } |
107 | |
|
108 | |
|
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | 18 | private ConverterHelper convHelper = new ConverterHelper(); |
115 | |
|
116 | |
|
117 | |
|
118 | |
|
119 | |
|
120 | 18 | private transient Log log = null; |
121 | |
|
122 | |
|
123 | |
|
124 | |
|
125 | |
|
126 | 18 | private transient Messages messages = null; |
127 | |
|
128 | |
|
129 | |
|
130 | |
|
131 | |
|
132 | |
|
133 | 18 | private VariableResolver original = null; |
134 | |
|
135 | |
|
136 | |
|
137 | |
|
138 | |
|
139 | 18 | private PropertyHelper propHelper = new PropertyHelper(); |
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
|
146 | |
|
147 | |
|
148 | |
|
149 | |
|
150 | |
|
151 | |
|
152 | |
|
153 | |
|
154 | |
|
155 | |
public Object resolveVariable(FacesContext context, |
156 | |
String name) throws EvaluationException { |
157 | |
|
158 | 22 | if (log().isDebugEnabled()) { |
159 | 22 | log().debug("resolveVariable(" + name + ")"); |
160 | |
} |
161 | |
|
162 | |
|
163 | 22 | Object value = context.getExternalContext().getRequestMap().get(name); |
164 | 22 | if (value == null) { |
165 | 20 | value = context.getExternalContext().getSessionMap().get(name); |
166 | |
} |
167 | 22 | if (value == null) { |
168 | 13 | value = context.getExternalContext().getApplicationMap().get(name); |
169 | |
} |
170 | 22 | if (value != null) { |
171 | 9 | if (log().isTraceEnabled()) { |
172 | 9 | log().trace("resolveVariable(" + name + ") --> existing bean, so delegate"); |
173 | |
} |
174 | 9 | return original.resolveVariable(context, name); |
175 | |
} |
176 | |
|
177 | |
|
178 | 13 | FacesConfigConfig config = config(context); |
179 | 13 | if (config == null) { |
180 | |
if (log().isTraceEnabled()) { |
181 | |
log().trace("resolveVariable(" + name + ") --> no FacesConfigConfig, so delegate"); |
182 | |
} |
183 | |
return original.resolveVariable(context, name); |
184 | |
} |
185 | 13 | ManagedBeanConfig mb = config.getManagedBean(name); |
186 | 13 | if (mb == null) { |
187 | 2 | if (log().isTraceEnabled()) { |
188 | 2 | log().trace("resolveVariable(" + name + ") --> no ManagedBeanConfig, so delegate"); |
189 | |
} |
190 | 2 | return original.resolveVariable(context, name); |
191 | |
} |
192 | |
|
193 | |
|
194 | 11 | Object created = create(context, mb); |
195 | 11 | return created; |
196 | |
|
197 | |
} |
198 | |
|
199 | |
|
200 | |
|
201 | |
|
202 | |
|
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | 18 | private FacesConfigConfig config = null; |
208 | |
|
209 | |
|
210 | |
|
211 | |
|
212 | |
|
213 | |
|
214 | |
|
215 | |
|
216 | |
private FacesConfigConfig config(FacesContext context) { |
217 | |
|
218 | 13 | if (config == null) { |
219 | 12 | config = (FacesConfigConfig) |
220 | |
context.getExternalContext().getApplicationMap(). |
221 | |
get(LifecycleListener2.FACES_CONFIG_CONFIG); |
222 | |
} |
223 | 13 | return config; |
224 | |
|
225 | |
} |
226 | |
|
227 | |
|
228 | |
|
229 | |
|
230 | |
|
231 | |
|
232 | |
|
233 | |
|
234 | |
|
235 | |
|
236 | |
|
237 | |
|
238 | |
private Object create(FacesContext context, ManagedBeanConfig mb) |
239 | |
throws EvaluationException { |
240 | |
|
241 | 11 | if (log().isDebugEnabled()) { |
242 | 11 | log().debug("create(" + mb.getName() + ")"); |
243 | |
} |
244 | |
|
245 | |
|
246 | 11 | Object instance = instance(context, mb); |
247 | |
|
248 | |
|
249 | 11 | for (ManagedPropertyConfig mp : mb.getProperties().values()) { |
250 | 27 | property(context, mb, mp, instance); |
251 | 27 | } |
252 | |
|
253 | |
|
254 | 11 | ListEntriesConfig listEntries = mb.getListEntries(); |
255 | 11 | if (listEntries != null) { |
256 | |
|
257 | 3 | if (!List.class.isAssignableFrom(instance.getClass())) { |
258 | |
throw new EvaluationException(messages(). |
259 | |
getMessage("list.list", |
260 | |
context.getViewRoot().getLocale(), |
261 | |
new Object[] { instance.getClass().getName() })); |
262 | |
} |
263 | 3 | list(context, listEntries, (List) instance); |
264 | |
} |
265 | |
|
266 | |
|
267 | 11 | MapEntriesConfig mapEntries = mb.getMapEntries(); |
268 | 11 | if (mapEntries != null) { |
269 | 1 | if (!Map.class.isAssignableFrom(instance.getClass())) { |
270 | |
throw new EvaluationException(messages(). |
271 | |
getMessage("map.map", |
272 | |
context.getViewRoot().getLocale(), |
273 | |
new Object[] { instance.getClass().getName() })); |
274 | |
} |
275 | 1 | map(context, mapEntries, (Map) instance); |
276 | |
} |
277 | |
|
278 | |
|
279 | 11 | scope(context, mb, instance); |
280 | |
|
281 | 11 | return instance; |
282 | |
|
283 | |
} |
284 | |
|
285 | |
|
286 | |
|
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
|
292 | |
|
293 | |
|
294 | |
|
295 | |
private Object instance(FacesContext context, ManagedBeanConfig mb) |
296 | |
throws EvaluationException { |
297 | |
|
298 | |
|
299 | 11 | if (mb.getType() == null) { |
300 | |
throw new EvaluationException(messages(). |
301 | |
getMessage("variable.type", |
302 | |
context.getViewRoot().getLocale(), |
303 | |
new Object[] { mb.getName() })); |
304 | |
} |
305 | |
|
306 | |
|
307 | 11 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
308 | 11 | Class clazz = null; |
309 | 11 | Object instance = null; |
310 | |
try { |
311 | 11 | clazz = cl.loadClass(mb.getType()); |
312 | 11 | instance = clazz.newInstance(); |
313 | |
} catch (ClassNotFoundException e) { |
314 | |
throw new EvaluationException(messages(). |
315 | |
getMessage("variable.class", |
316 | |
context.getViewRoot().getLocale(), |
317 | |
new Object[] { mb.getName(), mb.getType() }), e); |
318 | |
} catch (IllegalAccessException e) { |
319 | |
throw new EvaluationException(messages(). |
320 | |
getMessage("variable.access", |
321 | |
context.getViewRoot().getLocale(), |
322 | |
new Object[] { mb.getName(), mb.getType() }), e); |
323 | |
} catch (InstantiationException e) { |
324 | |
throw new EvaluationException(messages(). |
325 | |
getMessage("variable.instantiate", |
326 | |
context.getViewRoot().getLocale(), |
327 | |
new Object[] { mb.getName(), mb.getType() }), e); |
328 | 11 | } |
329 | |
|
330 | 11 | return instance; |
331 | |
|
332 | |
} |
333 | |
|
334 | |
|
335 | |
|
336 | |
|
337 | |
|
338 | |
|
339 | |
|
340 | |
|
341 | |
|
342 | |
|
343 | |
|
344 | |
|
345 | |
private void list(FacesContext context, ListEntriesConfig config, List list) { |
346 | |
|
347 | |
|
348 | 5 | String valueType = config.getValueType(); |
349 | 5 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
350 | 5 | Class type = null; |
351 | |
try { |
352 | 5 | if (valueType != null) { |
353 | 2 | type = cl.loadClass(valueType); |
354 | |
} |
355 | |
} catch (ClassNotFoundException e) { |
356 | |
throw new EvaluationException(messages(). |
357 | |
getMessage("list.class", |
358 | |
context.getViewRoot().getLocale(), |
359 | |
new Object[] { valueType }), e); |
360 | 5 | } |
361 | |
|
362 | |
|
363 | 5 | for (ListEntryConfig entry : config.getEntries()) { |
364 | 24 | if (entry.isNullValue()) { |
365 | 5 | list.add(null); |
366 | 5 | } else if (entry.isExpression()) { |
367 | |
|
368 | |
ValueBinding vb = |
369 | |
context.getApplication().createValueBinding(entry.getValue()); |
370 | |
list.add(vb.getValue(context)); |
371 | |
} else { |
372 | 19 | if (type != null) { |
373 | 7 | list.add(convHelper.asObject(context, type, entry.getValue())); |
374 | 7 | } else { |
375 | 12 | list.add(entry.getValue()); |
376 | |
} |
377 | |
} |
378 | 24 | } |
379 | |
|
380 | 5 | } |
381 | |
|
382 | |
|
383 | |
|
384 | |
|
385 | |
|
386 | |
|
387 | |
private Log log() { |
388 | |
|
389 | 146 | if (log == null) { |
390 | 18 | log = LogFactory.getLog(VariableResolverImpl.class); |
391 | |
} |
392 | 146 | return log; |
393 | |
|
394 | |
} |
395 | |
|
396 | |
|
397 | |
|
398 | |
|
399 | |
|
400 | |
|
401 | |
|
402 | |
|
403 | |
|
404 | |
|
405 | |
|
406 | |
|
407 | |
private void map(FacesContext context, MapEntriesConfig config, Map map) { |
408 | |
|
409 | 3 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); |
410 | |
|
411 | |
|
412 | 3 | String keyType = config.getKeyType(); |
413 | 3 | Class keyClass = null; |
414 | |
try { |
415 | 3 | if (keyType != null) { |
416 | 1 | keyClass = cl.loadClass(keyType); |
417 | |
} |
418 | |
} catch (ClassNotFoundException e) { |
419 | |
throw new EvaluationException(messages(). |
420 | |
getMessage("map.keyClass", |
421 | |
context.getViewRoot().getLocale(), |
422 | |
new Object[] { keyType }), e); |
423 | 3 | } |
424 | |
|
425 | |
|
426 | 3 | String valueType = config.getValueType(); |
427 | 3 | Class valueClass = null; |
428 | |
try { |
429 | 3 | if (valueType != null) { |
430 | 1 | valueClass = cl.loadClass(valueType); |
431 | |
} |
432 | |
} catch (ClassNotFoundException e) { |
433 | |
throw new EvaluationException(messages(). |
434 | |
getMessage("map.valueClass", |
435 | |
context.getViewRoot().getLocale(), |
436 | |
new Object[] { valueType }), e); |
437 | 3 | } |
438 | |
|
439 | |
|
440 | 3 | for (MapEntryConfig entry : config.getEntries()) { |
441 | 10 | Object key = null; |
442 | 10 | if (keyClass != null) { |
443 | 4 | key = convHelper.asObject(context, keyClass, entry.getKey()); |
444 | 4 | } else { |
445 | 6 | key = entry.getKey(); |
446 | |
} |
447 | 10 | if (entry.isNullValue()) { |
448 | 1 | map.put(key, null); |
449 | 1 | } else if (entry.isExpression()) { |
450 | |
|
451 | |
ValueBinding vb = |
452 | |
context.getApplication().createValueBinding(entry.getValue()); |
453 | |
map.put(key, vb.getValue(context)); |
454 | |
} else { |
455 | 9 | if (valueClass != null) { |
456 | 3 | map.put(key, convHelper.asObject(context, valueClass, entry.getValue())); |
457 | 3 | } else { |
458 | 6 | map.put(key, entry.getValue()); |
459 | |
} |
460 | |
} |
461 | 10 | } |
462 | |
|
463 | 3 | } |
464 | |
|
465 | |
|
466 | |
|
467 | |
|
468 | |
|
469 | |
|
470 | |
private Messages messages() { |
471 | |
|
472 | 18 | if (messages == null) { |
473 | 18 | messages = new Messages("org.apache.shale.tiger.faces.Bundle", |
474 | |
Thread.currentThread().getContextClassLoader()); |
475 | |
} |
476 | 18 | return messages; |
477 | |
|
478 | |
} |
479 | |
|
480 | |
|
481 | |
|
482 | |
|
483 | |
|
484 | |
|
485 | |
|
486 | |
|
487 | |
|
488 | |
|
489 | |
|
490 | |
|
491 | |
|
492 | |
private void property(FacesContext context, ManagedBeanConfig mb, |
493 | |
ManagedPropertyConfig mp, Object instance) |
494 | |
throws EvaluationException { |
495 | |
|
496 | |
|
497 | 27 | ListEntriesConfig listEntries = mp.getListEntries(); |
498 | 27 | if (listEntries != null) { |
499 | |
|
500 | |
|
501 | |
|
502 | 2 | Object property = null; |
503 | |
try { |
504 | 2 | property = propHelper.getValue(instance, mp.getName()); |
505 | |
|
506 | |
} catch (PropertyNotFoundException e) { |
507 | |
; |
508 | |
} catch (Exception e) { |
509 | |
throw new EvaluationException(messages(). |
510 | |
getMessage("list.get", |
511 | |
context.getViewRoot().getLocale(), |
512 | |
new Object[] { mp.getName(), mb.getName()}), e); |
513 | 2 | } |
514 | 2 | if (property == null) { |
515 | 1 | property = new ArrayList(); |
516 | |
} |
517 | |
|
518 | |
|
519 | 2 | if (!List.class.isAssignableFrom(property.getClass())) { |
520 | |
throw new EvaluationException(messages(). |
521 | |
getMessage("list.listProperty", |
522 | |
context.getViewRoot().getLocale(), |
523 | |
new Object[] { mp.getName(), mb.getName(), property.getClass().getName() })); |
524 | |
} |
525 | |
|
526 | |
|
527 | 2 | list(context, listEntries, (List) property); |
528 | |
|
529 | |
|
530 | |
try { |
531 | 2 | propHelper.setValue(instance, mp.getName(), property); |
532 | |
|
533 | |
} catch (Exception e) { |
534 | |
throw new EvaluationException(messages(). |
535 | |
getMessage("list.set", |
536 | |
context.getViewRoot().getLocale(), |
537 | |
new Object[] { mp.getName(), mb.getName()}), e); |
538 | 2 | } |
539 | |
|
540 | |
|
541 | 2 | return; |
542 | |
|
543 | |
} |
544 | |
|
545 | |
|
546 | 25 | MapEntriesConfig mapEntries = mp.getMapEntries(); |
547 | 25 | if (mapEntries != null) { |
548 | |
|
549 | |
|
550 | |
|
551 | 2 | Object property = null; |
552 | |
try { |
553 | 2 | property = propHelper.getValue(instance, mp.getName()); |
554 | |
|
555 | |
} catch (PropertyNotFoundException e) { |
556 | |
; |
557 | |
} catch (Exception e) { |
558 | |
throw new EvaluationException(messages(). |
559 | |
getMessage("map.get", |
560 | |
context.getViewRoot().getLocale(), |
561 | |
new Object[] { mp.getName(), mb.getName()}), e); |
562 | 2 | } |
563 | 2 | if (property == null) { |
564 | 1 | property = new HashMap(); |
565 | |
} |
566 | |
|
567 | 2 | if (!Map.class.isAssignableFrom(property.getClass())) { |
568 | |
throw new EvaluationException(messages(). |
569 | |
getMessage("map.mapProperty", |
570 | |
context.getViewRoot().getLocale(), |
571 | |
new Object[] { mp.getName(), mb.getName(), property.getClass().getName() })); |
572 | |
} |
573 | |
|
574 | |
|
575 | 2 | map(context, mapEntries, (Map) property); |
576 | |
|
577 | |
|
578 | |
try { |
579 | 2 | propHelper.setValue(instance, mp.getName(), property); |
580 | |
|
581 | |
} catch (Exception e) { |
582 | |
throw new EvaluationException(messages(). |
583 | |
getMessage("map.set", |
584 | |
context.getViewRoot().getLocale(), |
585 | |
new Object[] { mp.getName(), mb.getName()}), e); |
586 | 2 | } |
587 | |
|
588 | |
|
589 | 2 | return; |
590 | |
|
591 | |
} |
592 | |
|
593 | |
|
594 | 23 | if ((mp.getValue() == null) && !mp.isNullValue()) { |
595 | |
return; |
596 | |
} |
597 | |
|
598 | |
|
599 | 23 | Object value = null; |
600 | 23 | if (!mp.isNullValue()) { |
601 | 22 | if (mp.isExpression()) { |
602 | |
|
603 | 8 | ValueBinding vb = |
604 | |
context.getApplication().createValueBinding(mp.getValue()); |
605 | 8 | value = vb.getValue(context); |
606 | 8 | } else { |
607 | |
|
608 | 14 | value = mp.getValue(); |
609 | |
} |
610 | |
} |
611 | |
|
612 | |
|
613 | |
try { |
614 | 23 | Class type = propHelper.getType(instance, mp.getName()); |
615 | 23 | if ((value != null) && (value instanceof String)) { |
616 | 15 | value = convHelper.asObject(context, type, (String) value); |
617 | |
} |
618 | 23 | propHelper.setValue(instance, mp.getName(), value); |
619 | |
} catch (Exception e) { |
620 | |
throw new EvaluationException(messages(). |
621 | |
getMessage("variable.evaluate", |
622 | |
context.getViewRoot().getLocale(), |
623 | |
new Object[] { mb.getName(), mp.getName(), mp.getValue() }), e); |
624 | 23 | } |
625 | |
|
626 | 23 | } |
627 | |
|
628 | |
|
629 | |
|
630 | |
|
631 | |
|
632 | |
|
633 | |
|
634 | |
|
635 | |
|
636 | |
|
637 | |
|
638 | |
|
639 | |
private void scope(FacesContext context, ManagedBeanConfig mb, Object instance) |
640 | |
throws EvaluationException { |
641 | |
|
642 | 11 | if (log().isTraceEnabled()) { |
643 | 11 | log().trace("Store bean " + mb.getName() + " in scope " + mb.getScope()); |
644 | |
} |
645 | |
|
646 | 11 | ExternalContext econtext = context.getExternalContext(); |
647 | 11 | String scope = mb.getScope(); |
648 | 11 | if ("request".equalsIgnoreCase(scope)) { |
649 | 3 | econtext.getRequestMap().put(mb.getName(), instance); |
650 | 3 | } else if ("session".equalsIgnoreCase(scope)) { |
651 | 3 | econtext.getSessionMap().put(mb.getName(), instance); |
652 | 3 | } else if ("application".equalsIgnoreCase(scope)) { |
653 | 2 | econtext.getApplicationMap().put(mb.getName(), instance); |
654 | |
} |
655 | |
|
656 | 11 | } |
657 | |
|
658 | |
|
659 | |
} |