KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > ejb > entity > DataObjectTagsHandler


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

5 package xdoclet.modules.ejb.entity;
6
7 ////import xdoclet.util.serialveruid.*;
8

9 import java.text.MessageFormat JavaDoc;
10 import java.util.*;
11
12 import org.apache.commons.logging.Log;
13
14 import xjavadoc.*;
15
16 import xdoclet.DocletContext;
17 import xdoclet.DocletTask;
18 import xdoclet.XDocletException;
19 import xdoclet.modules.ejb.EjbTagsHandler;
20 import xdoclet.modules.ejb.XDocletModulesEjbMessages;
21 import xdoclet.modules.ejb.entity.DataObjectSubTask;
22 import xdoclet.modules.ejb.intf.InterfaceTagsHandler;
23 import xdoclet.tagshandler.MethodTagsHandler;
24 import xdoclet.util.LogUtil;
25 import xdoclet.util.Translator;
26
27 import xdoclet.util.TypeConversionUtil;
28
29 /**
30  * @author Ara Abrahamian (ara_e@email.com)
31  * @created 13. juni 2002
32  * @xdoclet.taghandler namespace="EjbDataObj"
33  * @version $Revision: 1.12 $
34  */

35 public class DataObjectTagsHandler extends EjbTagsHandler
36 {
37     protected static HashMap dataObjectClassnames = new HashMap();
38
39     protected static String JavaDoc currentDataObjectClassname = "";
40
41     /**
42      * @param clazz Description of Parameter
43      * @return the full qualified data-object class name
44      * @exception XDocletException
45      */

46     public static String JavaDoc getDataMostSuperObjectClass(XClass clazz) throws XDocletException
47     {
48         String JavaDoc currentDataClass = (String JavaDoc) dataObjectClassnames.get(clazz.getName());
49         // Begin at the first super class
50

51         XClass cur_clazz = clazz;
52
53         currentDataClass = generateDataObjectClass(cur_clazz);
54
55         loopa :
56         do {
57             // Find if we have an abstract data class definition to generate
58
Collection methods = cur_clazz.getMethods();
59             boolean found = false;
60
61             for (Iterator j = methods.iterator(); j.hasNext(); ) {
62                 XMethod method = (XMethod) j.next();
63
64                 if (method.getName().equals("getData")) {
65                     found = true;
66                     currentDataClass = generateDataObjectClass(cur_clazz);
67                 }
68
69                 if (found) {
70                     break loopa;
71                 }
72             }
73             cur_clazz = cur_clazz.getSuperclass();
74         } while (cur_clazz != null);
75
76         if (currentDataClass == null) {
77             throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.DATACLASS_NOT_FOUND));
78         }
79         return currentDataClass;
80     }
81
82     /**
83      * Gets the DataObjectMethod attribute of the DataObjectTagsHandler class
84      *
85      * @param method Describe what the parameter does
86      * @return The DataObjectMethod value
87      * @exception XDocletException
88      */

89     public static boolean isDataObjectMethod(XMethod method) throws XDocletException
90     {
91         if (EntityTagsHandler.isEntity(method.getContainingClass()) == false) {
92             return false;
93         }
94
95         boolean is_getData = isGetDataMethod(method);
96
97         if (is_getData) {
98             return true;
99         }
100         else {
101             return isSetDataMethod(method);
102         }
103     }
104
105     /**
106      * @param clazz Description of Parameter
107      * @return the full qualified data-object class name
108      */

109     public static String JavaDoc getDataObjectClassFor(XClass clazz)
110     {
111         if (dataObjectClassnames.get(clazz.getQualifiedName()) != null) {
112             return (String JavaDoc) dataObjectClassnames.get(clazz.getQualifiedName());
113         }
114
115         String JavaDoc fileName = clazz.getContainingPackage().getName();
116         String JavaDoc name_pattern = null;
117         String JavaDoc package_pattern = null;
118
119         String JavaDoc dataObjectClass = clazz.getDoc().getTagAttributeValue("ejb:data-object", "class", false);
120
121         if (dataObjectClass != null) {
122             return dataObjectClass;
123         }
124
125         name_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "pattern", false);
126
127         if (name_pattern == null) {
128             name_pattern = getDataObjectClassPattern();
129         }
130
131         package_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "package", false);
132
133         String JavaDoc dataObjectClass_name = null;
134
135         if (name_pattern.indexOf("{0}") != -1) {
136             dataObjectClass_name = MessageFormat.format(name_pattern, new Object JavaDoc[]{getShortEjbNameFor(clazz)});
137         }
138         else {
139             dataObjectClass_name = name_pattern;
140         }
141
142         // Fix package name
143
fileName = choosePackage(fileName, package_pattern, DocletTask.getSubTaskName(DataObjectSubTask.class));
144         if (fileName.length() > 0) {
145             fileName += ".";
146         }
147
148         fileName += dataObjectClass_name;
149
150         return fileName;
151     }
152
153     /**
154      * @return the current data-object class name
155      */

