KickJava   Java API By Example, From Geeks To Geeks.

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


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

5 package xdoclet.modules.ejb.entity;
6
7 import java.lang.reflect.Modifier JavaDoc;
8 import java.text.MessageFormat JavaDoc;
9 import java.util.*;
10
11 import org.apache.commons.logging.Log;
12
13 import xjavadoc.*;
14 import xdoclet.DocletContext;
15
16 import xdoclet.DocletTask;
17 import xdoclet.XDocletException;
18 import xdoclet.modules.ejb.EjbTagsHandler;
19 import xdoclet.modules.ejb.XDocletModulesEjbMessages;
20 import xdoclet.modules.ejb.entity.ValueObjectSubTask;
21 import xdoclet.modules.ejb.intf.InterfaceTagsHandler;
22 import xdoclet.tagshandler.MethodTagsHandler;
23 import xdoclet.util.LogUtil;
24 import xdoclet.util.Translator;
25
26 import xdoclet.util.TypeConversionUtil;
27
28 /**
29  * Tags used by the Value Object templates.
30  *
31  * @author Vincent Harcq (vincent.harcq@hubmethods.com)
32  * @created 13. juni 2002
33  * @xdoclet.taghandler namespace="EjbValueObj"
34  * @version $Revision: 1.28 $
35  */

36 public class ValueObjectTagsHandler
37      extends EjbTagsHandler
38 {
39     private XTag currentTag;
40
41     private String JavaDoc currentValueObjectClass;
42
43     private String JavaDoc currentValueObjectAttribute;
44
45     private String JavaDoc currentValueObjectMatch;
46
47     // For aggregation
48
private String JavaDoc currentAggregateType;
49
50     private String JavaDoc currentAggregateName;
51     private String JavaDoc currentAggregateNamePlural;
52
53     private String JavaDoc currentRelationBeanClass;
54
55     /**
56      * Checks if a method is a value object relation (aggregate or compose) matching a certain valueObject
57      *
58      * @param method
59      * @param valueObject
60      * @return
61      */

62     public static boolean isValueObjectRelation(XMethod method, String JavaDoc valueObject)
63     {
64         Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "isValueObjectRelation");
65         boolean ret = method.getDoc().hasTag("ejb:value-object");
66
67         if (log.isDebugEnabled())
68             log.debug(method.getName() + " has a ejb:value-object Tag " + ret);
69         if (ret) {
70             Collection tags = method.getDoc().getTags("ejb:value-object");
71
72             if (tags.size() == 0 && !"*".equals(valueObject)) {
73                 ret = false;
74             }
75             else {
76                 ret = false;
77
78                 boolean excluded = true;
79
80                 for (Iterator i = tags.iterator(); i.hasNext(); ) {
81                     XTag tag = (XTag) i.next();
82                     String JavaDoc exclude = tag.getAttributeValue("exclude");
83                     String JavaDoc aggreg = tag.getAttributeValue("aggregate");
84                     String JavaDoc comp = tag.getAttributeValue("compose");
85
86                     if ("true".equals(exclude) || (aggreg == null && comp == null)) {
87                         excluded = true;
88                         ret = false;
89                         break;
90                     }
91
92                     ret = matches(tag, valueObject);
93                     if (ret)
94                         break;
95                 }
96                 if ("*".equals(valueObject) && !excluded) {
97                     ret = true;
98                 }
99             }
100         }
101         return ret;
102     }
103
104     /**
105      * Gets the GenerationNeeded attribute of the ValueObjectTagsHandler class
106      *
107      * @param clazz Describe what the parameter does
108      * @return The GenerationNeeded value
109      */

110     public static boolean isGenerationNeeded(XClass clazz)
111     {
112         return true;
113         //TODO
114
}
115
116     /**
117      * Gets the CurrentValueObjectClass attribute of the ValueObjectTagsHandler class
118      *
119      * @param clazz Describe what the parameter does
120      * @param tag Describe what the parameter does
121      * @return The CurrentValueObjectClass value
122      * @exception XDocletException
123      */

