KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > ejb > home > HomeTagsHandler


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

5 package xdoclet.modules.ejb.home;
6
7 import java.text.MessageFormat JavaDoc;
8 import java.util.*;
9
10 import org.apache.commons.logging.Log;
11
12 import xjavadoc.*;
13
14 import xdoclet.DocletContext;
15 import xdoclet.DocletTask;
16 import xdoclet.XDocletException;
17 import xdoclet.XDocletMessages;
18 import xdoclet.modules.ejb.EjbTagsHandler;
19 import xdoclet.modules.ejb.XDocletModulesEjbMessages;
20 import xdoclet.modules.ejb.entity.CmpTagsHandler;
21 import xdoclet.modules.ejb.entity.EntityTagsHandler;
22 import xdoclet.modules.ejb.entity.PkTagsHandler;
23 import xdoclet.modules.ejb.home.LocalHomeInterfaceSubTask;
24 import xdoclet.modules.ejb.intf.InterfaceTagsHandler;
25 import xdoclet.modules.ejb.session.SessionTagsHandler;
26 import xdoclet.util.DocletUtil;
27 import xdoclet.util.LogUtil;
28 import xdoclet.util.Translator;
29 import xdoclet.util.TypeConversionUtil;
30
31 /**
32  * @author Ara Abrahamian (ara_e@email.com)
33  * @created Oct 15, 2001
34  * @xdoclet.taghandler namespace="EjbHome"
35  * @version $Revision: 1.37 $
36  */

37 public class HomeTagsHandler extends EjbTagsHandler
38 {
39
40     private String JavaDoc currentSignature;
41
42     private String JavaDoc currentExceptions;
43
44     private String JavaDoc currentPermission;
45
46     /**
47      * Similar to {@link xdoclet.modules.ejb.intf.InterfaceTagsHandler#getComponentInterface}. Relies on the ejb:home
48      * tag, which has the following relevant properties:
49      * <ul>
50      * <li> remote-class: The fully qualified name of the remote class - overrides all set patterns
51      * <li> local-class: The fully qualified name of the local class - overrides all set patterns
52      * <li> remote-pattern: The pattern to be used to determine the unqualified name of the remote class
53      * <li> local-pattern: The pattern to be used to determine the unqualified name of the local class
54      * <li> pattern: The pattern to be used in determining the unqualified remote and/or local home interface name -
55      * used where remote- or local- pattern are not specified.
56      * <li> remote-package: The package the remote home interface is to be placed in
57      * <li> local-package: The package the local home interface is to be placed in
58      * <li> package: The package the remote and/or local home interface is to be placed in - used where remote- or
59      * local- package are not specified.
60      * </ul>
61      *
62      *
63      * @param type The type of home interface - can be remote or local.
64      * @param clazz Description of Parameter
65      * @return The HomeInterface value
66      * @exception XDocletException
67      */

68     public static String JavaDoc getHomeInterface(String JavaDoc type, XClass clazz) throws XDocletException
69     {
70         Log log = LogUtil.getLog(HomeTagsHandler.class, "getHomeInterface");
71
72         // validate type
73
if (!"remote".equals(type) && !"local".equals(type)) {
74             throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.METHOD_ONLY_TAKES_REMOTE_OR_LOCAL, new String JavaDoc[]{"getHomeInterface", type}));
75         }
76
77         String JavaDoc fileName = clazz.getContainingPackage().getName();
78         String JavaDoc name_pattern = null;
79         String JavaDoc package_pattern = null;
80         String JavaDoc home_interface = null;
81
82         home_interface = clazz.getDoc().getTagAttributeValue("ejb:home", type + "-class");
83         if (log.isDebugEnabled()) {
84             log.debug(type + " home Interface for " + clazz.getQualifiedName() + " = " + home_interface);
85         }
86
87         if (home_interface != null) {
88             return home_interface;
89         }
90
91         name_pattern = clazz.getDoc().getTagAttributeValue("ejb:home", type + "-pattern");
92         if (name_pattern == null) {
93             name_pattern = clazz.getDoc().getTagAttributeValue("ejb:home", "pattern");
94             if (name_pattern == null) {
95                 name_pattern = "remote".equals(type) ? getHomeClassPattern() : getLocalHomeClassPattern();
96             }
97         }
98
99         package_pattern = clazz.getDoc().getTagAttributeValue("ejb:home", type + "-package");
100         if (package_pattern == null) {
101             package_pattern = clazz.getDoc().getTagAttributeValue("ejb:home", "package");
102         }
103
104         String JavaDoc ejb_name = null;
105
106         if (name_pattern.indexOf("{0}") != -1) {
107             ejb_name = MessageFormat.format(name_pattern, new Object JavaDoc[]{getShortEjbNameFor(clazz)});
108         }
109         else {
110             ejb_name = name_pattern;
111         }
112
113         String JavaDoc subtask_name = null;
114
115         if (type.equals("remote")) {
116             subtask_name = DocletTask.getSubTaskName(HomeInterfaceSubTask.class);
117         }
118         else {
119             subtask_name = DocletTask.getSubTaskName(LocalHomeInterfaceSubTask.class);
120         }
121
122         // Fix package name
123
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(choosePackage(fileName, package_pattern, subtask_name));
124
125         if (sb.length() > 0) {
126             sb.append('.');
127         }
128         sb.append(ejb_name);
129
130         return sb.toString();
131     }
132
133     /**
134      * Returns true if method is an ejbRemove method, false otherwise.
135      *
136      * @param method The method to test
137      * @return true if named ejbRemove
138      */

139     public static boolean isRemoveMethod(XMethod method)
140     {
141         return method.getName().equals("ejbRemove");
142     }
143
144     /**
145      * Returns true if method is a create method marked with a \@ejb.create-method tag, false otherwise.
146      *
147      * @param method The method to test
148      * @return true if ejb.create-method tag found
149      */

