1 5 package xdoclet.modules.ejb.entity; 6 7 import java.lang.reflect.Modifier ; 8 import java.text.MessageFormat ; 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 36 public class ValueObjectTagsHandler 37 extends EjbTagsHandler 38 { 39 private XTag currentTag; 40 41 private String currentValueObjectClass; 42 43 private String currentValueObjectAttribute; 44 45 private String currentValueObjectMatch; 46 47 private String currentAggregateType; 49 50 private String currentAggregateName; 51 private String currentAggregateNamePlural; 52 53 private String currentRelationBeanClass; 54 55 62 public static boolean isValueObjectRelation(XMethod method, String 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 exclude = tag.getAttributeValue("exclude"); 83 String aggreg = tag.getAttributeValue("aggregate"); 84 String 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 110 public static boolean isGenerationNeeded(XClass clazz) 111 { 112 return true; 113 } 115 116 124 public static String getCurrentValueObjectClass(XClass clazz, XTag tag) 125 throws XDocletException 126 { 127 String name = getCurrentValueObjectName(tag); 128 129 String _currentValueObjectClass; 130 131 _currentValueObjectClass = MessageFormat.format(getSubTask().getValueObjectClassPattern(), 132 new Object []{(name != null) ? name : getShortEjbNameFor(clazz)}); 133 134 String 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 150 public static String getCurrentValueObjectName(XTag tag) throws XDocletException 151 { 152 String name = tag.getAttributeValue("name"); 153 154 if (name != null) { 155 return name; 156 } 157 158 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 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 clazz = clazz.getSuperclass(); 174 } 175 throw new XDocletException("class defining value object is not EJB"); 176 } 177 178 185 public static String getCurrentValueObjectAttribute(XTag tag) throws XDocletException 186 { 187 String name = getCurrentValueObjectName(tag); 188 189 String _currentValueObjectAttribute; 190 191 if (name == null) { 192 _currentValueObjectAttribute = "Value"; 193 } 194 else { 195 _currentValueObjectAttribute = MessageFormat.format(getSubTask().getValueObjectClassPattern(), new Object []{name}); 196 } 197 198 return _currentValueObjectAttribute; 199 } 200 201 207 public static String getCurrentValueObjectMatch(XTag tag) 208 { 209 String match = tag.getAttributeValue("match"); 210 211 if (match == null) { 212 match = "*"; 213 } 214 return match; 215 } 216 217 public static String getCurrentValueObjectImplements(XTag tag) 218 { 219 String toImplement = tag.getAttributeValue("implements"); 220 221 return toImplement != null ? "," + toImplement : ""; 222 } 223 224 public static String getCurrentValueObjectExtends(XTag tag) 225 { 226 String toImplement = tag.getAttributeValue("extends"); 227 228 return toImplement != null ? toImplement : "java.lang.Object"; 229 } 230 231 236 private static ValueObjectSubTask getSubTask() 237 { 238 ValueObjectSubTask subtask = ((ValueObjectSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(ValueObjectSubTask.class))); 239 240 return subtask; 241 } 242 243 250 private static boolean matches(XTag tag, String valueObject) 251 { 252 Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "matches"); 253 String 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 274 public boolean isAbstractValueObject(String 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 298 public String getValueMostSuperObjectClass(XClass clazz) throws XDocletException 299 { 300 String currentDataClass = currentValueObjectClass; 301 303 XClass cur_clazz = clazz.getSuperclass(); 304 305 do { 306 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 337 public void ifGeneratePKConstructor(String template, Properties attributes) 338 throws XDocletException 339 { 340 if (getSubTask().getGeneratePKConstructor()) { 341 generate(template); 342 } 343 } 344 345 353 public void ifIsAbstractValueObject(String template) 354 throws XDocletException 355 { 356 if (isAbstractValueObject(valueObjectName(), getCurrentClass())) { 357 generate(template); 358 } 359 } 360 361 369 public void ifNotIsAbstractValueObject(String template) 370 throws XDocletException 371 { 372 if (!isAbstractValueObject(valueObjectName(), getCurrentClass())) { 373 generate(template); 374 } 375 } 376 377 384 public String valueObjectClass() throws XDocletException 385 { 386 return getSubTask().getCurrentValueObjectClass(); 387 } 388 389 396 public String valueObjectName() throws XDocletException 397 { 398 return getSubTask().getCurrentValueObjectName(); 399 } 400 401 408 public String valueObjectMatch() throws XDocletException 409 { 410 return getSubTask().getCurrentValueObjectMatch(); 411 } 412 413 424 public String extendsFrom(Properties attributes) throws XDocletException 425 { 426 return getSubTask().getCurrentValueObjectExtends(); 427 } 428 429 436 public void forAllValueObjects(String 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 468 public String currentValueObjectClass() 469 { 470 return currentValueObjectClass; 471 } 472 473 479 public String currentValueObjectAttribute() 480 { 481 return currentValueObjectAttribute; 482 } 483 484 490 public String currentValueObjectMatch() 491 { 492 return currentValueObjectMatch; 493 } 494 495 503 public String currentAggregateType(Properties attributes) 504 { 505 String sh = attributes.getProperty("short"); 506 String 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 527 public String valueObjectImplements() 528 { 529 return getSubTask().getCurrentValueObjectImplements(); 530 } 531 532 544 public String currentAggregateName(Properties attributes) 545 { 546 String plural = attributes.getProperty("plural"); 547 String decapitalize = attributes.getProperty("decapitalize"); 548 String 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 564 public String currentRelationBeanClass() 565 { 566 return currentRelationBeanClass; 567 } 568 569 576 public String concreteCollectionType() throws XDocletException 577 { 578 String concreteType = getCurrentMethod().getDoc().getTagAttributeValue("ejb.value-object", "concrete-type"); 579 Class concreteClass = null; 580 581 if (concreteType != null) { 583 try { 584 concreteClass = Class.forName(concreteType); 585 } 586 catch (ClassNotFoundException e) { 587 throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, 588 XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_NOT_FOUND, 589 new String []{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 []{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 []{concreteType})); 600 } 601 } 602 603 String 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 if (!Collection.class.isAssignableFrom(concreteClass)) { 612 throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, 613 XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_INVALID, 614 new String []{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 if (!Set.class.isAssignableFrom(concreteClass)) { 627 throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, 628 XDocletModulesEjbMessages.VALUE_OBJECT_CONCRETE_TYPE_INVALID, 629 new String []{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 648 public String collectionType() throws XDocletException 649 { 650 return getCurrentMethod().getReturnType().getType().getQualifiedName(); 651 } 652 653 660 public void ifIsCollection(String template) throws XDocletException 661 { 662 if (isCollection()) { 663 generate(template); 664 } 665 } 666 667 674 public void ifIsNotCollection(String template) throws XDocletException 675 { 676 if (!isCollection()) { 677 generate(template); 678 } 679 } 680 681 690 public String valueMostSuperObjectClass() throws XDocletException 691 { 692 return getValueMostSuperObjectClass(getCurrentClass()); 693 } 694 695 702 public void forAllSuperSetValue(String 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 742 public void forAllAggregates(String template, Properties attributes) throws XDocletException 743 { 744 String superclasses_str = attributes.getProperty("superclasses"); 745 boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true); 746 747 String valueObject = attributes.getProperty("valueobject"); 748 749 forAllRelations(template, superclasses, valueObject, "aggregate"); 750 } 751 752 763 public void forAllComposes(String template, Properties attributes) throws XDocletException 764 { 765 String superclasses_str = attributes.getProperty("superclasses"); 766 boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true); 767 768 String valueObject = attributes.getProperty("valueobject"); 769 770 forAllRelations(template, superclasses, valueObject, "compose"); 771 } 772 773 784 public void forAllRelations(String template, Properties attributes) throws XDocletException 785 { 786 String superclasses_str = attributes.getProperty("superclasses"); 787 boolean superclasses = TypeConversionUtil.stringToBoolean(superclasses_str, true); 788 789 String valueObject = attributes.getProperty("valueobject"); 790 791 forAllRelations(template, superclasses, valueObject, "aggregate"); 792 forAllRelations(template, superclasses, valueObject, "compose"); 793 } 794 795 802 public void ifUsingValueObject(String template) throws XDocletException 803 { 804 if (DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(ValueObjectSubTask.class))) { 805 generate(template); 806 } 807 } 808 809 protected void forAllSetters(String template, String methodName) throws XDocletException 810 { 811 Log log = LogUtil.getLog(ValueObjectTagsHandler.class, "forAllSetters"); 812 813 if (log.isDebugEnabled()) { 814 log.debug(methodName); 815 } 816 817 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 847 private boolean isCollection() 848 { 849 String 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 valueObjectName, XTag tag) 855 { 856 boolean isAbstract = false; 857 String 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 874 private void forAllRelations(String template, boolean superclasses, String valueObject, String 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 aggreg = tag.getAttributeValue(type); 916 String aggregName = tag.getAttributeValue(type + "-name"); 917 String 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 currentReturnType = getCurrentMethod().getReturnType().getType().getQualifiedName(); 929 930 if (log.isDebugEnabled()) { 931 log.debug("********* METHOD=" + getCurrentMethod().getName() + " " + currentReturnType); 932 } 933 934 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 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 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 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 |