124     public static String JavaDoc getCurrentValueObjectClass(XClass clazz, XTag tag)
125          throws XDocletException
126     {
127         String JavaDoc name = getCurrentValueObjectName(tag);
128
129         String JavaDoc _currentValueObjectClass;
130
131         _currentValueObjectClass = MessageFormat.format(getSubTask().getValueObjectClassPattern(),
132             new Object JavaDoc[]{(name != null) ? name : getShortEjbNameFor(clazz)});
133
134         String JavaDoc packageName = clazz.getContainingPackage().getName();
135
136         packageName = choosePackage(packageName, null, DocletTask.getSubTaskName(ValueObjectSubTask.class));
137
138         _currentValueObjectClass = packageName + '.' + _currentValueObjectClass;
139
140         return _currentValueObjectClass;
141     }
142
143     /**
144      * Gets the CurrentValueObjectName attribute of the ValueObjectTagsHandler class
145      *
146      * @param tag Describe what the parameter does
147      * @return The CurrentValueObjectName value
148      * @exception XDocletException
149      */

150     public static String JavaDoc getCurrentValueObjectName(XTag tag) throws XDocletException
151     {
152         String JavaDoc name = tag.getAttributeValue("name");
153
154         if (name != null) {
155             return name;
156         }
157
158         // name is null, must look whether it's defined in current class level
159
XClass clazz = getCurrentClass();
160
161         while (clazz != null) {
162             for (Iterator i = clazz.getDoc().getTags(tag.getName()).iterator(); i.hasNext(); ) {
163                 if (tag.equals(i.next())) {
164                     // ok, we are defined here return defined ejb name
165
name = EjbTagsHandler.getShortEjbNameFor(clazz);
166                     if (name == null) {
167                         throw new XDocletException("unable to determine value object name in class " + clazz.getName());
168                     }
169                     return name;
170                 }
171             }
172             // not found on current level. try with superclass
173
clazz = clazz.getSuperclass();
174         }
175         throw new XDocletException("class defining value object is not EJB");
176     }
177
178     /**
179      * Gets the CurrentValueObjectAttribute attribute of the ValueObjectTagsHandler class
180      *
181      * @param tag Describe what the parameter does
182      * @return The CurrentValueObjectAttribute value
183      * @exception XDocletException
184      */

185     public static String JavaDoc getCurrentValueObjectAttribute(XTag tag) throws XDocletException
186     {
187         String JavaDoc name = getCurrentValueObjectName(tag);
188
189         String JavaDoc _currentValueObjectAttribute;
190
191         if (name == null) {
192             _currentValueObjectAttribute = "Value";
193         }
194         else {
195             _currentValueObjectAttribute = MessageFormat.format(getSubTask().getValueObjectClassPattern(), new Object JavaDoc[]{name});
196         }
197
198         return _currentValueObjectAttribute;
199     }
200
201     /**
202      * Gets the CurrentValueObjectMatch attribute of the ValueObjectTagsHandler class
203      *
204      * @param tag Describe what the parameter does
205      * @return The CurrentValueObjectMatch value
206      */

207     public static String JavaDoc getCurrentValueObjectMatch(XTag tag)
208     {
209         String JavaDoc match = tag.getAttributeValue("match");
210
211         if (match == null) {
212             match = "*";
213         }
214         return match;
215     }
216
217     public static String JavaDoc getCurrentValueObjectImplements(XTag tag)
218     {
219         String JavaDoc toImplement = tag.getAttributeValue("implements");
220
221         return toImplement != null ? "," + toImplement : "";
222     }
223
224     public static String JavaDoc getCurrentValueObjectExtends(XTag tag)
225     {
226         String JavaDoc toImplement = tag.getAttributeValue("extends");
227
228         return toImplement != null ? toImplement : "java.lang.Object";
229     }
230
231     /**
232      * Gets a reference to the <valueobject> subtask.
233      *
234      * @return subtask
235      */

236     private static ValueObjectSubTask getSubTask()
237     {
238         ValueObjectSubTask subtask = ((ValueObjectSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(ValueObjectSubTask.class)));
239
240         return subtask;
241     }
242
243     /**
244      * Returns whether the passed tag matches for the passed value object
245      *
246      * @param tag the tag
247      * @param valueObject the value-object's match
248      * @return <code>true</code> if the passed tag matches
249      */

