KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > hibernate > HibernateTagsHandler


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

5 package xdoclet.modules.hibernate;
6
7 import java.util.Collection JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.LinkedList JavaDoc;
10 import java.util.Properties JavaDoc;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.tools.ant.types.Parameter;
14
15 import xjavadoc.XClass;
16 import xjavadoc.XMethod;
17 import xdoclet.DocletContext;
18 import xdoclet.DocletSupport;
19 import xdoclet.DocletTask;
20 import xdoclet.XDocletException;
21 import xdoclet.XDocletTagSupport;
22 import xdoclet.tagshandler.ClassTagsHandler;
23 import xdoclet.tagshandler.TypeTagsHandler;
24 import xdoclet.util.LogUtil;
25 import xdoclet.util.Translator;
26 /**
27  * Specific tags handler to make the template easy.
28  *
29  * @author Sébastien Guimont (sebastieng@sympatico.ca)
30  * @created August 9th, 2002
31  * @version $Revision: 1.38 $
32  * @xdoclet.taghandler namespace="Hibernate"
33  */

34 public class HibernateTagsHandler
35      extends XDocletTagSupport
36 {
37
38     // prefix for @hibernate.component columns
39
private LinkedList JavaDoc columnPrefixes = new LinkedList JavaDoc();
40
41     private String JavaDoc currentTag;
42
43     private String JavaDoc currentMappingElement;
44
45     private Parameter currentJndiParameter;
46
47     private Parameter currentOtherParameter;
48
49     private Parameter currentOtherMapping;
50
51     /**
52      * Returns full path of hibernate file for the current class.
53      *
54      * @return The full file path of the current class.
55      * @exception XDocletException
56      * @doc.tag type="content"
57      */

58     public String JavaDoc getFileName()
59          throws XDocletException
60     {
61         return getCurrentClass().getQualifiedName().replace('.', '/');
62     }
63
64     public JBossServiceSubTask getJBossServiceSubTask()
65     {
66         return (JBossServiceSubTask) (DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(JBossServiceSubTask.class)));
67     }
68
69     public FactoryClassSubTask getFactoryClassSubTask()
70     {
71         return (FactoryClassSubTask) (DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(FactoryClassSubTask.class)));
72     }
73
74     public HibernateProperties getHibernateProperties() throws XDocletException
75     {
76         try {
77             return (HibernateProperties) DocletContext.getInstance().getActiveSubTask();
78         }
79         catch (ClassCastException JavaDoc e) {
80             throw new XDocletException(e, "May occur if attribute is used with incorrect subtask.");
81         }
82     }
83
84     /**
85      * find id property of current class.
86      *
87      * @return
88      * @exception XDocletException
89      */

