1 /* 2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.javadoc.internal.doclets.toolkit; 27 28 import java.io.ByteArrayOutputStream; 29 import java.io.IOException; 30 import java.io.OutputStream; 31 import java.io.OutputStreamWriter; 32 import java.io.UnsupportedEncodingException; 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.HashSet; 36 import java.util.LinkedHashSet; 37 import java.util.List; 38 import java.util.MissingResourceException; 39 import java.util.Set; 40 import java.util.StringTokenizer; 41 import java.util.TreeSet; 42 43 import jdk.javadoc.doclet.Doclet; 44 import jdk.javadoc.doclet.Reporter; 45 import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 46 import jdk.javadoc.internal.doclets.toolkit.util.Utils; 47 48 import static javax.tools.Diagnostic.Kind.ERROR; 49 50 /** 51 * Storage for the format-independent options supported by the toolkit. 52 * The objects to handle command-line options, and to initialize this 53 * object, are all subtypes of {@link BaseOptions.Option}, 54 * returned by {@link BaseOptions#getSupportedOptions()}. 55 * 56 * <p>Some of the methods used to access the values of options 57 * have names that begin with a verb, such as {@link #copyDocfileSubdirs} 58 * or {@link #showVersion}. Unless otherwise stated, 59 * these methods should all be taken as just accessing the value 60 * of the associated option. 61 */ 62 public abstract class BaseOptions { 63 64 //<editor-fold desc="Option values"> 65 66 /** 67 * Argument for command-line option {@code --allow-script-in-comments}. 68 * Allow JavaScript in doc comments. 69 */ 70 private boolean allowScriptInComments = false; 71 72 /** 73 * Argument for command-line option {@code -docfilessubdirs}. 74 * True if we should recursively copy the doc-file subdirectories 75 */ 76 private boolean copyDocfileSubdirs = false; 77 78 /** 79 * Arguments for command-line option {@code -tag} and {@code -taglet}. 80 */ 81 private final LinkedHashSet<List<String>> customTagStrs = new LinkedHashSet<>(); 82 83 /** 84 * Argument for command-line option {@code -d}. 85 * Destination directory name, in which doclet will generate the entire 86 * documentation. Default is current directory. 87 */ 88 private String destDirName = ""; 89 90 /** 91 * Argument for command-line option {@code --disable-javafx-strict-checks}. 92 * Primarily used to disable strict checks in the regression 93 * tests allowing those tests to be executed successfully, for 94 * instance, with OpenJDK builds which may not contain FX libraries. 95 */ 96 private boolean disableJavaFxStrictChecks = false; 97 98 /** 99 * Argument for command-line option {@code -docencoding}. 100 * Encoding for this document. Default is default encoding for this 101 * platform. 102 */ 103 private String docEncoding = null; 104 105 /** 106 * Argument for command-line option {@code ???}. 107 * Destination directory name, in which doclet will copy the doc-files to. 108 */ 109 private String docFileDestDirName = ""; 110 111 /** 112 * Argument for hidden command-line option {@code --dump-on-error}. 113 */ 114 private boolean dumpOnError = false; 115 116 /** 117 * Argument for command-line option {@code -encoding}. 118 * Encoding for this document. Default is default encoding for this 119 * platform. 120 */ 121 private String encoding = null; 122 123 /** 124 * Argument for command-line option {@code -excludedocfilessubdir}. 125 * The set of doc-file subdirectories to exclude. 126 */ 127 private Set<String> excludedDocFileDirs; 128 129 /** 130 * Argument for command-line option {@code -noqualifier}. 131 * The set of qualifiers to exclude. 132 */ 133 private Set<String> excludedQualifiers; 134 135 /** 136 * Arguments for command-line option {@code -group} 137 */ 138 private List<Utils.Pair<String, String>> groupPairs; 139 140 /** 141 * Argument for command-line option {@code --javafx} or {@code -javafx}. 142 * Generate documentation for JavaFX getters and setters automatically 143 * by copying it from the appropriate property definition. 144 */ 145 private boolean javafx = false; 146 147 /** 148 * Argument for command-line option {@code -keywords}. 149 * True if user wants to add member names as meta keywords. 150 * Set to false because meta keywords are ignored in general 151 * by most Internet search engines. 152 */ 153 private boolean keywords = false; 154 155 /** 156 * Arguments for command-line option {@code -link}. 157 */ 158 // A list containing urls 159 private final List<String> linkList = new ArrayList<>(); 160 161 /** 162 * Arguments for command-line option {@code -linkoffline}. 163 */ 164 // A list of pairs containing urls and package list 165 private final List<Utils.Pair<String, String>> linkOfflineList = new ArrayList<>(); 166 167 /** 168 * Argument for command-line option {@code -linksource}. 169 * True if we should generate browsable sources. 170 */ 171 private boolean linkSource = false; 172 173 /** 174 * Argument for command-line option {@code -nocomment}. 175 * True if user wants to suppress descriptions and tags. 176 */ 177 private boolean noComment = false; 178 179 /** 180 * Argument for command-line option {@code -nodeprecated}. 181 * Don't generate deprecated API information at all, if -nodeprecated 182 * option is used. <code>nodeprecated</code> is set to true if 183 * -nodeprecated option is used. Default is generate deprecated API 184 * information. 185 */ 186 private boolean noDeprecated = false; 187 188 /** 189 * Argument for command-line option {@code -nosince}. 190 * True if command-line option "-nosince" is used. Default value is 191 * false. 192 */ 193 private boolean noSince = false; 194 195 /** 196 * Argument for command-line option {@code -notimestamp}. 197 * True if user wants to suppress time stamp in output. 198 * Default is false. 199 */ 200 private boolean noTimestamp = false; 201 202 /** 203 * Argument for command-line option {@code -quiet}. 204 * Suppress all messages 205 */ 206 private boolean quiet = false; 207 208 /** 209 * Argument for command-line option {@code -serialwarn}. 210 * This is true if option "-serialwarn" is used. Default value is false to 211 * suppress excessive warnings about serial tag. 212 */ 213 private boolean serialWarn = false; 214 215 /** 216 * Argument for command-line option {@code -author}. 217 * Generate author specific information for all the classes if @author 218 * tag is used in the doc comment and if -author option is used. 219 * <code>showauthor</code> is set to true if -author option is used. 220 * Default is don't show author information. 221 */ 222 private boolean showAuthor = false; 223 224 /** 225 * Argument for command-line option {@code --show-taglets}. 226 * Show taglets (internal debug switch) 227 */ 228 private boolean showTaglets = false; 229 230 /** 231 * Argument for command-line option {@code -version}. 232 * Generate version specific information for the all the classes 233 * if @version tag is used in the doc comment and if -version option is 234 * used. {@code showVersion} is set to true if -version option is 235 * used. Default is don't show version information. 236 */ 237 private boolean showVersion = false; 238 239 /** 240 * Argument for command-line option {@code -sourcetab}. 241 * The specified amount of space between tab stops. 242 */ 243 private int sourceTabSize; 244 245 /** 246 * Value for command-line option {@code --override-methods summary} 247 * or {@code --override-methods detail}. 248 * Specifies whether those methods that override a super-type's method 249 * with no changes to the API contract should be summarized in the 250 * footnote section. 251 */ 252 private boolean summarizeOverriddenMethods = false; 253 254 /** 255 * Argument for command-line option {@code -tagletpath}. 256 * The path to Taglets 257 */ 258 private String tagletPath = null; 259 260 //</editor-fold> 261 262 private final BaseConfiguration config; 263 BaseOptions(BaseConfiguration config)264 protected BaseOptions(BaseConfiguration config) { 265 this.config = config; 266 267 excludedDocFileDirs = new HashSet<>(); 268 excludedQualifiers = new HashSet<>(); 269 sourceTabSize = DocletConstants.DEFAULT_TAB_STOP_LENGTH; 270 groupPairs = new ArrayList<>(0); 271 } 272 getSupportedOptions()273 public Set<? extends Option> getSupportedOptions() { 274 Resources resources = config.getDocResources(); 275 Messages messages = config.getMessages(); 276 Reporter reporter = config.getReporter(); 277 278 List<Option> options = List.of( 279 new Option(resources, "-author") { 280 @Override 281 public boolean process(String opt, List<String> args) { 282 showAuthor = true; 283 return true; 284 } 285 }, 286 287 new Option(resources, "-d", 1) { 288 @Override 289 public boolean process(String opt, List<String> args) { 290 destDirName = addTrailingFileSep(args.get(0)); 291 return true; 292 } 293 }, 294 295 new Option(resources, "-docencoding", 1) { 296 @Override 297 public boolean process(String opt, List<String> args) { 298 docEncoding = args.get(0); 299 return true; 300 } 301 }, 302 303 new Option(resources, "-docfilessubdirs") { 304 @Override 305 public boolean process(String opt, List<String> args) { 306 copyDocfileSubdirs = true; 307 return true; 308 } 309 }, 310 311 new Hidden(resources, "-encoding", 1) { 312 @Override 313 public boolean process(String opt, List<String> args) { 314 encoding = args.get(0); 315 return true; 316 } 317 }, 318 319 new Option(resources, "-excludedocfilessubdir", 1) { 320 @Override 321 public boolean process(String opt, List<String> args) { 322 addToSet(excludedDocFileDirs, args.get(0)); 323 return true; 324 } 325 }, 326 327 new Option(resources, "-group", 2) { 328 @Override 329 public boolean process(String opt, List<String> args) { 330 groupPairs.add(new Utils.Pair<>(args.get(0), args.get(1))); 331 return true; 332 } 333 }, 334 335 new Option(resources, "--javafx -javafx") { 336 @Override 337 public boolean process(String opt, List<String> args) { 338 javafx = true; 339 return true; 340 } 341 }, 342 343 new Option(resources, "-keywords") { 344 @Override 345 public boolean process(String opt, List<String> args) { 346 keywords = true; 347 return true; 348 } 349 }, 350 351 new Option(resources, "-link", 1) { 352 @Override 353 public boolean process(String opt, List<String> args) { 354 linkList.add(args.get(0)); 355 return true; 356 } 357 }, 358 359 new Option(resources, "-linksource") { 360 @Override 361 public boolean process(String opt, List<String> args) { 362 linkSource = true; 363 return true; 364 } 365 }, 366 367 new Option(resources, "-linkoffline", 2) { 368 @Override 369 public boolean process(String opt, List<String> args) { 370 linkOfflineList.add(new Utils.Pair<>(args.get(0), args.get(1))); 371 return true; 372 } 373 }, 374 new Option(resources, "-nocomment") { 375 @Override 376 public boolean process(String opt, List<String> args) { 377 noComment = true; 378 return true; 379 } 380 }, 381 382 new Option(resources, "-nodeprecated") { 383 @Override 384 public boolean process(String opt, List<String> args) { 385 noDeprecated = true; 386 return true; 387 } 388 }, 389 390 new Option(resources, "-nosince") { 391 @Override 392 public boolean process(String opt, List<String> args) { 393 noSince = true; 394 return true; 395 } 396 }, 397 398 new Option(resources, "-notimestamp") { 399 @Override 400 public boolean process(String opt, List<String> args) { 401 noTimestamp = true; 402 return true; 403 } 404 }, 405 406 new Option(resources, "-noqualifier", 1) { 407 @Override 408 public boolean process(String opt, List<String> args) { 409 addToSet(excludedQualifiers, args.get(0)); 410 return true; 411 } 412 }, 413 414 new Option(resources, "--override-methods", 1) { 415 @Override 416 public boolean process(String opt, List<String> args) { 417 String o = args.get(0); 418 switch (o) { 419 case "summary": 420 summarizeOverriddenMethods = true; 421 break; 422 case "detail": 423 summarizeOverriddenMethods = false; 424 break; 425 default: 426 reporter.print(ERROR, 427 resources.getText("doclet.Option_invalid",o, "--override-methods")); 428 return false; 429 } 430 return true; 431 } 432 }, 433 434 new Hidden(resources, "-quiet") { 435 @Override 436 public boolean process(String opt, List<String> args) { 437 quiet = true; 438 return true; 439 } 440 }, 441 442 new Option(resources, "-serialwarn") { 443 @Override 444 public boolean process(String opt, List<String> args) { 445 serialWarn = true; 446 return true; 447 } 448 }, 449 450 new Option(resources, "-sourcetab", 1) { 451 @Override 452 public boolean process(String opt, List<String> args) { 453 linkSource = true; 454 try { 455 sourceTabSize = Integer.parseInt(args.get(0)); 456 } catch (NumberFormatException e) { 457 //Set to -1 so that warning will be printed 458 //to indicate what is valid argument. 459 sourceTabSize = -1; 460 } 461 if (sourceTabSize <= 0) { 462 messages.warning("doclet.sourcetab_warning"); 463 sourceTabSize = DocletConstants.DEFAULT_TAB_STOP_LENGTH; 464 } 465 return true; 466 } 467 }, 468 469 new Option(resources, "-tag", 1) { 470 @Override 471 public boolean process(String opt, List<String> args) { 472 ArrayList<String> list = new ArrayList<>(); 473 list.add(opt); 474 list.add(args.get(0)); 475 customTagStrs.add(list); 476 return true; 477 } 478 }, 479 480 new Option(resources, "-taglet", 1) { 481 @Override 482 public boolean process(String opt, List<String> args) { 483 ArrayList<String> list = new ArrayList<>(); 484 list.add(opt); 485 list.add(args.get(0)); 486 customTagStrs.add(list); 487 return true; 488 } 489 }, 490 491 new Option(resources, "-tagletpath", 1) { 492 @Override 493 public boolean process(String opt, List<String> args) { 494 tagletPath = args.get(0); 495 return true; 496 } 497 }, 498 499 new Option(resources, "-version") { 500 @Override 501 public boolean process(String opt, List<String> args) { 502 showVersion = true; 503 return true; 504 } 505 }, 506 507 new Hidden(resources, "--dump-on-error") { 508 @Override 509 public boolean process(String opt, List<String> args) { 510 dumpOnError = true; 511 return true; 512 } 513 }, 514 515 new Option(resources, "--allow-script-in-comments") { 516 @Override 517 public boolean process(String opt, List<String> args) { 518 allowScriptInComments = true; 519 return true; 520 } 521 }, 522 523 new Hidden(resources, "--disable-javafx-strict-checks") { 524 @Override 525 public boolean process(String opt, List<String> args) { 526 disableJavaFxStrictChecks = true; 527 return true; 528 } 529 }, 530 531 new Hidden(resources, "--show-taglets") { 532 @Override 533 public boolean process(String opt, List<String> args) { 534 showTaglets = true; 535 return true; 536 } 537 } 538 ); 539 return new TreeSet<>(options); 540 } 541 542 /** 543 * This checks for the validity of the options used by the user. 544 * As of this writing, this checks only docencoding. 545 * 546 * @return true if all the options are valid. 547 */ generalValidOptions()548 protected boolean generalValidOptions() { 549 if (docEncoding != null) { 550 if (!checkOutputFileEncoding(docEncoding)) { 551 return false; 552 } 553 } 554 if (docEncoding == null && (encoding != null && !encoding.isEmpty())) { 555 if (!checkOutputFileEncoding(encoding)) { 556 return false; 557 } 558 } 559 return true; 560 } 561 562 /** 563 * Check the validity of the given Source or Output File encoding on this 564 * platform. 565 * 566 * @param docencoding output file encoding. 567 */ checkOutputFileEncoding(String docencoding)568 private boolean checkOutputFileEncoding(String docencoding) { 569 OutputStream ost = new ByteArrayOutputStream(); 570 OutputStreamWriter osw = null; 571 try { 572 osw = new OutputStreamWriter(ost, docencoding); 573 } catch (UnsupportedEncodingException exc) { 574 config.reporter.print(ERROR, 575 config.getDocResources().getText("doclet.Encoding_not_supported", docencoding)); 576 return false; 577 } finally { 578 try { 579 if (osw != null) { 580 osw.close(); 581 } 582 } catch (IOException exc) { 583 } 584 } 585 return true; 586 } 587 addToSet(Set<String> s, String str)588 private void addToSet(Set<String> s, String str) { 589 StringTokenizer st = new StringTokenizer(str, ":"); 590 String current; 591 while (st.hasMoreTokens()) { 592 current = st.nextToken(); 593 s.add(current); 594 } 595 } 596 597 /** 598 * Add a trailing file separator, if not found. Remove superfluous 599 * file separators if any. Preserve the front double file separator for 600 * UNC paths. 601 * 602 * @param path Path under consideration. 603 * @return String Properly constructed path string. 604 */ addTrailingFileSep(String path)605 protected static String addTrailingFileSep(String path) { 606 String fs = System.getProperty("file.separator"); 607 String dblfs = fs + fs; 608 int indexDblfs; 609 while ((indexDblfs = path.indexOf(dblfs, 1)) >= 0) { 610 path = path.substring(0, indexDblfs) + 611 path.substring(indexDblfs + fs.length()); 612 } 613 if (!path.endsWith(fs)) 614 path += fs; 615 return path; 616 } 617 618 /** 619 * Argument for command-line option {@code --allow-script-in-comments}. 620 * Allow JavaScript in doc comments. 621 */ allowScriptInComments()622 boolean allowScriptInComments() { 623 return allowScriptInComments; 624 } 625 626 /** 627 * Argument for command-line option {@code -docfilessubdirs}. 628 * True if we should recursively copy the doc-file subdirectories 629 */ copyDocfileSubdirs()630 public boolean copyDocfileSubdirs() { 631 return copyDocfileSubdirs; 632 } 633 634 /** 635 * Arguments for command-line option {@code -tag} and {@code -taglet}. 636 */ customTagStrs()637 LinkedHashSet<List<String>> customTagStrs() { 638 return customTagStrs; 639 } 640 641 /** 642 * Argument for command-line option {@code -d}. 643 * Destination directory name, in which doclet will generate the entire 644 * documentation. Default is current directory. 645 */ destDirName()646 String destDirName() { 647 return destDirName; 648 } 649 650 /** 651 * Argument for command-line option {@code --disable-javafx-strict-checks}. 652 * Primarily used to disable strict checks in the regression 653 * tests allowing those tests to be executed successfully, for 654 * instance, with OpenJDK builds which may not contain FX libraries. 655 */ disableJavaFxStrictChecks()656 boolean disableJavaFxStrictChecks() { 657 return disableJavaFxStrictChecks; 658 } 659 660 /** 661 * Argument for command-line option {@code -docencoding}. 662 * Encoding for this document. Default is default encoding for this 663 * platform. 664 */ docEncoding()665 public String docEncoding() { 666 return docEncoding; 667 } 668 setDocEncoding(String docEncoding)669 public void setDocEncoding(String docEncoding) { 670 this.docEncoding = docEncoding; 671 } 672 673 674 /** 675 * Argument for command-line option {@code ???}. 676 * Destination directory name, in which doclet will copy the doc-files to. 677 */ docFileDestDirName()678 String docFileDestDirName() { 679 return docFileDestDirName; 680 } 681 682 /** 683 * Argument for hidden command-line option {@code --dump-on-error}. 684 */ dumpOnError()685 boolean dumpOnError() { 686 return dumpOnError; 687 } 688 689 /** 690 * Argument for command-line option {@code -encoding}. 691 * Encoding for this document. Default is default encoding for this 692 * platform. 693 */ encoding()694 public String encoding() { 695 return encoding; 696 } 697 698 /** 699 * Argument for command-line option {@code -excludedocfilessubdir}. 700 * The set of doc-file subdirectories to exclude. 701 */ excludedDocFileDirs()702 Set<String> excludedDocFileDirs() { 703 return excludedDocFileDirs; 704 } 705 706 /** 707 * Argument for command-line option {@code -noqualifier}. 708 * The set of qualifiers to exclude. 709 */ excludedQualifiers()710 Set<String> excludedQualifiers() { 711 return excludedQualifiers; 712 } 713 714 /** 715 * Arguments for command-line option {@code -group} 716 */ groupPairs()717 List<Utils.Pair<String, String>> groupPairs() { 718 return groupPairs; 719 } 720 721 /** 722 * Argument for command-line option {@code --javafx} or {@code -javafx}. 723 * Generate documentation for JavaFX getters and setters automatically 724 * by copying it from the appropriate property definition. 725 */ javafx()726 public boolean javafx() { 727 return javafx; 728 } 729 setJavaFX(boolean javafx)730 public void setJavaFX(boolean javafx) { 731 this.javafx = javafx; 732 } 733 734 /** 735 * Argument for command-line option {@code -keywords}. 736 * True if user wants to add member names as meta keywords. 737 * Set to false because meta keywords are ignored in general 738 * by most Internet search engines. 739 */ keywords()740 public boolean keywords() { 741 return keywords; 742 } 743 744 /** 745 * Arguments for command-line option {@code -link}. 746 */ linkList()747 List<String> linkList() { 748 return linkList; 749 } 750 751 /** 752 * Arguments for command-line option {@code -linkoffline}. 753 */ linkOfflineList()754 List<Utils.Pair<String, String>> linkOfflineList() { 755 return linkOfflineList; 756 } 757 758 /** 759 * Argument for command-line option {@code -linksource}. 760 * True if we should generate browsable sources. 761 */ linkSource()762 public boolean linkSource() { 763 return linkSource; 764 } 765 766 /** 767 * Argument for command-line option {@code -nocomment}. 768 * True if user wants to suppress descriptions and tags. 769 */ noComment()770 public boolean noComment() { 771 return noComment; 772 } 773 774 /** 775 * Argument for command-line option {@code -nodeprecated}. 776 * Don't generate deprecated API information at all if -nodeprecated 777 * option is used. {@code noDeprecated} is set to {@code true} if 778 * {@code -nodeprecated} option is used. 779 * Default is generate deprecated API information. 780 */ noDeprecated()781 public boolean noDeprecated() { 782 return noDeprecated; 783 } 784 785 /** 786 * Argument for command-line option {@code -nosince}. 787 * True if command-line option {@code -nosince"} is used. 788 * Default value is false. 789 */ noSince()790 public boolean noSince() { 791 return noSince; 792 } 793 794 /** 795 * Argument for command-line option {@code -notimestamp}. 796 * True if user wants to suppress time stamp in output. 797 * Default is false. 798 */ noTimestamp()799 public boolean noTimestamp() { 800 return noTimestamp; 801 } 802 803 /** 804 * Argument for command-line option {@code -quiet}. 805 * Suppress all messages 806 */ quiet()807 boolean quiet() { 808 return quiet; 809 } 810 811 /** 812 * Argument for command-line option {@code -serialwarn}. 813 * This is true if option "-serialwarn" is used. Default value is false to 814 * suppress excessive warnings about serial tag. 815 */ serialWarn()816 public boolean serialWarn() { 817 return serialWarn; 818 } 819 820 /** 821 * Argument for command-line option {@code -author}. 822 * Generate author specific information for all the classes if @author 823 * tag is used in the doc comment and if -author option is used. 824 * <code>showauthor</code> is set to true if -author option is used. 825 * Default is don't show author information. 826 */ showAuthor()827 public boolean showAuthor() { 828 return showAuthor; 829 } 830 831 /** 832 * Argument for command-line option {@code --show-taglets}. 833 * Show taglets (internal debug switch) 834 */ showTaglets()835 public boolean showTaglets() { 836 return showTaglets; 837 } 838 839 /** 840 * Argument for command-line option {@code -version}. 841 * Generate version specific information for the all the classes 842 * if @version tag is used in the doc comment and if -version option is 843 * used. {@code showVersion} is set to true if -version option is 844 * used. Default is don't show version information. 845 */ showVersion()846 public boolean showVersion() { 847 return showVersion; 848 } 849 850 /** 851 * Argument for command-line option {@code -sourcetab}. 852 * The specified amount of space between tab stops. 853 */ sourceTabSize()854 public int sourceTabSize() { 855 return sourceTabSize; 856 } 857 858 /** 859 * Value for command-line option {@code --override-methods summary} 860 * or {@code --override-methods detail}. 861 * Specifies whether those methods that override a super-type's method 862 * with no changes to the API contract should be summarized in the 863 * footnote section. 864 */ summarizeOverriddenMethods()865 public boolean summarizeOverriddenMethods() { 866 return summarizeOverriddenMethods; 867 } 868 869 /** 870 * Argument for command-line option {@code -tagletpath}. 871 * The path to Taglets 872 */ tagletPath()873 public String tagletPath() { 874 return tagletPath; 875 } 876 877 protected abstract static class Option implements Doclet.Option, Comparable<Option> { 878 private final String[] names; 879 private final String parameters; 880 private final String description; 881 private final int argCount; 882 Option(Resources resources, String name, int argCount)883 protected Option(Resources resources, String name, int argCount) { 884 this(resources, null, name, argCount); 885 } 886 Option(Resources resources, String keyBase, String name, int argCount)887 protected Option(Resources resources, String keyBase, String name, int argCount) { 888 this.names = name.trim().split("\\s+"); 889 if (keyBase == null) { 890 keyBase = "doclet.usage." + names[0].toLowerCase().replaceAll("^-+", ""); 891 } 892 String desc = getOptionsMessage(resources, keyBase + ".description"); 893 if (desc.isEmpty()) { 894 this.description = "<MISSING KEY>"; 895 this.parameters = "<MISSING KEY>"; 896 } else { 897 this.description = desc; 898 this.parameters = getOptionsMessage(resources, keyBase + ".parameters"); 899 } 900 this.argCount = argCount; 901 } 902 Option(Resources resources, String name)903 protected Option(Resources resources, String name) { 904 this(resources, name, 0); 905 } 906 getOptionsMessage(Resources resources, String key)907 private String getOptionsMessage(Resources resources, String key) { 908 try { 909 return resources.getText(key); 910 } catch (MissingResourceException ignore) { 911 return ""; 912 } 913 } 914 915 @Override getDescription()916 public String getDescription() { 917 return description; 918 } 919 920 @Override getKind()921 public Kind getKind() { 922 return Kind.STANDARD; 923 } 924 925 @Override getNames()926 public List<String> getNames() { 927 return Arrays.asList(names); 928 } 929 930 @Override getParameters()931 public String getParameters() { 932 return parameters; 933 } 934 935 @Override toString()936 public String toString() { 937 return Arrays.toString(names); 938 } 939 940 @Override getArgumentCount()941 public int getArgumentCount() { 942 return argCount; 943 } 944 matches(String option)945 public boolean matches(String option) { 946 for (String name : names) { 947 boolean matchCase = name.startsWith("--"); 948 if (option.startsWith("--") && option.contains("=")) { 949 return name.equals(option.substring(option.indexOf("=") + 1)); 950 } else if (matchCase) { 951 return name.equals(option); 952 } 953 return name.toLowerCase().equals(option.toLowerCase()); 954 } 955 return false; 956 } 957 958 @Override compareTo(Option that)959 public int compareTo(Option that) { 960 return this.getNames().get(0).compareTo(that.getNames().get(0)); 961 } 962 } 963 964 protected abstract static class XOption extends Option { 965 XOption(Resources resources, String prefix, String name, int argCount)966 public XOption(Resources resources, String prefix, String name, int argCount) { 967 super(resources, prefix, name, argCount); 968 } 969 XOption(Resources resources, String name, int argCount)970 public XOption(Resources resources, String name, int argCount) { 971 super(resources, name, argCount); 972 } 973 XOption(Resources resources, String name)974 public XOption(Resources resources, String name) { 975 this(resources, name, 0); 976 } 977 978 @Override getKind()979 public Option.Kind getKind() { 980 return Kind.EXTENDED; 981 } 982 } 983 984 protected abstract static class Hidden extends Option { 985 Hidden(Resources resources, String name, int argCount)986 public Hidden(Resources resources, String name, int argCount) { 987 super(resources, name, argCount); 988 } 989 Hidden(Resources resources, String name)990 public Hidden(Resources resources, String name) { 991 this(resources, name, 0); 992 } 993 994 @Override getKind()995 public Option.Kind getKind() { 996 return Kind.OTHER; 997 } 998 } 999 } 1000