250     private static boolean matches(XTag tag, String JavaDoc valueObject)
251     {
252         Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "matches");
253         String JavaDoc value = tag.getAttributeValue("match");
254
255         if (log.isDebugEnabled()) {
256             log.debug("Match=" + value + "==" + valueObject);
257         }
258
259         if (value == null) {
260             return "*".equals(valueObject);
261         }
262         return value.equals(valueObject) || value.equals("*") || "*".equals(valueObject);
263     }
264
265     /**
266      * Whether or not the <code>abstract</code> parameter is set to true on the supplied class' ejb.value-object tag for
267      * the given VO name.
268      *
269      * @param valueObjectName
270      * @param currentClass
271      * @return
272      * @exception XDocletException
273      */

274     public boolean isAbstractValueObject(String JavaDoc valueObjectName,
275         XClass currentClass)
276          throws XDocletException
277     {
278         boolean isAbstract = false;
279
280         Collection valueObjectTags =
281             currentClass.getDoc().getTags("ejb:value-object");
282
283         for (Iterator i = valueObjectTags.iterator();
284             i.hasNext() && !isAbstract; ) {
285             XTag tag = (XTag) i.next();
286
287             isAbstract = isAbstractValueObject(valueObjectName, tag);
288         }
289
290         return isAbstract;
291     }
292
293     /**
294      * @param clazz Description of Parameter
295      * @return the full qualified data-object class name
296      * @exception XDocletException
297      */

298     public String JavaDoc getValueMostSuperObjectClass(XClass clazz) throws XDocletException
299     {
300         String JavaDoc currentDataClass = currentValueObjectClass;
301         // Begin at the first super class
302

303         XClass cur_clazz = clazz.getSuperclass();
304
305         do {
306             // Find if we have an abstract data class definition to generate
307
Collection methods = cur_clazz.getMethods();
308             boolean found = false;
309
310             for (Iterator j = methods.iterator(); j.hasNext(); ) {
311                 XMethod method = (XMethod) j.next();
312
313                 if (method.getName().equals("get" + currentValueObjectAttribute)) {
314                     found = true;
315                     currentDataClass = getCurrentValueObjectClass(cur_clazz, currentTag);
316                 }
317
318                 if (found) {
319                     break;
320                 }
321             }
322             cur_clazz = cur_clazz.getSuperclass();
323         } while (cur_clazz != null);
324
325         return currentDataClass;
326     }
327
328     /**
329      * Evaluates the body if the <code>valueobject</code> subtask's <code>generatePKConstructor</code> parameter is
330      * <code>true</code>.
331      *
332      * @param template The body of the block tag
333      * @param attributes The attributes of the template tag
334      * @exception XDocletException
335      * @doc.tag type="block"
336      */

337     public void ifGeneratePKConstructor(String JavaDoc template, Properties attributes)
338          throws XDocletException
339     {
340         if (getSubTask().getGeneratePKConstructor()) {
341             generate(template);
342         }
343     }
344
345     /**
346      * Evaluates the body if the <code>abstract</code> parameter is set to true on the ejb.value-object tag for the
347      * current VO.
348      *
349      * @param template The body of the block tag
350      * @exception XDocletException
351      * @doc.tag type="block"
352      */

353     public void ifIsAbstractValueObject(String JavaDoc template)
354          throws XDocletException
355     {
356         if (isAbstractValueObject(valueObjectName(), getCurrentClass())) {
357             generate(template);
358         }
359     }
360
361     /**
362      * Evaluates the body if the <code>abstract</code> parameter is set to false (or is missing) on the ejb.value-object
363      * tag for the current VO.
364      *
365      * @param template The body of the block tag
366      * @exception XDocletException
367      * @doc.tag type="block"
368      */

369     public void ifNotIsAbstractValueObject(String JavaDoc template)
370          throws XDocletException
371     {
372         if (!isAbstractValueObject(valueObjectName(), getCurrentClass())) {
373             generate(template);
374         }
375     }
376
377     /**
378      * Return the current value object's class name.
379      *
380      * @return class name
381      * @exception XDocletException
382      * @doc.tag type="content"
383      */