150     public static boolean isCreateMethod(XMethod method)
151     {
152         return method.getDoc().hasTag("ejb.create-method");
153     }
154
155     /**
156      * Returns true if method is a home method marked with a \@ejb.home-method tag, false otherwise.
157      *
158      * @param method The method to test
159      * @return true if ejb.home-method tag found
160      */

161     public static boolean isHomeMethod(XMethod method)
162     {
163         return method.getDoc().hasTag("ejb.home-method");
164     }
165
166     /**
167      * Returns a suitable component name (which could be used, for example, in JNDI lookups) for a class.
168      *
169      * @param clazz the class
170      * @param type interface view type, \"local\" or \"remote\"
171      * @return compname
172      */

173     public static String JavaDoc getCompNameFor(XClass clazz, String JavaDoc type)
174     {
175         String JavaDoc compName = getEjbNameFor(clazz).replace('.', '/');
176
177         if (type.equals("local")) {
178             compName = compName + LOCAL_SUFFIX;
179         }
180
181         return compName;
182     }
183
184     /**
185      * Returns true if method is an ejbFind method, false otherwise.
186      *
187      * @param method The method to test
188      * @return true if name starts with ejbFind
189      */

190     public static boolean isFinderMethod(XMethod method)
191     {
192         return method.getName().startsWith("ejbFind");
193     }
194
195     /**
196      * Gets the HomeDefinition attribute of the HomeTagsHandler class
197      *
198      * @param clazz Describe what the parameter does
199      * @param method Describe what the parameter does
200      * @param tagType Describe what the parameter does
201      * @param type Describe what the parameter does
202      * @return The HomeDefinition value
203      * @exception XDocletException
204      */

205     public static String JavaDoc getHomeDefinition(XClass clazz, XMethod method, String JavaDoc tagType, String JavaDoc type)
206          throws XDocletException
207     {
208         String JavaDoc methodName = method.getName().substring(3);
209         StringBuffer JavaDoc homeMethodName = new StringBuffer JavaDoc();
210
211         if (tagType.equals("ejb:finder")) {
212             String JavaDoc ejbReturn = method.getReturnType().getType().getQualifiedName();
213
214             if (ejbReturn.equals("java.util.Collection") ||
215                 ejbReturn.equals("java.util.Enumeration") ||
216                 ejbReturn.equals("java.util.Set")) {
217                 homeMethodName.append(ejbReturn);
218
219             }
220             else {
221                 homeMethodName.append(InterfaceTagsHandler.getComponentInterface(type, clazz));
222
223             }
224         }
225         else if (tagType.equals("ejb:create-method")) {
226             homeMethodName.append(InterfaceTagsHandler.getComponentInterface(type, clazz));
227         }
228         else if (tagType.equals("ejb:home-method")) {
229             methodName = methodName.substring(4);
230             homeMethodName.append(method.getReturnType().getType().getQualifiedName());
231         }
232         homeMethodName.append(" ");
233         homeMethodName.append(methodName.substring(0, 1).toLowerCase());
234         homeMethodName.append(methodName.substring(1));
235         homeMethodName.append("(");
236
237         for (Iterator i = method.getParameters().iterator(); i.hasNext(); ) {
238             homeMethodName.append(i.next());
239             if (i.hasNext())
240                 homeMethodName.append(" , ");
241         }
242         homeMethodName.append(")");
243         return fullPackageChange(homeMethodName.toString());
244     }
245
246     public static String JavaDoc getJndiNameOfTypeFor(String JavaDoc type, XClass clazz)
247     {
248         XTag bean_tag = clazz.getDoc().getTag("ejb:bean");
249         String JavaDoc compName = getCompNameFor(clazz, type);
250
251         if (bean_tag != null) {
252             String JavaDoc jndiName = bean_tag.getAttributeValue("jndi-name");
253             String JavaDoc localJndiName = bean_tag.getAttributeValue("local-jndi-name");
254
255             //Return "local" jndi name
256
if ("local".equals(type)) {
257                 return localJndiName != null ? localJndiName : compName;
258             }
259
260             //Didn't ask for local, assume remote
261
return jndiName != null ? jndiName : compName;
262         }
263
264         //nothing specified so madeup one
265
return compName;
266     }
267
268     /**
269      * Converts ejbHome<em>blabla</em> to home<em>blabla</em> , the one that should appear in home interface.
270      *
271      * @param methodName Method name to be converted.
272      * @return Equivalent home interface method name.
273      */

274     public static String JavaDoc toHomeMethod(String JavaDoc methodName)
275     {
276         // Remove "ejbHome" prefix and lower case first char in rest: "ejbHomeFoo"->"foo"
277
return Character.toLowerCase(methodName.charAt(7)) + methodName.substring(8);
278     }
279
280     /**
281      * Converts ejbCreate<em>blabla</em> to create<em>blabla</em> , the one that should appear in home interface.
282      *
283      * @param methodName Method name to be converted.
284      * @return Equivalent home interface method name.
285      */

286     public static String JavaDoc toCreateMethod(String JavaDoc methodName)
287     {
288         if (methodName.length() > 9) {
289             // Remove "ejbCreate" prefix and lower case first char in rest: "ejbCreateFoo"->"createFoo", EJB 2 only
290
return "create" + Character.toUpperCase(methodName.charAt(9)) + methodName.substring(10);
291         }
292         else {
293             return "create";
294         }
295     }
296
297     /**
298      * Describe what the method does
299      *
300      * @param clazz Describe what the parameter does
301      * @return Describe the return value
302      */

