KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > spring > SpringValidatorTagsHandler


1 /*
2  * Copyright (c) 2001, 2002 The XDoclet team
3  * All rights reserved.
4  */

5 package xdoclet.modules.spring;
6
7 import java.beans.Introspector JavaDoc;
8 import java.util.ArrayList JavaDoc;
9 import java.util.Collection JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.Map JavaDoc;
13 import java.util.Properties JavaDoc;
14
15 import org.apache.commons.collections.SequencedHashMap;
16 import xjavadoc.XClass;
17 import xjavadoc.XMethod;
18 import xjavadoc.XParameter;
19 import xjavadoc.XTag;
20
21 import xdoclet.DocletSupport;
22 import xdoclet.XDocletException;
23 import xdoclet.tagshandler.AbstractProgramElementTagsHandler;
24 import xdoclet.tagshandler.MethodTagsHandler;
25
26 /**
27  * Spring Validator tag handler tags
28  *
29  * @author Matt Raible (matt@raibledesigns.com)
30  * @created April 26, 2004
31  * @xdoclet.taghandler namespace="CommonsValidator"
32  * @version $Revision: 1.3 $
33  */

34 public class SpringValidatorTagsHandler extends AbstractProgramElementTagsHandler
35 {
36     private final static List JavaDoc supportedTypes = new ArrayList JavaDoc();
37     private String JavaDoc curFieldName;
38     private String JavaDoc currentArgKey;
39     private Map JavaDoc args;
40
41     static {
42         supportedTypes.add("java.lang.String");
43         supportedTypes.add("java.lang.Integer");
44         supportedTypes.add("int");
45         supportedTypes.add("java.lang.Float");
46         supportedTypes.add("float");
47         supportedTypes.add("java.lang.Long");
48         supportedTypes.add("long");
49         supportedTypes.add("java.lang.Double");
50         supportedTypes.add("double");
51         supportedTypes.add("java.lang.Boolean");
52         supportedTypes.add("boolean");
53         supportedTypes.add("java.util.Date");
54     }
55
56     /**
57      * Iterates over all POJOs and evaluates the body of the tag for each class.
58      *
59      * @param template The body of the block tag
60      * @param attributes The attributes of the template tag
61      * @exception XDocletException
62      * @doc.tag type="block"
63      */

64     public void forAllForms(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
65     {
66         Collection JavaDoc classes = getAllClasses();
67
68         for (Iterator JavaDoc i = classes.iterator(); i.hasNext(); ) {
69             XClass currentClass = (XClass) i.next();
70
71             setCurrentClass(currentClass);
72             if (DocletSupport.isDocletGenerated(getCurrentClass()) || (getCurrentClass().isAbstract())) {
73                 continue;
74             }
75             generate(template);
76         }
77     }
78
79     /**
80      * Gets the "name" attribute for the <form> element in the xml descriptor. This should be the "path" form
81      * attribute if this is a ValidatorActionForm or the "name" attribute otherwise.
82      *
83      * @param attributes The content tag attributes.
84      * @return form name
85      * @throws XDocletException if anything goes awry.
86      * @doc.tag type="content"
87      */

88     public String JavaDoc formName(Properties JavaDoc attributes) throws XDocletException
89     {
90         return Introspector.decapitalize(getCurrentClass().getTransformedName());
91     }
92
93     /**
94      * Iterates over all arguments for the current field.
95      *
96      * @param template The body of the block tag
97      * @param attributes The attributes of the template tag
98      * @throws XDocletException
99      * @doc.tag type="block"
100      */

101     public void forAllFieldArgs(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
102     {
103         for (Iterator JavaDoc iterator = args.keySet().iterator(); iterator.hasNext(); ) {
104             currentArgKey = (String JavaDoc) iterator.next();
105             generate(template);
106         }
107     }
108
109     /**
110      * Current argument index number (0 to 3).
111      *
112      * @param props The attributes of the template tag
113      * @return argument index
114      * @doc.tag type="content"
115      */

116     public String JavaDoc argIndex(Properties JavaDoc props)
117     {
118         return currentArgKey.charAt(3) + "";
119     }
120
121     /**
122      * Current argument name - only valid if argument is for a specific validator type.
123      *
124      * @param props The attributes of the template tag
125      * @return argument name
126      * @doc.tag type="content"
127      */

128     public String JavaDoc argName(Properties JavaDoc props)
129     {
130         String JavaDoc name = currentArgKey.substring(currentArgKey.indexOf('_') + 1);
131
132         return name;
133     }
134
135     /**
136      * Current argument value, which is either an inline value or resource key.
137      *
138      * @param props The attributes of the template tag
139      * @return argument value
140      * @doc.tag type="content"
141      */

142     public String JavaDoc argValue(Properties JavaDoc props)
143     {
144         return (String JavaDoc) args.get(currentArgKey);
145     }
146
147     /**
148      * Evaluates body if current argument is a resource key.
149      *
150      * @param template The body of the block tag
151      * @param attributes The attributes of the template tag
152      * @throws XDocletException
153      * @doc.tag type="block"
154      */

155     public void ifArgIsResource(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
156     {
157         if (currentArgKey.indexOf("resource") > 0) {
158             generate(template);
159         }
160     }
161
162     /**
163      * Evaluates the body if the current argument is an inline value rather than a resource key.
164      *
165      * @param template The body of the block tag
166      * @param attributes The attributes of the template tag
167      * @throws XDocletException
168      * @doc.tag type="block"
169      */

170     public void ifArgIsValue(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
171     {
172         if (currentArgKey.indexOf("value") > 0) {
173             generate(template);
174         }
175     }
176
177     /**
178      * Evaluates the body if the current argument is a validator-specific argument.
179      *
180      * @param template The body of the block tag
181      * @param attributes The attributes of the template tag
182      * @throws XDocletException
183      * @doc.tag type="block"
184      */

185     public void ifArgIsForType(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
186     {
187         if (currentArgKey.indexOf('_') > 0) {
188             generate(template);
189         }
190     }
191
192     /**
193      * Evaluates the body if there is no arg0 specified.
194      *
195      * @param template The body of the block tag
196      * @param attributes The attributes of the template tag
197      * @throws XDocletException
198      * @doc.tag type="block"
199      */

200     public void ifNoArg0(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
201     {
202         if (args.get("arg0resource") == null && args.get("arg0value") == null) {
203             generate(template);
204         }
205     }
206
207     /**
208      * Evaluates the body if form has fields requiring validation.
209      *
210      * @param template The body of the block tag
211      * @param attributes The attributes of the template tag
212      * @throws XDocletException
213      * @doc.tag type="block"
214      */

215     public void ifFormHasFields(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
216     {
217         if (getFields(getCurrentClass()).size() > 0) {
218             generate(template);
219         }
220     }
221
222     /**
223      * Iterates the body for each field of the current form requiring validation.
224      *
225      * @param template The body of the block tag
226      * @param attributes The attributes of the template tag
227      * @throws XDocletException
228      * @doc.tag type="block"
229      */

230     public void forAllFields(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
231     {
232         XClass clazz = getCurrentClass();
233         Map JavaDoc setters = getFields(clazz);
234
235         for (Iterator JavaDoc iterator = setters.keySet().iterator(); iterator.hasNext(); ) {
236             curFieldName = (String JavaDoc) iterator.next();
237
238             XMethod field = (XMethod) setters.get(curFieldName);
239
240             setCurrentMethod(field);
241             loadFieldArguments();
242             generate(template);
243         }
244     }
245
246     /**
247      * Returns the current fields name.
248      *
249      * @param props The attributes of the template tag
250      * @return current field's name
251      * @doc.tag type="content"
252      */

253     public String JavaDoc fieldName(Properties JavaDoc props)
254     {
255         return curFieldName;
256     }
257
258     /**
259      * Returns a comma-separated list of the specified validator types.
260      *
261      * @param props The attributes of the template tag
262      * @return validator type list
263      * @doc.tag type="content"
264      */

265     public String JavaDoc validatorList(Properties JavaDoc props)
266     {
267         XMethod method = getCurrentMethod();
268         Collection JavaDoc tags = method.getDoc().getTags("spring.validator");
269         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
270
271         for (Iterator JavaDoc iterator = tags.iterator(); iterator.hasNext(); ) {
272             XTag tag = (XTag) iterator.next();
273
274             buffer.append(tag.getAttributeValue("type"));
275             if (iterator.hasNext()) {
276                 buffer.append(",");
277             }
278         }
279         return buffer.toString();
280     }
281
282     private Map JavaDoc getFields(XClass clazz) throws XDocletException
283     {
284         return getFields(clazz, "");
285     }
286
287     private Map JavaDoc getFields(XClass clazz, String JavaDoc prefix) throws XDocletException
288     {
289         Map JavaDoc fields = new SequencedHashMap();
290
291         Collection JavaDoc curFields = clazz.getMethods(true);
292
293         // TODO: nested forms currently won't work unless
294
// there is a setter for it, but that is not needed
295
// as only the sub-forms must have setters. The top-level
296
// only requires a getter.
297
for (Iterator JavaDoc iterator = curFields.iterator(); iterator.hasNext(); ) {
298             XMethod setter = (XMethod) iterator.next();
299
300             if (MethodTagsHandler.isSetterMethod(setter)) {
301                 if (setter.getDoc().getTag("spring.validator") != null) {
302                     String JavaDoc name = MethodTagsHandler.getPropertyNameFor(setter);
303                     XParameter param = (XParameter) setter.getParameters().iterator().next();
304                     String JavaDoc type = param.getType().getQualifiedName();
305
306                     if (supportedTypes.contains(type)) {
307                         fields.put(prefix + name, setter);
308                     }
309                     else {
310                         fields.putAll(getFields(param.getType(), prefix + (prefix.length() == 0 ? "" : ".") + name + "."));
311                     }
312                 }
313             }
314         }
315
316         return fields;
317     }
318
319     private void loadFieldArguments()
320     {
321         /*
322          * A bit of explanation is due here. Rather than come up with
323          * some fancy data structure to keep validator arguments stored into,
324          * I simply store them into a Map with the value being the value
325          * from the parameter. The name, however, represents the argument
326          * index, whether its a resource or an inline value, and whether it
327          * is attached to a particular validator type. The name format is:
328          * argN[resource|value][_TYPE]
329          * the argN[resource|value] piece is the actual parameter name.
330          * N is the argument index.
331          * TYPE is added only if the parameter appears on spring.validator tag
332          * which indicates its only associated with a specific validator type.
333          */

334         args = new SequencedHashMap();
335
336         XMethod method = getCurrentMethod();
337
338         // Collect all general args
339
Collection JavaDoc argTags = method.getDoc().getTags("spring.validator-args");
340
341         for (Iterator JavaDoc argsIterator = argTags.iterator(); argsIterator.hasNext(); ) {
342             XTag tag = (XTag) argsIterator.next();
343             Collection JavaDoc attributeNames = tag.getAttributeNames();
344
345             for (Iterator JavaDoc attributesIterator = attributeNames.iterator(); attributesIterator.hasNext(); ) {
346                 String JavaDoc name = (String JavaDoc) attributesIterator.next();
347
348                 if (name.startsWith("arg")) {
349                     args.put(name, tag.getAttributeValue(name));
350                 }
351             }
352         }
353
354         // Collect all type-specific args
355
Collection JavaDoc argTypeTags = method.getDoc().getTags("spring.validator");
356
357         for (Iterator JavaDoc typeTagsIterator = argTypeTags.iterator(); typeTagsIterator.hasNext(); ) {
358             XTag tag = (XTag) typeTagsIterator.next();
359             Collection JavaDoc attributeNames = tag.getAttributeNames();
360             String JavaDoc type = tag.getAttributeValue("type");
361
362             for (Iterator JavaDoc attributesIterator = attributeNames.iterator(); attributesIterator.hasNext(); ) {
363                 String JavaDoc name = (String JavaDoc) attributesIterator.next();
364
365                 if (name.startsWith("arg")) {
366                     args.put(name + "_" + type, tag.getAttributeValue(name));
367                 }
368             }
369         }
370     }
371 }
372
Popular Tags