384     public String JavaDoc valueObjectClass() throws XDocletException
385     {
386         return getSubTask().getCurrentValueObjectClass();
387     }
388
389     /**
390      * Return the current value object's name.
391      *
392      * @return VO name
393      * @exception XDocletException
394      * @doc.tag type="content"
395      */

396     public String JavaDoc valueObjectName() throws XDocletException
397     {
398         return getSubTask().getCurrentValueObjectName();
399     }
400
401     /**
402      * Return the current value object's match parameter.
403      *
404      * @return match value
405      * @exception XDocletException
406      * @doc.tag type="content"
407      */

408     public String JavaDoc valueObjectMatch() throws XDocletException
409     {
410         return getSubTask().getCurrentValueObjectMatch();
411     }
412
413     /**
414      * Returns the name of the class the specified value object extends. If no <code>extends</code> parameter exists on
415      * the <code>ejb.value-object</code> tag, <code>java.lang.Object</code> is returned.
416      *
417      * @param attributes The attributes of the template tag
418      * @return The name of generated PK class.
419      * @exception XDocletException
420      * @doc.tag type="content"
421      * @doc.param name="valueobject" optional="false" description="The name of the value object to
422      * check."
423      */

424     public String JavaDoc extendsFrom(Properties attributes) throws XDocletException
425     {
426         return getSubTask().getCurrentValueObjectExtends();
427     }
428
429     /**
430      * Loops over all the ejb.value-object tags in the class, and generates the body for each one.
431      *
432      * @param pTemplate The body of the block tag
433      * @exception XDocletException
434      * @doc.tag type="block"
435      */

436     public void forAllValueObjects(String JavaDoc pTemplate) throws XDocletException
437     {
438         Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "forAllValueObjects");
439         Collection dos = getCurrentClass().getDoc().getTags("ejb:value-object", true);
440
441         if (log.isDebugEnabled()) {
442             log.debug("Number of tags ejb:value-object in " + getCurrentClass() + " = " + dos.size());
443         }
444         for (Iterator i = dos.iterator(); i.hasNext(); ) {
445             currentTag = (XTag) i.next();
446
447             if (!isAbstractValueObject(getCurrentValueObjectName(currentTag),
448                 currentTag)) {
449
450                 currentValueObjectClass = getCurrentValueObjectClass(getCurrentClass(), currentTag);
451                 currentValueObjectAttribute = getCurrentValueObjectAttribute(currentTag);
452                 currentValueObjectMatch = getCurrentValueObjectMatch(currentTag);
453                 if (log.isDebugEnabled()) {
454                     log.debug("Generate for " + currentValueObjectClass + " attr=" + currentValueObjectAttribute + " match=" + currentValueObjectMatch);
455                 }
456
457                 generate(pTemplate);
458             }
459         }
460     }
461
462     /**
463      * Return the current value object's class name.
464      *
465      * @return class name
466      * @doc.tag type="content"
467      */

468     public String JavaDoc currentValueObjectClass()
469     {
470         return currentValueObjectClass;
471     }
472
473     /**
474      * Return the current value object's attribute name.
475      *
476      * @return attribute
477      * @doc.tag type="content"
478      */

479     public String JavaDoc currentValueObjectAttribute()
480     {
481         return currentValueObjectAttribute;
482     }
483
484     /**
485      * Return the current value object's match parameter.
486      *
487      * @return match value
488      * @doc.tag type="content"
489      */

490     public String JavaDoc currentValueObjectMatch()
491     {
492         return currentValueObjectMatch;
493     }
494
495     /**
496      * Returns the class name of the current aggregate attribute's type.
497      *
498      * @param attributes The attributes of the template tag
499      * @return class
500      * @doc.tag type="content"
501      * @doc.param name="short" description="Use the short (not fully-qualified) class name."
502      */

503     public String JavaDoc currentAggregateType(Properties attributes)
504     {
505         String JavaDoc sh = attributes.getProperty("short");
506         String JavaDoc ret = "";
507
508         if (sh == null) {
509             ret = currentAggregateType;
510         }
511         else {
512             StringTokenizer st = new StringTokenizer(currentAggregateType, ".");
513
514             while (st.hasMoreTokens()) {
515                 ret = st.nextToken();
516             }
517         }
518         return ret;
519     }
520
521     /**
522      * return interfaces to be implemented
523      *
524      * @return interfaces
525      * @doc.tag type="content"
526      */

