1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.util;
20
21 import java.lang.reflect.Method;
22 import java.util.Iterator;
23
24 import javax.el.ValueExpression;
25 import javax.faces.component.UIComponent;
26 import javax.faces.component.UIInput;
27 import javax.faces.context.FacesContext;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /***
33 * @author Martin Marinschek (latest modification by $Author: grantsmith $)
34 * @version $Revision: 169655 $ $Date: 2005-05-11 18:45:06 +0200 (Mi, 11 Mai 2005) $
35 */
36 public class RestoreStateUtils
37 {
38 private static Log log = LogFactory.getLog(RestoreStateUtils.class);
39
40 /***
41 * Walk the component tree, executing any component-bindings to reattach
42 * components to their backing beans.
43 * <p>
44 * Note that this method effectively breaks encapsulation; instead of
45 * asking each component to update itself and its children, this
46 * method just reaches into each component. That makes it impossible
47 * for any component to customise its behaviour at this point.
48 * <p>
49 * This has been filed as an issue against the spec. Until this
50 * issue is resolved, we'll add a new marker-interface for components
51 * to allow them to define their interest in handling children bindings themselves.
52 */
53 public static void recursivelyHandleComponentReferencesAndSetValid(FacesContext facesContext,
54 UIComponent parent)
55 {
56 recursivelyHandleComponentReferencesAndSetValid(facesContext, parent, false);
57 }
58
59 public static void recursivelyHandleComponentReferencesAndSetValid(FacesContext facesContext,
60 UIComponent parent, boolean forceHandle)
61 {
62 Method handleBindingsMethod = getBindingMethod(parent);
63
64 if(handleBindingsMethod!=null && !forceHandle)
65 {
66 try
67 {
68 handleBindingsMethod.invoke(parent,new Object[]{});
69 }
70 catch (Throwable th)
71 {
72 log.error("Exception while invoking handleBindings on component with client-id:"
73 +parent.getClientId(facesContext),th);
74 }
75 }
76 else
77 {
78 for (Iterator it = parent.getFacetsAndChildren(); it.hasNext(); )
79 {
80 UIComponent component = (UIComponent)it.next();
81
82 ValueExpression binding = component.getValueExpression("binding");
83 if (binding != null)
84 {
85 binding.setValue(facesContext.getELContext(), component);
86 }
87
88
89
90
91
92
93
94 recursivelyHandleComponentReferencesAndSetValid(facesContext, component);
95 }
96 }
97 }
98
99 /***This is all a hack to work around a spec-bug which will be fixed in JSF2.0
100 *
101 * @param parent
102 * @return true if this component is bindingAware (e.g. aliasBean)
103 */
104 private static Method getBindingMethod(UIComponent parent)
105 {
106 Class[] clazzes = parent.getClass().getInterfaces();
107
108 for (int i = 0; i < clazzes.length; i++)
109 {
110 Class clazz = clazzes[i];
111
112 if(clazz.getName().indexOf("BindingAware")!=-1)
113 {
114 try
115 {
116 return parent.getClass().getMethod("handleBindings",new Class[]{});
117 }
118 catch (NoSuchMethodException e)
119 {
120
121 }
122 }
123 }
124
125 return null;
126 }
127 }