KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > apache > struts > StrutsValidatorTagsHandler


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

5 package xdoclet.modules.apache.struts;
6
7 import java.util.ArrayList JavaDoc;
8
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
17 import xjavadoc.XClass;
18 import xjavadoc.XMethod;
19 import xjavadoc.XParameter;
20 import xjavadoc.XTag;
21
22 import xdoclet.DocletSupport;
23 import xdoclet.XDocletException;
24 import xdoclet.tagshandler.AbstractProgramElementTagsHandler;
25 import xdoclet.tagshandler.MethodTagsHandler;
26 import xdoclet.tagshandler.TypeTagsHandler;
27 import xdoclet.util.Translator;
28
29 /**
30  * Struts Validator tag handler tags
31  *
32  * @author Erik Hatcher (ehatcher@apache.org)
33  * @created August 23, 2002
34  * @xdoclet.taghandler namespace="Validator"
35  * @version $Revision: 1.12 $
36  */

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

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

92     public String JavaDoc formName(Properties JavaDoc attributes) throws XDocletException
93     {
94         if (getCurrentClass().isA("org.apache.struts.validator.ValidatorActionForm"))
95             return getTagValue(FOR_CLASS, "struts.form", "path", null, null, false, true);
96         else
97             return getTagValue(FOR_CLASS, "struts.form", "name", null, null, false, true);
98     }
99
100     /**
101      * Iterates over all arguments for the current field.
102      *
103      * @param template The body of the block tag
104      * @param attributes The attributes of the template tag
105      * @throws XDocletException
106      * @doc.tag type="block"
107      */

