2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.tiger.view.faces;
19
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.util.HashMap;
23 import java.util.Map;
24 import javax.faces.context.FacesContext;
25 import org.apache.shale.tiger.view.Preprocess;
26 import org.apache.shale.tiger.view.Prerender;
27 import org.apache.shale.tiger.view.View;
28 import org.apache.shale.view.ViewController;
29 import org.apache.shale.view.faces.ViewControllerCallbacks;
30
31 /***
32 * <p>Utility class to perform the event callbacks specified by the
33 * {@link ViewController} interface. This version will call through
34 * to ViewController methods if the bean class actually implements this
35 * interface, or ituses annotations to identify the relevant methods.</p>
36 *
37 * <p><strong>NOTE</strong> - The annotated callback methods must be
38 * public, and take no arguments. They may exist on the class of the
39 * instance being passed in, or be inherited from a superclass.</p>
40 *
41 * $Id: ViewControllerCallbacks2.java 465074 2006-10-17 22:05:53Z rahul $
42 *
43 * @since 1.0.1
44 */
45 public class ViewControllerCallbacks2 extends ViewControllerCallbacks {
46
47
48
49
50
51
52
53
54
55
56
57 /***
58 * <p>Perform the <code>preprocess</code> callback on the specified
59 * instance.</p>
60 *
61 * @param instance Bean instance on which to perform this callback
62 */
63 public void preprocess(Object instance) {
64
65 if (instance instanceof ViewController) {
66 try {
67 ((ViewController) instance).preprocess();
68 } catch (Exception e) {
69 handleException(FacesContext.getCurrentInstance(), e);
70 }
71 return;
72 }
73
74 Method method = method(instance, Preprocess.class);
75 if (method != null) {
76 try {
77 method.invoke(instance, new Object[0]);
78 } catch (IllegalAccessException e) {
79 handleException(FacesContext.getCurrentInstance(), e);
80 } catch (InvocationTargetException e) {
81 handleException(FacesContext.getCurrentInstance(), (Exception) e.getCause());
82 }
83 }
84
85 }
86
87
88 /***
89 * <p>Perform the <code>prerender</code> callback on the specified
90 * instance.</p>
91 *
92 * @param instance Bean instance on which to perform this callback
93 */
94 public void prerender(Object instance) {
95
96 if (instance instanceof ViewController) {
97 try {
98 ((ViewController) instance).prerender();
99 } catch (Exception e) {
100 handleException(FacesContext.getCurrentInstance(), e);
101 }
102 return;
103 }
104
105 Method method = method(instance, Prerender.class);
106 if (method != null) {
107 try {
108 method.invoke(instance, new Object[0]);
109 } catch (IllegalAccessException e) {
110 handleException(FacesContext.getCurrentInstance(), e);
111 } catch (InvocationTargetException e) {
112 handleException(FacesContext.getCurrentInstance(), (Exception) e.getCause());
113 }
114 }
115
116 }
117
118
119
120
121
122 /***
123 * <p>The set of method annotations for callbacks of interest.</p>
124 */
125 private static final Class[] annotations =
126 { Preprocess.class, Prerender.class };
127
128
129
130 /***
131 * <p>Data structure to maintain information about annotated
132 * methods. In this map, the key is the Class being analyzed,
133 * and the value is an inner map. In the inner map, the key
134 * is an Annotation class, and the value is the corresponding
135 * Method instance.</p>
136 */
137 private transient Map<Class,Map<Class,Method>> maps =
138 new HashMap<Class,Map<Class,Method>>();
139
140
141 /***
142 * <p>Return the <code>Method</code> to be called for the specified
143 * annotation on the specified instance, if any. If there is no such
144 * method, return <code>null</code>.</p>
145 *
146 * @param instance Instance on which callbacks will be performed
147 * @param annotation Annotation for which to return a method
148 */
149 private Method method(Object instance, Class annotation) {
150
151
152
153 Class clazz = instance.getClass();
154 if (clazz.getAnnotation(View.class) == null) {
155 return null;
156 }
157
158 synchronized (maps) {
159
160
161
162 Map<Class,Method> map = maps.get(clazz);
163 if (map != null) {
164 return map.get(annotation);
165 }
166
167
168
169 map = new HashMap<Class,Method>();
170 Method[] methods = clazz.getMethods();
171 for (int i = 0; i < methods.length; i++) {
172 if (methods[i].getParameterTypes().length > 0) {
173 continue;
174 }
175 for (int j = 0; j < annotations.length; j++) {
176 if (methods[i].getAnnotation(annotations[j]) != null) {
177 map.put(annotations[j], methods[i]);
178 }
179 }
180 }
181 maps.put(clazz, map);
182 return map.get(annotation);
183
184 }
185
186 }
187
188
189 }