156     public static String JavaDoc getCurrentDataObjectClassname()
157     {
158         return currentDataObjectClassname;
159     }
160
161     /**
162      * Returns true if ejb:data-object defined and generate param is true, false if not true.
163      *
164      * @param clazz Description of Parameter
165      * @return Description of the Returned Value
166      */

167     public static boolean isGenerationNeeded(XClass clazz)
168     {
169         if (isDataObjectSubTaskActive() == false) {
170             return false;
171         }
172
173         // When the tag is there and is set to "false" then return false
174
if (clazz.getDoc().hasTag("ejb:data-object")) {
175             String JavaDoc generate_str = clazz.getDoc().getTagAttributeValue("ejb:data-object", "generate", false);
176             boolean generate = TypeConversionUtil.stringToBoolean(generate_str, true);
177
178             return generate;
179         }
180         else {
181             return true;
182         }
183     }
184
185     /**
186      * @param current_data_object_classname
187      */

188     public static void setCurrentDataObjectClassname(String JavaDoc current_data_object_classname)
189     {
190         currentDataObjectClassname = current_data_object_classname;
191     }
192
193     /**
194      * @param name Description of Parameter
195      * @param value Description of Parameter
196      */

197     public static void putDataObjectClassnames(String JavaDoc name, String JavaDoc value)
198     {
199         dataObjectClassnames.put(name, value);
200     }
201
202     /**
203      * Used by dataMostSuperObjectClass() to get the data object's full qualified class name. If name and package
204      * parameters of ejb:data-object defined, theire values are used, otherwise defaults are used.
205      *
206      * @param clazz Description of Parameter
207      * @return Description of the Returned Value
208      * @see #dataMostSuperObjectClass()
209      */

210     public static String JavaDoc generateDataObjectClass(XClass clazz)
211     {
212         String JavaDoc fileName = clazz.getContainingPackage().getName();
213         String JavaDoc name_pattern = null;
214         String JavaDoc package_pattern = null;
215
216         name_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "name", false);
217         if (name_pattern == null) {
218             name_pattern = getDataObjectClassPattern();
219         }
220
221         package_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "package", false);
222
223         String JavaDoc dataobject_name = null;
224
225         if (name_pattern.indexOf("{0}") != -1) {
226             dataobject_name = MessageFormat.format(name_pattern, new Object JavaDoc[]{getShortEjbNameFor(clazz)});
227         }
228         else {
229             dataobject_name = name_pattern;
230         }
231
232         // Fix package name
233
fileName = choosePackage(fileName, package_pattern, DocletTask.getSubTaskName(DataObjectSubTask.class));
234         fileName += "." + dataobject_name;
235
236         return fileName;
237     }
238
239     /**
240      * @param clazz Description of Parameter
241      * @return Description of the Returned Value
242      */

243     public static boolean hasCustomBulkData(XClass clazz)
244     {
245         Log log = LogUtil.getLog(DataObjectSubTask.class, "hasCustomBulkData");
246
247         if (log.isDebugEnabled()) {
248             log.debug("Searching @ejb:bulk-data in Class " + clazz);
249         }
250
251         if (isDataObjectSubTaskActive() == false) {
252             return false;
253         }
254
255         return clazz.getDoc().hasTag("ejb:bulk-data");
256     }
257
258     /**
259      * @return the data-object class pattern
260      */

261     protected static String JavaDoc getDataObjectClassPattern()
262     {
263         final DataObjectSubTask dataobject_subtask = ((DataObjectSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(DataObjectSubTask.class)));
264
265         if (dataobject_subtask != null) {
266             return dataobject_subtask.getDataObjectClassPattern();
267         }
268         else {
269             return DataObjectSubTask.DEFAULT_DATAOBJECT_CLASS_PATTERN;
270         }
271     }
272
273     /**
274      * @param clazz
275      * @return True if there is a Data Container equals() needed because user set tag "data-equals"
276      * to true or ommitted it
277      * @exception XDocletException
278      */