303     public static XMethod findFirstCreateMethodFor(XClass clazz)
304     {
305         Collection methods = clazz.getMethods();
306
307         do {
308             for (Iterator j = methods.iterator(); j.hasNext(); ) {
309                 XMethod method = (XMethod) j.next();
310
311                 if (HomeTagsHandler.isCreateMethod(method)) {
312                     return method;
313                 }
314             }
315
316             clazz = clazz.getSuperclass();
317         } while (clazz != null);
318
319         return null;
320     }
321
322     /**
323      * Converts ejbFind<em>blabla</em> to find<em>blabla</em> , the one that should appear in home interface.
324      *
325      * @param methodName Method name to be converted.
326      * @return Equivalent home interface method name.
327      */

328     public static String JavaDoc toFinderMethod(String JavaDoc methodName)
329     {
330         // Remove "ejb" prefix and lower case first char in rest: "ejbFindByPrimaryKey"->"findByPrimaryKey"
331
return Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
332     }
333
334     /**
335      * Convert various collection types within a string to their fully qualified forms.
336      *
337      * @param s String to be converted.
338      * @return String with fully qualified collection types.
339      */

340     public static String JavaDoc fullPackageChange(String JavaDoc s)
341     {
342         StringTokenizer st = new StringTokenizer(s, " ");
343         String JavaDoc sign = st.nextToken();
344         StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
345
346         if (sign.equals("Collection")) {
347             ret.append("java.util.Collection");
348         }
349         else if (sign.equals("Enumeration")) {
350             ret.append("java.util.Enumeration");
351         }
352         else if (sign.equals("Set")) {
353             ret.append("java.util.Set");
354         }
355         else {
356             ret.append(sign);
357         }
358         while (st.hasMoreTokens()) {
359             ret.append(" ").append(st.nextToken());
360         }
361         return ret.toString();
362     }
363
364     /**
365      * Describe what the method does
366      *
367      * @param s Describe what the parameter does
368      * @param clazz
369      * @param type
370      * @return Describe the return value
371      * @exception XDocletException
372      */

373     public static String JavaDoc finderSignatureFunger(String JavaDoc s, XClass clazz, String JavaDoc type) throws XDocletException
374     {
375         StringTokenizer st = new StringTokenizer(s, " ");
376         String JavaDoc sign = st.nextToken();
377         StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
378
379         if (sign.equals("Collection") || sign.equals("java.util.Collection")) {
380             ret.append("java.util.Collection");
381         }
382         else if (sign.equals("Enumeration") || sign.equals("java.util.Enumeration")) {
383             ret.append("java.util.Enumeration");
384         }
385         else if (sign.equals("Set") || sign.equals("java.util.Set")) {
386             ret.append("java.util.Set");
387         }
388         else {
389             ret.append(InterfaceTagsHandler.getComponentInterface(type, clazz));
390         }
391         while (st.hasMoreTokens()) {
392             ret.append(" ").append(st.nextToken());
393         }
394         return ret.toString();
395     }
396
397     /**
398      * Gets the LocalHomeClassPattern attribute of the HomeTagsHandler class.
399      *
400      * @return The LocalHomeClassPattern value
401      */

402     protected static String JavaDoc getLocalHomeClassPattern()
403     {
404         LocalHomeInterfaceSubTask localhomeintf_subtask = ((LocalHomeInterfaceSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(LocalHomeInterfaceSubTask.class)));
405
406         if (localhomeintf_subtask != null) {
407             return localhomeintf_subtask.getLocalHomeClassPattern();
408         }
409         else {
410             return LocalHomeInterfaceSubTask.DEFAULT_LOCALHOMEINTERFACE_CLASS_PATTERN;
411         }
412     }
413
414     /**
415      * Gets the HomeClassPattern attribute of the HomeTagsHandler class.
416      *
417      * @return The HomeClassPattern value
418      */

419     protected static String JavaDoc getHomeClassPattern()
420     {
421         HomeInterfaceSubTask homeintf_subtask = ((HomeInterfaceSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(HomeInterfaceSubTask.class)));
422
423         if (homeintf_subtask != null) {
424             return homeintf_subtask.getHomeClassPattern();
425         }
426         else {
427             return HomeInterfaceSubTask.DEFAULT_HOMEINTERFACE_CLASS_PATTERN;
428         }
429     }
430
431     public void setCurrentPermission(String JavaDoc permission)
432     {
433         currentPermission = permission;
434     }
435
436     /**
437      * Returns the full qualified local or remote home interface name for the bean, depending on the value of type
438      * parameter.
439      *
440      * @param attributes The attributes of the template tag
441      * @return Description of the Returned Value
442      * @exception XDocletException
443      * @doc.tag type="content"
444      * @doc.param name="type" optional="false" values="remote,local" description="Specifies the type
445      * of component home interface."
446      */

447     public String JavaDoc homeInterface(Properties attributes) throws XDocletException
448     {
449         String JavaDoc type = attributes.getProperty("type");
450
451         type = type != null ? type : "remote";
452
453         return getHomeInterface(type, getCurrentClass());
454     }
455
456     /**
457      * Evaluates the body block if current method is a create method. Create methods should have ejb:create-method
458      * defined.
459      *
460      * @param template The body of the block tag
461      * @param attributes The attributes of the template tag
462      * @exception XDocletException
463      * @see #isCreateMethod(xjavadoc.XMethod)
464      * @doc.tag type="block"
465      * @doc.param name="superclasses" optional="true" description="Traverse superclasses too. With
466      * false value used in remote/local home interface templates. Default is False."
467      */

