Hi,

I have attached my fix to XDT-1061 for your review.
Problem description:
==============
The @hibernate.query tag is currently coupled with @hibernate.class tag, making it impossible to generate hibernate mapping files that contains only named query definitions. This requirement is essential for large projects where named queries are defined with the Data Access Objects.
Fix for the problem:
=============
To fix the problem, two issues have to be addressed:
1. In XDoclet core, a TemplateSubTask has to support the ability to use multiple "havingClassTag" values (a String array of tag names). In the case of Hibernate module, both "hibernate.class" and "hibernate.query" should qualify for XDoclet generation.
2. In XDoclet Hibernate module, the hibernate.xdt template file has to be changed so that the "hibernate.class" tag is no longer a requirement for the "hibernate.query" tag to be processed.


The attached patch file contains fixes to the above problems.

Regards.

Peilin Zhang

? patch.diff
Index: core/src/xdoclet/TemplateSubTask.java
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet/core/src/xdoclet/TemplateSubTask.java,v
retrieving revision 1.79
diff -b -u -r1.79 TemplateSubTask.java
--- core/src/xdoclet/TemplateSubTask.java       6 Apr 2005 23:56:18 -0000       
1.79
+++ core/src/xdoclet/TemplateSubTask.java       11 Apr 2005 18:22:10 -0000
@@ -19,6 +19,7 @@
 import xdoclet.template.TemplateEngine;
 import xdoclet.template.TemplateException;
 import xdoclet.template.XDocletTemplateMessages;
+import xdoclet.util.DocletUtil;
 import xdoclet.util.LogUtil;
 import xdoclet.util.Translator;
 
@@ -85,7 +86,7 @@
      * @see   #setHavingClassTag(java.lang.String)
      * @see   #getHavingClassTag()
      */
-    private String  havingClassTag = null;
+    private String[] havingClassTags = null;
 
     /**
      * The subtask class.
@@ -222,13 +223,13 @@
     }
 
     /**
-     * Gets the HavingClassTag attribute of the TemplateSubTask object
+     * Gets the HavingClassTags attribute of the TemplateSubTask object
      *
      * @return   The HavingClassTag value
      */
-    public String getHavingClassTag()
+    public String[] getHavingClassTags()
     {
-        return havingClassTag;
+        return havingClassTags;
     }
 
     /**
@@ -383,13 +384,23 @@
     }
 
     /**
-     * Sets the HavingClassTag attribute of the TemplateSubTask object
+     * Sets the HavingClassTags attribute of the TemplateSubTask object
      *
      * @param havingClassTag  The new HavingClassTag value
      */
     public void setHavingClassTag(String havingClassTag)
     {
-        this.havingClassTag = havingClassTag;
+        setHavingClassTags( new String[]{havingClassTag} );
+    }
+
+       /**
+     * Sets the HavingClassTags attribute of the TemplateSubTask object
+     *
+     * @param havingClassTags  The new HavingClassTag value
+     */  
+    public void setHavingClassTags(String[] havingClassTags)
+    {
+        this.havingClassTags = havingClassTags;
     }
 
     public void setOfType(String ofType)
@@ -437,7 +448,7 @@
             addOfType((OfType) src.ofType.get(i));
         }
         setExtentValue(src.getExtent());