279     protected static boolean hasDataEquals(XClass clazz) throws XDocletException
280     {
281         Log log = LogUtil.getLog(DataObjectSubTask.class, "hasDataEquals");
282
283         if (log.isDebugEnabled()) {
284             log.debug("Searching @ejb:data-object equals for Class " + clazz.getQualifiedName());
285         }
286
287         if (isDataObjectSubTaskActive() == false) {
288             return false;
289         }
290
291         String JavaDoc value = getTagValue(
292             FOR_CLASS,
293             clazz.getDoc(),
294             "ejb:data-object",
295             "equals",
296             "true,false",
297             "true",
298             true,
299             false
300             );
301
302         return TypeConversionUtil.stringToBoolean(value, true);
303     }
304
305     /**
306      * Gets the DataObjectSubTaskActive attribute of the DataObjectTagsHandler class
307      *
308      * @return The DataObjectSubTaskActive value
309      */

310     private static boolean isDataObjectSubTaskActive()
311     {
312         return DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(DataObjectSubTask.class));
313     }
314
315     /**
316      * Returns true if method is getData()
317      *
318      * @param method Description of Parameter
319      * @return The GetDataMethod value
320      * @exception XDocletException
321      */

322     private static boolean isGetDataMethod(XMethod method) throws XDocletException
323     {
324         if (isDataObjectSubTaskActive() == false) {
325             return false;
326         }
327
328         return method.isAbstract() && method.getName().equals("getData") && DataObjectTagsHandler.getDataMostSuperObjectClass(method.getContainingClass()).equals(method.getReturnType().getType());
329     }
330
331     /**
332      * Returns true if method is setData()
333      *
334      * @param method Description of Parameter
335      * @return The SetDataMethod value
336      */

337     private static boolean isSetDataMethod(XMethod method)
338     {
339         if (isDataObjectSubTaskActive() == false) {
340             return false;
341         }
342
343         if (method.isAbstract() && method.getName().equals("setData")) {
344             Collection params = method.getParameters();
345
346             if (params.size() == 1 &&
347                 ((XParameter) params.iterator().next()).getType().getQualifiedName().equals(DataObjectTagsHandler.getDataObjectClassFor(method.getContainingClass()))
348                 ) {
349                 return true;
350             }
351             else {
352                 return false;
353             }
354         }
355         else {
356             return false;
357         }
358     }
359
360     /**
361      * Returns true if ejb:data-object defined and setdata param is true, false if not true.
362      *
363      * @param clazz
364      * @return Description of the Returned Value
365      * @exception XDocletException
366      */

367     private static boolean hasDataMethod(XClass clazz) throws XDocletException
368     {
369         if (isDataObjectSubTaskActive() == false) {
370             return false;
371         }
372
373         String JavaDoc value = getTagValue(
374             FOR_CLASS,
375             clazz.getDoc(),
376             "ejb:data-object",
377             "setdata",
378             "true,false",
379             "true",
380             true,
381             false
382             );
383
384         boolean result = TypeConversionUtil.stringToBoolean(value, false);
385
386         return result;
387     }
388
389     /**
390      * @param pTemplate Description of Parameter
391      * @exception XDocletException
392      */

393     public void isDataContentEquals(String JavaDoc pTemplate) throws XDocletException
394     {
395         if (hasDataEquals(getCurrentClass())) {
396             generate(pTemplate);
397         }
398     }
399
400     /**
401      * Returns data-object class name for the bean.
402      *
403      * @return The data-object class name for the bean.
404      * @exception XDocletException
405      * @doc.tag type="content"
406      */

407     public String JavaDoc dataObjectClass() throws XDocletException
408     {
409         return getDataObjectClassFor(getCurrentClass());
410     }
411
412     /**
413      * Returns the data-object class name highest in the hierarchy of derived beans. Because of possible inheritance
414      * between entity bean, the type of the generated getData method must be the one of the most super class of the
415      * current entity bean. The current Data class must extend the corresponding super Data class.
416      *
417      * @return The data-object class name highest in the hierarchy of derived beans.
418      * @exception XDocletException
419      * @doc.tag type="content"
420      */

421     public String JavaDoc dataMostSuperObjectClass() throws XDocletException
422     {
423         return getDataMostSuperObjectClass(getCurrentClass());
424     }
425
426     /**
427      * @return Description of the Returned Value
428      * @exception XDocletException
429      * @doc.tag type="content"
430      */

