KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > annotations > AnnotationsConfigurator


1 /*
2  * Copyright 2006 Maik Schreiber <blizzy AT blizzy DOT de>
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.annotations;
17
18 import java.beans.Introspector JavaDoc;
19 import java.lang.reflect.Field JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Set JavaDoc;
27
28 import org.directwebremoting.AjaxFilter;
29 import org.directwebremoting.Container;
30 import org.directwebremoting.convert.BeanConverter;
31 import org.directwebremoting.create.NewCreator;
32 import org.directwebremoting.extend.AccessControl;
33 import org.directwebremoting.extend.AjaxFilterManager;
34 import org.directwebremoting.extend.Configurator;
35 import org.directwebremoting.extend.Converter;
36 import org.directwebremoting.extend.ConverterManager;
37 import org.directwebremoting.extend.Creator;
38 import org.directwebremoting.extend.CreatorManager;
39 import org.directwebremoting.util.LocalUtil;
40 import org.directwebremoting.util.Logger;
41
42 /**
43  * A Configurator that works off Annotations.
44  * @author Maik Schreiber [blizzy AT blizzy DOT de]
45  * @author Joe Walker [joe at getahead dot ltd dot uk]
46  */

47 public class AnnotationsConfigurator implements Configurator
48 {
49     /* (non-Javadoc)
50      * @see org.directwebremoting.Configurator#configure(org.directwebremoting.Container)
51      */

52     public void configure(Container container)
53     {
54         Object JavaDoc data = container.getBean("classes");
55         if (data == null)
56         {
57             return;
58         }
59
60         if (data instanceof String JavaDoc)
61         {
62             String JavaDoc classesStr = (String JavaDoc) data;
63             String JavaDoc[] classNames = classesStr.split(",");
64             for (int i = 0; i < classNames.length; i++)
65             {
66                 String JavaDoc className = classNames[i].trim();
67                 try
68                 {
69                     Class JavaDoc<?> clazz = LocalUtil.classForName(className);
70                     processClass(clazz, container);
71                 }
72                 catch (Exception JavaDoc ex)
73                 {
74                     log.error("Failed to process class: " + className, ex);
75                 }
76             }
77         }
78         else
79         {
80             try
81             {
82                 processClass(data.getClass(), container);
83             }
84             catch (Exception JavaDoc ex)
85             {
86                 log.error("Failed to process class: " + data.getClass().getName(), ex);
87             }
88         }
89     }
90
91     /**
92      * Process the annotations on a given class
93      * @param clazz The class to search for annotations
94      * @param container The IoC container to configure
95      * @throws IllegalAccessException If annotation processing fails
96      * @throws InstantiationException If annotation processing fails
97      */

98     private void processClass(Class JavaDoc<?> clazz, Container container) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc
99     {
100         RemoteProxy createAnn = clazz.getAnnotation(RemoteProxy.class);
101         if (createAnn != null)
102         {
103             processCreate(clazz, createAnn, container);
104         }
105
106         DataTransferObject convertAnn = clazz.getAnnotation(DataTransferObject.class);
107         if (convertAnn != null)
108         {
109             processConvert(clazz, convertAnn, container);
110         }
111
112         GlobalFilter globalFilterAnn = clazz.getAnnotation(GlobalFilter.class);
113         if (globalFilterAnn != null)
114         {
115             processGlobalFilter(clazz, globalFilterAnn, container);
116         }
117     }
118
119     /**
120      * Process the @RemoteProxy annotaion on a given class
121      * @param clazz The class annotated with @RemoteProxy
122      * @param createAnn The annotation
123      * @param container The IoC container to configure
124      */

125     private void processCreate(Class JavaDoc<?> clazz, RemoteProxy createAnn, Container container)
126     {
127         Class JavaDoc<? extends Creator> creator = createAnn.creator();
128         String JavaDoc creatorClass = creator.getName();
129         Map JavaDoc<String JavaDoc, String JavaDoc> creatorParams = getParamsMap(createAnn.creatorParams());
130         ScriptScope scope = createAnn.scope();
131
132         CreatorManager creatorManager = (CreatorManager) container.getBean(CreatorManager.class.getName());
133         String JavaDoc creatorName = LocalUtil.replace(creatorClass, ".", "_");
134         creatorManager.addCreatorType(creatorName, creatorClass);
135
136         Map JavaDoc<String JavaDoc, String JavaDoc> params = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
137         if (NewCreator.class.isAssignableFrom(creator))
138         {
139             params.put("class", clazz.getName());
140         }
141         params.putAll(creatorParams);
142         params.put("scope", scope.getValue());
143
144         String JavaDoc name = createAnn.name();
145         if (name == null || name.length() == 0)
146         {
147             name = LocalUtil.getShortClassName(clazz);
148         }
149
150         try
151         {
152             log.info("Adding class " + clazz.getName() + " as " + name);
153             creatorManager.addCreator(name, creatorName, params);
154         }
155         catch (Exception JavaDoc ex)
156         {
157             log.error("Failed to add class as Creator: " + clazz.getName(), ex);
158         }
159
160         AccessControl accessControl = (AccessControl) container.getBean(AccessControl.class.getName());
161         Method JavaDoc[] methods = clazz.getMethods();
162         for (int i = 0; i < methods.length; i++)
163         {
164             if (methods[i].getAnnotation(RemoteMethod.class) != null)
165             {
166                 accessControl.addIncludeRule(name, methods[i].getName());
167
168                 Auth authAnn = methods[i].getAnnotation(Auth.class);
169                 if (authAnn != null)
170                 {
171                     accessControl.addRoleRestriction(name, methods[i].getName(), authAnn.role());
172                 }
173             }
174         }
175
176         Filters filtersAnn = clazz.getAnnotation(Filters.class);
177         if (filtersAnn != null)
178         {
179             Filter[] fs = filtersAnn.value();
180             for (int i = 0; i < fs.length; i++)
181             {
182                 processFilter(fs[i], name, container);
183             }
184         }
185         // process single filter for convenience
186
else
187         {
188             Filter filterAnn = clazz.getAnnotation(Filter.class);
189             if (filterAnn != null)
190             {
191                 processFilter(filterAnn, name, container);
192             }
193         }
194     }
195
196     /**
197      * Process the @Filter annotaion
198      * @param filterAnn The filter annotation
199      * @param name The Javascript name of the class to filter
200      * @param container The IoC container to configure
201      */

202     private void processFilter(Filter filterAnn, String JavaDoc name, Container container)
203     {
204         Map JavaDoc<String JavaDoc, String JavaDoc> filterParams = getParamsMap(filterAnn.params());
205         AjaxFilter filter = (AjaxFilter) LocalUtil.classNewInstance(name, filterAnn.type().getName(), AjaxFilter.class);
206         if (filter != null)
207         {
208             LocalUtil.setParams(filter, filterParams, null);
209             AjaxFilterManager filterManager = (AjaxFilterManager) container.getBean(AjaxFilterManager.class.getName());
210             filterManager.addAjaxFilter(filter, name);
211         }
212     }
213
214     /**
215      * Process the @DataTransferObject annotaion on a given class
216      * @param clazz The class annotated with @DataTransferObject
217      * @param convertAnn The annotation
218      * @param container The IoC container to configure
219      * @throws InstantiationException
220      * @throws IllegalAccessException
221      */

222     private void processConvert(Class JavaDoc<?> clazz, DataTransferObject convertAnn, Container container) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc
223     {
224         Class JavaDoc<? extends Converter> converter = convertAnn.converter();
225         String JavaDoc converterClass = converter.getName();
226         Map JavaDoc<String JavaDoc, String JavaDoc> params = getParamsMap(convertAnn.params());
227
228         ConverterManager converterManager = (ConverterManager) container.getBean(ConverterManager.class.getName());
229         String JavaDoc converterName = LocalUtil.replace(converterClass, ".", "_");
230         converterManager.addConverterType(converterName, converterClass);
231
232         if (BeanConverter.class.isAssignableFrom(converter))
233         {
234             StringBuilder JavaDoc properties = new StringBuilder JavaDoc();
235             Set JavaDoc<Field JavaDoc> fields = new HashSet JavaDoc<Field JavaDoc>();
236             fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
237             fields.addAll(Arrays.asList(clazz.getFields()));
238             for (Field JavaDoc field : fields)
239             {
240                 if (field.getAnnotation(RemoteProperty.class) != null)
241                 {
242                     properties.append(',').append(field.getName());
243                 }
244             }
245
246             Method JavaDoc[] methods = clazz.getMethods();
247             for (int i = 0; i < methods.length; i++)
248             {
249                 if (methods[i].getAnnotation(RemoteProperty.class) != null)
250                 {
251                     String JavaDoc name = methods[i].getName();
252                     if (name.startsWith(METHOD_PREFIX_GET) || name.startsWith(METHOD_PREFIX_IS))
253                     {
254                         if (name.startsWith(METHOD_PREFIX_GET))
255                         {
256                             name = name.substring(3);
257                         }
258                         else
259                         {
260                             name = name.substring(2);
261                         }
262                         name = Introspector.decapitalize(name);
263                         properties.append(',').append(name);
264                     }
265                 }
266             }
267             if (properties.length() > 0)
268             {
269                 properties.deleteCharAt(0);
270                 params.put("include", properties.toString());
271             }
272         }
273
274         converterManager.addConverter(clazz.getName(), converterName, params);
275     }
276
277     /**
278      * Global Filters apply to all classes
279      * @param clazz The class to use as a filter
280      * @param globalFilterAnn The filter annotation
281      * @param container The IoC container to configure
282      * @throws InstantiationException In case we can't create the given clazz
283      * @throws IllegalAccessException In case we can't create the given clazz
284      */

285     private void processGlobalFilter(Class JavaDoc<?> clazz, GlobalFilter globalFilterAnn, Container container) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc
286     {
287         if (!AjaxFilter.class.isAssignableFrom(clazz))
288         {
289             throw new IllegalArgumentException JavaDoc(clazz.getName() + " is not an AjaxFilter implementation");
290         }
291
292         Map JavaDoc<String JavaDoc, String JavaDoc> filterParams = getParamsMap(globalFilterAnn.params());
293         AjaxFilter filter = (AjaxFilter) clazz.newInstance();
294         if (filter != null)
295         {
296             LocalUtil.setParams(filter, filterParams, null);
297             AjaxFilterManager filterManager = (AjaxFilterManager) container.getBean(AjaxFilterManager.class.getName());
298             filterManager.addAjaxFilter(filter);
299         }
300     }
301
302     /**
303      * Utility to turn a Param array into a Map<String, String>.
304      * TODO: Should we move this code into Param? Is that even possible?
305      * @param params The params array from annotations
306      * @return A Map<String, String>
307      */

308     private Map JavaDoc<String JavaDoc, String JavaDoc> getParamsMap(Param[] params)
309     {
310         Map JavaDoc<String JavaDoc, String JavaDoc> result = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
311         if (params != null)
312         {
313             for (int i = 0; i < params.length; i++)
314             {
315                 Param p = params[i];
316                 result.put(p.name(), p.value());
317             }
318         }
319         return result;
320     }
321
322     /**
323      * The getter prefix for boolean variables
324      */

325     private static final String JavaDoc METHOD_PREFIX_IS = "is";
326
327     /**
328      * The getter prefix for non-boolean variables
329      */

330     private static final String JavaDoc METHOD_PREFIX_GET = "get";
331
332     /**
333      * The log stream
334      */

335     private static final Logger log = Logger.getLogger(AnnotationsConfigurator.class);
336 }
337
Popular Tags