1
2
3
4 package org.rcfaces.core.internal.adapter;
5
6 import java.util.ArrayList;
7 import java.util.Collection;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import javax.faces.FacesException;
16 import javax.faces.context.FacesContext;
17
18 import org.apache.commons.digester.Digester;
19 import org.apache.commons.digester.Rule;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.rcfaces.core.internal.RcfacesContext;
23 import org.rcfaces.core.internal.util.ClassLocator;
24 import org.rcfaces.core.lang.IAdapterFactory;
25 import org.rcfaces.core.provider.AbstractProvider;
26 import org.xml.sax.Attributes;
27
28
29
30
31
32
33 public class AdapterManagerImpl extends AbstractProvider implements
34 IAdapterManager {
35 private static final String REVISION = "$Revision: 1.8 $";
36
37 private static final Log LOG = LogFactory.getLog(AdapterManagerImpl.class);
38
39 protected final Map factories;
40
41 protected Map adapterLookup;
42
43 protected Map classSearchOrderLookup;
44
45 public AdapterManagerImpl() {
46 factories = new HashMap(5);
47 adapterLookup = null;
48
49 RcfacesContext rcfacesContext = RcfacesContext.getCurrentInstance();
50
51 if (rcfacesContext.getAdapterManager() == null) {
52 rcfacesContext.setAdapterManager(this);
53 }
54 }
55
56 public String getId() {
57 return "AdapterManager";
58 }
59
60 public void configureRules(Digester digester) {
61 super.configureRules(digester);
62
63 digester.addRule("rcfaces-config/adapters/adapter", new Rule() {
64 private static final String REVISION = "$Revision: 1.8 $";
65
66 public void begin(String namespace, String name,
67 Attributes attributes) throws Exception {
68
69 super.digester.push(new AdapterBean());
70 }
71
72 public void end(String namespace, String name) throws Exception {
73 AdapterBean adapterBean = (AdapterBean) super.digester.pop();
74
75 declareAdapter(adapterBean);
76 }
77 });
78
79 digester.addBeanPropertySetter(
80 "rcfaces-config/adapters/adapter/adaptable-class", "className");
81
82 digester.addBeanPropertySetter(
83 "rcfaces-config/adapters/adapter/adapterFactory-class",
84 "adapterFactoryClassName");
85
86 }
87
88 protected void declareAdapter(AdapterBean adapterBean) {
89 String adapterClassName = adapterBean.getClassName();
90 String factoryClassName = adapterBean.getAdapterFactoryClassName();
91
92 LOG.debug("Declare adapter adapterClassName='" + adapterClassName
93 + "' factoryClassName='" + factoryClassName + "'.");
94
95 if (adapterClassName == null || adapterClassName.length() < 1
96 || factoryClassName == null || factoryClassName.length() < 1) {
97 throw new FacesException(
98 "Invalid adapter configuration. (adapter-class='"
99 + adapterClassName + "' adapterFactory-class='"
100 + factoryClassName + "')");
101 }
102
103 FacesContext facesContext = FacesContext.getCurrentInstance();
104
105
106
107
108
109
110
111 Class adapterClass;
112 try {
113 adapterClass = ClassLocator.load(adapterClassName, this,
114 facesContext);
115
116 } catch (ClassNotFoundException e) {
117 LOG.info("Adapter class not found '" + adapterClassName
118 + "', ignore adapter !", e);
119 return;
120 }
121
122 Class factoryClass;
123 try {
124 factoryClass = ClassLocator.load(factoryClassName, this,
125 facesContext);
126
127 } catch (ClassNotFoundException e) {
128 LOG.info("Factory class '" + factoryClassName
129 + "' for adapterClass='" + adapterClassName
130 + "' is not found, ignore adapter !", e);
131 return;
132 }
133
134 IAdapterFactory adapterFactory;
135 try {
136 adapterFactory = (IAdapterFactory) factoryClass.newInstance();
137
138 } catch (Throwable th) {
139 LOG.info("Can not instanciate factory class '" + factoryClassName
140 + "' for adapterClass='" + adapterClassName
141 + "', ignore adapter !", th);
142 return;
143 }
144
145 registerAdapters(adapterFactory, adapterClass);
146 }
147
148 private Map getFactories(Class adaptable) {
149
150 Map lookup = adapterLookup;
151 if (lookup == null) {
152 adapterLookup = lookup = new HashMap(30);
153 }
154
155 Map table = (Map) lookup.get(adaptable.getName());
156 if (table == null) {
157
158 table = new HashMap(4);
159 Class[] classes = computeClassOrder(adaptable);
160 for (int i = 0; i < classes.length; i++) {
161 addFactoriesFor(classes[i].getName(), table);
162 }
163
164
165 lookup.put(adaptable.getName(), table);
166 }
167 return table;
168 }
169
170 public Object getAdapter(Object adaptable, Class adapterType,
171 Object parameter) {
172 IAdapterFactory factory = (IAdapterFactory) getFactories(
173 adaptable.getClass()).get(adapterType.getName());
174 Object result = null;
175 if (factory != null) {
176 result = factory.getAdapter(adaptable, adapterType, parameter);
177 }
178
179 if (result == null && adapterType.isInstance(adaptable)) {
180 return adaptable;
181 }
182
183 return result;
184 }
185
186 private Class[] computeClassOrder(Class adaptable) {
187 List classes = null;
188
189 Map lookup = classSearchOrderLookup;
190 if (lookup != null) {
191 classes = (List) lookup.get(adaptable);
192 }
193
194
195 if (classes == null) {
196 classes = new ArrayList();
197 computeClassOrder(adaptable, classes);
198 if (lookup == null) {
199 classSearchOrderLookup = lookup = new HashMap();
200 }
201 lookup.put(adaptable, classes);
202 }
203
204 return (Class[]) classes.toArray(new Class[classes.size()]);
205 }
206
207 private void computeClassOrder(Class adaptable, Collection classes) {
208 Class clazz = adaptable;
209 Set seen = new HashSet(4);
210 while (clazz != null) {
211 classes.add(clazz);
212 computeInterfaceOrder(clazz.getInterfaces(), classes, seen);
213 clazz = clazz.getSuperclass();
214 }
215 }
216
217 private void computeInterfaceOrder(Class[] interfaces, Collection classes,
218 Set seen) {
219 List newInterfaces = new ArrayList(interfaces.length);
220 for (int i = 0; i < interfaces.length; i++) {
221 Class interfac = interfaces[i];
222 if (seen.add(interfac)) {
223
224
225 classes.add(interfac);
226 newInterfaces.add(interfac);
227 }
228 }
229
230 for (Iterator it = newInterfaces.iterator(); it.hasNext();) {
231 computeInterfaceOrder(((Class) it.next()).getInterfaces(), classes,
232 seen);
233 }
234 }
235
236 private void addFactoriesFor(String typeName, Map table) {
237 List factoryList;
238 synchronized (factories) {
239 factoryList = (List) factories.get(typeName);
240 }
241
242 if (factoryList == null) {
243 return;
244 }
245
246 synchronized (factoryList) {
247 int size = factoryList.size();
248 for (int i = 0; i < size; i++) {
249 IAdapterFactory factory = (IAdapterFactory) factoryList.get(i);
250
251 Class[] adapters = factory.getAdapterList();
252 for (int j = 0; j < adapters.length; j++) {
253 String adapterName = adapters[j].getName();
254 if (table.containsKey(adapterName)) {
255 continue;
256 }
257
258 table.put(adapterName, factory);
259 }
260 }
261 }
262 }
263
264 public void registerAdapters(IAdapterFactory factory, Class adaptable) {
265 registerFactory(factory, adaptable.getName());
266
267 flushLookup();
268 }
269
270 private synchronized void flushLookup() {
271 adapterLookup = null;
272 classSearchOrderLookup = null;
273 }
274
275 private void registerFactory(IAdapterFactory factory, String adaptableType) {
276 List list;
277 synchronized (factories) {
278 list = (List) factories.get(adaptableType);
279 if (list == null) {
280 list = new ArrayList(5);
281 factories.put(adaptableType, list);
282 }
283 }
284 synchronized (list) {
285 list.add(factory);
286 }
287 }
288
289
290
291
292
293
294 public static class AdapterBean {
295 private String className;
296
297 private String adapterFactoryClassName;
298
299 public final String getAdapterFactoryClassName() {
300 return adapterFactoryClassName;
301 }
302
303 public final String getClassName() {
304 return className;
305 }
306
307 public final void setAdapterFactoryClassName(
308 String adapterFactoryClassName) {
309 this.adapterFactoryClassName = adapterFactoryClassName;
310 }
311
312 public final void setClassName(String className) {
313 this.className = className;
314 }
315
316 }
317
318 }