431     public String JavaDoc generateDataObjectClass() throws XDocletException
432     {
433         return generateDataObjectClass(getCurrentClass());
434     }
435
436     /**
437      * Evaluate the body block if ejb:data-object setdata="true". If not defined then default is true.
438      *
439      * @param pTemplate Description of Parameter
440      * @exception XDocletException
441      * @see #ifIsWithDataContainer(java.lang.String)
442      * @doc.tag type="block"
443      */

444     public void ifIsWithDataMethod(String JavaDoc pTemplate) throws XDocletException
445     {
446         if (hasDataMethod(getCurrentClass())) {
447             generate(pTemplate);
448         }
449     }
450
451     /**
452      * Evaluate the body block if ejb:data-object container="true". If not defined then default is true.
453      *
454      * @param pTemplate Description of Parameter
455      * @exception XDocletException
456      * @doc.tag type="block"
457      */

458     public void ifIsWithDataContainer(String JavaDoc pTemplate) throws XDocletException
459     {
460         if (isGenerationNeeded(getCurrentClass())) {
461             generate(pTemplate);
462         }
463         // We can also have a generate false because we use the same dataclass
464
// that the super class (e.g. BMP extends CMP)
465
else {
466             String JavaDoc hasClass = getTagValue(
467                 FOR_CLASS,
468                 getCurrentClass().getDoc(),
469                 "ejb:data-object",
470                 "class",
471                 null,
472                 null,
473                 false,
474                 false
475                 );
476
477             if (hasClass != null) {
478                 generate(pTemplate);
479             }
480         }
481     }
482
483     /**
484      * Evaluate the body block if ejb:aggregate is defined for current getter method, denoting that the specified getter
485      * method returns an aggregated object.
486      *
487      * @param template The body of the block tag
488      * @exception XDocletException
489      * @see #ifIsNotAggregate(java.lang.String)
490      * @see #isAggregate(xjavadoc.XMethod)
491      * @doc.tag type="block"
492      */

493     public void ifIsAggregate(String JavaDoc template) throws XDocletException
494     {
495         if (isAggregate(getCurrentMethod())) {
496             generate(template);
497         }
498     }
499
500     /**
501      * Evaluate the body block if ejb:aggregate is not defined for current getter method.
502      *
503      * @param template The body of the block tag
504      * @exception XDocletException
505      * @see #ifIsAggregate(java.lang.String)
506      * @see #isAggregate(xjavadoc.XMethod)
507      * @doc.tag type="block"
508      */

509     public void ifIsNotAggregate(String JavaDoc template) throws XDocletException
510     {
511         if (!isAggregate(getCurrentMethod())) {
512             generate(template);
513         }
514     }
515
516     /**
517      * Evaluates the body block for each setData method.
518      *
519      * @param template The body of the block tag
520      * @exception XDocletException
521      * @see #forAllSuper(java.lang.String,java.lang.String)
522      * @doc.tag type="block"
523      */

524     public void forAllSuperSetData(String JavaDoc template) throws XDocletException
525     {
526         forAllSuper(template, "setData");
527     }
528
529     /**
530      * @return Description of the Returned Value
531      * @exception XDocletException
532      */

533     public String JavaDoc parentDataObjectClass() throws XDocletException
534     {
535         Log log = LogUtil.getLog(DataObjectSubTask.class, "parentDataObjectClass");
536
537         if (log.isDebugEnabled()) {
538             log.debug("Searching for @ejb:data-object in Current/Super Class " + getCurrentClass().getName());
539         }
540
541         if (getCurrentClass().getDoc().hasTag("ejb:data-object", false)) {
542             String JavaDoc extends_class = getCurrentClass().getDoc().getTagAttributeValue("ejb:data-object", "extends", false);
543
544             return extends_class != null ? extends_class : "java.lang.Object";
545         }
546
547         if (getCurrentClass().getSuperclass() != null && isEjb(getCurrentClass().getSuperclass())) {
548             pushCurrentClass(getCurrentClass().getSuperclass());
549
550             String JavaDoc clazz = dataObjectClass();
551
552             popCurrentClass();
553
554             if (clazz == null) {
555                 return "java.lang.Object";
556             }
557
558             return clazz;
559         }
560         else {
561             return "java.lang.Object";
562         }
563     }
564
565     /**
566      * Returns the name of the class dataobject class extends.
567      *
568      * @return The name of generated PK class.
569      * @exception XDocletException
570      * @doc.tag type="content"
571      */

