1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.shared.util;
20
21 import java.lang.reflect.Method;
22 import java.util.Iterator;
23 import java.util.logging.Level;
24 import java.util.logging.Logger;
25
26 import javax.el.ValueExpression;
27 import javax.faces.component.UIComponent;
28 import javax.faces.context.FacesContext;
29
30 /**
31 * @author Martin Marinschek (latest modification by $Author: bommel $)
32 * @version $Revision: 1187700 $ $Date: 2011-10-22 07:19:37 -0500 (Sat, 22 Oct 2011) $
33 */
34 public class RestoreStateUtils
35 {
36 //private static Log log = LogFactory.getLog(RestoreStateUtils.class);
37 private static Logger log = Logger.getLogger(RestoreStateUtils.class.getName());
38
39 /**
40 * Walk the component tree, executing any component-bindings to reattach
41 * components to their backing beans.
42 * <p>
43 * Note that this method effectively breaks encapsulation; instead of
44 * asking each component to update itself and its children, this
45 * method just reaches into each component. That makes it impossible
46 * for any component to customise its behaviour at this point.
47 * <p>
48 * This has been filed as an issue against the spec. Until this
49 * issue is resolved, we'll add a new marker-interface for components
50 * to allow them to define their interest in handling children bindings themselves.
51 */
52 public static void recursivelyHandleComponentReferencesAndSetValid(FacesContext facesContext,
53 UIComponent parent)
54 {
55 recursivelyHandleComponentReferencesAndSetValid(facesContext, parent, false);
56 }
57
58 public static void recursivelyHandleComponentReferencesAndSetValid(FacesContext facesContext,
59 UIComponent parent, boolean forceHandle)
60 {
61 Method handleBindingsMethod = getBindingMethod(parent);
62
63 if(handleBindingsMethod!=null && !forceHandle)
64 {
65 try
66 {
67 handleBindingsMethod.invoke(parent,new Object[]{});
68 }
69 catch (Throwable th)
70 {
71 log.log(Level.SEVERE, "Exception while invoking handleBindings on component with client-id:"
72 +parent.getClientId(facesContext),th);
73 }
74 }
75 else
76 {
77 for (Iterator it = parent.getFacetsAndChildren(); it.hasNext(); )
78 {
79 UIComponent component = (UIComponent)it.next();
80
81 ValueExpression binding = component.getValueExpression("binding"); //TODO: constant
82 if (binding != null)
83 {
84 binding.setValue(facesContext.getELContext(), component);
85 }
86
87 //This part is not necessary on JSF 1.2
88 //if (component instanceof UIInput)
89 //{
90 // ((UIInput)component).setValid(true);
91 //}
92
93 recursivelyHandleComponentReferencesAndSetValid(facesContext, component);
94 }
95 }
96 }
97
98 /**This is all a hack to work around a spec-bug which will be fixed in JSF2.0
99 *
100 * @param parent
101 * @return true if this component is bindingAware (e.g. aliasBean)
102 */
103 private static Method getBindingMethod(UIComponent parent)
104 {
105 Class[] clazzes = parent.getClass().getInterfaces();
106
107 for (int i = 0; i < clazzes.length; i++)
108 {
109 Class clazz = clazzes[i];
110
111 if(clazz.getName().indexOf("BindingAware")!=-1)
112 {
113 try
114 {
115 return parent.getClass().getMethod("handleBindings",new Class[]{});
116 }
117 catch (NoSuchMethodException e)
118 {
119 // return
120 }
121 }
122 }
123
124 return null;
125 }
126 }