468     public void ifIsCreateMethod(String JavaDoc template, Properties attributes) throws XDocletException
469     {
470         String JavaDoc superclasses_str = attributes.getProperty("superclasses");
471         boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true);
472
473         if (isCreateMethod(getCurrentMethod())) {
474             boolean currentMethodDoesntBelongToCurrentClass = !getCurrentMethod().getContainingClass().equals(getCurrentClass());
475             boolean shouldTraverse = shouldTraverseSuperclassForDependentClass(getCurrentMethod().getContainingClass(), "ejb:home");
476
477             if (superclasses == false && currentMethodDoesntBelongToCurrentClass == true && shouldTraverse == false) {
478                 return;
479             }
480
481             generate(template);
482         }
483     }
484
485     /**
486      * Evaluates the body block if current create method's ejbPostCreate method does not exist.
487      *
488      * @param template The body of the block tag
489      * @param attributes The attributes of the template tag
490      * @exception XDocletException
491      * @doc.tag type="block"
492      */

493     public void ifDoesntHavePostCreateMethod(String JavaDoc template, Properties attributes)
494          throws XDocletException
495     {
496         XMethod currentMethod = getCurrentMethod();
497
498         if (!isCreateMethod(currentMethod)) {
499             String JavaDoc msg = Translator.getString(XDocletModulesEjbMessages.class,
500                 XDocletModulesEjbMessages.CURRENT_METHOD_NOT_CREATE,
501                 new String JavaDoc[]{currentMethod.toString()});
502
503             throw new XDocletException(msg);
504         }
505
506         StringBuffer JavaDoc currentMethodName = new StringBuffer JavaDoc(currentMethod.getNameWithSignature(false));
507
508         currentMethodName.insert(3, "Post");
509
510         XMethod ejbPostCreateMethod = getCurrentClass().getMethod(currentMethodName.toString());
511
512         if (ejbPostCreateMethod == null) {
513             generate(template);
514         }
515     }
516
517     /**
518      * Returns the appropriate ejbPostCreate method name for the current ejbCreate method.
519      *
520      * @param attributes The attributes of the template tag
521      * @return Equivalent ejbPostCreate method name
522      * @doc.tag type="content"
523      */

524     public String JavaDoc ejbPostCreateSignature(Properties attributes)
525     {
526         StringBuffer JavaDoc currentMethodName = new StringBuffer JavaDoc(getCurrentMethod().getName());
527
528         currentMethodName.insert(3, "Post");
529         return currentMethodName.toString();
530     }
531
532     /**
533      * Evaluates the body block if current method is a home method. Home methods should have ejb:home-method defined.
534      *
535      * @param template The body of the block tag
536      * @param attributes The attributes of the template tag
537      * @exception XDocletException
538      * @see #isHomeMethod(xjavadoc.XMethod)
539      * @doc.tag type="block"
540      * @doc.param name="superclasses" optional="true" description="Traverse superclasses too. With
541      * false value used in remote/local home interface templates. Default is False."
542      */

543     public void ifIsHomeMethod(String JavaDoc template, Properties attributes) throws XDocletException
544     {
545         String JavaDoc superclasses_str = attributes.getProperty("superclasses");
546         boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true);
547
548         if (isHomeMethod(getCurrentMethod())) {
549             if (superclasses == false && getCurrentMethod().getContainingClass() != getCurrentClass()
550                 && shouldTraverseSuperclassForDependentClass(getCurrentMethod().getContainingClass(), "ejb:home") == false) {
551                 return;
552             }
553
554             generate(template);
555         }
556     }
557
558     /**
559      * Evaluates the body block if current method is not an ejbRemove method.
560      *
561      * @param template The body of the block tag
562      * @exception XDocletException
563      * @see #isRemoveMethod(xjavadoc.XMethod)
564      * @doc.tag type="block"
565      */

566     public void ifNotRemoveMethod(String JavaDoc template) throws XDocletException
567     {
568         if (!isRemoveMethod(getCurrentMethod())) {
569             generate(template);
570         }
571     }
572
573     /**
574      * Evaluates the body block if current method is a ejbFind method.
575      *
576      * @param template The body of the block tag
577      * @param attributes The attributes of the template tag
578      * @exception XDocletException Description of Exception
579      * @see #isFinderMethod(xjavadoc.XMethod)
580      * @doc.tag type="block"
581      * @doc.param name="superclasses" optional="true" description="Traverse superclasses too. With
582      * false value used in remote/local home interface templates. Default is False."
583      */

584     public void ifIsFinderMethod(String JavaDoc template, Properties attributes) throws XDocletException
585     {
586         String JavaDoc superclasses_str = attributes.getProperty("superclasses");
587         boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true);
588
589         if (isFinderMethod(getCurrentMethod())) {
590             boolean currentMethodDoesntBelongToCurrentClass = !getCurrentMethod().getContainingClass().equals(getCurrentClass());
591             boolean shouldTraverse = shouldTraverseSuperclassForDependentClass(getCurrentMethod().getContainingClass(), "ejb:home");
592
593             if (superclasses == false && currentMethodDoesntBelongToCurrentClass == true && shouldTraverse == false) {
594                 return;
595             }
596
597             generate(template);
598         }
599     }
600
601     /**
602      * @param attributes The attributes of the template tag
603      * @return Description of the Returned Value
604      * @exception XDocletException
605      * @doc.tag type="content"
606      * @doc.param name="prefixWithEjbSlash" optional="true" values="true,false" description="Specifies
607      * whether to prefix it with ejb/ or not. False by default."
608      * @doc.param name="type" optional="false" values="remote,local" description="Specifies if we want
609      * the jndi name value for local or remote lookup."
610      */