90     public XMethod getIdMethod() throws XDocletException
91     {
92         XClass clazz = getCurrentClass();
93         Iterator JavaDoc methodIterator = clazz.getMethods(true).iterator();
94
95         // iterate through all the methods defined in this class
96
XMethod method;
97
98         while (methodIterator.hasNext()) {
99             method = (XMethod) methodIterator.next();
100
101             if (method.getDoc().hasTag("hibernate.id")) {
102                 return method;
103             }
104         }
105         return null;
106     }
107
108     public String JavaDoc getCurrentTag(Properties JavaDoc attributes)
109     {
110         return currentTag;
111     }
112
113     public String JavaDoc getCurrentMappingElement(Properties JavaDoc attributes)
114     {
115         return currentMappingElement;
116     }
117
118     public void setCurrentTag(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
119     {
120         currentTag = attributes.getProperty("name");
121         currentMappingElement = attributes.getProperty("mappingElement");
122         generate(template);
123         currentTag = null;
124         currentMappingElement = null;
125     }
126
127     /**
128      * Set the prefix for the \@hibernate.component, as there may be more than one component in a class that refer to
129      * the same target class.
130      *
131      * @param template
132      * @param attributes
133      * @throws XDocletException
134      */

135     public void setColumnPrefix(String JavaDoc template, Properties JavaDoc attributes)
136          throws XDocletException
137     {
138         String JavaDoc columnPrefix = attributes.getProperty("prefix", "");
139
140         columnPrefixes.addLast(columnPrefix);
141         generate(template);
142         columnPrefixes.removeLast();
143     }
144
145     /**
146      * Get the attribute used for collection property names in this version of Hibernate (ie. "role" or "name").
147      *
148      * @param attributes
149      * @return
150      */

151     public String JavaDoc roleAttribute(Properties JavaDoc attributes)
152     {
153         return "1.1".equals(getHibernateSubTask().getVersion()) ? "role" : "name";
154     }
155
156     /**
157      * Get the name of the class the implements the SessionFactory as a MBean is this version of Hibernate.
158      *
159      * @param attributes
160      * @return
161      */

162     public String JavaDoc serviceClassName(Properties JavaDoc attributes)
163     {
164         if ("1.1".equals(getHibernateSubTask().getVersion()))
165             return "cirrus.hibernate.jmx.HibernateService";
166         else
167             return "net.sf.hibernate.jmx.HibernateService";
168     }
169
170     /**
171      * Render template if the current mapping element is not the one specified.
172      *
173      * @param template the template
174      * @param attributes the tag attributes
175      * @exception XDocletException
176      * @doc.tag type="block"
177      */

178     public void ifCurrentMappingElementIsnt(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
179     {
180         String JavaDoc element = attributes.getProperty("mappingElement");
181
182         if (currentMappingElement == null || element == null
183             || !currentMappingElement.equals(element)) {
184             generate(template);
185         }
186     }
187
188     /**
189      * Render template if ID is composite.
190      *
191      * @param template
192      * @param attributes
193      * @exception XDocletException
194      * @doc.tag type="block"
195      */

196     public void ifHasCompositeId(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
197     {
198         hasCompositeId_Impl(template, true);
199     }
200
201     /**
202      * Render template if id is primitive.
203      *
204      * @param template
205      * @param attributes
206      * @exception XDocletException
207      * @doc.tag type="block"
208      */

209     public void ifHasPrimitiveId(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
210     {
211         hasCompositeId_Impl(template, false);
212     }
213
214     /**
215      * Return configured service name.
216      *
217      * @return
218      * @exception XDocletException
219      * @doc.tag type="content"
220      */

221     public String JavaDoc serviceName() throws XDocletException
222     {
223         return getJBossServiceSubTask().getServiceName();
224     }
225
226     /**
227      * Configured JNDI name.
228      *
229      * @return
230      * @exception XDocletException
231      * @doc.tag type="content"
232      */

233     public String JavaDoc jndiName() throws XDocletException
234     {
235         return getHibernateProperties().getJndiName();
236     }
237
238     /**
239      * Render template if jndiName of JBossServiceSubtask is valid. This is a required parameter, but the user might not
240      * be using that subtask.
241      *
242      * @param template
243      * @param attributes
244      * @exception XDocletException
245      * @doc.tag type="block"
246      */

247     public void ifUseJndiFactory(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
248     {
249         if (getFactoryClassSubTask().isUseJndiFactory()) {
250             generate(template);
251         }
252     }
253
254     /**
255      * Render template if jndiName of JBossServiceSubtask is valid. This is a required parameter, but the user might not
256      * be using that subtask.
257      *
258      * @param template
259      * @param attributes
260      * @exception XDocletException
261      * @doc.tag type="block"
262      */

263     public void ifNotUseJndiFactory(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
264     {
265         if (!getFactoryClassSubTask().isUseJndiFactory()) {
266             generate(template);
267         }
268     }
269
270     /**
271      * Render template if jndiName of JBossServiceSubtask is valid. This is a required parameter, but the user might not
272      * be using that subtask.
273      *
274      * @param template
275      * @param attributes
276      * @exception XDocletException
277      * @doc.tag type="block"
278      */

279     public void ifHasJndiName(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
280     {
281         if (jndiName() != null) {
282             generate(template);
283         }
284     }
285
286     /**
287      * Render template if all of the properties needed are valid.
288      *
289      * @param template
290      * @param attributes
291      * @exception XDocletException
292      * @doc.tag type="block"
293      */

294     public void ifGeneratePropertyCache(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
295     {
296         if (dialect() != null
297             && driver() != null
298             && jdbcUrl() != null
299             && userName() != null
300             && password() != null) {
301             generate(template);
302         }
303         if (dialect() != null && jndiName() != null) {
304             generate(template);
305         }
306     }
307
308     /**
309      * Render template if jndiName of JBossServiceSubtask is not valid.
310      *
311      * @param template
312      * @param attributes
313      * @exception XDocletException
314      * @doc.tag type="block"
315      */

316     public void ifNotHasJndiName(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
317     {
318         if (jndiName() == null) {
319             generate(template);
320         }
321     }
322
323     /**
324      * SQL dialect extractor.
325      *
326      * @return
327      * @exception XDocletException
328      * @doc.tag type="content"
329      */

330
331     public String JavaDoc dialect() throws XDocletException
332     {
333         return getHibernateProperties().getDialect();
334     }
335
336     /**
337      * Data source JNDI Name extractor.
338      *
339      * @return
340      * @exception XDocletException
341      * @doc.tag type="content"
342      */

343     public String JavaDoc dataSource() throws XDocletException
344     {
345         return getHibernateProperties().getDataSource();
346     }
347
348     /**
349      * Driver Name extractor.
350      *
351      * @return
352      * @exception XDocletException
353      * @doc.tag type="content"
354      */

355     public String JavaDoc driver() throws XDocletException
356     {
357         return getHibernateProperties().getDriver();
358     }
359
360     /**
361      * JDBC URL extractor.
362      *
363      * @return
364      * @exception XDocletException
365      * @doc.tag type="content"
366      */

367     public String JavaDoc jdbcUrl() throws XDocletException
368     {
369         return getHibernateProperties().getJdbcUrl();
370     }
371
372     /**
373      * username extractor.
374      *
375      * @return
376      * @exception XDocletException
377      * @doc.tag type="content"
378      */

379     public String JavaDoc userName() throws XDocletException
380     {
381         return getHibernateProperties().getUserName();
382     }
383
384     /**
385      * password extractor.
386      *
387      * @return
388      * @exception XDocletException
389      * @doc.tag type="content"
390      */

391     public String JavaDoc password() throws XDocletException
392     {
393         return getHibernateProperties().getPassword();
394     }
395
396     /**
397      * poolSize extractor.
398      *
399      * @return
400      * @exception XDocletException
401      * @doc.tag type="content"
402      */

403     public String JavaDoc poolSize() throws XDocletException
404     {
405         return getHibernateProperties().getPoolSize();
406     }
407
408     /**
409      * classname extractor.
410      *
411      * @return
412      * @exception XDocletException
413      * @doc.tag type="content"
414      */

415     public String JavaDoc factoryClass() throws XDocletException
416     {
417         return getFactoryClassSubTask().getFactoryClass();
418     }
419
420     /**
421      * Comma separated list of hibernate mappings.
422      *
423      * @return
424      * @exception XDocletException
425      * @doc.tag type="content"
426      */

427     public String JavaDoc mappingList() throws XDocletException
428     {
429         String JavaDoc mappingName;
430         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
431         Collection JavaDoc classes = ClassTagsHandler.getAllClasses();
432         XClass clazz;
433
434         for (Iterator JavaDoc i = classes.iterator(); i.hasNext(); ) {
435             clazz = (XClass) i.next();
436
437             if (clazz.getDoc().hasTag("hibernate.class", false)) {
438                 mappingName = getHibernateSubTask().getMappingURL(clazz);
439                 sb.append(mappingName);
440                 sb.append(",");
441             }
442         }
443         if (sb.length() > 0) {
444             return sb.substring(0, sb.length() - 1);
445         }
446         else {
447             return "";
448         }
449     }
450
451     /**
452      * Print the name of the current class to the console.
453      *
454      * @param attributes
455      * @exception XDocletException
456      * @doc.tag type="content"
457      */

458     public void logMapping(Properties JavaDoc attributes) throws XDocletException
459     {
460         System.out.println(" " + getCurrentClass().getQualifiedName());
461     }
462
463
464     /**
465      * Iterates over all classes marked as persistent.
466      *
467      * @param template The body of the block tag
468      * @param attributes The attributes of the template tag
469      * @exception XDocletException Description of Exception
470      * @doc.tag type="block"
471      */

472     public void forAllPersistentClasses(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
473     {
474         Collection JavaDoc classes = ClassTagsHandler.getAllClasses();
475         XClass clazz;
476
477         for (Iterator JavaDoc i = classes.iterator(); i.hasNext(); ) {
478             clazz = (XClass) i.next();
479
480             if (clazz.getDoc().hasTag("hibernate.class", false)) {
481                 pushCurrentClass(clazz);
482                 generate(template);
483                 popCurrentClass();
484             }
485         }
486     }
487
488     /**
489      * Iterates over all jndiProperties specified.
490      *
491      * @param template The body of the block tag
492      * @param attributes The attributes of the template tag
493      * @exception XDocletException Description of Exception
494      * @doc.tag type="block"
495      */

496     public void forAllJndiProperties(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
497     {
498         Collection JavaDoc properties = getHibernateProperties().getJndiProperties();
499
500         for (Iterator JavaDoc i = properties.iterator(); i.hasNext(); ) {
501             currentJndiParameter = (Parameter) i.next();
502             generate(template);
503             currentJndiParameter = null;
504         }
505     }
506
507     /**
508      * Iterates over all otherProperties specified.
509      *
510      * @param template The body of the block tag
511      * @param attributes The attributes of the template tag
512      * @exception XDocletException Description of Exception
513      * @doc.tag type="block"
514      */

515     public void forAllOtherProperties(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
516     {
517         Collection JavaDoc properties = getHibernateProperties().getOtherProperties();
518
519         for (Iterator JavaDoc i = properties.iterator(); i.hasNext(); ) {
520             currentOtherParameter = (Parameter) i.next();
521             generate(template);
522             currentOtherParameter = null;
523         }
524     }
525
526     /**
527      * Iterates over all otherMappings specified.
528      *
529      * @param template The body of the block tag
530      * @param attributes The attributes of the template tag
531      * @exception XDocletException Description of Exception
532      * @doc.tag type="block"
533      */

534     public void forAllOtherMappings(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
535     {
536         Collection JavaDoc properties = getHibernateProperties().getOtherMappings();
537
538         for (Iterator JavaDoc i = properties.iterator(); i.hasNext(); ) {
539             currentOtherMapping = (Parameter) i.next();
540             generate(template);
541             currentOtherMapping = null;
542         }
543     }
544
545     public String JavaDoc jndiParameterName()
546     {
547         return currentJndiParameter.getName();
548     }
549
550     public String JavaDoc jndiParameterValue()
551     {
552         return currentJndiParameter.getValue();
553     }
554
555     public String JavaDoc otherParameterName()
556     {
557         return currentOtherParameter.getName();
558     }
559
560     public String JavaDoc otherParameterValue()
561     {
562         return currentOtherParameter.getValue();
563     }
564
565     public String JavaDoc otherMappingName()
566     {
567         return currentOtherMapping.getName();
568     }
569
570     public String JavaDoc otherMappingValue()
571     {
572         return currentOtherMapping.getValue();
573     }
574
575     /**
576      * Iterates over all classes loaded by javadoc that are direct subclasses of the current class and evaluates the
577      * body of the tag for each class. It discards classes that have an xdoclet-generated class tag defined.
578      *
579      * @param template The body of the block tag
580      * @param attributes The attributes of the template tag
581      * @exception XDocletException Description of Exception
582      * @doc.tag type="block"
583      */

584     public void forAllSubclasses(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
585     {
586
587         Log log = LogUtil.getLog(HibernateTagsHandler.class, "forAllSubclasses");
588
589         try {
590
591             String JavaDoc typeName = getCurrentClass().getQualifiedName();
592
593             if (log.isDebugEnabled())
594                 log.debug("typeName=" + typeName);
595
596             Collection JavaDoc classes = getXJavaDoc().getSourceClasses();
597             XClass clazz;
598
599             for (Iterator JavaDoc i = classes.iterator(); i.hasNext(); ) {
600                 clazz = (XClass) i.next();
601
602                 log.debug("clazz=" + clazz);
603
604                 if (DocletSupport.isDocletGenerated(clazz)) {
605                     log.debug("isDocletGenerated");
606                 }
607                 else if (clazz.getSuperclass() != null && clazz.getSuperclass().getQualifiedName().equals(typeName)) {
608                     log.debug("is a subclass");
609
610                     XClass current = getCurrentClass();
611
612                     pushCurrentClass(clazz);
613                     generate(template);
614                     popCurrentClass();
615
616                     if (getCurrentClass() != current)
617                         setCurrentClass(current);
618                     //TODO: why do we need this?!
619
}
620                 else {
621                     log.debug("is not a subclass");
622                 }
623             }
624         }
625         catch (Exception JavaDoc e) {
626             log.error("exception occurred", e);
627         }
628     }
629
630     /**
631      * The column name for a component is prefix + basename
632      *
633      * @param attributes
634      * @return
635      */

636     public String JavaDoc computeColumnName(Properties JavaDoc attributes)
637     {
638         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
639         Iterator JavaDoc i = columnPrefixes.iterator();
640
641         while (i.hasNext()) {
642             String JavaDoc columnPrefix = (String JavaDoc) i.next();
643
644             if (columnPrefix != null && columnPrefix.length() > 0) {
645                 buf.append(columnPrefix);
646             }
647         }
648
649         buf.append(attributes.getProperty("base"));
650         return buf.toString();
651     }
652
653     /**
654      * Actual templating for composite/primitive IDs.
655      *
656      * @param template
657      * @param composite
658      * @exception XDocletException
659      */

660     void hasCompositeId_Impl(String JavaDoc template, boolean composite) throws XDocletException
661     {
662         XClass oldClass = getCurrentClass();
663
664         XMethod method = getIdMethod();
665
666         // bomb politely if no ID method could be found
667
if (method == null) {
668             throw new XDocletException(
669                 Translator.getString(XDocletModulesHibernateMessages.class,
670                 XDocletModulesHibernateMessages.NO_ID_PROPERTY,
671                 new String JavaDoc[]{getCurrentClass().getQualifiedName()}));
672         }
673
674         // Determine whether or not the ID is a user-defined type.
675
// If it is then it is not a composite id.
676
boolean isUserType = false;
677
678         String JavaDoc typeStr = method.getDoc().getTagAttributeValue("hibernate.id", "type");
679
680         if (typeStr != null) {
681             // The type attribute was supplied, so check
682
// whether it implements cirrus.hibernate.UserType
683
XClass typeClass = getXJavaDoc().getXClass(typeStr);
684
685             if (typeClass != null) {
686                 isUserType = typeClass.isA("cirrus.hibernate.UserType") || typeClass.isA("net.sf.hibernate.UserType");
687             }
688         }
689         else {
690             typeStr = method.getReturnType().getType().getQualifiedName();
691         }
692
693         // decide whether we have composite or primitive ID
694
boolean isPrimitive = TypeTagsHandler.isPrimitiveType(typeStr) ||
695             "java.lang.Byte".equals(typeStr) ||
696             "java.lang.Double".equals(typeStr) ||
697             "java.lang.Float".equals(typeStr) ||
698             "java.lang.Integer".equals(typeStr) ||
699             "java.lang.Long".equals(typeStr) ||
700             "java.lang.Short".equals(typeStr) ||
701             "java.lang.String".equals(typeStr) ||
702             "java.math.BigDecimal".equals(typeStr) ||
703             "java.math.BigInteger".equals(typeStr) ||
704             isUserType;
705
706         if (isPrimitive && !composite) {
707             setCurrentMethod(method);
708             generate(template);
709         }
710
711         if (composite && !isPrimitive) {
712             // check whether specified type satisfies us
713
// it has to be serializable,
714
// and implement equals itself.
715
// bomb if not.
716
XClass returnType = method.getReturnType().getType();
717
718             if (returnType.isA("java.io.Serializable") && !returnType.isAbstract() &&
719                 !"java.lang.Object".equals(returnType.getMethod("equals(java.lang.Object)", true).getContainingClass().getQualifiedName())) {
720                 setCurrentMethod(method);
721                 generate(template);
722
723             }
724             else {
725                 // bomb politely that given property does not qualify as composite ID
726
throw new XDocletException(
727                     Translator.getString(XDocletModulesHibernateMessages.class,
728                     XDocletModulesHibernateMessages.WRONG_COMPOSITE_ID,
729                     new String JavaDoc[]{returnType.getQualifiedName()}));
730             }
731         }
732
733         if (getCurrentClass() != oldClass)
734             setCurrentClass(oldClass);
735         //TODO: Why do we need this!!??
736
}
737
738     private HibernateSubTask getHibernateSubTask()
739     {
740         return ((HibernateSubTask) (DocletContext.getInstance()
741             .getSubTaskBy(DocletTask.getSubTaskName(HibernateSubTask.class))));
742     }
743 }
744
745
Popular Tags