KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > ejb > env > EnvTagsHandler


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

5 package xdoclet.modules.ejb.env;
6
7 import java.lang.reflect.Modifier JavaDoc;
8 import java.util.Collection JavaDoc;
9 import java.util.Collections JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.List JavaDoc;
13 import java.util.Map JavaDoc;
14 import java.util.Properties JavaDoc;
15 import java.util.StringTokenizer JavaDoc;
16 import xjavadoc.XClass;
17 import xjavadoc.XField;
18 import xjavadoc.XMember;
19 import xjavadoc.XMethod;
20 import xjavadoc.XTag;
21
22 import xdoclet.XDocletException;
23 import xdoclet.XDocletTagSupport;
24 import xdoclet.util.TypeConversionUtil;
25
26 /**
27  * Handles field level tag's for configuring a bean's environment.
28  *
29  * @author <a HREF="mailto:matthias@germann.com">Matthias Germann</a>
30  * @created March 31, 2005
31  * @xdoclet.taghandler namespace="EjbEnv"
32  * @version $Revision: 1.3 $
33  */

34 public class EnvTagsHandler extends XDocletTagSupport
35 {
36     /**
37      * Maps primitive types to their wrapper classes
38      */

39     private final static Map JavaDoc wrappers;
40
41     protected XTag currentTag;
42     protected XMember currentMember;
43     protected int currentTagType;
44     static {
45         Map JavaDoc wps = new HashMap JavaDoc();
46
47         wps.put("boolean", "java.lang.Boolean");
48         wps.put("byte", "java.lang.Byte");
49         wps.put("char", "java.lang.Character");
50         wps.put("short", "java.lang.Short");
51         wps.put("int", "java.lang.Integer");
52         wps.put("float", "java.lang.Float");
53         wps.put("long", "java.lang.Long");
54         wps.put("double", "java.lang.Double");
55         wrappers = Collections.unmodifiableMap(wps);
56     }
57
58     /**
59      * Executes the template for all class-, method- and field-level tags with the passed name
60      *
61      * @param template the template
62      * @param attributes the attributes
63      * @throws XDocletException if an error occures
64      * @doc.param name="tagName" optional="false" description="the tag name"
65      * @doc.param name="paramName" optional="true" description="the required parameter"
66      * @doc.param name="paramValue" optional="true" description="the value for the required parameter"
67      * @doc.tag type="block"
68      */

69     public void forAllTags(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
70     {
71         forTags(template, attributes, true, true, true);
72     }
73
74     /**
75      * Executes the template for all method- and field-level tags with the passed name
76      *
77      * @param template the template
78      * @param attributes the attributes
79      * @throws XDocletException if an error occures
80      * @doc.param name="tagName" optional="false" description="the tag name"
81      * @doc.param name="paramName" optional="true" description="the required parameter"
82      * @doc.param name="paramValue" optional="true" description="the value for the required parameter"
83      * @doc.tag type="block"
84      */

85     public void forAllMemberTags(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
86     {
87         forTags(template, attributes, false, true, true);
88
89     }
90
91     /**
92      * Executes the template for all method-level tags with the passed name
93      *
94      * @param template the template
95      * @param attributes the attributes
96      * @throws XDocletException if an error occures
97      * @doc.param name="tagName" optional="false" description="the tag name"
98      * @doc.param name="paramName" optional="true" description="the required parameter"
99      * @doc.param name="paramValue" optional="true" description="the value for the required parameter"
100      * @doc.tag type="block"
101      */

102     public void forAllMethodTags(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
103     {
104         forTags(template, attributes, false, true, false);
105     }
106
107     /**
108      * Returns the name parameter value for the current tag. If the name parameter is not specified for a method- or
109      * field-level tag, the member's name is returned. If the name parameter is not specified for a class level tag, an
110      * error is generated.
111      *
112      * @param attributes the attributes
113      * @return the name
114      * @exception XDocletException if an error occures
115      * @doc.param name="paramName" optional="false" description="the name of the name parameter"
116      * @doc.tag type="content"
117      */

118     public String JavaDoc name(Properties JavaDoc attributes) throws XDocletException
119     {
120         String JavaDoc paramName = attributes.getProperty("paramName");
121
122         if (paramName == null) {
123             throw new XDocletException("paramName attribute is mandatory");
124         }
125
126         String JavaDoc name = null;
127         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(paramName, ",");
128
129         while (name == null && st.hasMoreTokens()) {
130             name = currentTag.getAttributeValue(st.nextToken());
131         }
132
133         if (name == null) {
134             if (currentMember == null) {
135                 // class level
136
mandatoryParamNotFound(currentTag.getDoc(), paramName, currentTag.getName());
137             }
138             else {
139                 // method or field level
140
name = currentMember.getName();
141             }
142         }
143         return name;
144     }
145
146     /**
147      * Returns the type parameter value for the current tag. Returns the field type for field-level tags and the return
148      * value for method-level tags. For class-level tags, the value of the type parameter is returned. The wrapper class
149      * is returned for primitive fields an methods with primitive return values.
150      *
151      * @param attributes the attributes
152      * @return the type
153      * @exception XDocletException if an error occures
154      * @doc.param name="paramName" optional="false" description="the name of the type parameter"
155      * @doc.param name="values" description="The valid values for the parameter, comma separated. An
156      * error message is printed if the parameter value is not one of the values."
157      * @doc.param name="default" description="The default value is returned if parameter not specified
158      * by user for the tag."
159      * @doc.param name="mandatory" values="true,false" description="Generate an error if parameter not
160      * @doc.tag type="content"
161      */

162     public String JavaDoc type(Properties JavaDoc attributes) throws XDocletException
163     {
164         if (currentMember == null) {
165             // class level tags
166
return paramValue(attributes);
167         }
168         else {
169             // method and field level tags
170
String JavaDoc type = currentMemberType();
171             String JavaDoc wrapper = (String JavaDoc) wrappers.get(type);
172
173             return wrapper == null ? type : wrapper;
174         }
175     }
176
177     /**
178      * Executes the body only if the current tag is either a method- or fiel-level tag or has a type parameter.
179      *
180      * @param template the template
181      * @param attributes the attributes
182      * @exception XDocletException if an error occures
183      * @doc.param name="paramName" optional="false" description="the name of the name parameter"
184      * @doc.tag type="block"
185      */

186     public void ifHasType(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
187     {
188         String JavaDoc paramName = attributes.getProperty("paramName");
189
190         if (paramName == null) {
191             throw new XDocletException("paramName attribute is mandatory");
192         }
193
194         if (currentMember == null) {
195             // class level tags
196
String JavaDoc type = currentTag.getAttributeValue(paramName);
197
198             if (type != null) {
199                 generate(template);
200             }
201         }
202         else {
203             // method and field level tags
204
generate(template);
205         }
206     }
207
208     /**
209      * Returns the method or field name. Can only be used inside <code>forAllMemberTags</code> or <code>forAllMethodTags</code>
210      * .
211      *
212      * @param attributes the attributes
213      * @return the memeber's name
214      * @exception XDocletException if an error occures
215      * @doc.param name="prefix" optional="true" description="the prefix for the name"
216      * @doc.tag type="content"
217      */

218     public String JavaDoc memberName(Properties JavaDoc attributes) throws XDocletException
219     {
220         if (currentMember == null) {
221             throw new XDocletException("XDtEjbEnv:memberName can only be used inside forAllMemberTags or forAllMethodTags");
222         }
223
224         String JavaDoc name = currentMember.getName();
225         String JavaDoc prefix = attributes.getProperty("prefix");
226
227         if (prefix != null) {
228             name = prefix + "/" + name;
229         }
230         return name;
231     }
232
233     /**
234      * Returns the method's return type or the field's type. Can only be used inside <code>forAllMemberTags</code> or
235      * <code>forAllMethodTags</code>.
236      *
237      * @return the member's type
238      * @exception XDocletException if an error occures
239      * @doc.tag type="content"
240      */

241     public String JavaDoc memberType() throws XDocletException
242     {
243         if (currentMember == null) {
244             throw new XDocletException("XDtEjbEnv:memberType can only be used inside forAllMemberTags or forAllMethodTags");
245         }
246         return currentMemberType();
247     }
248
249     /**
250      * Returns the method signature for the current method. Can only be used inside <code>forAllMethodTags</code>.
251      *
252      * @return the current method's signature
253      * @exception XDocletException if an error occures
254      * @doc.tag type="content"
255      */

256     public String JavaDoc methodSignature() throws XDocletException
257     {
258         if (currentMember == null || !(currentMember instanceof XMethod)) {
259             throw new XDocletException("XDtEjbEnv:methodSignature can only be used inside forAllMemberTags or forAllMethodTags");
260         }
261
262         XMethod method = (XMethod) currentMember;
263         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
264
265         if (Modifier.isProtected(method.getModifierSpecifier())) {
266             sb.append("protected ");
267         }
268         if (Modifier.isPublic(method.getModifierSpecifier())) {
269             sb.append("public ");
270         }
271         sb.append(method.getReturnType().getType().getQualifiedName());
272         sb.append(' ');
273         sb.append(method.getNameWithSignature(true));
274
275         List JavaDoc exceptions = method.getThrownExceptions();
276
277         if (exceptions.size() > 0) {
278             sb.append(" throws ");
279             for (Iterator JavaDoc it = exceptions.iterator(); it.hasNext(); ) {
280                 XClass exception = (XClass) it.next();
281
282                 sb.append(exception.getQualifiedName());
283                 if (it.hasNext()) {
284                     sb.append(", ");
285                 }
286             }
287         }
288
289         return sb.toString();
290     }
291
292     /**
293      * Returns the value of a parameter.
294      *
295      * @param attributes the attributes
296      * @return the value
297      * @exception XDocletException if an error occures
298      * @doc.param name="paramName" optional="false" description="the name of the parameter"
299      * @doc.param name="values" description="The valid values for the parameter, comma separated. An
300      * error message is printed if the parameter value is not one of the values."
301      * @doc.param name="default" description="The default value is returned if parameter not specified
302      * by user for the tag."
303      * @doc.param name="mandatory" values="true,false" description="Generate an error if parameter not
304      * @doc.tag type="content"
305      */

306     public String JavaDoc paramValue(Properties JavaDoc attributes) throws XDocletException
307     {
308         attributes.setProperty("tagName", currentTag.getName());
309         return getTagValue(attributes, currentTagType);
310     }
311
312     /**
313      * Executes the body only if the current tag has a specified parameter
314      *
315      * @param template the template
316      * @param attributes the attributes
317      * @exception XDocletException if an error occures
318      * @doc.param name="paramName" optional="false" description="the name of the parameter"
319      * @doc.tag type="body"
320      */

321     public void ifHasParam(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
322     {
323         if (paramValue(attributes) != null) {
324             generate(template);
325         }
326     }
327
328     /**
329      * Executes the body only if the specified tag's value is equal to the specified value
330      *
331      * @param template the template
332      * @param attributes the attributes
333      * @exception XDocletException if an error occures
334      * @doc.param name="paramName" optional="false" description="the name of the parameter"
335      * @doc.param name="value" optional="false" description="the value of the parameter"
336      * @doc.tag type="body"
337      */

338     public void ifParamValueEquals(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
339     {
340         if (isParamValueEqual(attributes)) {
341             generate(template);
342         }
343     }
344
345     /**
346      * Executes the body only if the specified tag's value is equal to the specified value
347      *
348      * @param template the template
349      * @param attributes the attributes
350      * @exception XDocletException if an error occures
351      * @doc.param name="paramName" optional="false" description="the name of the parameter"
352      * @doc.param name="value" optional="false" description="the value of the parameter"
353      * @doc.tag type="body"
354      */

355     public void ifParamValueNotEquals(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
356     {
357         if (!isParamValueEqual(attributes)) {
358             generate(template);
359         }
360     }
361
362
363     /**
364      * Executes the body only if the current field type or method return type is primitive.
365      *
366      * @param template the template
367      * @param attributes the attributes
368      * @exception XDocletException if an error occures
369      * @doc.tag type="block"
370      */

371     public void ifPrimitiveMember(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
372     {
373         if (isPrimitiveMember()) {
374             generate(template);
375         }
376     }
377
378     /**
379      * Executes the body only if the current field type or method return type is not a primitive.
380      *
381      * @param template the template
382      * @param attributes the attributes
383      * @exception XDocletException if an error occures
384      * @doc.tag type="block"
385      */

386     public void ifNotPrimitiveMember(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
387     {
388         if (!isPrimitiveMember()) {
389             generate(template);
390         }
391     }
392
393     /**
394      * Executes the body only if the current class has at least one ot the passed tags at field- or method-level
395      *
396      * @param template the template
397      * @param attributes the attributes
398      * @exception XDocletException if an error occures
399      * @doc.tag type="block"
400      * @doc.param name="tagName" optional="false" description="the tag names (comma separated)"
401      * @doc.param name="paramName" optional="true" description="tags must have this parameter"
402      * @doc.param name="paramValue" optional="true" description="tags must have this value for the
403      * parameter with 'paramName'"
404      */

405     public void ifHasTag(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
406     {
407         String JavaDoc tags = attributes.getProperty("tagName");
408
409         if (tags == null) {
410             throw new XDocletException("tagName is mandatory");
411         }
412
413         String JavaDoc paramName = attributes.getProperty("paramName");
414         String JavaDoc paramValue = attributes.getProperty("paramValue");
415
416         if (hasMemberWithTag(getCurrentClass().getMethods(true), tags, paramName, paramValue)) {
417             generate(template);
418         }
419         else {
420             if (hasMemberWithTag(getCurrentClass().getFields(true), tags, paramName, paramValue)) {
421                 generate(template);
422             }
423         }
424     }
425
426
427     /**
428      * Executes the passed template for the passed
429      *
430      * @param template the template
431      * @param attributes the parameters
432      * @param forClass indicates whether the template should be excuted for class level tags
433      * @param forMethod indicates whether the template should be excuted for method level tags
434      * @param forField indicates whether the template should be excuted for field level tags
435      * @throws XDocletException if an error occures
436      */

437     protected void forTags(String JavaDoc template, Properties JavaDoc attributes, boolean forClass, boolean forMethod, boolean forField) throws XDocletException
438     {
439         boolean superclasses = TypeConversionUtil.stringToBoolean(attributes.getProperty("superclasses"), true);
440
441         String JavaDoc tagName = attributes.getProperty("tagName");
442
443         if (tagName == null) {
444             throw new XDocletException("tagName is mandatory");
445         }
446
447         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(tagName, ",");
448
449         while (st.hasMoreTokens()) {
450             attributes.setProperty("tagName", st.nextToken());
451             forTagsInternal(template, attributes, superclasses, forClass, forMethod, forField);
452         }
453     }
454
455     /**
456      * Called for each tag in the <code>forTags</code> loop. The default behaviour is to call <code>generate(template)</code>
457      *
458      * @param template the template
459      * @throws XDocletException if an error occures
460      */

461     protected void doGenerate(String JavaDoc template) throws XDocletException
462     {
463         generate(template);
464     }
465
466
467     /**
468      * Returns whether the current field type or method return type is primitive.
469      *
470      * @return <code>true</code> it the current member is primitive
471      */

472     private boolean isPrimitiveMember()
473     {
474         if (currentMember != null) {
475             String JavaDoc type = currentMemberType();
476             String JavaDoc wrapper = (String JavaDoc) wrappers.get(type);
477
478             if (wrapper != null) {
479                 return true;
480             }
481         }
482         return false;
483     }
484
485     /**
486      * Returns whether the parameter's value is equal to the specfied value
487      *
488      * @param attributes the attributes
489      * @return <code>true</code> if it is equal
490      * @throws XDocletException if an error occures
491      */

492     private boolean isParamValueEqual(Properties JavaDoc attributes) throws XDocletException
493     {
494         String JavaDoc value = attributes.getProperty("value");
495
496         if (value == null) {
497             throw new XDocletException("value is mandatory");
498         }
499         return value.equals(paramValue(attributes));
500     }
501
502     /**
503      * Executes the passed template for the passed
504      *
505      * @param template the template
506      * @param attributes the attriubtes
507      * @param superclasses indicates whether the superclasses of the current class should also be searched
508      * @param forClass indicates whether the template should be excuted for class level tags
509      * @param forMethod indicates whether the template should be excuted for method level tags
510      * @param forField indicates whether the template should be excuted for field level tags
511      * @throws XDocletException if an error occures
512      */

513     private void forTagsInternal(String JavaDoc template, Properties JavaDoc attributes, boolean superclasses, boolean forClass, boolean forMethod, boolean forField) throws XDocletException
514     {
515
516         String JavaDoc tagName = attributes.getProperty("tagName");
517         String JavaDoc paramName = attributes.getProperty("paramName");
518         String JavaDoc paramValue = attributes.getProperty("paramValue");
519
520         // class level tags
521
if (forClass) {
522             currentTagType = FOR_CLASS;
523
524             Collection JavaDoc tags = getCurrentClass().getDoc().getTags(tagName, superclasses);
525
526             for (Iterator JavaDoc it = tags.iterator(); it.hasNext(); ) {
527                 currentTag = (XTag) it.next();
528                 if (tagMatches(currentTag, paramName, paramValue)) {
529                     setCurrentClassTag(currentTag);
530                     currentMember = null;
531                     doGenerate(template);
532                     setCurrentClassTag(null);
533                 }
534             }
535         }
536
537         // method level tags
538
if (forMethod) {
539             currentTagType = FOR_METHOD;
540
541             Collection JavaDoc methods = getCurrentClass().getMethods(superclasses);
542
543             for (Iterator JavaDoc it = methods.iterator(); it.hasNext(); ) {
544                 XMethod method = (XMethod) it.next();
545
546                 setCurrentMethod(method);
547
548                 Collection JavaDoc tags = method.getDoc().getTags(tagName);
549
550                 for (Iterator JavaDoc it2 = tags.iterator(); it2.hasNext(); ) {
551                     currentTag = (XTag) it2.next();
552                     if (tagMatches(currentTag, paramName, paramValue)) {
553                         setCurrentMethodTag(currentTag);
554                         currentMember = method;
555                         doGenerate(template);
556                         setCurrentMethodTag(null);
557                     }
558                 }
559                 setCurrentMethod(null);
560             }
561         }
562
563         // field level tags
564
if (forField) {
565             currentTagType = FOR_FIELD;
566
567             Collection JavaDoc fields = getCurrentClass().getFields(superclasses);
568
569             for (Iterator JavaDoc it = fields.iterator(); it.hasNext(); ) {
570                 XField field = (XField) it.next();
571
572                 setCurrentField(field);
573
574                 Collection JavaDoc tags = field.getDoc().getTags(tagName);
575
576                 for (Iterator JavaDoc it2 = tags.iterator(); it2.hasNext(); ) {
577                     currentTag = (XTag) it2.next();
578                     if (tagMatches(currentTag, paramName, paramValue)) {
579                         setCurrentFieldTag(currentTag);
580                         currentMember = field;
581                         doGenerate(template);
582                         setCurrentFieldTag(null);
583                     }
584                 }
585                 setCurrentField(null);
586             }
587         }
588
589         currentTagType = 0;
590     }
591
592     /**
593      * Returns whether the passed tag matches for the passed parameter name and value
594      *
595      * @param tag the tag
596      * @param paramName the parameter name or <code>null</code> for no parameter restriction
597      * @param paramValue the value for the parameter <code>paramName</code> or <code>null</code> for no parameter value
598      * restriction
599      * @return <code>true</code> it the tag matches
600      */

601     private boolean tagMatches(XTag tag, String JavaDoc paramName, String JavaDoc paramValue)
602     {
603         if (paramName == null) {
604             return true;
605         }
606
607         String JavaDoc value = tag.getAttributeValue(paramName);
608
609         return value != null && (paramValue == null || value.equals(paramValue));
610     }
611
612     /**
613      * Returns whether the passed Collection of Members has at least one the passed tags for which a value is bound in
614      * the java componenet environement jndi namespace
615      *
616      * @param members a <code>Collection</code> o {@link XMember}
617      * @param tagNames the tag names
618      * @param paramName the required parameter or <code>null</code>
619      * @param paramValue the required value of the parameter <code>paramName</code> or <code>null</code>
620      * @return <code>true</code> if the passed Collection of Members has at least one of the tags for which a
621      * value is bound in the java componenet environement jndi namespace
622      */

623     private boolean hasMemberWithTag(Collection JavaDoc members, String JavaDoc tagNames, String JavaDoc paramName, String JavaDoc paramValue)
624     {
625
626         for (Iterator JavaDoc it = members.iterator(); it.hasNext(); ) {
627             XMember member = (XMember) it.next();
628
629             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(tagNames, ",");
630
631             while (st.hasMoreTokens()) {
632                 Collection JavaDoc tags = member.getDoc().getTags(st.nextToken());
633
634                 if (tags.size() > 0) {
635                     if (paramName == null) {
636                         return true;
637                     }
638                     else {
639                         for (Iterator JavaDoc it2 = tags.iterator(); it2.hasNext(); ) {
640                             XTag tag = (XTag) it2.next();
641                             String JavaDoc value = tag.getAttributeValue(paramName);
642
643                             if (value != null && (paramValue == null || paramValue.equals(value))) {
644                                 return true;
645                             }
646                         }
647                     }
648                 }
649             }
650         }
651         return false;
652     }
653
654     /**
655      * Returns the type of the current member
656      *
657      * @return the type
658      */

659     private String JavaDoc currentMemberType()
660     {
661         if (currentMember instanceof XField) {
662             return ((XField) currentMember).getType().getQualifiedName();
663         }
664         else {
665             return ((XMethod) currentMember).getReturnType().getType().getQualifiedName();
666         }
667
668     }
669
670 }
671
Popular Tags