611     public String JavaDoc compName(Properties attributes) throws XDocletException
612     {
613         String JavaDoc prefix_with_ejbslash_str = attributes.getProperty("prefixWithEjbSlash");
614         boolean prefix_with_ejbslash = TypeConversionUtil.stringToBoolean(prefix_with_ejbslash_str, false);
615         String JavaDoc type = attributes.getProperty("type");
616
617         String JavaDoc ejb_name = getCompNameFor(getCurrentClass(), type);
618
619         String JavaDoc compName;
620
621         if (prefix_with_ejbslash == true) {
622             compName = prefixWithEjbSlash(ejb_name);
623         }
624         else {
625             compName = ejb_name;
626         }
627
628         return compName;
629     }
630
631     /**
632      * @param attributes
633      * @return Description of the Returned Value
634      * @exception XDocletException
635      * @doc.tag type="content"
636      * @doc.param name="type" optional="false" values="remote,local" description="Specifies if we want
637      * the jndi name value for local or remote lookup."
638      */

639     public String JavaDoc jndiName(Properties attributes) throws XDocletException
640     {
641         return getJndiNameOfTypeFor(attributes.getProperty("type"), getCurrentClass());
642     }
643
644     /**
645      * Returns the name of the class home interface extends.
646      *
647      * @param attributes
648      * @return The name of generated PK class.
649      * @exception XDocletException
650      * @doc.tag type="content"
651      */

652     public String JavaDoc extendsFrom(Properties attributes) throws XDocletException
653     {
654         String JavaDoc type = attributes.getProperty("type");
655
656         type = type != null ? type : "remote";
657
658         String JavaDoc extends_param_name = type.equals("remote") ? "extends" : "local-extends";
659         String JavaDoc def_base_class_name = type.equals("remote") ? "javax.ejb.EJBHome" : "javax.ejb.EJBLocalHome";
660
661         return extendsFromFor(getCurrentClass(), "ejb:home", type, extends_param_name, def_base_class_name);
662     }
663
664     /**
665      * Iterates over all home methods of specified type (finder or create method) defined in a class and super classes.
666      *
667      * @param template The body of the block tag
668      * @param attributes The attributes of the template tag
669      * @exception XDocletException
670      * @doc.tag type="block"
671      * @doc.param name="tagName" optional="false" description="The tag name for the method type to
672      * iterate over." values="ejb:finder,ejb:create-method"
673      * @doc.param name="superclasses" values="true,false" description="If true then traverse
674      * superclasses also, otherwise look up the tag in current concrete class only."
675      * @doc.param name="tagKey" description="A tag property that will be used as a unique key. This is
676      * used to avoid duplicate code due to similar tags in superclasses."
677      */

