1 5 package xdoclet.tagshandler; 6 7 import java.util.*; 8 9 import org.apache.commons.logging.Log; 10 11 import xjavadoc.*; 12 13 import xdoclet.DocletContext; 14 import xdoclet.SubTask; 15 import xdoclet.XDocletException; 16 import xdoclet.XDocletTagSupport; 17 import xdoclet.template.PrettyPrintWriter; 18 import xdoclet.util.LogUtil; 19 import xdoclet.util.Translator; 20 import xdoclet.util.TypeConversionUtil; 21 22 27 public abstract class AbstractProgramElementTagsHandler extends XDocletTagSupport 28 { 29 33 protected static String currentToken; 34 35 39 protected static StringTokenizer tagTokenizer; 40 41 45 protected static String matchPattern; 46 47 53 public static String getClassNameFor(XClass clazz) 54 { 55 return clazz.getName(); 56 } 57 58 64 public static String getFullClassNameFor(XClass clazz) 65 { 66 return clazz.getQualifiedName(); 67 } 68 69 75 public static String getFullSuperclassNameFor(XClass clazz) 76 { 77 if (clazz.getSuperclass() != null) { 78 return clazz.getSuperclass().getQualifiedName(); 79 } 80 else { 81 return "java.lang.Object"; 82 } 83 } 84 85 91 public static Collection getAllClasses() 92 { 93 if (DocletContext.getInstance().getActiveSubTask().getCurrentPackage() == null) { 94 return getXJavaDoc().getSourceClasses(); 96 } 97 else { 98 return DocletContext.getInstance().getActiveSubTask().getCurrentPackage().getClasses(); 99 } 100 } 101 102 112 protected static boolean hasExecutableMember_OLD(XClass clazz, String executableMemberName, String [] parameters, boolean setCurrentExecutableMember, int forType) 113 throws XDocletException 114 { 115 Log log = LogUtil.getLog(AbstractProgramElementTagsHandler.class, "hasExecutableMember"); 116 117 while (clazz != null) { 118 Collection executableMembers = null; 119 120 switch (forType) { 121 case FOR_CONSTRUCTOR: 122 executableMembers = clazz.getConstructors(); 123 break; 124 case FOR_METHOD: 125 executableMembers = clazz.getMethods(); 126 break; 127 default: 128 throw new XDocletException("Bad type: " + forType); 129 } 130 131 int j = 0; 132 133 loop : 134 for (Iterator m = executableMembers.iterator(); m.hasNext(); ) { 135 XExecutableMember executableMember = (XExecutableMember) m.next(); 136 137 if (executableMember.getName().equals(executableMemberName)) { 138 if (parameters != null) { 140 Collection params = executableMember.getParameters(); 141 142 log.debug("params.length=" + params.size()); 143 144 for (Iterator p = params.iterator(); p.hasNext(); ) { 145 XParameter param = (XParameter) p.next(); 146 147 String paramType = new StringBuffer (param.getType().getQualifiedName()).append(param.getDimensionAsString()).toString(); 148 149 if (log.isDebugEnabled()) { 150 log.debug("params[j]=" + paramType); 151 log.debug("parameters[j]=" + parameters[j]); 152 } 153 if (paramType.equals(parameters[j++])) { 154 continue loop; 155 } 156 } 157 } 158 159 if (setCurrentExecutableMember) { 161 switch (forType) { 162 case FOR_CONSTRUCTOR: 163 setCurrentConstructor((XConstructor) executableMember); 164 break; 165 case FOR_METHOD: 166 setCurrentMethod((XMethod) executableMember); 167 break; 168 default: 169 throw new XDocletException("Bad type: " + forType); 170 } 171 } 172 return true; 173 } 174 } 175 176 clazz = clazz.getSuperclass(); 178 } 179 180 return false; 181 } 182 183 189 protected static Object [] makeCopyOfArray(Object [] objects) 190 { 191 Object [] objects_copy = (Object []) java.lang.reflect.Array.newInstance(objects.getClass().getComponentType(), objects.length); 192 193 System.arraycopy(objects, 0, objects_copy, 0, objects.length); 194 195 return objects_copy; 196 } 197 198 protected static boolean hasExecutableMember(XClass clazz, String executableMemberName, String [] parameters, boolean setCurrentExecutableMember, int forType) 199 throws XDocletException 200 { 201 Log log = LogUtil.getLog(AbstractProgramElementTagsHandler.class, "hasExecutableMember"); 202 203 StringBuffer executableMemberNameWithSignature = new StringBuffer (executableMemberName).append("("); 204 boolean comma = false; 205 206 if (parameters != null) { 207 for (int i = 0; i < parameters.length; i++) { 208 if (comma) { 209 executableMemberNameWithSignature.append(','); 210 } 211 executableMemberNameWithSignature.append(getXJavaDoc().getXClass(parameters[i]).getQualifiedName()); 212 } 213 } 214 executableMemberNameWithSignature.append(')'); 215 216 XExecutableMember executableMember = null; 217 218 switch (forType) { 219 case FOR_CONSTRUCTOR: 220 executableMember = clazz.getConstructor(executableMemberNameWithSignature.toString()); 221 break; 222 case FOR_METHOD: 223 executableMember = clazz.getMethod(executableMemberNameWithSignature.toString(), true); 224 break; 225 default: 226 throw new XDocletException("Bad type: " + forType); 227 } 228 if (setCurrentExecutableMember && executableMember != null) { 229 switch (forType) { 230 case FOR_CONSTRUCTOR: 231 setCurrentConstructor((XConstructor) executableMember); 232 break; 233 case FOR_METHOD: 234 setCurrentMethod((XMethod) executableMember); 235 break; 236 default: 237 throw new XDocletException("Bad type: " + forType); 238 } 239 } 240 241 return executableMember != null; 242 } 243 244 253 public void setMatchValue(String template, Properties attributes) throws XDocletException 254 { 255 matchPattern = attributes.getProperty("value"); 256 generate(template); 257 matchPattern = null; 258 } 259 260 268 public String matchValue() throws XDocletException 269 { 270 return matchPattern; 271 } 272 273 281 public String currentToken(Properties attributes) throws XDocletException 282 { 283 Log log = LogUtil.getLog(SubTask.class, "currentToken"); 284 285 log.debug("current token: " + currentToken); 286 287 if (currentToken == null) { 288 log.error("null token found"); 289 return ""; 290 } 291 else { 292 return currentToken; 293 } 294 } 295 296 304 public String skipToken(Properties attributes) throws XDocletException 305 { 306 if (tagTokenizer.hasMoreTokens()) { 307 tagTokenizer.nextToken(); 308 } 309 310 return ""; 311 } 312 313 321 protected XExecutableMember getXExecutableMemberForMemberName(String memberName, int forType) throws XDocletException 322 { 323 if (memberName != null) { 324 return extractXExecutableMember(getCurrentClass(), memberName, forType); 325 } 326 327 return null; 328 } 329 330 339 protected XExecutableMember getXExecutableMemberForMemberName(String memberName, boolean superclasses, int forType) throws XDocletException 340 { 341 if (!superclasses) { 342 return getXExecutableMemberForMemberName(memberName, forType); 343 } 344 345 for (XClass clazz = getCurrentClass(); clazz != null; clazz = clazz.getSuperclass()) { 346 XExecutableMember member = extractXExecutableMember(clazz, memberName, forType); 347 348 if (member != null) { 349 return member; 350 } 351 } 352 return null; 353 } 354 355 366 protected char[] getIndentChars(Properties attributes) 367 { 368 String indentStr = attributes.getProperty("indent"); 369 370 if (indentStr == null) { 371 return new char[0]; 372 } 373 374 int indent = new Integer (indentStr).intValue(); 375 char[] spaces = new char[indent]; 376 377 Arrays.fill(spaces, ' '); 378 return spaces; 379 } 380 381 392 protected String exceptionList(Properties attributes, int forType) throws XDocletException 393 { 394 String skipExceptions = attributes.getProperty("skip"); 395 String appendExceptions = attributes.getProperty("append"); 396 String memberName = null; 397 Collection exceptions = null; 398 399 XExecutableMember executableMember = null; 400 401 switch (forType) { 402 case FOR_CONSTRUCTOR: 403 executableMember = getCurrentConstructor(); 404 memberName = attributes.getProperty("constructor"); 405 break; 406 case FOR_METHOD: 407 executableMember = getCurrentMethod(); 408 memberName = attributes.getProperty("method"); 409 break; 410 default: 411 throw new XDocletException("Can't exceptionList for type " + forType); 412 } 413 414 if (executableMember == null && memberName == null) { 415 exceptions = new ArrayList(); 416 } 417 418 if (memberName == null) { 419 exceptions = executableMember.getThrownExceptions(); 420 } 421 else { 422 executableMember = getXExecutableMemberForMemberName(memberName, true, forType); 423 424 if (executableMember != null) { 426 exceptions = executableMember.getThrownExceptions(); 427 } 428 else { 429 exceptions = new ArrayList(); 430 } 431 } 432 433 StringBuffer sbuf = new StringBuffer (); 434 String type = null; 435 436 for (Iterator i = exceptions.iterator(); i.hasNext(); ) { 437 type = ((XClass) i.next()).getQualifiedName(); 438 439 if (isInSkipExceptionsList(skipExceptions, type) == false && 440 isInAppendExceptionsList(appendExceptions, type) == false) { 441 appendException(sbuf, type); 442 } 443 } 444 445 if (appendExceptions != null) { 447 appendException(sbuf, appendExceptions); 448 } 449 450 return sbuf.toString(); 451 } 452 453 461 protected void forAllMemberTagTokens(String template, Properties attributes, int for_type) throws XDocletException 462 { 463 Log log = LogUtil.getLog(MethodTagsHandler.class, "forAllMemberTagTokens"); 464 465 String tagValue; 466 467 tagValue = getTagValue(attributes, for_type); 468 469 String delimiter = attributes.getProperty("delimiter"); 470 String skipStr = attributes.getProperty("skip"); 471 int skip; 472 473 try { 474 skip = Integer.valueOf(skipStr).intValue(); 475 } 476 catch (Throwable t) { 477 skip = 0; 478 } 479 480 if (delimiter == null) { 481 log.debug("got null delimiter - forAllMemberTagTokens"); 482 delimiter = PARAMETER_DELIMITER; 483 } 484 485 log.debug("Tag Value = " + tagValue); 486 487 tagTokenizer = new StringTokenizer(tagValue, delimiter, false); 488 currentToken = ""; 489 matchPattern = null; 490 491 for (int i = 0; tagTokenizer.hasMoreTokens() && i < skip; i++) { 492 tagTokenizer.nextToken(); 493 } 494 495 while (tagTokenizer.hasMoreTokens()) { 496 currentToken = tagTokenizer.nextToken(); 497 498 log.debug("generate current token: " + currentToken); 499 500 generate(template); 501 } 502 503 currentToken = null; 504 tagTokenizer = null; 505 matchPattern = null; 506 } 507 508 518 protected void forAllMemberTags(String template, Properties attributes, int forType, String resourceKey, String [] arguments) throws XDocletException 519 { 520 Log log = LogUtil.getLog(AbstractProgramElementTagsHandler.class, "forAllMemberTags"); 521 boolean superclasses = TypeConversionUtil.stringToBoolean(attributes.getProperty("superclasses"), true); 522 XMember member = null; 523 524 switch (forType) { 525 case FOR_FIELD: 526 member = getCurrentField(); 527 break; 528 case FOR_CONSTRUCTOR: 529 member = getCurrentConstructor(); 530 break; 531 case FOR_METHOD: 532 member = getCurrentMethod(); 533 break; 534 default: 535 throw new XDocletException("Bad type " + forType); 536 } 537 538 if (member == null) { 539 throw new XDocletException(Translator.getString(XDocletTagshandlerMessages.class, resourceKey, arguments)); 540 } 541 542 546 StringTokenizer st = new StringTokenizer(attributes.getProperty("tagName"), "|"); 547 boolean found = false; 548 549 while (st.hasMoreTokens() && !found) { 550 String tagName = st.nextToken(); 551 Collection tags = member.getDoc().getTags(tagName, superclasses); 552 553 for (Iterator i = tags.iterator(); i.hasNext(); ) { 554 found = true; 555 556 XTag tag = (XTag) i.next(); 557 558 if (forType == FOR_METHOD || forType == FOR_CONSTRUCTOR) { 559 setCurrentMethodTag(tag); 560 } 561 else { 562 setCurrentFieldTag(tag); 563 } 564 565 String m = getTagValue(attributes, forType); 566 567 if (log.isDebugEnabled()) { 568 log.debug((getCurrentMethod() == null) ? "<no current method>" : getCurrentMethod().getName() + " ** Tag/Param = " 569 + attributes.getProperty("tagName") + '/' + attributes.getProperty("paramName") 570 + " ** Value = " + m 571 + " MatchPattern = " + matchPattern); 572 } 573 574 if (matchPattern == null) { 575 generate(template); 576 } 577 else if (matchPattern != null && (matchPattern.equals(m) || m.equals("*"))) { 578 generate(template); 579 } 580 } 581 582 if (forType == FOR_METHOD || forType == FOR_CONSTRUCTOR) { 583 setCurrentMethodTag(null); 584 } 585 else { 586 setCurrentFieldTag(null); 587 } 588 } 589 } 590 591 604 protected String memberComment(Properties attributes, int forType) throws XDocletException 605 { 606 String noCommentSigns = attributes.getProperty("no-comment-signs"); 607 608 XMember member = null; 609 610 switch (forType) { 611 case FOR_FIELD: 612 member = getCurrentField(); 613 break; 614 case FOR_CONSTRUCTOR: 615 member = getCurrentConstructor(); 616 break; 617 case FOR_METHOD: 618 member = getCurrentMethod(); 619 break; 620 default: 621 throw new XDocletException("Bad type " + forType); 622 } 623 624 if (noCommentSigns != null && noCommentSigns.equalsIgnoreCase("true")) { 625 return member.getDoc().getCommentText(); 626 } 627 628 char[] spaces = getIndentChars(attributes); 629 Collection memberTags = member.getDoc().getTags(); 630 631 if (memberTags.size() > 0) { 632 StringBuffer sbuf = new StringBuffer (); 633 634 StringTokenizer st = new StringTokenizer(member.getDoc().getCommentText().trim(), "\n", false); 636 637 if (st.countTokens() > 0) { 638 sbuf.append(spaces).append("/**").append(PrettyPrintWriter.LINE_SEPARATOR); 639 while (st.hasMoreTokens()) { 640 sbuf.append(spaces).append(" * ").append(st.nextToken().trim()).append(PrettyPrintWriter.LINE_SEPARATOR); 641 } 642 643 for (Iterator i = memberTags.iterator(); i.hasNext(); ) { 644 XTag memberTag = (XTag) i.next(); 645 String memberTagName = memberTag.getName(); 647 648 if (memberTagName.indexOf(':') == -1 && memberTagName.indexOf('.') == -1 649 && getDocletContext().getExcludedTags().indexOf(memberTagName) == -1) { 650 sbuf.append(spaces).append(" * ") 651 .append('@').append(memberTag.getName()).append(' ') 652 .append(memberTag.getValue()); 653 654 if (i.hasNext()) { 656 sbuf.append(PrettyPrintWriter.LINE_SEPARATOR); 657 } 658 } 659 } 660 sbuf.append(spaces).append(" */"); 661 } 662 663 return sbuf.toString(); 664 } 665 else { 666 return ""; 667 } 668 } 669 670 677 protected String firstSentenceDescriptionOfCurrentMember(XMember member) throws XDocletException 678 { 679 return member.getDoc().getFirstSentence() != null ? member.getDoc().getFirstSentence() : ""; 680 } 681 682 690 protected void forAllMembers(String template, Properties attributes, int forType) throws XDocletException 691 { 692 boolean superclasses = TypeConversionUtil.stringToBoolean(attributes.getProperty("superclasses"), true); 693 boolean sort = TypeConversionUtil.stringToBoolean(attributes.getProperty("sort"), true); 694 XClass currentClass = getCurrentClass(); 695 696 if (currentClass == null) { 697 throw new XDocletException("currentClass == null!!!"); 698 } 699 700 Collection members = null; 701 702 switch (forType) { 703 case FOR_FIELD: 704 members = currentClass.getFields(superclasses); 705 break; 706 case FOR_CONSTRUCTOR: 707 members = currentClass.getConstructors(); 708 break; 709 case FOR_METHOD: 710 members = currentClass.getMethods(superclasses); 711 break; 712 default: 713 throw new XDocletException("Bad type: " + forType); 714 } 715 716 if (sort) { 717 List sortedMembers = new ArrayList(members); 719 720 members = sortedMembers; 721 } 722 723 for (Iterator j = members.iterator(); j.hasNext(); ) { 724 XMember member = (XMember) j.next(); 725 726 switch (forType) { 727 case FOR_FIELD: 728 setCurrentField((XField) member); 729 break; 730 case FOR_CONSTRUCTOR: 731 setCurrentConstructor((XConstructor) member); 732 break; 733 case FOR_METHOD: 734 setCurrentMethod((XMethod) member); 735 break; 736 default: 737 throw new XDocletException("Bad type: " + forType); 738 } 739 740 setCurrentClass(member.getContainingClass()); 741 generate(template); 742 } 743 setCurrentClass(currentClass); 744 745 } 746 747 753 protected String checkForWrap(String pText) 754 { 755 int lIndex = pText.indexOf(PrettyPrintWriter.LINE_SEPARATOR); 756 757 while (lIndex >= 0) { 758 if (lIndex < pText.length() - 1) { 759 pText = new StringBuffer (pText.substring(0, lIndex).trim()).append(' ').append(pText.substring(lIndex + 1).trim()).toString(); 760 } 761 else { 762 pText = pText.substring(0, lIndex); 763 } 764 765 lIndex = pText.indexOf(PrettyPrintWriter.LINE_SEPARATOR); 766 } 767 768 return pText.trim(); 770 } 771 772 779 private boolean isInAppendExceptionsList(String appendExceptions, String type) 780 { 781 if (appendExceptions == null) { 782 return false; 783 } 784 else { 785 return appendExceptions.indexOf(type) != -1; 786 } 787 } 788 789 796 private boolean isInSkipExceptionsList(String skipExceptions, String type) 797 { 798 if (skipExceptions == null) { 799 return false; 800 } 801 else { 802 return skipExceptions.indexOf(type) != -1; 803 } 804 } 805 806 812 private void appendException(StringBuffer sbuf, String type) 813 { 814 if (sbuf.length() == 0) { 815 sbuf.append("throws ").append(type); 816 } 817 else { 818 sbuf.append(", ").append(type); 819 } 820 } 821 822 831 private XExecutableMember extractXExecutableMember(XClass clazz, String memberName, int forType) throws XDocletException 832 { 833 Collection executableMembers = null; 834 835 switch (forType) { 836 case FOR_CONSTRUCTOR: 837 executableMembers = clazz.getConstructors(); 838 break; 839 case FOR_METHOD: 840 executableMembers = clazz.getMethods(); 841 break; 842 default: 843 throw new XDocletException("Bad type: " + forType); 844 } 845 846 for (Iterator i = executableMembers.iterator(); i.hasNext(); ) { 847 XExecutableMember executableMember = (XExecutableMember) i.next(); 848 849 if (executableMember.getName().equals(memberName)) { 850 return executableMember; 851 } 852 } 853 854 return null; 855 } 856 } 857 | Popular Tags |