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 & 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()) {