678     public void forAllHomeMethods(String JavaDoc template, Properties attributes) throws XDocletException
679     {
680         Log log = LogUtil.getLog(HomeTagsHandler.class, "forAllHomeMethods");
681         boolean superclasses = TypeConversionUtil.stringToBoolean(attributes.getProperty("superclasses"), false);
682         String JavaDoc type = attributes.getProperty("type");
683         String JavaDoc tagType = attributes.getProperty("tagName");
684
685         if (type == null) {
686             throw new XDocletException(Translator.getString(XDocletMessages.class,
687                 XDocletMessages.ATTRIBUTE_NOT_PRESENT_ERROR,
688                 new String JavaDoc[]{"type"}));
689         }
690
691         Set already = new HashSet();
692         // Exclude definition coming from super classes
693
XClass currentClass = getCurrentClass().getSuperclass();
694
695         while (currentClass != null) {
696             if (log.isDebugEnabled()) {
697                 log.debug("Looking for super definition in " + currentClass.getName());
698             }
699
700             // 1. METHOD tags
701
Collection methods = currentClass.getMethods();
702
703             for (Iterator j = methods.iterator(); j.hasNext(); ) {
704                 XMethod method = (XMethod) j.next();
705
706                 // search all this methods tags to ensure that the type of
707
// Home we are generating matches the view-type (if available)
708
//
709
Collection tags =
710                     method.getDoc().getTags(tagType, superclasses);
711
712                 if (!matchesViewType(tags, type)) {
713                     continue;
714                 }
715
716                 if (tagType.equals("ejb:finder")) {
717                     if (!isFinderMethod(method)) {
718                         continue;
719                     }
720                 }
721                 else if (tagType.equals("ejb:create-method")) {
722                     if (!isCreateMethod(method)) {
723                         continue;
724                     }
725                 }
726                 else if (tagType.equals("ejb:home-method")) {
727                     if (!isHomeMethod(method)) {
728                         continue;
729                     }
730                 }
731
732                 String JavaDoc signature = getHomeDefinition(currentClass, method, tagType, type);
733
734                 if (log.isDebugEnabled()) {
735                     log.debug("Found " + signature);
736                 }
737                 already.add(signature);
738             }
739
740             // 2. CLASS tags
741
Collection superTags = currentClass.getDoc().getTags(tagType, true);
742
743             for (Iterator i = superTags.iterator(); i.hasNext(); ) {
744                 XTag superTag = (XTag) i.next();
745
746                 // ensure that the type of Home we are generating matches the
747
// view-type (if available)
748
//
749
if (!matchesViewType(superTag, type)) {
750                     continue;
751                 }
752
753                 String JavaDoc signature = fullPackageChange(superTag.getAttributeValue("signature"));
754                 String JavaDoc typeMapping = superTag.getAttributeValue("result-type-mapping");
755
756                 if (typeMapping == null || typeMapping.equalsIgnoreCase(type)) {
757                     if (log.isDebugEnabled()) {
758                         log.debug("Found " + signature);
759                     }
760                     already.add(signature);
761                 }
762             }
763             currentClass = currentClass.getSuperclass();
764         }
765
766         // 1. Handle METHOD Tag level ejb:finder
767
Collection methods = getCurrentClass().getMethods();
768         boolean fbpkFound = false;
769
770         for (Iterator j = methods.iterator(); j.hasNext(); ) {
771             XMethod method = (XMethod) j.next();
772
773             // search all this methods tags to ensure that the type of Home
774
// we are generating matches the view-type (if available)
775
//
776
Collection tags =
777                 method.getDoc().getTags(tagType, superclasses);
778
779             if (!matchesViewType(tags, type)) {
780                 continue;
781             }
782
783             String JavaDoc signature = null;
784
785             if (method.getDoc().getTag("ejb.permission") != null) {
786                 setCurrentPermission("@ejb.permission " + method.getDoc().getTag("ejb.permission").getValue());
787             }
788
789             if (log.isDebugEnabled()) {
790                 log.debug("Finder Method = " + signature);
791             }
792
793             if (tagType.equals("ejb:finder")) {
794                 if (!isFinderMethod(method)) {
795                     continue;
796                 }
797                 signature = getHomeDefinition(getCurrentClass(), method, tagType, type);
798
799                 if (!already.add(signature)) {
800                     continue;
801                 }
802
803             }
804             else if (tagType.equals("ejb:create-method")) {
805                 if (!isCreateMethod(method)) {
806                     continue;
807                 }
808                 signature = getHomeDefinition(getCurrentClass(), method, tagType, type);
809
810                 if (!already.add(signature)) {
811                     continue;
812                 }
813             }
814             else if (tagType.equals("ejb:home-method")) {
815                 if (!isHomeMethod(method)) {
816                     continue;
817                 }
818                 signature = getHomeDefinition(getCurrentClass(), method, tagType, type);
819
820                 if (!already.add(signature)) {
821                     continue;
822                 }
823             }
824             if (signature != null) {
825                 setCurrentSignature(signature);
826
827                 Collection exceptions = method.getThrownExceptions();
828                 StringBuffer JavaDoc exc = new StringBuffer JavaDoc();
829
830                 boolean comma = false;
831
832                 for (Iterator k = exceptions.iterator(); k.hasNext(); ) {
833                     XClass exception = (XClass) k.next();
834
835                     // Skip EJBException
836
if (exception.getQualifiedName().equals("javax.ejb.EJBException"))
837                         continue;
838
839                     if (comma) {
840                         exc.append(',');
841                     }
842                     exc.append(exception.getQualifiedName());
843                     comma = true;
844                 }
845                 // Add javax.ejb.FinderException to the exception list of finder methods
846
// if not already done
847
if (tagType.equals("ejb:finder") && exc.indexOf("javax.ejb.FinderException") < 0) {
848                     if (exc.length() > 0) {
849                         exc.append(",");
850                     }
851                     exc.append("javax.ejb.FinderException");
852                 }
853                 // Add javax.ejb.CreateException to the exception list of create methods
854
// if not already done
855
if (tagType.equals("ejb:create-method") && exc.indexOf("javax.ejb.CreateException") < 0) {
856                     if (exc.length() > 0) {
857                         exc.append(",");
858                     }
859                     exc.append("javax.ejb.CreateException");
860                 }
861                 // Add java.rmi.RemoteExceptions to the exception list of remote and remote home
862
// interfaces
863
if (type.equalsIgnoreCase("remote")) {
864                     if (exc.length() > 0) {
865                         exc.append(",");
866                     }
867                     exc.append("java.rmi.RemoteException");
868                 }
869                 setCurrentExceptions(exc.toString());
870                 // For javadoc comment only
871
setCurrentMethod(method);
872
873                 // If custom findByPrimaryKey exists then we should not add the
874
// mandatory later
875
if (method.getName().equals("findByPrimaryKey")) {
876                     fbpkFound = true;
877                 }
878
879                 generate(template);
880             }
881         }
882
883         // 2. Handle CLASS Tag level ejb:finder
884
Collection tags = getCurrentClass().getDoc().getTags(tagType, superclasses);
885
886         for (Iterator i = tags.iterator(); i.hasNext(); ) {
887             XTag tag = (XTag) i.next();
888
889             // ensure that the type of Home we are generating matches the
890
// view-type (if available)
891
//
892
if (!matchesViewType(tag, type)) {
893                 continue;
894             }
895
896             String JavaDoc signature = finderSignatureFunger(tag.getAttributeValue("signature"), getCurrentClass(), type);
897             String JavaDoc typeMapping = tag.getAttributeValue("result-type-mapping");
898
899             if (typeMapping == null || typeMapping.equalsIgnoreCase(type)) {
900                 if (!already.add(signature)) {
901                     continue;
902                 }
903
904                 if (log.isDebugEnabled()) {
905                     log.debug("Finder Method = " + signature);
906                 }
907
908                 if (signature.indexOf("findByPrimaryKey") != -1) {
909                     fbpkFound = true;
910                 }
911
912                 setCurrentClassTag(tag);
913                 setCurrentSignature(signature);
914
915                 if (tag.getAttributeValue("unchecked") != null) {
916                     setCurrentPermission("@ejb.permission unchecked=\"true\"");
917                 }
918                 else if (tag.getAttributeValue("role-name") != null) {
919                     setCurrentPermission("@ejb.permission role-name=\"" + tag.getAttributeValue("role-name") + "\"");
920                 }
921                 else {
922                     // nothing found - nothing set....
923
setCurrentPermission("");
924                 }
925
926                 StringBuffer JavaDoc exc = new StringBuffer JavaDoc();
927
928                 exc.append("javax.ejb.FinderException");
929                 if (type.equalsIgnoreCase("remote")) {
930                     exc.append(",java.rmi.RemoteException");
931                 }
932                 setCurrentExceptions(exc.toString());
933
934                 generate(template);
935             }
936         }
937
938         // Add mandatory findByPrimaryKey if not already there
939
if (!fbpkFound && CmpTagsHandler.isEntityCmp(getCurrentClass()) && tagType.equals("ejb:finder") && EntityTagsHandler.isAConcreteEJBean(getCurrentClass())) {
940             StringBuffer JavaDoc fbpkSign = new StringBuffer JavaDoc(InterfaceTagsHandler.getComponentInterface(type, getCurrentClass()));
941
942             fbpkSign.append(" findByPrimaryKey(");
943             fbpkSign.append(PkTagsHandler.getPkClassFor(getCurrentClass())).append(" pk").append(")");
944             if (already.add(fbpkSign)) {
945                 setCurrentSignature(fbpkSign.toString());
946
947                 StringBuffer JavaDoc exc = new StringBuffer JavaDoc();
948
949                 exc.append("javax.ejb.FinderException");
950                 if (type.equalsIgnoreCase("remote")) {
951                     exc.append(",java.rmi.RemoteException");
952                 }
953
954                 setCurrentExceptions(exc.toString());
955                 setCurrentMethod(null);
956                 generate(template);
957             }
958         }
959
960         // Add mandatory create() method for stateless beans if the bean is not abstract
961
if (SessionTagsHandler.isSession(getCurrentClass()) && tagType.equals("ejb:create-method")) {
962             if (already.size() == 0 && SessionTagsHandler.isAConcreteEJBean(getCurrentClass())) {
963                 StringBuffer JavaDoc createSign = new StringBuffer JavaDoc(InterfaceTagsHandler.getComponentInterface(type, getCurrentClass()));
964
965                 createSign.append(" create()");
966                 setCurrentSignature(createSign.toString());
967
968                 StringBuffer JavaDoc exc = new StringBuffer JavaDoc();
969
970                 exc.append("javax.ejb.CreateException");
971                 if (type.equalsIgnoreCase("remote")) {
972                     exc.append(",java.rmi.RemoteException");
973                 }
974                 setCurrentExceptions(exc.toString());
975                 setCurrentMethod(null);
976                 generate(template);
977             }
978         }
979
980         setCurrentClassTag(null);
981         setCurrentMethodTag(null);
982         setCurrentSignature(null);
983         setCurrentExceptions(null);
984         setCurrentMethod(null);
985
986     }
987
988     /**
989      * Return signature of current home method.
990      *
991      * @return Describe the return value
992      * @exception XDocletException
993      */