527     public String JavaDoc valueObjectImplements()
528     {
529         return getSubTask().getCurrentValueObjectImplements();
530     }
531
532     /**
533      * Returns the current aggregate's name
534      *
535      * @param attributes
536      * @return aggregate name
537      * @throws XDocletException if an error occures
538      * @doc.param name="plural" optional="true" values="true, false" default="false" descriptions="return
539      * the plural of the aggregate's name if set to true"
540      * @doc.param name="decapitalize" optional="true" values="true, false" default="false"
541      * descriptions="return the decapitalize aggregate's name if set to true"
542      * @doc.tag type="content"
543      */

544     public String JavaDoc currentAggregateName(Properties attributes)
545     {
546         String JavaDoc plural = attributes.getProperty("plural");
547         String JavaDoc decapitalize = attributes.getProperty("decapitalize");
548         String JavaDoc name = "true".equals(plural) ? currentAggregateNamePlural : currentAggregateName;
549
550         if ("true".equals(decapitalize)) {
551             if (name != null && name.length() > 0) {
552                 name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
553             }
554         }
555         return name;
556     }
557
558     /**
559      * Return the bean class name for the current relation.
560      *
561      * @return class name
562      * @doc.tag type="content"
563      */

564     public String JavaDoc currentRelationBeanClass()
565     {
566         return currentRelationBeanClass;
567     }
568
569     /**
570      * Type of the constructor for aggregates or compositions.
571      *
572      * @return Type of the constructor for aggregates or compositions.
573      * @exception XDocletException
574      * @doc.tag type="content"
575      */

576     public String JavaDoc concreteCollectionType() throws XDocletException
577     {
578         String JavaDoc concreteType = getCurrentMethod().getDoc().getTagAttributeValue("ejb.value-object", "concrete-type");
579         Class JavaDoc concreteClass = null;
580
581         // test the concrete class
582
if (concreteType != null) {
583             try {
584                 concreteClass = Class.forName(concreteType);
585             }
586             catch (ClassNotFoundException JavaDoc e) {
587                 throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class,
588                     XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_NOT_FOUND,
589                     new String JavaDoc[]{concreteType}));
590             }
591             if (concreteClass.isInterface()) {
592                 throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class,
593                     XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_IS_INTF,
594                     new String JavaDoc[]{concreteType}));
595             }
596             if (Modifier.isAbstract(concreteClass.getModifiers())) {
597                 throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class,
598                     XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_IS_ABSTRACT,
599                     new String JavaDoc[]{concreteType}));
600             }
601         }
602
603         String JavaDoc currentReturnType = getCurrentMethod().getReturnType().getType().getQualifiedName();
604
605         if (currentReturnType.equals("java.util.Collection")) {
606             if (concreteClass == null) {
607                 return "java.util.ArrayList";
608             }
609             else {
610                 // verify that the concrete class is a Collection
611
if (!Collection.class.isAssignableFrom(concreteClass)) {
612                     throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class,
613                         XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_INVALID,
614                         new String JavaDoc[]{concreteType, "java.util.Collection"}));
615                 }
616                 return concreteType;
617             }
618
619         }
620         else if (currentReturnType.equals("java.util.Set")) {
621             if (concreteClass == null) {
622                 return "java.util.HashSet";
623             }
624             else {
625                 // verify that the concrete class is a Set
626
if (!Set.class.isAssignableFrom(concreteClass)) {
627                     throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class,
628                         XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_INVALID,
629                         new String JavaDoc[]{concreteType, "java.util.Set"}));
630                 }
631                 return concreteType;
632             }
633         }
634         else {
635             throw new XDocletException("Invalid return type (" +
636                 currentReturnType +
637                 " on aggregate or composition.");
638         }
639     }
640
641     /**
642      * Returns the collection type for the current field.
643      *
644      * @return the type
645      * @throws XDocletException if an error occures
646      * @doc.tag type="content"
647      */

648     public String JavaDoc collectionType() throws XDocletException
649     {
650         return getCurrentMethod().getReturnType().getType().getQualifiedName();
651     }
652
653     /**
654      * Executes the body only if the current field is a collection.
655      *
656      * @param template the template
657      * @exception XDocletException if an error occures
658      * @doc.tag type="block"
659      */

