1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.bean;
20
21 import java.lang.reflect.Array;
22
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import javax.el.ValueExpression;
32
33 import javax.faces.component.PartialStateHolder;
34 import javax.faces.component.StateHolder;
35 import javax.faces.component.behavior.ClientBehavior;
36 import javax.faces.context.FacesContext;
37 import javax.faces.el.ValueBinding;
38
39 import org.apache.myfaces.trinidad.bean.util.FlaggedPropertyMap;
40 import org.apache.myfaces.trinidad.bean.util.StateUtils;
41 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
42
43
44
45
46
47
48 abstract public class FacesBeanImpl implements FacesBean
49 {
50 public FacesBeanImpl()
51 {
52 }
53
54
55
56
57
58 abstract public Type getType();
59
60 final public Object getProperty(PropertyKey key)
61 {
62 Object o = getLocalProperty(key);
63 if (o != null)
64 return o;
65
66
67 if (key.getSupportsBinding())
68 {
69 ValueExpression expression = getValueExpression(key);
70 if (expression != null)
71 {
72 FacesContext context = FacesContext.getCurrentInstance();
73 return expression.getValue(context.getELContext());
74 }
75 }
76
77 return null;
78 }
79
80
81
82
83 final public Object getRawProperty(PropertyKey key)
84 {
85 Object local = getLocalProperty(key);
86 if (local != null)
87 return local;
88
89
90 return key.getSupportsBinding() ? getValueExpression(key) : null;
91 }
92
93
94
95
96
97 public void setProperty(PropertyKey key, Object value)
98 {
99 _checkNotListKey(key);
100 setPropertyImpl(key, value);
101 }
102
103 final public Object getLocalProperty(PropertyKey key)
104 {
105 _checkNotListKey(key);
106
107 return getLocalPropertyImpl(key);
108 }
109
110 final public ValueExpression getValueExpression(PropertyKey key)
111 {
112 _checkNotListKey(key);
113
114 PropertyMap map = _getExpressionsMap(false);
115 if (map == null)
116 return null;
117
118 return (ValueExpression) map.get(key);
119 }
120
121 final public void setValueExpression(PropertyKey key,
122 ValueExpression expression)
123 {
124 _checkNotListKey(key);
125
126 if (!key.getSupportsBinding())
127 {
128 throw new IllegalArgumentException(_LOG.getMessage(
129 "CANNOT_FIND_PROPERTY", key.getName()));
130 }
131
132 if (expression == null)
133 {
134 PropertyMap map = _getExpressionsMap(false);
135 if (map != null)
136 map.remove(key);
137 }
138 else
139 {
140 _getExpressionsMap(true).put(key, expression);
141 }
142
143 }
144
145 @SuppressWarnings("deprecation")
146 final public ValueBinding getValueBinding(PropertyKey key)
147 {
148 ValueExpression ve = getValueExpression(key);
149
150 if (ve == null)
151 {
152 return null;
153 }
154 else
155 {
156
157 return ValueExpressionValueBinding.getValueBinding(ve);
158 }
159 }
160
161 @SuppressWarnings("deprecation")
162 final public void setValueBinding(PropertyKey key, ValueBinding binding)
163 {
164 ValueExpression ve;
165
166 if (binding == null)
167 {
168 ve = null;
169 }
170 else
171 {
172 ve = ValueBindingValueExpression.getValueExpression(binding);
173 }
174
175 setValueExpression(key, ve);
176 }
177
178 @SuppressWarnings("unchecked")
179 final public void addEntry(PropertyKey listKey, Object value)
180 {
181 _checkListKey(listKey);
182
183 List<Object> l = (List<Object>) getLocalPropertyImpl(listKey);
184 if (l == null)
185 {
186 l = _createList();
187 setPropertyImpl(listKey, l);
188 }
189
190 l.add(value);
191
192
193
194 if (_initialStateMarked)
195 setPropertyImpl(listKey, l);
196 }
197
198 @SuppressWarnings("unchecked")
199 final public void removeEntry(PropertyKey listKey, Object value)
200 {
201 _checkListKey(listKey);
202
203 List<Object> l = (List<Object>) getLocalPropertyImpl(listKey);
204 if (l != null)
205 {
206 l.remove(value);
207 }
208
209
210
211 if (_initialStateMarked && (l != null))
212 setPropertyImpl(listKey, l);
213 }
214
215 @SuppressWarnings("unchecked")
216 final public Object[] getEntries(PropertyKey listKey, Class clazz)
217 {
218 _checkListKey(listKey);
219
220 List<Object> l = (List<Object>) getLocalPropertyImpl(listKey);
221 if (l == null)
222 return (Object[]) Array.newInstance(clazz, 0);
223
224 int size = l.size();
225 ArrayList<Object> tempList = new ArrayList<Object>(size);
226 for (int i = 0; i < size; i++)
227 {
228 Object o = l.get(i);
229 if (clazz.isInstance(o))
230 tempList.add(o);
231 }
232
233 return tempList.toArray((Object[]) Array.newInstance(clazz,
234 tempList.size()));
235 }
236
237 @SuppressWarnings("unchecked")
238 final public boolean containsEntry(PropertyKey listKey, Class<?> clazz)
239 {
240 _checkListKey(listKey);
241
242 List<Object> l = (List<Object>) getLocalPropertyImpl(listKey);
243 if (l == null)
244 return false;
245
246 int size = l.size();
247 for (int i = 0; i < size; i++)
248 {
249 Object o = l.get(i);
250 if (clazz.isInstance(o))
251 return true;
252 }
253
254 return false;
255 }
256
257 @SuppressWarnings("unchecked")
258 final public Iterator<Object> entries(PropertyKey listKey)
259 {
260 _checkListKey(listKey);
261
262 List<Object> l = (List<Object>) getLocalPropertyImpl(listKey);
263 if (l == null)
264 return Collections.emptyList().iterator();
265
266 return l.iterator();
267 }
268
269
270
271 public void addAll(FacesBean from)
272 {
273 if (from == this)
274 return;
275
276 for(PropertyKey fromKey : from.keySet())
277 {
278 PropertyKey toKey = _convertKey(fromKey);
279 if ((toKey != null) &&
280 _isCompatible(fromKey, toKey))
281 {
282 if (!fromKey.isList())
283 {
284 setProperty(toKey, from.getLocalProperty(fromKey));
285 }
286 else
287 {
288 Iterator<? extends Object> entries = from.entries(fromKey);
289 while (entries.hasNext())
290 addEntry(toKey, entries.next());
291 }
292 }
293 }
294
295 for(PropertyKey fromKey : from.bindingKeySet())
296 {
297 PropertyKey toKey = _convertKey(fromKey);
298 if (toKey.getSupportsBinding())
299 {
300 setValueExpression(toKey, from.getValueExpression(fromKey));
301 }
302 }
303 }
304
305 public Set<PropertyKey> keySet()
306 {
307 if (_properties == null)
308 return Collections.emptySet();
309 else
310 return _properties.keySet();
311 }
312
313 @SuppressWarnings("unchecked")
314 final public Set<PropertyKey> bindingKeySet()
315 {
316 if (_expressions == null)
317 return Collections.emptySet();
318
319 return _expressions.keySet();
320 }
321
322 public void markInitialState()
323 {
324 _initialStateMarked = true;
325
326 if (_properties != null)
327 _properties.markInitialState();
328
329 if (_expressions != null)
330 _expressions.markInitialState();
331 }
332
333 public void clearInitialState()
334 {
335 _initialStateMarked = false;
336
337 if (_properties != null)
338 _properties.clearInitialState();
339
340 if (_expressions != null)
341 _expressions.clearInitialState();
342 }
343
344 public boolean initialStateMarked()
345 {
346 return _initialStateMarked;
347 }
348
349 public void restoreState(FacesContext context, Object state)
350 {
351 if (_LOG.isFiner())
352 {
353 _LOG.finer("Restoring state into " + this);
354 }
355
356 if (state instanceof Object[])
357 {
358 Object[] asArray = (Object[]) state;
359 if (asArray.length == 2)
360 {
361 Object propertyState = asArray[0];
362 Object bindingsState = asArray[1];
363 _getPropertyMap().restoreState(context, getType(), propertyState);
364 _getExpressionsMap(true).restoreState(context, getType(), bindingsState);
365 return;
366 }
367 else if (asArray.length == 1)
368 {
369 Object propertyState = asArray[0];
370 _getPropertyMap().restoreState(context, getType(), propertyState);
371 return;
372 }
373 }
374
375 _getPropertyMap().restoreState(context, getType(), state);
376 }
377
378 public Object saveState(FacesContext context)
379 {
380 if (_LOG.isFiner())
381 {
382 _LOG.finer("Saving state of " + this);
383 }
384
385 Object propertyState = (_properties == null)
386 ? null
387 : _properties.saveState(context);
388 Object bindingsState = (_expressions == null)
389 ? null
390 : _expressions.saveState(context);
391
392 if (bindingsState != null)
393 {
394 return new Object[] { propertyState, bindingsState };
395 }
396
397 if (propertyState == null)
398 return null;
399
400 if (propertyState instanceof Object[])
401 {
402 Object[] asArray = (Object[]) propertyState;
403 if (asArray.length <= 2)
404 return new Object[]{propertyState};
405 }
406
407 return propertyState;
408 }
409
410 @Override
411 public String toString()
412 {
413 String className = getClass().getName();
414 int lastPeriod = className.lastIndexOf('.');
415 if (lastPeriod < 0)
416 return className;
417
418 return className.substring(lastPeriod + 1);
419 }
420
421 protected void setPropertyImpl(PropertyKey key, Object value)
422 {
423 if (value == null)
424 _getPropertyMap().remove(key);
425 else
426 _getPropertyMap().put(key, value);
427 }
428
429 protected Object getLocalPropertyImpl(PropertyKey key)
430 {
431 return _getPropertyMap().get(key);
432 }
433
434 protected PropertyMap createPropertyMap()
435 {
436 FlaggedPropertyMap map = new FlaggedPropertyMap();
437
438
439
440
441 map.setType(getType());
442 return map;
443 }
444
445 protected PropertyMap createExpressionsMap()
446 {
447 return new FlaggedPropertyMap();
448 }
449
450
451
452
453 private List<Object> _createList(
454 {
455 return new ArrayList<Object>();
456 }
457
458
459
460
461 private PropertyKey _convertKey(PropertyKey fromKey)
462 {
463 Type type = getType();
464
465
466 PropertyKey toKey = type.findKey(fromKey.getIndex());
467 if (toKey == fromKey)
468 return toKey;
469
470
471 String name = fromKey.getName();
472 toKey = type.findKey(name);
473 if (toKey != null)
474 return toKey;
475
476
477 return new PropertyKey(name);
478 }
479
480
481
482
483 static private boolean _isCompatible(
484 PropertyKey fromKey, PropertyKey toKey)
485 {
486 return (fromKey.isList() == toKey.isList());
487 }
488
489 private PropertyMap _getPropertyMap()
490 {
491 if (_properties == null)
492 _properties = createPropertyMap();
493
494 return _properties;
495 }
496
497
498 private PropertyMap _getExpressionsMap(boolean createIfNew)
499 {
500 if (_expressions == null)
501 {
502 if (createIfNew)
503 {
504 _expressions = createExpressionsMap();
505 }
506 }
507
508 return _expressions;
509 }
510
511 static private void _checkListKey(PropertyKey listKey)
512 throws IllegalArgumentException
513 {
514 if (!listKey.isList())
515 throw new IllegalArgumentException(_LOG.getMessage(
516 ">KEY_CANNOT_BE_USED_FOR_LISTS", listKey));
517 }
518
519 static private void _checkNotListKey(PropertyKey key)
520 throws IllegalArgumentException
521 {
522 if (key.isList())
523 throw new IllegalArgumentException(_LOG.getMessage(
524 "KEY_IS_LIST_KEY", key));
525 }
526
527 private PropertyMap _properties;
528 private PropertyMap _expressions;
529
530 private transient boolean _initialStateMarked;
531
532 static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
533 FacesBeanImpl.class);
534 }