diff -uprN xdoclet-1.2.2.orig/modules/hibernate/src/xdoclet/modules/hibernate/HibernateTagsHandler.java xdoclet-1.2.2/modules/hibernate/src/xdoclet/modules/hibernate/HibernateTagsHandler.java --- xdoclet-1.2.2.orig/modules/hibernate/src/xdoclet/modules/hibernate/HibernateTagsHandler.java 2004-10-14 04:39:06.000000000 +0200 +++ xdoclet-1.2.2/modules/hibernate/src/xdoclet/modules/hibernate/HibernateTagsHandler.java 2005-04-03 15:20:31.000000000 +0200 @@ -4,10 +4,7 @@ */ package xdoclet.modules.hibernate; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Properties; +import java.util.*; import org.apache.commons.logging.Log; import org.apache.tools.ant.types.Parameter; @@ -48,6 +45,18 @@ public class HibernateTagsHandler private Parameter currentOtherMapping; + private static boolean isHibernated(XClass xClass) + { + if (xClass == null) { + return false; + } + + return ( + xClass.getDoc().getTag("hibernate.class") != null || + xClass.getDoc().getTag("hibernate.subclass") != null + ); + } + /** * Returns full path of hibernate file for the current class. * @@ -594,9 +603,11 @@ public class HibernateTagsHandler log.debug("typeName=" + typeName); Collection classes = getXJavaDoc().getSourceClasses(); + List reorderedClasses = flattenHierachy(getCurrentClass(), classes); + XClass clazz; - for (Iterator i = classes.iterator(); i.hasNext(); ) { + for (Iterator i = reorderedClasses.iterator(); i.hasNext(); ) { clazz = (XClass) i.next(); log.debug("clazz=" + clazz); @@ -604,8 +615,13 @@ public class HibernateTagsHandler if (DocletSupport.isDocletGenerated(clazz)) { log.debug("isDocletGenerated"); } - else if (clazz.getSuperclass() != null && clazz.getSuperclass().getQualifiedName().equals(typeName)) { - log.debug("is a subclass"); + else if (isValidSubclass(clazz, getCurrentClass())) { + if (getCurrentClass().isInterface()) { + log.debug("is an implementing class"); + } + else { + log.debug("is a subclass"); + } XClass current = getCurrentClass(); @@ -735,10 +751,108 @@ public class HibernateTagsHandler //TODO: Why do we need this!!?? } + private boolean isValidSubclass(XClass clazz, XClass currentClass) + { + String typeName = currentClass.getQualifiedName(); + + // easy case, clazz is implementing interface of hibernated class + // NB: not easy anymore, if we've got a hibernated interface hierachy + // only return true for "deepest" implemented interface in this hierachy + if (currentClass.isInterface() && clazz.isImplementingInterface(typeName)) { + List extending = currentClass.getExtendingInterfaces(); + + if (extending.isEmpty()) { + return true; + } + + for (int i = 0; i < extending.size(); i++) { + XClass xClass = (XClass) extending.get(i); + + if (isHibernated(xClass) && clazz.isImplementingInterface(xClass.getQualifiedName())) { + // we found an interface deeper in the hierachy + return false; + } + } + return true; + } + + if (clazz.getSuperclass() != null) { + // easy case, this class is direct subclass of the hibernated type + if (clazz.getSuperclass().equals(typeName)) { + return true; + } + else { + // go up class hierarchy to find first hibernate tag + XClass xc = clazz; + + do { + xc = xc.getSuperclass(); + + } while (xc != null && !isHibernated(xc)); + + // did we find a valid superclass, is it the current ? + if (xc != null) { + return xc.equals(currentClass); + } + } + } + + return false; + } + private HibernateSubTask getHibernateSubTask() { return ((HibernateSubTask) (DocletContext.getInstance() .getSubTaskBy(DocletTask.getSubTaskName(HibernateSubTask.class)))); } + + /** + * Flattens the collection of classes by eliminating descendants (for hibernated non + * interface classes). + * + * @param currentClass + * @param classes + * @return + */ + private List flattenHierachy(XClass currentClass, Collection classes) + { + Log log = LogUtil.getLog(HibernateTagsHandler.class, "flattenHierachy"); + + log.debug("for class " + currentClass); + + if (!currentClass.isInterface()) { + List l = new ArrayList(classes); + + l.retainAll(currentClass.getAllSubclasses()); + return l; + } + + Set s = new HashSet(classes); + + log.debug("initial set size: " + s.size()); + + for (Iterator iterator = classes.iterator(); iterator.hasNext(); ) { + XClass xClass = (XClass) iterator.next(); + + if (xClass.isInterface() || !isHibernated(xClass)) { + continue; + } + + List subClasses = xClass.getAllSubclasses(); + + for (int i = 0; i < subClasses.size(); i++) { + XClass aClass = (XClass) subClasses.get(i); + + if (s.contains(aClass)) { + log.debug("removing " + aClass + " from set"); + s.remove(aClass); + } + } + } + + log.debug("new set size: " + s.size()); + + return new ArrayList(s); + } } diff -uprN xdoclet-1.2.2.orig/modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate-properties.xdt xdoclet-1.2.2/modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate-properties.xdt --- xdoclet-1.2.2.orig/modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate-properties.xdt 2004-10-10 11:43:05.000000000 +0200 +++ xdoclet-1.2.2/modules/hibernate/src/xdoclet/modules/hibernate/resources/hibernate-properties.xdt 2005-04-03 15:20:31.000000000 +0200 @@ -1,4 +1,4 @@ - + " @@ -20,7 +20,7 @@ - + " @@ -43,7 +43,7 @@ - + " @@ -59,7 +59,7 @@ /> - + " @@ -84,7 +84,7 @@ /> - + ="" @@ -114,7 +114,7 @@ - + ="" @@ -143,7 +143,7 @@ - + ="" @@ -166,7 +166,7 @@ - + ="" @@ -193,7 +193,7 @@ - + ="" @@ -218,7 +218,7 @@ - + ="" @@ -236,7 +236,7 @@ - + "