-        setHavingClassTag(src.getHavingClassTag());
+        setHavingClassTags(src.getHavingClassTags());
         setSubTaskClassName(src.getSubTaskClassName());
         for (int i = 0; i < src.packageSubstitutions.size(); i++) {
             addPackageSubstitution((PackageTagsHandler.PackageSubstitution) 
src.packageSubstitutions.get(i));
@@ -589,7 +600,7 @@
             log.debug("getDestinationfile()=" + getDestinationFile());
             log.debug("getOfType()=" + getOfType());
             log.debug("getExtent()=" + getExtent());
-            log.debug("getHavingClassTag()=" + getHavingClassTag());
+            log.debug("getHavingClassTag()=" + 
DocletUtil.arrayToDelimitedString(getHavingClassTags(), ", "));
         }
 
         if (isGenerationPerClass()) {
@@ -723,16 +734,28 @@
         if (ofType.size() > 0 && classIsntOfOneOfTheTypes(clazz, log))
             return false;
 
-        if (getHavingClassTag() != null) {
-            if (!clazz.getDoc().hasTag(getHavingClassTag(), false)) {
+        String[] havingClassTags = getHavingClassTags();
+
+        if (havingClassTags != null && havingClassTags.length > 0) {
+
+            XDoc xdoc = clazz.getDoc();
+            boolean foundClassTag = false;
+
+            for (int i = 0; i < havingClassTags.length; i++) {
+                if (xdoc.hasTag(havingClassTags[i])) {
+                    foundClassTag = true;
+                    break;
+                }
+            }
+            if (!foundClassTag) {
                 if (log.isDebugEnabled()) {
-                    log.debug("Reject class '" + clazz.getQualifiedName() + "' 
because it doesn't have class tag '" + getHavingClassTag() + "'.");
+                    log.debug("Reject class '" + clazz.getQualifiedName() + "' 
because it doesn't have at least one of class tags '" + 
DocletUtil.arrayToDelimitedString(havingClassTags, ", ") + "'.");
                 }
                 return false;
             }
             else {
                 if (log.isDebugEnabled()) {
-                    log.debug("Accept class '" + clazz.getQualifiedName() + "' 
because it has class tag '" + getHavingClassTag() + "'.");
+                    log.debug("Accept class '" + clazz.getQualifiedName() + "' 
because it has at least one of class tags '" + 
DocletUtil.arrayToDelimitedString(havingClassTags, ", ") + "'.");
                 }
             }
         }
Index: core/src/xdoclet/XDocletTagSupport.java
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet/core/src/xdoclet/XDocletTagSupport.java,v
retrieving revision 1.61
diff -b -u -r1.61 XDocletTagSupport.java
--- core/src/xdoclet/XDocletTagSupport.java     1 Mar 2005 22:42:52 -0000       
1.61
+++ core/src/xdoclet/XDocletTagSupport.java     11 Apr 2005 18:22:11 -0000
@@ -14,6 +14,7 @@
 import xdoclet.template.TemplateEngine;
 import xdoclet.template.TemplateException;
 import xdoclet.template.TemplateTagHandler;
+import xdoclet.util.DocletUtil;
 import xdoclet.util.LogUtil;
 import xdoclet.util.Translator;
 import xdoclet.util.TypeConversionUtil;
@@ -800,19 +801,31 @@
 
         TemplateSubTask templTask = (TemplateSubTask) task;
 
-        if (templTask.getHavingClassTag() == null) {
+        String[] havingClassTags = templTask.getHavingClassTags();
+
+        if (havingClassTags == null || havingClassTags.length < 1) {
             return true;
         }
 
-        if (!clazz.getDoc().hasTag(templTask.getHavingClassTag(), false)) {
+        boolean foundClassTag = false;
+        XDoc xdoc = clazz.getDoc();
+
+        for (int i = 0; i < havingClassTags.length; i++) {
+            if (xdoc.hasTag(havingClassTags[i])) {
+                foundClassTag = true;
+                break;
+            }
+        }
+
+        if (!foundClassTag) {
             if (log.isDebugEnabled()) {
-                log.debug("Reject class '" + clazz.getQualifiedName() + "' 
because it doesn't have class tag '" + templTask.getHavingClassTag() + "'.");
+                log.debug("Reject class '" + clazz.getQualifiedName() + "' 
because it doesn't have one of the required class tags '" + 
DocletUtil.arrayToDelimitedString(havingClassTags, ", ") + "'.");
             }
             return false;
         }
         else {
             if (log.isDebugEnabled()) {
-                log.debug("Accept class '" + clazz.getQualifiedName() + "' 
because it has class tag '" + templTask.getHavingClassTag() + "'.");
+                log.debug("Accept class '" + clazz.getQualifiedName() + "' 
because it has one of the required class tags '" + 
DocletUtil.arrayToDelimitedString(havingClassTags, ", ") + "'.");
             }
             return true;
         }
Index: core/src/xdoclet/util/DocletUtil.java
===================================================================
RCS file: /cvsroot/xdoclet/xdoclet/core/src/xdoclet/util/DocletUtil.java,v
retrieving revision 1.19
diff -b -u -r1.19 DocletUtil.java
--- core/src/xdoclet/util/DocletUtil.java       10 Jun 2003 13:32:39 -0000      
1.19
+++ core/src/xdoclet/util/DocletUtil.java       11 Apr 2005 18:22:13 -0000
@@ -8,7 +8,7 @@
 
 /**
  * @author    Ara Abrahamian ([EMAIL PROTECTED])
- * @author    <a href="[EMAIL PROTECTED]">Aslak Hellesøy</a>
+ * @author    <a href="[EMAIL PROTECTED]">Aslak Helles�y</a>
  * @created   July 14, 2001
  * @version   $Revision: 1.19 $
  */
@@ -34,4 +34,25 @@
         }
         return ret;
     }
+
+    /**
+     * Return a tokenizable String by the specified delimiter from an Object 
array.
+     *
+     * @param array  the array to be concatenated into a string with the 
specified delimiter
+     * @param delim  the delimiter to use
+     * @return       a tokenizable String by the specified delimiter from an 
Object array.
+     */
+    public static String arrayToDelimitedString(Object[] array, String delim)
+    {
+        if (array == null)
+            return null;
+        StringBuffer buff = new StringBuffer();
+
+        for (int i = 0; i < array.length; i++) {
+            if (i != 0)
+                buff.append(delim);
+            buff.append(array[i]);
+        }
+        return buff.toString();
+    }
 }
Index: modules/hibernate/src/xdoclet/modules/hibernate/HibernateSubTask.java
===================================================================
RCS file: 
/cvsroot/xdoclet/xdoclet/modules/hibernate/src/xdoclet/modules/hibernate/HibernateSubTask.java,v
retrieving revision 1.12
diff -b -u -r1.12 HibernateSubTask.java
--- modules/hibernate/src/xdoclet/modules/hibernate/HibernateSubTask.java       
3 Apr 2005 10:22:34 -0000       1.12
+++ modules/hibernate/src/xdoclet/modules/hibernate/HibernateSubTask.java       
11 Apr 2005 18:22:37 -0000
@@ -15,7 +15,7 @@
 /**
  * This task generates Hibernate xml mapping file for a given class. Supports 
Hibernate 1.1, 2.0, 2.1 &amp; 3.0.
  *
- * @author               Sébastien Guimont ([EMAIL PROTECTED])
+ * @author               S�bastien Guimont ([EMAIL PROTECTED])
  * @author               <a href="mailto:dchannon at 
users.sourceforge.net">David Channon</a>
  * @created              August 9th, 2002
  * @version              $Revision: 1.12 $
@@ -73,7 +73,7 @@
      */
     public HibernateSubTask()
     {
-        setHavingClassTag("hibernate.class");
+        setHavingClassTags(new String[]{"hibernate.class", "hibernate.query"});
         
setTemplateURL(getClass().getResource(DEFAULT_HIBERNATE_TEMPLATE_FILE));
         setDestinationFile(GENERATED_HIBERNATE_FILE_NAME);
     }
Index: modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate.xdt
===================================================================
RCS file: 
/cvsroot/xdoclet/xdoclet/modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate.xdt,v
retrieving revision 1.35
diff -b -u -r1.35 hibernate.xdt
--- modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate.xdt     
17 Mar 2005 21:48:21 -0000      1.35
+++ modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate.xdt     
11 Apr 2005 18:22:39 -0000
@@ -16,6 +16,11 @@
       </XDtClass:ifHasClassTag>

 >


     <XDtHibernate:logMapping/>

+    

+    <XDtCollection:create name="backupClass" type="map" />

+    <XDtCollection:put name="backupClass" key="oldClassName" 
value="<XDtClass:fullClassName />" />

+    

+    <XDtClass:ifHasClassTag tagName="hibernate.class" superclasses="false">

     <class

       <XDtClass:ifHasClassTag tagName="hibernate.class" superclasses="false">

         name="<XDtClass:fullTransformedClassName />"

@@ -223,9 +228,6 @@
         </XDtMethod:ifHasMethodTag>

     </XDtMethod:forAllMethods>

 

-    <XDtCollection:create name="backupClass" type="map" />

-    <XDtCollection:put name="backupClass" key="oldClassName" 
value="<XDtClass:fullClassName />" />

-

     <XDtMethod:forAllMethods superclasses="true" sort="true">

         <XDtMerge:merge 
file="xdoclet/modules/hibernate/resources/hibernate-properties.xdt">

         </XDtMerge:merge>

@@ -248,6 +250,7 @@
     </XDtMerge:merge>

 

     </class>

+       </XDtClass:ifHasClassTag>

 

     <XDtClass:pushClass value="<XDtCollection:get name='backupClass' 
key='oldClassName' />">

         <XDtClass:forAllClassTags tagName="hibernate.query" 
superclasses="false">

Index: modules/jdo/src/xdoclet/modules/jdo/JdoXmlMetadataSubTask.java
===================================================================
RCS file: 
/cvsroot/xdoclet/xdoclet/modules/jdo/src/xdoclet/modules/jdo/JdoXmlMetadataSubTask.java,v
retrieving revision 1.11
diff -b -u -r1.11 JdoXmlMetadataSubTask.java
--- modules/jdo/src/xdoclet/modules/jdo/JdoXmlMetadataSubTask.java      16 Aug 
2004 13:27:58 -0000      1.11
+++ modules/jdo/src/xdoclet/modules/jdo/JdoXmlMetadataSubTask.java      11 Apr 
2005 18:22:42 -0000
@@ -18,6 +18,7 @@
 import xdoclet.modules.jdo.JdoDocletTask.JdoSpecVersion;
 import xdoclet.tagshandler.PackageTagsHandler;
 import xdoclet.template.TemplateException;
+import xdoclet.util.DocletUtil;
 import xdoclet.util.LogUtil;
 import xdoclet.util.Translator;
 
@@ -169,7 +170,7 @@
             log.debug("getDestinationfile()=" + getDestinationFile());
             log.debug("getOfType()=" + getOfType());
             log.debug("getExtent()=" + getExtent());
-            log.debug("getHavingClassTag()=" + getHavingClassTag());
+            log.debug("getHavingClassTag()=" + 
DocletUtil.arrayToDelimitedString(getHavingClassTags(), ", "));
         }
 
         if (isGenerationPerClass()) {

Reply via email to