660     public void ifIsCollection(String JavaDoc template) throws XDocletException
661     {
662         if (isCollection()) {
663             generate(template);
664         }
665     }
666
667     /**
668      * Executes the body only if the current field is not a collection.
669      *
670      * @param template the template
671      * @exception XDocletException if an error occures
672      * @doc.tag type="block"
673      */

674     public void ifIsNotCollection(String JavaDoc template) throws XDocletException
675     {
676         if (!isCollection()) {
677             generate(template);
678         }
679     }
680
681     /**
682      * Returns the data-object class name highest in the hierarchy of derived beans. Because of possible inheritance
683      * between entity bean, the type of the generated getData method must be the one of the most super class of the
684      * current entity bean. The current Data class must extend the corresponding super Data class.
685      *
686      * @return The data-object class name highest in the hierarchy of derived beans.
687      * @exception XDocletException
688      * @doc.tag type="content"
689      */

690     public String JavaDoc valueMostSuperObjectClass() throws XDocletException
691     {
692         return getValueMostSuperObjectClass(getCurrentClass());
693     }
694
695     /**
696      * Describe what the method does
697      *
698      * @param template The body of the block tag
699      * @exception XDocletException
700      * @doc.tag type="block"
701      */

702     public void forAllSuperSetValue(String JavaDoc template) throws XDocletException
703     {
704         XClass oldClass = getCurrentClass();
705
706         XClass superclass = null;
707
708         do {
709             Collection dos = getCurrentClass().getDoc().getTags("ejb:value-object", false);
710
711             for (Iterator i = dos.iterator(); i.hasNext(); ) {
712                 currentTag = (XTag) i.next();
713                 currentValueObjectClass = getCurrentValueObjectClass(getCurrentClass(), currentTag);
714                 currentValueObjectAttribute = getCurrentValueObjectAttribute(currentTag);
715                 currentValueObjectMatch = getCurrentValueObjectMatch(currentTag);
716
717                 forAllSetters(template, "set" + currentValueObjectAttribute);
718             }
719
720             superclass = getCurrentClass().getSuperclass();
721
722             if (superclass != null) {
723                 pushCurrentClass(superclass);
724             }
725         } while (superclass != null);
726
727         setCurrentClass(oldClass);
728
729     }
730
731     /**
732      * Loop over all the aggregate fields in the given value object, and generate the body for each one.
733      *
734      * @param template The body of the block tag
735      * @param attributes The attributes of the template tag
736      * @exception XDocletException
737      * @doc.tag type="block"
738      * @doc.param name="superclasses" values="true,false" description="Whether to include fields in
739      * superclasses."
740      * @doc.param name="valueobject" optional="false" description="The value object name."
741      */

742     public void forAllAggregates(String JavaDoc template, Properties attributes) throws XDocletException
743     {
744         String JavaDoc superclasses_str = attributes.getProperty("superclasses");
745         boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true);
746
747         String JavaDoc valueObject = attributes.getProperty("valueobject");
748
749         forAllRelations(template, superclasses, valueObject, "aggregate");
750     }
751
752     /**
753      * Loop over all the composed fields in the given value object, and generate the body for each one.
754      *
755      * @param template The body of the block tag
756      * @param attributes The attributes of the template tag
757      * @exception XDocletException
758      * @doc.tag type="block"
759      * @doc.param name="superclasses" values="true,false" description="Whether to include fields in
760      * superclasses."
761      * @doc.param name="valueobject" optional="false" description="The value object name."
762      */

763     public void forAllComposes(String JavaDoc template, Properties attributes) throws XDocletException
764     {
765         String JavaDoc superclasses_str = attributes.getProperty("superclasses");
766         boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true);
767
768         String JavaDoc valueObject = attributes.getProperty("valueobject");
769
770         forAllRelations(template, superclasses, valueObject, "compose");
771     }
772
773     /**
774      * Loop over all the relation fields in the given value object, and generate the body for each one.
775      *
776      * @param template The body of the block tag
777      * @param attributes The attributes of the template tag
778      * @exception XDocletException
779      * @doc.tag type="block"
780      * @doc.param name="superclasses" values="true,false" description="Whether to include fields in
781      * superclasses."
782      * @doc.param name="valueobject" optional="false" description="The value object name."
783      */

