View Javadoc

1   /*
2    * $Id: ComponentEngineManager.java,v 1.3 2010/02/10 14:39:05 oeuillot Exp $
3    */
4   package org.rcfaces.core.internal.component;
5   
6   import java.lang.reflect.Field;
7   import java.lang.reflect.Method;
8   import java.util.HashMap;
9   import java.util.Map;
10  
11  import org.rcfaces.core.internal.capability.IComponentEngine;
12  import org.rcfaces.core.internal.capability.IRCFacesComponent;
13  
14  /**
15   * 
16   * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
17   * @version $Revision: 1.3 $ $Date: 2010/02/10 14:39:05 $
18   */
19  class ComponentEngineManager {
20  
21      private static final Map fields = new HashMap(256);
22  
23      private static final Map getters = new HashMap(256);
24  
25      private static final Map setters = new HashMap(256);
26  
27      private static final Class SETTER_PARAMETERS[] = new Class[] { IComponentEngine.class };
28  
29      private static final String COMPONENT_ENGINE_GETTER_METHOD_NAME = "getComponentEngine";
30  
31      private static final String COMPONENT_ENGINE_SETTER_METHOD_NAME = "setComponentEngine";
32  
33      private static final String COMPONENT_ENGINE_FIELD_NAME = "engine";
34  
35      public static void setComponentEngine(IRCFacesComponent component,
36              IComponentEngine componentEngine) {
37  
38          Field field = getField(component.getClass());
39  
40          try {
41              field.set(component, componentEngine);
42  
43          } catch (Throwable e) {
44              throw new RuntimeException("Can not set field '" + field
45                      + "' for value '" + componentEngine + "'.");
46          }
47  
48          if (false) {
49              Method method = getSetter(component.getClass());
50  
51              try {
52                  method.invoke(component, new Object[] { componentEngine });
53  
54              } catch (Throwable e) {
55                  throw new RuntimeException("Can not call setter '" + method
56                          + "' for value '" + componentEngine + "'.");
57              }
58          }
59      }
60  
61      public static IComponentEngine getComponentEngine(
62              IRCFacesComponent component) {
63  
64          if (false) {
65              Method method = getGetter(component.getClass());
66  
67              try {
68                  return (IComponentEngine) method.invoke(component,
69                          (Object[]) null);
70  
71              } catch (Throwable e) {
72                  throw new RuntimeException("Can not call getter '" + method
73                          + "'.");
74              }
75          }
76  
77          Field field = getField(component.getClass());
78  
79          try {
80              return (IComponentEngine) field.get(component);
81  
82          } catch (Throwable e) {
83              throw new RuntimeException("Can not get value '" + field + "'.");
84          }
85      }
86  
87      private static Method getGetter(Class componentClass) {
88  
89          synchronized (getters) {
90              Method method = (Method) getters.get(componentClass);
91              if (method != null) {
92                  return method;
93              }
94  
95              Throwable th = null;
96              for (Class cls = componentClass; cls != null; cls = cls
97                      .getSuperclass()) {
98                  try {
99                      method = cls
100                             .getDeclaredMethod(
101                                     COMPONENT_ENGINE_GETTER_METHOD_NAME,
102                                     (Class[]) null);
103 
104                     break;
105 
106                 } catch (Throwable th2) {
107                     if (th == null) {
108                         th = th2;
109                     }
110                 }
111             }
112 
113             if (method == null) {
114                 throw new RuntimeException("Can not get method '"
115                         + COMPONENT_ENGINE_GETTER_METHOD_NAME + "' of class '"
116                         + componentClass + "'.", th);
117             }
118 
119             getters.put(componentClass, method);
120 
121             return method;
122         }
123     }
124 
125     private static Method getSetter(Class componentClass) {
126 
127         synchronized (setters) {
128             Method method = (Method) setters.get(componentClass);
129             if (method != null) {
130                 return method;
131             }
132 
133             Throwable th = null;
134             for (Class cls = componentClass; cls != null; cls = cls
135                     .getSuperclass()) {
136                 try {
137                     method = cls.getDeclaredMethod(
138                             COMPONENT_ENGINE_SETTER_METHOD_NAME,
139                             SETTER_PARAMETERS);
140 
141                     break;
142 
143                 } catch (Throwable th2) {
144                     if (th == null) {
145                         th = th2;
146                     }
147                 }
148             }
149 
150             if (method == null) {
151                 throw new RuntimeException("Can not get method '"
152                         + COMPONENT_ENGINE_SETTER_METHOD_NAME + "' of class '"
153                         + componentClass + "'.", th);
154             }
155 
156             setters.put(componentClass, method);
157 
158             return method;
159         }
160     }
161 
162     private static Field getField(Class componentClass) {
163 
164         synchronized (fields) {
165             Field field = (Field) fields.get(componentClass);
166             if (field != null) {
167                 return field;
168             }
169 
170             Throwable th = null;
171             for (Class cls = componentClass; cls != null; cls = cls
172                     .getSuperclass()) {
173                 try {
174                     field = cls.getDeclaredField("engine");
175 
176                     break;
177 
178                 } catch (Throwable th2) {
179                     if (th == null) {
180                         th = th2;
181                     }
182                 }
183             }
184 
185             if (field == null) {
186                 throw new RuntimeException("Can not get field '"
187                         + COMPONENT_ENGINE_GETTER_METHOD_NAME + "' of class '"
188                         + componentClass + "'.", th);
189             }
190 
191             fields.put(componentClass, field);
192 
193             return field;
194         }
195     }
196 
197     public static void cloneComponentEngine(IRCFacesComponent component) {
198         IComponentEngine componentEngine = getComponentEngine(component);
199 
200         IComponentEngine newComponentEngine = componentEngine
201                 .copyOriginalState();
202 
203         setComponentEngine(component, newComponentEngine);
204     }
205 }