1 5 package xdoclet; 6 7 8 import java.util.Properties ; 9 import java.util.StringTokenizer ; 10 11 import org.apache.commons.logging.Log; 12 13 import xjavadoc.*; 14 import xdoclet.template.TemplateEngine; 15 import xdoclet.template.TemplateException; 16 import xdoclet.template.TemplateTagHandler; 17 import xdoclet.util.LogUtil; 18 import xdoclet.util.Translator; 19 import xdoclet.util.TypeConversionUtil; 20 21 28 public abstract class XDocletTagSupport extends TemplateTagHandler 29 { 30 public final static int FOR_CLASS = 0; 31 public final static int FOR_METHOD = 1; 32 public final static int FOR_FIELD = 2; 33 public final static int FOR_CONSTRUCTOR = 3; 34 35 38 protected final static String PARAMETER_DELIMITER = ","; 39 40 43 public static XTag getCurrentMethodTag() 44 { 45 return getDocletContext().getActiveSubTask().getCurrentMethodTag(); 46 } 47 48 51 public static XTag getCurrentClassTag() 52 { 53 return getDocletContext().getActiveSubTask().getCurrentClassTag(); 54 } 55 56 59 public static XTag getCurrentFieldTag() 60 { 61 return getDocletContext().getActiveSubTask().getCurrentFieldTag(); 62 } 63 64 70 public static XMethod getCurrentMethod() 71 { 72 return getDocletContext().getActiveSubTask().getCurrentMethod(); 73 } 74 75 81 public static XField getCurrentField() 82 { 83 return getDocletContext().getActiveSubTask().getCurrentField(); 84 } 85 86 92 public static XConstructor getCurrentConstructor() 93 { 94 return getDocletContext().getActiveSubTask().getCurrentConstructor(); 95 } 96 97 104 public static XClass getCurrentClass() 105 { 106 return getDocletContext().getActiveSubTask().getCurrentClass(); 107 } 108 109 114 public static XPackage getCurrentPackage() 115 { 116 return getDocletContext().getActiveSubTask().getCurrentPackage(); 117 } 118 119 125 public static void setCurrentMethod(XMethod method) 126 { 127 getDocletContext().getActiveSubTask().setCurrentMethod(method); 128 } 129 130 136 public static void setCurrentConstructor(XConstructor constructor) 137 { 138 getDocletContext().getActiveSubTask().setCurrentConstructor(constructor); 139 } 140 141 148 public static void setCurrentClass(XClass clazz) 149 { 150 getDocletContext().getActiveSubTask().setCurrentClass(clazz); 151 } 152 153 159 public static void setCurrentPackage(XPackage pakkage) 160 { 161 getDocletContext().getActiveSubTask().setCurrentPackage(pakkage); 162 } 163 164 169 public static void setCurrentMethodTag(XTag currentTag) 170 { 171 getDocletContext().getActiveSubTask().setCurrentMethodTag(currentTag); 172 } 173 174 179 public static void setCurrentClassTag(XTag currentTag) 180 { 181 getDocletContext().getActiveSubTask().setCurrentClassTag(currentTag); 182 } 183 184 189 public static void setCurrentFieldTag(XTag currentTag) 190 { 191 getDocletContext().getActiveSubTask().setCurrentFieldTag(currentTag); 192 } 193 194 200 public static void setCurrentField(XField field) 201 { 202 getDocletContext().getActiveSubTask().setCurrentField(field); 203 } 204 205 213 public static XClass pushCurrentClass(XClass clazz) 214 { 215 return getDocletContext().getActiveSubTask().pushCurrentClass(clazz); 216 } 217 218 225 public static XClass popCurrentClass() 226 { 227 return getDocletContext().getActiveSubTask().popCurrentClass(); 228 } 229 230 233 protected static DocletContext getDocletContext() 234 { 235 return DocletContext.getInstance(); 236 } 237 238 247 protected static String getExpandedDelimitedTagValue(Properties attributes, int forType) throws XDocletException 248 { 249 String tagValue = getTagValue(attributes, forType); 250 251 tagValue = delimit(tagValue, attributes); 252 tagValue = expandClassName(tagValue, attributes); 253 return tagValue; 254 } 255 256 267 protected static String getTagValue(Properties attributes, int forType) throws XDocletException 268 { 269 String tagName = attributes.getProperty("tagName"); 270 String paramName = attributes.getProperty("paramName"); 271 String validValues = attributes.getProperty("values"); 272 String defaultValue = attributes.getProperty("default"); 273 String paramNum = attributes.getProperty("paramNum"); 274 boolean superclasses = TypeConversionUtil.stringToBoolean(attributes.getProperty("superclasses"), true); 275 boolean mandatory = TypeConversionUtil.stringToBoolean(attributes.getProperty("mandatory"), false); 276 277 290 StringTokenizer tagTokenizer = new StringTokenizer (tagName, ","); 291 StringTokenizer paramTokenizer = new StringTokenizer (paramName != null ? paramName : "", ","); 292 StringTokenizer paramNumTokenizer = new StringTokenizer (paramNum != null ? paramNum : "", ","); 293 294 if (paramTokenizer.countTokens() > tagTokenizer.countTokens()) { 296 throw new XDocletException("paramName can't contain more alternatives than tagName"); 297 } 298 299 String tagValue = null; 301 302 while (tagTokenizer.hasMoreTokens() && tagValue == null) { 303 String currentTag = tagTokenizer.nextToken().trim(); 304 String currentParam = null; 305 306 if (paramTokenizer.hasMoreTokens()) { 307 currentParam = paramTokenizer.nextToken().trim(); 308 if ("".equals(currentParam)) { 309 currentParam = null; 310 } 311 } 312 tagValue = getTagValue( 316 forType, 317 currentTag, 318 currentParam, 319 validValues, 320 defaultValue, 321 superclasses, 322 mandatory 323 ); 324 325 if (tagValue == null && currentParam == null) { 327 String currentParamNumber = null; 328 329 if (paramNumTokenizer.hasMoreTokens()) { 330 currentParamNumber = paramNumTokenizer.nextToken().trim(); 331 } 332 333 335 if (currentParamNumber != null) { 336 XProgramElement programElement = getProgramElement(forType); 337 XDoc doc = programElement.getDoc(); 338 XTag tag = doc.getTag(currentTag, superclasses); 339 340 if (tag != null) { 341 tagValue = tag.getValue(); 342 } 343 if (tagValue != null && tagValue.trim().length() == 0) { 344 tagValue = null; 345 } 346 } 347 } 348 350 if (tagValue != null && tagValue.startsWith("\"")) { 351 tagValue = tagValue.substring(1, tagValue.length() - 1); 352 } 353 354 } 355 356 return tagValue; 358 } 359 360 373 protected static String getTagValue( 374 int forType, 375 String tagName, 376 String paramName, 377 String validValues, 378 String defaultValue, 379 boolean superclasses, 380 boolean mandatory 381 ) throws XDocletException 382 { 383 384 XProgramElement programElement = getProgramElement(forType); 385 386 if (programElement == null) { 387 return null; 388 } 389 390 XDoc doc = programElement.getDoc(); 391 392 return getTagValue( 393 forType, 394 doc, 395 tagName, 396 paramName, 397 validValues, 398 defaultValue, 399 superclasses, 400 mandatory 401 ); 402 } 403 404 417 protected static String getTagValue( 418 int forType, 419 XDoc doc, 420 String tagName, 421 String paramName, 422 String validValues, 423 String defaultValue, 424 boolean superclasses, 425 boolean mandatory) throws XDocletException 426 { 427 XTag tag = null; 428 429 if (forType == FOR_METHOD || forType == FOR_CONSTRUCTOR) 431 tag = getCurrentMethodTag(); 432 else if (forType == FOR_CLASS) 433 tag = getCurrentClassTag(); 434 else if (forType == FOR_FIELD) 435 tag = getCurrentFieldTag(); 436 437 boolean noCurrentTag = tag == null; 438 439 if (tag != null && !tag.getName().equals(XDoc.dotted(tagName))) 440 tag = null; 441 442 if (tag == null) { 443 tag = doc.getTag(tagName, superclasses); 445 } 446 447 String value = null; 448 449 if (tag != null) { 451 if (paramName == null) { 452 value = tag.getValue(); 454 } 455 else { 456 value = tag.getAttributeValue(paramName); 457 } 458 } 459 460 if (noCurrentTag && value == null && paramName != null && superclasses) { 464 value = doc.getTagAttributeValue(tagName, paramName, superclasses); 465 } 466 467 if (value == null) { 468 if (mandatory) { 470 mandatoryParamNotFound(doc, paramName, tagName); 472 } 473 if (defaultValue != null) { 474 return defaultValue; 475 } 476 else { 477 return null; 478 } 479 } 480 else { 481 if (validValues != null) { 483 StringTokenizer st = new StringTokenizer (validValues, ","); 485 486 while (st.hasMoreTokens()) { 487 if (st.nextToken().equals(value)) { 488 return value; 489 } 490 } 491 invalidParamValueFound(doc, paramName, tagName, value, validValues); 492 } 493 } 494 return value; 495 } 496 497 506 protected static boolean isTagValueEqual(Properties attributes, int forType) throws XDocletException 507 { 508 String value = attributes.getProperty("value"); 510 511 if (value == null) { 512 throw new XDocletException("The value property is not specified"); 513 } 514 515 String attributeValue = null; 516 517 String tagName = attributes.getProperty("tagName"); 521 String paramName = attributes.getProperty("paramName"); 522 523 XTag currentTag = null; 524 525 if (forType == FOR_METHOD || forType == FOR_CONSTRUCTOR) 526 currentTag = getCurrentMethodTag(); 527 else if (forType == FOR_CLASS) 528 currentTag = getCurrentClassTag(); 529 else if (forType == FOR_FIELD) 530 currentTag = getCurrentFieldTag(); 531 532 if (currentTag != null && currentTag.getName().equals(XDoc.dotted(tagName))) { 533 attributeValue = currentTag.getAttributeValue(paramName); 534 } 535 else { 536 attributeValue = getTagValue(attributes, forType); 537 } 538 attributeValue = delimit(attributeValue, attributes); 539 540 return value.equals(attributeValue); 541 } 542 543 protected static String expandClassName(String value, Properties attributes) 544 { 545 boolean expand = TypeConversionUtil.stringToBoolean(attributes.getProperty("expandClassName"), false); 546 547 if (expand) { 548 value = getCurrentClass().qualify(value).getQualifiedName(); 549 } 550 return value; 552 } 553 554 563 protected static void mandatoryParamNotFound(XDoc doc, String paramName, String tagName) throws XDocletException 564 { 565 XProgramElement programElement = doc.getOwner(); 566 567 if (programElement instanceof XMethod) { 568 XMethod method = (XMethod) programElement; 569 570 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.MANDATORY_TAG_PARAM_MISSING_METHOD, 571 new String []{paramName, tagName, method.getName(), method.getContainingClass().getQualifiedName()})); 572 } 573 else if (programElement instanceof XClass) { 574 XClass clazz = (XClass) programElement; 575 576 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.MANDATORY_TAG_PARAM_MISSING_CLASS, 577 new String []{paramName, tagName, clazz.getQualifiedName()})); 578 } 579 else if (programElement instanceof XConstructor) { 580 XConstructor constructor = (XConstructor) programElement; 581 582 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.MANDATORY_TAG_PARAM_MISSING_CONSTRUCTOR, 583 new String []{paramName, tagName, constructor.getContainingClass().getQualifiedName()})); 584 } 585 else if (programElement instanceof XField) { 586 XField field = (XField) programElement; 587 588 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.MANDATORY_TAG_PARAM_MISSING_FIELD, 589 new String []{paramName, tagName, field.getName(), field.getContainingClass().getQualifiedName()})); 590 } 591 else { 592 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.BAD_PRGELEMDOC_TYPE, 593 new String []{programElement.toString()})); 594 } 595 } 596 597 606 protected static boolean hasTag(Properties attributes, int forType) throws XDocletException 607 { 608 return getTagValue(attributes, forType) != null; 609 } 610 611 617 protected static String delimit(String attributeValue, Properties attributes) 618 { 619 String delim = attributes.getProperty("delimiter"); 621 String tokenNumberStr = attributes.getProperty("tokenNumber"); 622 int tokenNumber = 0; 623 624 if (tokenNumberStr != null) { 625 tokenNumber = Integer.parseInt(tokenNumberStr); 626 } 627 if (delim != null) { 628 if (delim.equals("()") && attributeValue.indexOf(delim) != -1) { 629 attributeValue = null; 630 } 631 else { 632 StringTokenizer st = new StringTokenizer (attributeValue, delim); 633 String tok = null; 634 635 for (int i = 0; i <= tokenNumber; i++) { 636 if (st.hasMoreTokens()) { 637 tok = st.nextToken(); 638 } 639 else { 640 tok = null; 641 } 642 } 643 attributeValue = tok; 644 } 645 } 646 return attributeValue; 647 } 648 649 656 private static XProgramElement getProgramElement(int forType) throws XDocletException 657 { 658 XProgramElement programElement = null; 659 660 switch (forType) { 661 case FOR_CLASS: 662 programElement = getCurrentClass(); 663 break; 664 case FOR_METHOD: 665 programElement = getCurrentMethod(); 666 break; 667 case FOR_CONSTRUCTOR: 668 programElement = getCurrentConstructor(); 669 break; 670 case FOR_FIELD: 671 programElement = getCurrentField(); 672 break; 673 default: 674 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.BAD_TAGVALUE_TYPE)); 675 } 676 return programElement; 677 } 678 679 690 private static void invalidParamValueFound(XDoc doc, String paramName, String tagName, String value, String validValues) throws XDocletException 691 { 692 XProgramElement programElement = doc.getOwner(); 693 694 if (programElement instanceof XMethod) { 695 XMethod method = (XMethod) programElement; 696 697 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.INVALID_TAG_PARAM_VALUE_METHOD, 698 new String []{value, paramName, tagName, method.getName(), method.getContainingClass().getQualifiedName(), validValues})); 699 } 700 else if (programElement instanceof XClass) { 701 XClass clazz = (XClass) programElement; 702 703 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.INVALID_TAG_PARAM_VALUE_CLASS, 704 new String []{value, paramName, tagName, clazz.getQualifiedName(), validValues})); 705 } 706 else if (programElement instanceof XConstructor) { 707 XConstructor constructor = (XConstructor) programElement; 708 709 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.INVALID_TAG_PARAM_VALUE_CONSTRUCTOR, 710 new String []{value, paramName, tagName, constructor.getContainingClass().getQualifiedName(), validValues})); 711 } 712 else if (programElement instanceof XField) { 713 XField field = (XField) programElement; 714 715 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.INVALID_TAG_PARAM_VALUE_FIELD, 716 new String []{value, paramName, tagName, field.getName(), field.getContainingClass().getQualifiedName(), validValues})); 717 } 718 else { 719 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.INVALID_TAG_PARAM_VALUE_METHOD, 720 new String []{programElement.toString()})); 721 } 722 } 723 724 729 public TemplateEngine getEngine() 730 { 731 return ((TemplateSubTask) getDocletContext().getActiveSubTask()).getEngine(); 732 } 733 734 739 public void generate(String template) throws XDocletException 740 { 741 try { 742 getEngine().generate(template); 743 } 744 catch (TemplateException e) { 745 if (e instanceof XDocletException) { 746 throw (XDocletException) e; 747 } 748 else { 749 750 throw new XDocletException(e, Translator.getString(XDocletMessages.class, XDocletMessages.RUNNING_FAILED) + ": " + e.toString()); 751 } 752 } 753 } 754 755 762 protected String modifiers(int forType) throws XDocletException 763 { 764 return getProgramElement(forType).getModifiers(); 765 } 766 767 775 protected void mandatoryTemplateTagParamNotFound(String templateTagName, String paramName) throws XDocletException 776 { 777 throw new XDocletException(Translator.getString(XDocletMessages.class, XDocletMessages.MANDATORY_TAG_PARAM_MISSING_TEMPLATE, 778 new String []{paramName, templateTagName})); 779 } 780 781 790 protected boolean hasHavingClassTag(XClass clazz) 791 { 792 Log log = LogUtil.getLog(getClass(), "hasHavingClassTag"); 793 794 DocletContext ctx = getDocletContext(); 795 SubTask task = ctx.getActiveSubTask(); 796 797 if (!(task instanceof TemplateSubTask)) { 798 return true; 799 } 800 801 TemplateSubTask templTask = (TemplateSubTask) task; 802 803 if (templTask.getHavingClassTag() == null) { 804 return true; 805 } 806 807 if (!clazz.getDoc().hasTag(templTask.getHavingClassTag(), false)) { 808 if (log.isDebugEnabled()) { 809 log.debug("Reject class '" + clazz.getQualifiedName() + "' because it doesn't have class tag '" + templTask.getHavingClassTag() + "'."); 810 } 811 return false; 812 } 813 else { 814 if (log.isDebugEnabled()) { 815 log.debug("Accept class '" + clazz.getQualifiedName() + "' because it has class tag '" + templTask.getHavingClassTag() + "'."); 816 } 817 return true; 818 } 819 } 820 } 821 | Popular Tags |