994     public String JavaDoc currentSignature() throws XDocletException
995     {
996         return currentSignature;
997     }
998
999     /**
1000     * Return permission for current home method.
1001     *
1002     * @return
1003     * @exception XDocletException
1004     * @doc.tag type="content"
1005     */

1006    public String JavaDoc currentPermission() throws XDocletException
1007    {
1008        return currentPermission;
1009    }
1010
1011    /**
1012     * Return type of current home method.
1013     *
1014     * @return
1015     * @exception XDocletException
1016     * @doc.tag type="content"
1017     * @todo i18n
1018     */

1019    public String JavaDoc currentType() throws XDocletException
1020    {
1021        String JavaDoc sig = currentSignature();
1022
1023        int index = sig.indexOf(" ");
1024
1025        if (index >= 0) {
1026            return sig.substring(0, index);
1027        }
1028        throw new XDocletException("can not parse signature: " + sig);
1029    }
1030
1031    /**
1032     * generates name for finder utility class backing current finder
1033     *
1034     * @return
1035     * @exception XDocletException
1036     * @doc.tag type="content"
1037     * @todo i18n
1038     */

1039    public String JavaDoc finderClass() throws XDocletException
1040    {
1041        String JavaDoc sig = currentSignature();
1042        int start = sig.indexOf("find");
1043        int end = sig.indexOf("(");
1044
1045        if (start >= 0 && end > start) {
1046            return sig.substring(start, start + 1).toUpperCase() + sig.substring(start + 1, end);
1047        }
1048        throw new XDocletException("Cannot parse signature: " + sig);
1049    }
1050
1051    /**
1052     * Whether current finder return collection.
1053     *
1054     * @param template
1055     * @param param
1056     * @exception XDocletException
1057     * @doc.tag type="block"
1058     */

1059    public void ifIsCollectionType(String JavaDoc template, Properties param) throws XDocletException
1060    {
1061        String JavaDoc currentType = currentType();
1062
1063        if ("Collection".equals(currentType) ||
1064            "java.util.Collection".equals(currentType) ||
1065            "Set".equals(currentType) ||
1066            "java.util.Set".equals(currentType)) {
1067            generate(template);
1068        }
1069    }
1070
1071    /**
1072     * Whether current finder return enumeration.
1073     *
1074     * @param template
1075     * @param param
1076     * @exception XDocletException
1077     * @doc.tag type="block"
1078     */

1079    public void ifIsEnumerationType(String JavaDoc template, Properties param) throws XDocletException
1080    {
1081        String JavaDoc currentType = currentType();
1082
1083        if ("Enumeration".equals(currentType) || "java.util.Enumeration".equals(currentType)) {
1084            generate(template);
1085        }
1086    }
1087
1088    /**
1089     * Whether current finder return interface.
1090     *
1091     * @param template
1092     * @param param
1093     * @exception XDocletException
1094     * @doc.tag type="block"
1095     */

1096    public void ifIsInterfaceType(String JavaDoc template, Properties param) throws XDocletException
1097    {
1098
1099        String JavaDoc type = currentType();
1100
1101        if (type.equals(InterfaceTagsHandler.getComponentInterface("local", getCurrentClass())) ||
1102            type.equals(InterfaceTagsHandler.getComponentInterface("remote", getCurrentClass()))) {
1103            generate(template);
1104        }
1105    }
1106
1107    /**
1108     * Return name of current home method.
1109     *
1110     * @return method name
1111     * @exception XDocletException
1112     * @doc.tag type="content"
1113     * @todo i18n
1114     */