784     public void forAllRelations(String JavaDoc template, Properties attributes) throws XDocletException
785     {
786         String JavaDoc superclasses_str = attributes.getProperty("superclasses");
787         boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true);
788
789         String JavaDoc valueObject = attributes.getProperty("valueobject");
790
791         forAllRelations(template, superclasses, valueObject, "aggregate");
792         forAllRelations(template, superclasses, valueObject, "compose");
793     }
794
795     /**
796      * Evaluate the body block if Value Object subtask being used.
797      *
798      * @param template The body of the block tag
799      * @exception XDocletException
800      * @doc.tag type="block"
801      */

802     public void ifUsingValueObject(String JavaDoc template) throws XDocletException
803     {
804         if (DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(ValueObjectSubTask.class))) {
805             generate(template);
806         }
807     }
808
809     protected void forAllSetters(String JavaDoc template, String JavaDoc methodName) throws XDocletException
810     {
811         Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "forAllSetters");
812
813         if (log.isDebugEnabled()) {
814             log.debug(methodName);
815         }
816
817         // Find if we have an abstract data class definition to generate
818
Collection methods = getCurrentClass().getMethods();
819         XMethod methodFound = null;
820
821         for (Iterator j = methods.iterator(); j.hasNext(); ) {
822             XMethod method = (XMethod) j.next();
823
824             if (method.getName().equals(methodName)) {
825                 methodFound = method;
826             }
827
828             if (methodFound != null) {
829                 if (log.isDebugEnabled()) {
830                     log.debug(methodFound);
831                 }
832                 break;
833             }
834         }
835
836         if (methodFound != null) {
837             generate(template);
838         }
839
840     }
841
842     /**
843      * Returns whether the current field is a collection
844      *
845      * @return <code>true</code> it the current field is a collection
846      */

847     private boolean isCollection()
848     {
849         String JavaDoc currentReturnType = getCurrentMethod().getReturnType().getType().getQualifiedName();
850
851         return "java.util.Collection".equals(currentReturnType) || "java.util.Set".equals(currentReturnType);
852     }
853
854     private boolean isAbstractValueObject(String JavaDoc valueObjectName, XTag tag)
855     {
856         boolean isAbstract = false;
857         String JavaDoc attr = tag.getAttributeValue("abstract");
858
859         if (valueObjectName.equals(tag.getAttributeValue("name")) &&
860             attr != null) {
861             isAbstract = TypeConversionUtil.stringToBoolean(attr, false);
862         }
863         return isAbstract;
864     }
865
866     /**
867      * @param template Describe what the parameter does
868      * @param superclasses Describe what the parameter does
869      * @param valueObject Describe what the parameter does
870      * @param type Describe what the parameter does
871      * @exception XDocletException
872      * @todo (Aslak) use a HashSet instead of HashMap for foundFields
873      */