108     public void forAllFieldArgs(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
109     {
110         for (Iterator JavaDoc iterator = args.keySet().iterator(); iterator.hasNext(); ) {
111             currentArgKey = (String JavaDoc) iterator.next();
112             generate(template);
113         }
114     }
115
116     /**
117      * Current argument index number (0 to 3).
118      *
119      * @param props The content tag attributes.
120      * @return current argument index
121      * @doc.tag type="content"
122      */

123     public String JavaDoc argIndex(Properties JavaDoc props)
124     {
125         return currentArgKey.charAt(3) + "";
126     }
127
128     /**
129      * Current argument name - only valid if argument is for a specific validator type.
130      *
131      * @param props The content tag attributes.
132      * @return current argument name
133      * @doc.tag type="content"
134      */

135     public String JavaDoc argName(Properties JavaDoc props)
136     {
137         String JavaDoc name = currentArgKey.substring(currentArgKey.indexOf('_') + 1);
138
139         return name;
140     }
141
142     /**
143      * Current argument value, which is either an inline value or resource key.
144      *
145      * @param props The content tag attributes.
146      * @return current argument value
147      * @doc.tag type="content"
148      */

149     public String JavaDoc argValue(Properties JavaDoc props)
150     {
151         return (String JavaDoc) args.get(currentArgKey);
152     }
153
154     /**
155      * Evaluates body if current argument is a resource key.
156      *
157      * @param template The body of the block tag
158      * @param attributes The attributes of the template tag
159      * @throws XDocletException
160      * @doc.tag type="block"
161      */

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

177     public void ifArgIsValue(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
178     {
179         if (currentArgKey.indexOf("value") > 0) {
180             generate(template);
181         }
182     }
183
184     /**
185      * Evaluates the body if the current argument is a validator-specific argument.
186      *
187      * @param template The body of the block tag
188      * @param attributes The attributes of the template tag
189      * @throws XDocletException
190      * @doc.tag type="block"
191      */

192     public void ifArgIsForType(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
193     {
194         if (currentArgKey.indexOf('_') > 0) {
195             generate(template);
196         }
197     }
198
199     /**
200      * Evaluates the body if there is no arg0 specified.
201      *
202      * @param template The body of the block tag
203      * @param attributes The attributes of the template tag
204      * @throws XDocletException
205      * @doc.tag type="block"
206      */

207     public void ifNoArg0(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
208     {
209         if (args.get("arg0resource") == null && args.get("arg0value") == null) {
210             generate(template);
211         }
212     }
213
214     /**
215      * Evaluates the body if form has fields requiring validation.
216      *
217      * @param template The body of the block tag
218      * @param attributes The attributes of the template tag
219      * @throws XDocletException
220      * @doc.tag type="block"
221      */

222     public void ifFormHasFields(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
223     {
224         if (getFields(getCurrentClass()).size() > 0) {
225             generate(template);
226         }
227     }
228
229     /**
230      * Evaluates the body if the current field has an indexed component.
231      *
232      * @param template The body of the block tag
233      * @param attributes The attributes of the template tag
234      * @throws XDocletException
235      * @doc.tag type="block"
236      */

237     public void ifFieldIsIndexed(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
238     {
239         if (curFieldName.indexOf("[]") >= 0) {
240             generate(template);
241         }
242     }
243
244     /**
245      * Iterates the body for each field of the current form requiring validation.
246      *
247      * @param template The body of the block tag
248      * @param attributes The attributes of the template tag
249      * @throws XDocletException
250      * @doc.tag type="block"
251      */

252     public void forAllFields(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
253     {
254         XClass clazz = getCurrentClass();
255         Map JavaDoc setters = getFields(clazz);
256
257         for (Iterator JavaDoc iterator = setters.keySet().iterator(); iterator.hasNext(); ) {
258             curFieldName = (String JavaDoc) iterator.next();
259
260             XMethod field = (XMethod) setters.get(curFieldName);
261
262             setCurrentMethod(field);
263             loadFieldArguments();
264             generate(template);
265         }
266     }
267
268     /**
269      * Returns the current field's name, local to the indexed property if there is one.
270      *
271      * @param props The content tag attributes.
272      * @return current field name
273      * @doc.tag type="content"
274      */

275     public String JavaDoc fieldName(Properties JavaDoc props)
276     {
277         int listIdx = curFieldName.indexOf("[]");
278
279         if (listIdx == -1)
280             return curFieldName;
281
282         String JavaDoc result = curFieldName.substring(listIdx + 3);
283
284         if (result.length() == 0)
285             return curFieldName.substring(0, listIdx);
286
287         return result;
288     }
289
290     /**
291      * Returns the current field's indexedListProperty attribute, if any.
292      *
293      * @param props The content tag attributes.
294      * @return current field's indexedListProperty
295      * @doc.tag type="content"
296      */

297     public String JavaDoc indexedListProperty(Properties JavaDoc props)
298     {
299         int listIdx = curFieldName.indexOf("[]");
300
301         if (listIdx == -1)
302             return "";
303
304         return curFieldName.substring(0, listIdx);
305     }
306
307     /**
308      * Returns a comma-separated list of the specified validator types.
309      *
310      * @param props The content tag attributes.
311      * @return validator types list
312      * @doc.tag type="content"
313      */

314     public String JavaDoc validatorList(Properties JavaDoc props)
315     {
316         XMethod method = getCurrentMethod();
317         Collection JavaDoc tags = method.getDoc().getTags("struts.validator");
318         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
319
320         for (Iterator JavaDoc iterator = tags.iterator(); iterator.hasNext(); ) {
321             XTag tag = (XTag) iterator.next();
322
323             buffer.append(tag.getAttributeValue("type"));
324             if (iterator.hasNext()) {
325                 buffer.append(",");
326             }
327         }
328         return buffer.toString();
329     }
330
331     protected Map JavaDoc getFields(XClass clazz) throws XDocletException
332     {
333         return getFields(clazz, "");
334     }
335
336     protected Map JavaDoc getFields(XClass clazz, String JavaDoc prefix) throws XDocletException
337     {
338         Map JavaDoc fields = new SequencedHashMap();
339
340         Collection JavaDoc curFields = clazz.getMethods(true);
341
342         // TODO: nested forms currently won't work unless
343
// there is a setter for it, but that is not needed
344
// as only the sub-forms must have setters. The top-level
345
// only requires a getter.
346
for (Iterator JavaDoc iterator = curFields.iterator(); iterator.hasNext(); ) {
347             XMethod method = (XMethod) iterator.next();
348             XTag tag = method.getDoc().getTag("struts.validator");
349             String JavaDoc override = null;
350
351             if (tag != null) {
352                 override = tag.getAttributeValue("override");
353             }
354
355             if (tag != null) {
356                 List JavaDoc params = method.getParameters();
357                 String JavaDoc name = method.getPropertyName();
358                 XParameter param = null;
359
360                 if (MethodTagsHandler.isSetterMethod(method)) {
361                     param = (XParameter) params.get(0);
362                 }
363                 else if (params.size() == 2) {
364                     // Check for indexed setter setBlah(int index, <type> value)
365
if (!MethodTagsHandler.isSetter(method.getName()))
366                         continue;
367
368                     Iterator JavaDoc paramIter = params.iterator();
369
370                     if (!((XParameter) paramIter.next()).getType().isA("int"))
371                         continue;
372
373                     if (name.indexOf("[]") >= 0) {
374                         throw new XDocletException(Translator.getString(StrutsValidatorMessages.class,
375                             StrutsValidatorMessages.ONLY_ONE_LEVEL_LIST_PROPS,
376                             new String JavaDoc[]{clazz.getName() + '.' + name + "[]"}));
377                     }
378
379                     name = name + "[]";
380                     param = (XParameter) paramIter.next();
381                 }
382                 else
383                     continue;
384
385                 String JavaDoc type = param.getType().getQualifiedName();
386
387                 if (supportedTypes.contains(type)) {
388                     fields.put(prefix + name, method);
389                 }
390                 else if ((override != null) && (override.equals("true"))) {
391                     fields.put(prefix + name, method);
392                 }
393                 else {
394
395                     boolean preDot = (prefix.length() > 0 && prefix.charAt(prefix.length() - 1) != '.');
396
397                     fields.putAll(getFields(param.getType(), prefix + (preDot ? "." : "") + name + "."));
398                 }
399             }
400         }
401
402         return fields;
403     }
404
405     protected void loadFieldArguments()
406     {
407         /*
408          * A bit of explanation is due here. Rather than come up with
409          * some fancy data structure to keep validator arguments stored into,
410          * I simply store them into a Map with the value being the value
411          * from the parameter. The name, however, represents the argument
412          * index, whether it's a resource or an inline value, and whether it
413          * is attached to a particular validator type. The name format is:
414          * argN[resource|value][_TYPE]
415          * the argN[resource|value] piece is the actual parameter name.
416          * N is the argument index.
417          * TYPE is added only if the parameter appears on struts.validator tag
418          * which indicates it's only associated with a specific validator type.
419          */

420         args = new SequencedHashMap();
421
422         XMethod method = getCurrentMethod();
423
424         // Collect all general args
425
Collection JavaDoc argTags = method.getDoc().getTags("struts.validator-args");
426
427         for (Iterator JavaDoc argsIterator = argTags.iterator(); argsIterator.hasNext(); ) {
428             XTag tag = (XTag) argsIterator.next();
429             Collection JavaDoc attributeNames = tag.getAttributeNames();
430
431             for (Iterator JavaDoc attributesIterator = attributeNames.iterator(); attributesIterator.hasNext(); ) {
432                 String JavaDoc name = (String JavaDoc) attributesIterator.next();
433
434                 if (name.startsWith("arg")) {
435                     args.put(name, tag.getAttributeValue(name));
436                 }
437             }
438         }
439
440         // Collect all type-specific args
441
Collection JavaDoc argTypeTags = method.getDoc().getTags("struts.validator");
442
443         for (Iterator JavaDoc typeTagsIterator = argTypeTags.iterator(); typeTagsIterator.hasNext(); ) {
444             XTag tag = (XTag) typeTagsIterator.next();
445             Collection JavaDoc attributeNames = tag.getAttributeNames();
446             String JavaDoc type = tag.getAttributeValue("type");
447
448             for (Iterator JavaDoc attributesIterator = attributeNames.iterator(); attributesIterator.hasNext(); ) {
449                 String JavaDoc name = (String JavaDoc) attributesIterator.next();
450
451                 if (name.startsWith("arg")) {
452                     args.put(name + "_" + type, tag.getAttributeValue(name));
453                 }
454             }
455         }
456     }
457 }
458
Popular Tags