572     public String JavaDoc extendsFrom() throws XDocletException
573     {
574         return extendsFromFor(getCurrentClass(), "ejb:data-object", null, "extends", "java.lang.Object");
575     }
576
577     /**
578      * Return the dataobject class name from interface name.
579      *
580      * @return the data-object class name
581      * @exception XDocletException
582      * @doc.tag type="content"
583      */

584     public String JavaDoc dataObjectClassNameFromInterfaceName() throws XDocletException
585     {
586         String JavaDoc return_type = MethodTagsHandler.getMethodTypeFor(getCurrentMethod());
587
588         if (return_type == null) {
589             throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_NOT_FOUND, new String JavaDoc[]{getCurrentMethod().getName()}));
590         }
591
592         String JavaDoc bean_class_name = InterfaceTagsHandler.getBeanClassNameFromInterfaceNameFor(return_type);
593
594         if (bean_class_name == null) {
595             throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_IMPL_NOT_FOUND, new String JavaDoc[]{return_type}));
596         }
597
598         XClass bean_class = getXJavaDoc().getXClass(bean_class_name);
599
600         if (bean_class == null) {
601             throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_IMPL_COULDNT_LOAD, new String JavaDoc[]{return_type}));
602         }
603
604         String JavaDoc dataobject_class_name = DataObjectTagsHandler.getDataObjectClassFor(bean_class);
605
606         if (dataobject_class_name == null) {
607             throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_DATAOBJECT_NOT_KNOWN, new String JavaDoc[]{return_type}));
608         }
609
610         return dataobject_class_name;
611     }
612
613     /**
614      * Returns true if method has ejb:aggregate, false otherwise.
615      *
616      * @param method Description of Parameter
617      * @return The Aggregate value
618      * @exception XDocletException
619      */

620     protected boolean isAggregate(XMethod method) throws XDocletException
621     {
622         if (isDataObjectSubTaskActive() == false) {
623             return false;
624         }
625
626         return method.getDoc().hasTag("ejb:aggregate");
627     }
628
629     /**
630      * Gets the DependentClassFor attribute of the DataObjectTagsHandler object
631      *
632      * @param clazz Describe what the parameter does
633      * @param type Describe what the parameter does
634      * @return The DependentClassFor value
635      * @exception XDocletException
636      */

637     protected String JavaDoc getDependentClassFor(XClass clazz, String JavaDoc type) throws XDocletException
638     {
639         return getDataObjectClassFor(clazz);
640     }
641
642     /**
643      * Browse all super classes and search for a special method to generate it in the current CMP/BMP class.
644      *
645      * @param template The body of the block tag
646      * @param methodName Description of Parameter
647      * @exception XDocletException
648      */

649     protected void forAllSuper(String JavaDoc template, String JavaDoc methodName) throws XDocletException
650     {
651         XClass oldClass = getCurrentClass();
652         XClass superclass = null;
653         List already = new ArrayList();
654
655         // Begin at the first super class
656
//pushCurrentClass( getCurrentClass().superclass() );
657

658         do {
659             // Find if we have an abstract data class definition to generate
660
Collection methods = getCurrentClass().getMethods();
661             XMethod methodFound = null;
662
663             for (Iterator j = methods.iterator(); j.hasNext(); ) {
664                 XMethod method = (XMethod) j.next();
665
666                 if (method.getName().equals(methodName)) {
667                     methodFound = method;
668                 }
669
670                 if (methodFound != null) {
671                     break;
672                 }
673             }
674
675             if (methodFound != null) {
676                 // We can not use contains because it is based on equals() and
677
// we need to compare based on compareTo()
678
Iterator i = already.iterator();
679                 boolean contained = false;
680
681                 while (i.hasNext()) {
682                     if (((XMethod) i.next()).compareTo(methodFound) == 0) {
683                         contained = true;
684                     }
685
686                     if (contained) {
687                         break;
688                     }
689                 }
690
691                 if (contained == false) {
692                     generate(template);
693                     already.add(methodFound);
694                 }
695             }
696
697             superclass = getCurrentClass().getSuperclass();
698
699             if (superclass != null) {
700                 pushCurrentClass(superclass);
701             }
702
703         } while (superclass != null);
704
705         setCurrentClass(oldClass);
706     }
707 }
708
Popular Tags