874     private void forAllRelations(String JavaDoc template, boolean superclasses, String JavaDoc valueObject, String JavaDoc type) throws XDocletException
875     {
876         Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "forAllRelations");
877         Map foundFields = new HashMap();
878         XClass currentClass = getCurrentClass();
879         XMethod oldMethod = getCurrentMethod();
880
881         if (log.isDebugEnabled())
882             log.debug("*** forAllRelations on class=" + currentClass.getName() + " valueobject=" + valueObject);
883         do {
884             pushCurrentClass(currentClass);
885
886             if (log.isDebugEnabled()) {
887                 log.debug("****** CurrentClass=" + getCurrentClass());
888             }
889
890             Collection methods = getCurrentClass().getMethods();
891
892             for (Iterator j = methods.iterator(); j.hasNext(); ) {
893                 XMethod method = (XMethod) j.next();
894
895                 setCurrentMethod(method);
896
897                 if (MethodTagsHandler.isGetter(getCurrentMethod().getName()) &&
898                     !foundFields.containsKey(getCurrentMethod().getName()) &&
899                     isValueObjectRelation(getCurrentMethod(), valueObject)) {
900
901                     boolean ret = getCurrentMethod().getDoc().hasTag("ejb:value-object");
902
903                     if (log.isDebugEnabled())
904                         log.debug("****** Method " + getCurrentMethod().getName() + " has VO tag : " + ret);
905                     if (ret) {
906                         Collection tags = getCurrentMethod().getDoc().getTags("ejb:value-object");
907
908                         for (Iterator i = tags.iterator(); i.hasNext(); ) {
909                             XTag tag = (XTag) i.next();
910
911                             if (!matches(tag, valueObject)) {
912                                 continue;
913                             }
914
915                             String JavaDoc aggreg = tag.getAttributeValue(type);
916                             String JavaDoc aggregName = tag.getAttributeValue(type + "-name");
917                             String JavaDoc aggregNamePlural = tag.getAttributeValue(type + "s-name");
918
919                             if (aggregNamePlural == null) {
920                                 aggregNamePlural = aggregName + "s";
921                             }
922
923                             if (log.isDebugEnabled()) {
924                                 log.debug("********* " + method.getName() + " ejb:value-object Tag - Type = " + type + " - Value = " + aggreg + " - Name = " + aggregName);
925                             }
926
927                             if (aggreg != null) {
928                                 String JavaDoc currentReturnType = getCurrentMethod().getReturnType().getType().getQualifiedName();
929
930                                 if (log.isDebugEnabled()) {
931                                     log.debug("********* METHOD=" + getCurrentMethod().getName() + " " + currentReturnType);
932                                 }
933
934                                 // Store that we found this field so we don't add it twice
935
foundFields.put(getCurrentMethod().getName(), getCurrentMethod().getName());
936                                 if (currentReturnType.equals("java.util.Collection") ||
937                                     currentReturnType.equals("java.util.Set")) {
938
939                                     if (log.isDebugEnabled()) {
940                                         log.debug("********* Type Collection or Set");
941                                     }
942                                     currentAggregateType = aggreg;
943                                     currentAggregateName = aggregName;
944                                     currentAggregateNamePlural = aggregNamePlural;
945
946                                     String JavaDoc relationInterface = tag.getAttributeValue("members");
947
948                                     if (log.isDebugEnabled()) {
949                                         log.debug(relationInterface);
950                                     }
951                                     if (relationInterface != null && !relationInterface.equals("")) {
952                                         currentRelationBeanClass = InterfaceTagsHandler.getBeanClassNameFromInterfaceNameFor(relationInterface);
953                                     }
954                                 }
955                                 else {
956                                     if (log.isDebugEnabled()) {
957                                         log.debug("********* Type " + getCurrentMethod().getReturnType().getType().toString());
958                                     }
959                                     currentAggregateType = aggreg;
960                                     currentAggregateName = aggregName;
961                                     currentAggregateNamePlural = aggregNamePlural;
962                                     currentRelationBeanClass = InterfaceTagsHandler.getBeanClassNameFromInterfaceNameFor(getCurrentMethod().getReturnType().getType().getQualifiedName());
963                                 }
964                                 generate(template);
965                                 currentAggregateType = null;
966                                 currentAggregateName = null;
967                                 currentAggregateNamePlural = null;
968                                 currentRelationBeanClass = null;
969                             }
970                         }
971                     }
972                 }
973             }
974
975             // Add super class info
976
XClass superclass = getCurrentClass().getSuperclass();
977
978             if (superclass == null) {
979                 popCurrentClass();
980                 break;
981             }
982
983             if (superclass.getQualifiedName().equals("java.lang.Object")) {
984                 popCurrentClass();
985                 break;
986             }
987
988             popCurrentClass();
989
990             // superclasses is true for *CMP/BMP/Session
991
if (superclasses == true) {
992                 currentClass = currentClass.getSuperclass();
993             }
994             else {
995                 if (shouldTraverseSuperclassForDependentClass(currentClass.getSuperclass(), getDependentClassTagName())) {
996                     currentClass = currentClass.getSuperclass();
997                 }
998                 else {
999                     break;
1000                }
1001            }
1002        } while (true);
1003
1004        setCurrentMethod(oldMethod);
1005
1006        log.debug("Finished.");
1007    }
1008}
1009
Popular Tags