1115    public String JavaDoc currentMethod() throws XDocletException
1116    {
1117        String JavaDoc sig = currentSignature();
1118        int start = sig.indexOf(" ");
1119        int stop = sig.indexOf("(");
1120
1121        if (start < 0 || stop < 0) {
1122            throw new XDocletException("Cannot parse signature: " + sig);
1123        }
1124        return sig.substring(start + 1, stop);
1125    }
1126
1127    /**
1128     * Return parameter list definition (types and names) for current home method.
1129     *
1130     * @return comma-separated parameter list
1131     * @exception XDocletException
1132     * @doc.tag type="content"
1133     * @todo i18n
1134     */

1135    public String JavaDoc parameterListDefinition() throws XDocletException
1136    {
1137        String JavaDoc sig = currentSignature();
1138        int start = sig.indexOf("(");
1139        int stop = sig.indexOf(")");
1140
1141        if (start < 0 || stop < 0) {
1142            throw new XDocletException("Cannot parse signature: " + sig);
1143        }
1144        return sig.substring(start + 1, stop);
1145    }
1146
1147    /**
1148     * Return parameter list (names only) for current home method.
1149     *
1150     * @return comma-separated parameter list
1151     * @exception XDocletException
1152     * @doc.tag type="content"
1153     */

1154    public String JavaDoc parameterList() throws XDocletException
1155    {
1156
1157        String JavaDoc[] parameters = DocletUtil.tokenizeDelimitedToArray(parameterListDefinition(), " ,");
1158        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1159
1160        for (int i = 1; i < parameters.length; i += 2) {
1161            if (i > 1) {
1162                sb.append(", ");
1163            }
1164            sb.append(parameters[i]);
1165        }
1166        return sb.toString();
1167    }
1168
1169    /**
1170     * Return exceptions for current home method.
1171     *
1172     * @return exceptions
1173     * @exception XDocletException
1174     * @doc.tag type="content"
1175     */

1176    public String JavaDoc currentExceptions() throws XDocletException
1177    {
1178        return currentExceptions;
1179    }
1180
1181    /**
1182     * Gets the DependentClassFor attribute of the HomeTagsHandler object
1183     *
1184     * @param clazz Describe what the parameter does
1185     * @param type Describe what the parameter does
1186     * @return The DependentClassFor value
1187     * @exception XDocletException
1188     */

1189    protected String JavaDoc getDependentClassFor(XClass clazz, String JavaDoc type) throws XDocletException
1190    {
1191        if ((type.equals("local") && InterfaceTagsHandler.isLocalEjb(clazz)) || (type.equals("remote") && InterfaceTagsHandler.isRemoteEjb(clazz))) {
1192            return getHomeInterface(type, clazz);
1193        }
1194        else {
1195            return null;
1196        }
1197    }
1198
1199    /**
1200     * Sets the CurrentSignature attribute of the HomeTagsHandler object.
1201     *
1202     * @param cs The new CurrentSignature value
1203     */

1204    protected void setCurrentSignature(String JavaDoc cs)
1205    {
1206        this.currentSignature = cs;
1207    }
1208
1209    /**
1210     * Sets the CurrentExceptions attribute of the HomeTagsHandler object.
1211     *
1212     * @param es The new CurrentExceptions value
1213     */

1214    protected void setCurrentExceptions(String JavaDoc es)
1215    {
1216        this.currentExceptions = es;
1217    }
1218
1219    /**
1220     * Describe what the method does
1221     *
1222     * @param clazz Describe what the parameter does
1223     * @param tag_name Describe what the parameter does
1224     * @return Describe the return value
1225     * @exception XDocletException
1226     */

1227    protected boolean shouldTraverseSuperclassForDependentClass(XClass clazz, String JavaDoc tag_name) throws XDocletException
1228    {
1229        if (super.shouldTraverseSuperclassForDependentClass(clazz, tag_name) == false) {
1230            return false;
1231        }
1232
1233        //shouldn't include create methods of parent if parent is itself a concrete ejb
1234
if (isAConcreteEJBean(clazz)) {
1235            return false;
1236        }
1237
1238        return true;
1239    }
1240
1241    /**
1242     * Returns true if an XTag has a view-type compatible with the specified type. A view-type is compatible if it is
1243     * the same as type or \"both\". A missing or empty view-type is assumed to be compatible.
1244     *
1245     * @param tag The XTag to check
1246     * @param type The desired view-type
1247     * @return true if the tag's view-type is compatible
1248     */

1249    protected boolean matchesViewType(XTag tag, String JavaDoc type)
1250    {
1251        String JavaDoc attr = tag.getAttributeValue("view-type");
1252
1253        return attr == null || attr.length() == 0 || attr.equals(type) || attr.equals("both");
1254    }
1255
1256    /**
1257     * Check every XTag in a collection and return true if they all have a view-type compatible with the specified type.
1258     * A view-type is compatible if it is the same as type or \"both\". A missing or empty view-type is assumed to be
1259     * compatible.
1260     *
1261     * @param tags Collection of XTag to be checked.
1262     * @param type The desired view-type
1263     * @return true if all tags' view-type parameters are compatible
1264     */

1265    protected boolean matchesViewType(Collection tags, String JavaDoc type)
1266    {
1267        // search all the tags looking for the view-type parameter
1268
//
1269
boolean matches = true;
1270
1271        for (Iterator k = tags.iterator(); k.hasNext() && matches; ) {
1272            matches = matchesViewType((XTag) k.next(), type);
1273        }
1274        return matches;
1275    }
1276}
1277
Popular Tags