001/* 002 * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package org.jdrupes.mdoclet.internal.doclets.toolkit; 027 028import java.io.ByteArrayOutputStream; 029import java.io.IOException; 030import java.io.OutputStream; 031import java.io.OutputStreamWriter; 032import java.io.UnsupportedEncodingException; 033import java.net.URI; 034import java.net.URISyntaxException; 035import java.nio.file.Path; 036import java.time.Instant; 037import java.time.ZoneOffset; 038import java.time.ZonedDateTime; 039import java.time.format.DateTimeFormatter; 040import java.time.format.DateTimeParseException; 041import java.time.temporal.ChronoUnit; 042import java.time.temporal.TemporalUnit; 043import java.util.ArrayList; 044import java.util.Arrays; 045import java.util.Calendar; 046import java.util.HashSet; 047import java.util.LinkedHashSet; 048import java.util.List; 049import java.util.Locale; 050import java.util.MissingResourceException; 051import java.util.Set; 052import java.util.StringTokenizer; 053import java.util.TreeSet; 054 055import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocletConstants; 056import org.jdrupes.mdoclet.internal.doclets.toolkit.util.Utils; 057 058import jdk.javadoc.doclet.Doclet; 059import jdk.javadoc.doclet.Reporter; 060 061import static javax.tools.Diagnostic.Kind.ERROR; 062 063/** 064 * Storage for the format-independent options supported by the toolkit. 065 * The objects to handle command-line options, and to initialize this 066 * object, are all subtypes of {@link BaseOptions.Option}, 067 * returned by {@link BaseOptions#getSupportedOptions()}. 068 * 069 * <p>Some of the methods used to access the values of options 070 * have names that begin with a verb, such as {@link #copyDocfileSubdirs} 071 * or {@link #showVersion}. Unless otherwise stated, 072 * these methods should all be taken as just accessing the value 073 * of the associated option. 074 */ 075public abstract class BaseOptions { 076 077 // <editor-fold desc="Option values"> 078 079 /** 080 * Argument for command-line option {@code --allow-script-in-comments}. 081 * Allow JavaScript in doc comments. 082 */ 083 private boolean allowScriptInComments = false; 084 085 /** 086 * Argument for command-line option {@code -docfilessubdirs}. 087 * True if we should recursively copy the doc-file subdirectories 088 */ 089 private boolean copyDocfileSubdirs = false; 090 091 /** 092 * Arguments for command-line option {@code -tag} and {@code -taglet}. 093 */ 094 private final LinkedHashSet<List<String>> customTagStrs 095 = new LinkedHashSet<>(); 096 097 /** 098 * Argument for command-line option {@code --date}. 099 * {@code null} if option not given. 100 */ 101 private ZonedDateTime date; 102 103 /** 104 * Argument for command-line option {@code -d}. 105 * Destination directory name, in which doclet will generate the entire 106 * documentation. Default is current directory. 107 */ 108 private String destDirName = ""; 109 110 /** 111 * Argument for command-line option {@code --disable-javafx-strict-checks}. 112 * Primarily used to disable strict checks in the regression 113 * tests allowing those tests to be executed successfully, for 114 * instance, with OpenJDK builds which may not contain FX libraries. 115 */ 116 private boolean disableJavaFxStrictChecks = false; 117 118 /** 119 * Argument for command-line option {@code -docencoding}. 120 * Encoding for this document. Default is default encoding for this 121 * platform. 122 */ 123 private String docEncoding = null; 124 125 /** 126 * Argument for command-line option {@code ???}. 127 * Destination directory name, in which doclet will copy the doc-files to. 128 */ 129 private String docFileDestDirName = ""; 130 131 /** 132 * Argument for hidden command-line option {@code --dump-on-error}. 133 */ 134 private boolean dumpOnError = false; 135 136 /** 137 * Argument for command-line option {@code -encoding}. 138 * Encoding for this document. Default is default encoding for this 139 * platform. 140 */ 141 private String encoding = null; 142 143 /** 144 * Argument for command-line option {@code -excludedocfilessubdir}. 145 * The set of doc-file subdirectories to exclude. 146 */ 147 private Set<String> excludedDocFileDirs; 148 149 /** 150 * Argument for command-line option {@code -noqualifier}. 151 * The set of qualifiers to exclude. 152 */ 153 private Set<String> excludedQualifiers; 154 155 /** 156 * Arguments for command-line option {@code -group} 157 */ 158 private List<Utils.Pair<String, String>> groupPairs; 159 160 /** 161 * Argument for command-line option {@code --javafx} or {@code -javafx}. 162 * Generate documentation for JavaFX getters and setters automatically 163 * by copying it from the appropriate property definition. 164 */ 165 private boolean javafx = false; 166 167 /** 168 * Argument for command-line option {@code -keywords}. 169 * True if user wants to add member names as meta keywords. 170 * Set to false because meta keywords are ignored in general 171 * by most Internet search engines. 172 */ 173 private boolean keywords = false; 174 175 /** 176 * Arguments for command-line option {@code -link}. 177 */ 178 // A list containing urls 179 private final List<String> linkList = new ArrayList<>(); 180 181 /** 182 * Arguments for command-line option {@code -linkoffline}. 183 */ 184 // A list of pairs containing urls and package list 185 private final List<Utils.Pair<String, String>> linkOfflineList 186 = new ArrayList<>(); 187 188 /** 189 * An enum of policies for handling modularity mismatches in external documentation. 190 */ 191 public enum ModularityMismatchPolicy { 192 INFO, 193 WARN 194 } 195 196 /** 197 * Argument for command-line option {@code --link-modularity-mismatch}. 198 * Describes how to handle external documentation with non-matching modularity. 199 */ 200 private ModularityMismatchPolicy linkModularityMismatch 201 = ModularityMismatchPolicy.WARN; 202 203 /** 204 * Location of alternative platform link properties file. 205 */ 206 private String linkPlatformProperties; 207 208 /** 209 * Argument for command-line option {@code -linksource}. 210 * True if we should generate browsable sources. 211 */ 212 private boolean linkSource = false; 213 214 /** 215 * Argument for command-line option {@code -nocomment}. 216 * True if user wants to suppress descriptions and tags. 217 */ 218 private boolean noComment = false; 219 220 /** 221 * Argument for command-line option {@code -nodeprecated}. 222 * Don't generate deprecated API information at all, if -nodeprecated 223 * option is used. <code>nodeprecated</code> is set to true if 224 * -nodeprecated option is used. Default is generate deprecated API 225 * information. 226 */ 227 private boolean noDeprecated = false; 228 229 /** 230 * Argument for command-line option {@code --no-platform-links}. 231 * True if command-line option "--no-platform-links" is used. Default value is 232 * false. 233 */ 234 private boolean noPlatformLinks = false; 235 236 /** 237 * Argument for command-line option {@code -nosince}. 238 * True if command-line option "-nosince" is used. Default value is 239 * false. 240 */ 241 private boolean noSince = false; 242 243 /** 244 * Argument for command-line option {@code -notimestamp}. 245 * True if user wants to suppress time stamp in output. 246 * Default is false. 247 */ 248 private boolean noTimestamp = false; 249 250 /** 251 * Argument for command-line option {@code -quiet}. 252 * Suppress all messages 253 */ 254 private boolean quiet = false; 255 256 /** 257 * Argument for command-line option {@code -serialwarn}. 258 * This is true if option "-serialwarn" is used. Default value is false to 259 * suppress excessive warnings about serial tag. 260 */ 261 private boolean serialWarn = false; 262 263 /** 264 * Argument for command-line option {@code -author}. 265 * Generate author specific information for all the classes if @author 266 * tag is used in the doc comment and if -author option is used. 267 * <code>showauthor</code> is set to true if -author option is used. 268 * Default is don't show author information. 269 */ 270 private boolean showAuthor = false; 271 272 /** 273 * Argument for command-line option {@code --show-taglets}. 274 * Show taglets (internal debug switch) 275 */ 276 private boolean showTaglets = false; 277 278 /** 279 * Argument for command-line option {@code -version}. 280 * Generate version specific information for the all the classes 281 * if @version tag is used in the doc comment and if -version option is 282 * used. {@code showVersion} is set to true if -version option is 283 * used. Default is don't show version information. 284 */ 285 private boolean showVersion = false; 286 287 /** 288 * Argument for command line option {@code --since}. 289 * Specifies a list of release names for which to document API changes. 290 */ 291 private List<String> since = List.of(); 292 293 /** 294 * Argument for command line option {@code --since-label}. 295 * Specifies custom text to use as heading of New API page. 296 */ 297 private String sinceLabel; 298 299 /** 300 * Argument for command-line option {@code -sourcetab}. 301 * The specified amount of space between tab stops. 302 */ 303 private int sourceTabSize; 304 305 /** 306 * Argument for command-line option {@code --spec-base-url}. 307 * The base URL for relative URLs in {@code @spec} tags. 308 */ 309 private URI specBaseURI; 310 311 /** 312 * Value for command-line option {@code --override-methods summary} 313 * or {@code --override-methods detail}. 314 * Specifies whether those methods that override a supertype's method 315 * with no changes to the API contract should be summarized in the 316 * footnote section. 317 */ 318 private boolean summarizeOverriddenMethods = false; 319 320 /** 321 * Argument for command-line option {@code -tagletpath}. 322 * The path to Taglets 323 */ 324 private String tagletPath = null; 325 326 /** 327 * Argument for command-line option {@code --snippet-path}. 328 * The path for external snippets. 329 */ 330 private String snippetPath = null; 331 332 // </editor-fold> 333 334 private final BaseConfiguration config; 335 336 /** 337 * The default amount of space between tab stops. 338 */ 339 public static final int DEFAULT_TAB_STOP_LENGTH = 8; 340 341 protected BaseOptions(BaseConfiguration config) { 342 this.config = config; 343 344 excludedDocFileDirs = new HashSet<>(); 345 excludedQualifiers = new HashSet<>(); 346 sourceTabSize = DEFAULT_TAB_STOP_LENGTH; 347 groupPairs = new ArrayList<>(0); 348 } 349 350 public Set<? extends Option> getSupportedOptions() { 351 Resources resources = config.getDocResources(); 352 Messages messages = config.getMessages(); 353 Reporter reporter = config.getReporter(); 354 355 List<Option> options = List.of( 356 new Option(resources, "-author") { 357 @Override 358 public boolean process(String opt, List<String> args) { 359 showAuthor = true; 360 return true; 361 } 362 }, 363 364 new Option(resources, "-d", 1) { 365 @Override 366 public boolean process(String opt, List<String> args) { 367 destDirName = addTrailingFileSep(args.get(0)); 368 return true; 369 } 370 }, 371 372 new XOption(resources, "--date", 1) { 373 // Valid --date range: within ten years of now 374 private static final ZonedDateTime now = ZonedDateTime.now(); 375 static final ZonedDateTime DATE_MIN = now.minusYears(10); 376 static final ZonedDateTime DATE_MAX = now.plusYears(10); 377 378 @Override 379 public boolean process(String opt, List<String> args) { 380 if (noTimestamp) { 381 messages.error("doclet.Option_conflict", "--date", 382 "-notimestamp"); 383 return false; 384 } 385 String arg = args.get(0); 386 try { 387 date = ZonedDateTime.parse(arg, 388 DateTimeFormatter.ISO_ZONED_DATE_TIME); 389 if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { 390 messages.error("doclet.Option_date_out_of_range", 391 arg); 392 return false; 393 } 394 return true; 395 } catch (DateTimeParseException x) { 396 messages.error("doclet.Option_date_not_valid", arg); 397 return false; 398 } 399 } 400 }, 401 402 new Option(resources, "-docencoding", 1) { 403 @Override 404 public boolean process(String opt, List<String> args) { 405 docEncoding = args.get(0); 406 return true; 407 } 408 }, 409 410 new Option(resources, "-docfilessubdirs") { 411 @Override 412 public boolean process(String opt, List<String> args) { 413 copyDocfileSubdirs = true; 414 return true; 415 } 416 }, 417 418 new Hidden(resources, "-encoding", 1) { 419 @Override 420 public boolean process(String opt, List<String> args) { 421 encoding = args.get(0); 422 return true; 423 } 424 }, 425 426 new Option(resources, "-excludedocfilessubdir", 1) { 427 @Override 428 public boolean process(String opt, List<String> args) { 429 excludedDocFileDirs 430 .addAll(List.of(args.get(0).split("[,:]"))); 431 return true; 432 } 433 }, 434 435 new Option(resources, "-group", 2) { 436 @Override 437 public boolean process(String opt, List<String> args) { 438 groupPairs.add(new Utils.Pair<>(args.get(0), args.get(1))); 439 return true; 440 } 441 }, 442 443 new Option(resources, "--javafx -javafx") { 444 @Override 445 public boolean process(String opt, List<String> args) { 446 javafx = true; 447 return true; 448 } 449 }, 450 451 new Option(resources, "-keywords") { 452 @Override 453 public boolean process(String opt, List<String> args) { 454 keywords = true; 455 return true; 456 } 457 }, 458 459 new Option(resources, "-link", 1) { 460 @Override 461 public boolean process(String opt, List<String> args) { 462 linkList.add(args.get(0)); 463 return true; 464 } 465 }, 466 467 new Option(resources, "-linksource") { 468 @Override 469 public boolean process(String opt, List<String> args) { 470 linkSource = true; 471 return true; 472 } 473 }, 474 475 new Option(resources, "-linkoffline", 2) { 476 @Override 477 public boolean process(String opt, List<String> args) { 478 linkOfflineList 479 .add(new Utils.Pair<>(args.get(0), args.get(1))); 480 return true; 481 } 482 }, 483 484 new Option(resources, "--link-modularity-mismatch", 1) { 485 @Override 486 public boolean process(String opt, List<String> args) { 487 String s = args.get(0); 488 switch (s) { 489 case "warn", "info" -> linkModularityMismatch 490 = ModularityMismatchPolicy 491 .valueOf(s.toUpperCase(Locale.ROOT)); 492 default -> { 493 reporter.print(ERROR, resources.getText( 494 "doclet.Option_invalid", s, 495 "--link-modularity-mismatch")); 496 return false; 497 } 498 } 499 return true; 500 } 501 }, 502 503 new Option(resources, "--link-platform-properties", 1) { 504 @Override 505 public boolean process(String opt, List<String> args) { 506 linkPlatformProperties = args.get(0); 507 return true; 508 } 509 }, 510 511 new Option(resources, "-nocomment") { 512 @Override 513 public boolean process(String opt, List<String> args) { 514 noComment = true; 515 return true; 516 } 517 }, 518 519 new Option(resources, "-nodeprecated") { 520 @Override 521 public boolean process(String opt, List<String> args) { 522 noDeprecated = true; 523 return true; 524 } 525 }, 526 527 new Option(resources, "-nosince") { 528 @Override 529 public boolean process(String opt, List<String> args) { 530 noSince = true; 531 return true; 532 } 533 }, 534 535 new Option(resources, "-notimestamp") { 536 @Override 537 public boolean process(String opt, List<String> args) { 538 noTimestamp = true; 539 if (date != null) { 540 messages.error("doclet.Option_conflict", "--date", 541 "-notimestamp"); 542 return false; 543 } 544 return true; 545 } 546 }, 547 548 new Option(resources, "-noqualifier", 1) { 549 @Override 550 public boolean process(String opt, List<String> args) { 551 excludedQualifiers 552 .addAll(List.of(args.get(0).split("[,:]"))); 553 return true; 554 } 555 }, 556 557 new Option(resources, "--no-platform-links") { 558 @Override 559 public boolean process(String opt, List<String> args) { 560 noPlatformLinks = true; 561 return true; 562 } 563 }, 564 565 new Option(resources, "--override-methods", 1) { 566 @Override 567 public boolean process(String opt, List<String> args) { 568 String o = args.get(0); 569 switch (o) { 570 case "summary" -> summarizeOverriddenMethods = true; 571 case "detail" -> summarizeOverriddenMethods = false; 572 default -> { 573 reporter.print(ERROR, 574 resources.getText("doclet.Option_invalid", o, 575 "--override-methods")); 576 return false; 577 } 578 } 579 return true; 580 } 581 }, 582 583 new Hidden(resources, "-quiet") { 584 @Override 585 public boolean process(String opt, List<String> args) { 586 quiet = true; 587 return true; 588 } 589 }, 590 591 new Option(resources, "-serialwarn") { 592 @Override 593 public boolean process(String opt, List<String> args) { 594 serialWarn = true; 595 return true; 596 } 597 }, 598 599 new Option(resources, "--since", 1) { 600 @Override 601 public boolean process(String opt, List<String> args) { 602 since = Arrays.stream(args.get(0).split(",")) 603 .map(String::trim).toList(); 604 return true; 605 } 606 }, 607 608 new Option(resources, "--since-label", 1) { 609 @Override 610 public boolean process(String opt, List<String> args) { 611 sinceLabel = args.get(0); 612 return true; 613 } 614 }, 615 616 new Option(resources, "-sourcetab", 1) { 617 @Override 618 public boolean process(String opt, List<String> args) { 619 linkSource = true; 620 try { 621 sourceTabSize = Integer.parseInt(args.get(0)); 622 } catch (NumberFormatException e) { 623 // Set to -1 so that warning will be printed 624 // to indicate what is valid argument. 625 sourceTabSize = -1; 626 } 627 if (sourceTabSize <= 0) { 628 messages.warning("doclet.sourcetab_warning"); 629 sourceTabSize = DEFAULT_TAB_STOP_LENGTH; 630 } 631 return true; 632 } 633 }, 634 635 new Option(resources, "-tag", 1) { 636 @Override 637 public boolean process(String opt, List<String> args) { 638 ArrayList<String> list = new ArrayList<>(); 639 list.add(opt); 640 list.add(args.get(0)); 641 customTagStrs.add(list); 642 return true; 643 } 644 }, 645 646 new Option(resources, "-taglet", 1) { 647 @Override 648 public boolean process(String opt, List<String> args) { 649 ArrayList<String> list = new ArrayList<>(); 650 list.add(opt); 651 list.add(args.get(0)); 652 customTagStrs.add(list); 653 return true; 654 } 655 }, 656 657 new Option(resources, "-tagletpath", 1) { 658 @Override 659 public boolean process(String opt, List<String> args) { 660 tagletPath = args.get(0); 661 return true; 662 } 663 }, 664 665 new Option(resources, "--snippet-path", 1) { 666 @Override 667 public boolean process(String opt, List<String> args) { 668 snippetPath = args.get(0); 669 return true; 670 } 671 }, 672 673 new Option(resources, "-version") { 674 @Override 675 public boolean process(String opt, List<String> args) { 676 showVersion = true; 677 return true; 678 } 679 }, 680 681 new Hidden(resources, "--dump-on-error") { 682 @Override 683 public boolean process(String opt, List<String> args) { 684 dumpOnError = true; 685 return true; 686 } 687 }, 688 689 new Option(resources, "--allow-script-in-comments") { 690 @Override 691 public boolean process(String opt, List<String> args) { 692 allowScriptInComments = true; 693 return true; 694 } 695 }, 696 697 new Option(resources, "--spec-base-url", 1) { 698 @Override 699 public boolean process(String opt, List<String> args) { 700 String arg = args.get(0); 701 try { 702 if (!arg.endsWith("/")) { 703 // to ensure that URI.resolve works as expected 704 arg += "/"; 705 } 706 specBaseURI = new URI(arg); 707 return true; 708 } catch (URISyntaxException e) { 709 config.reporter.print(ERROR, 710 config.getDocResources().getText( 711 "doclet.Invalid_URL", 712 e.getMessage())); 713 return false; 714 } 715 } 716 }, 717 718 new Hidden(resources, "--disable-javafx-strict-checks") { 719 @Override 720 public boolean process(String opt, List<String> args) { 721 disableJavaFxStrictChecks = true; 722 return true; 723 } 724 }, 725 726 new Hidden(resources, "--show-taglets") { 727 @Override 728 public boolean process(String opt, List<String> args) { 729 showTaglets = true; 730 return true; 731 } 732 }); 733 return new TreeSet<>(options); 734 } 735 736 /** 737 * This checks for the validity of the options used by the user. 738 * As of this writing, this checks only docencoding. 739 * 740 * @return true if all the options are valid. 741 */ 742 protected boolean generalValidOptions() { 743 if (docEncoding != null) { 744 if (!checkOutputFileEncoding(docEncoding)) { 745 return false; 746 } 747 } 748 if (docEncoding == null && (encoding != null && !encoding.isEmpty())) { 749 if (!checkOutputFileEncoding(encoding)) { 750 return false; 751 } 752 } 753 return true; 754 } 755 756 /** 757 * Check the validity of the given Source or Output File encoding on this 758 * platform. 759 * 760 * @param docencoding output file encoding. 761 */ 762 private boolean checkOutputFileEncoding(String docencoding) { 763 OutputStream ost = new ByteArrayOutputStream(); 764 OutputStreamWriter osw = null; 765 try { 766 osw = new OutputStreamWriter(ost, docencoding); 767 } catch (UnsupportedEncodingException exc) { 768 config.reporter.print(ERROR, 769 config.getDocResources() 770 .getText("doclet.Encoding_not_supported", docencoding)); 771 return false; 772 } finally { 773 try { 774 if (osw != null) { 775 osw.close(); 776 } 777 } catch (IOException exc) { 778 } 779 } 780 return true; 781 } 782 783 /** 784 * Add a trailing file separator, if not found. Remove superfluous 785 * file separators if any. Preserve the front double file separator for 786 * UNC paths. 787 * 788 * @param path Path under consideration. 789 * @return String Properly constructed path string. 790 */ 791 protected static String addTrailingFileSep(String path) { 792 String fs = System.getProperty("file.separator"); 793 String dblfs = fs + fs; 794 int indexDblfs; 795 while ((indexDblfs = path.indexOf(dblfs, 1)) >= 0) { 796 path = path.substring(0, indexDblfs) + 797 path.substring(indexDblfs + fs.length()); 798 } 799 if (!path.endsWith(fs)) 800 path += fs; 801 return path; 802 } 803 804 /** 805 * Argument for command-line option {@code --allow-script-in-comments}. 806 * Allow JavaScript in doc comments. 807 */ 808 boolean allowScriptInComments() { 809 return allowScriptInComments; 810 } 811 812 /** 813 * Argument for command-line option {@code -docfilessubdirs}. 814 * True if we should recursively copy the doc-file subdirectories 815 */ 816 public boolean copyDocfileSubdirs() { 817 return copyDocfileSubdirs; 818 } 819 820 /** 821 * Arguments for command-line option {@code -tag} and {@code -taglet}. 822 */ 823 LinkedHashSet<List<String>> customTagStrs() { 824 return customTagStrs; 825 } 826 827 /** 828 * Argument for command-line option {@code --date}. 829 */ 830 public ZonedDateTime date() { 831 return date; 832 } 833 834 /** 835 * Argument for command-line option {@code -d}. 836 * Destination directory name, in which doclet will generate the entire 837 * documentation. Default is current directory. 838 */ 839 String destDirName() { 840 return destDirName; 841 } 842 843 /** 844 * Argument for command-line option {@code --disable-javafx-strict-checks}. 845 * Primarily used to disable strict checks in the regression 846 * tests allowing those tests to be executed successfully, for 847 * instance, with OpenJDK builds which may not contain FX libraries. 848 */ 849 boolean disableJavaFxStrictChecks() { 850 return disableJavaFxStrictChecks; 851 } 852 853 /** 854 * Argument for command-line option {@code -docencoding}. 855 * Encoding for this document. Default is default encoding for this 856 * platform. 857 */ 858 public String docEncoding() { 859 return docEncoding; 860 } 861 862 public void setDocEncoding(String docEncoding) { 863 this.docEncoding = docEncoding; 864 } 865 866 /** 867 * Argument for command-line option {@code ???}. 868 * Destination directory name, in which doclet will copy the doc-files to. 869 */ 870 String docFileDestDirName() { 871 return docFileDestDirName; 872 } 873 874 /** 875 * Argument for hidden command-line option {@code --dump-on-error}. 876 */ 877 boolean dumpOnError() { 878 return dumpOnError; 879 } 880 881 /** 882 * Argument for command-line option {@code -encoding}. 883 * Encoding for this document. Default is default encoding for this 884 * platform. 885 */ 886 public String encoding() { 887 return encoding; 888 } 889 890 /** 891 * Argument for command-line option {@code -excludedocfilessubdir}. 892 * The set of doc-file subdirectories to exclude. 893 */ 894 Set<String> excludedDocFileDirs() { 895 return excludedDocFileDirs; 896 } 897 898 /** 899 * Argument for command-line option {@code -noqualifier}. 900 * The set of qualifiers to exclude. 901 */ 902 Set<String> excludedQualifiers() { 903 return excludedQualifiers; 904 } 905 906 /** 907 * Arguments for command-line option {@code -group} 908 */ 909 List<Utils.Pair<String, String>> groupPairs() { 910 return groupPairs; 911 } 912 913 /** 914 * Argument for command-line option {@code --javafx} or {@code -javafx}. 915 * Generate documentation for JavaFX getters and setters automatically 916 * by copying it from the appropriate property definition. 917 */ 918 public boolean javafx() { 919 return javafx; 920 } 921 922 public void setJavaFX(boolean javafx) { 923 this.javafx = javafx; 924 } 925 926 /** 927 * Argument for command-line option {@code -keywords}. 928 * True if user wants to add member names as meta keywords. 929 * Set to false because meta keywords are ignored in general 930 * by most Internet search engines. 931 */ 932 public boolean keywords() { 933 return keywords; 934 } 935 936 /** 937 * Arguments for command-line option {@code -link}. 938 */ 939 List<String> linkList() { 940 return linkList; 941 } 942 943 /** 944 * Arguments for command-line option {@code -linkoffline}. 945 */ 946 List<Utils.Pair<String, String>> linkOfflineList() { 947 return linkOfflineList; 948 } 949 950 /** 951 * Argument for command-line option {@code --link-modularity-mismatch}. 952 * Describes how to handle external documentation with non-matching modularity. 953 */ 954 public ModularityMismatchPolicy linkModularityMismatch() { 955 return linkModularityMismatch; 956 } 957 958 /** 959 * Argument for command-line option {@code --link-platform-properties}. 960 */ 961 String linkPlatformProperties() { 962 return linkPlatformProperties; 963 } 964 965 /** 966 * Argument for command-line option {@code -linksource}. 967 * True if we should generate browsable sources. 968 */ 969 public boolean linkSource() { 970 return linkSource; 971 } 972 973 /** 974 * Argument for command-line option {@code -nocomment}. 975 * True if user wants to suppress descriptions and tags. 976 */ 977 public boolean noComment() { 978 return noComment; 979 } 980 981 /** 982 * Argument for command-line option {@code -nodeprecated}. 983 * Don't generate deprecated API information at all if -nodeprecated 984 * option is used. {@code noDeprecated} is set to {@code true} if 985 * {@code -nodeprecated} option is used. 986 * Default is generate deprecated API information. 987 */ 988 public boolean noDeprecated() { 989 return noDeprecated; 990 } 991 992 /** 993 * Argument for command-line option {@code --no-platform-links}. 994 * True if command-line option {@code --no-platform-links"} is used. 995 * Default value is false. 996 */ 997 public boolean noPlatformLinks() { 998 return noPlatformLinks; 999 } 1000 1001 /** 1002 * Argument for command-line option {@code -nosince}. 1003 * True if command-line option {@code -nosince"} is used. 1004 * Default value is false. 1005 */ 1006 public boolean noSince() { 1007 return noSince; 1008 } 1009 1010 /** 1011 * Argument for command-line option {@code -notimestamp}. 1012 * True if user wants to suppress time stamp in output. 1013 * Default is false. 1014 */ 1015 public boolean noTimestamp() { 1016 return noTimestamp; 1017 } 1018 1019 /** 1020 * Argument for command-line option {@code -quiet}. 1021 * Suppress all messages 1022 */ 1023 boolean quiet() { 1024 return quiet; 1025 } 1026 1027 /** 1028 * Argument for command-line option {@code -serialwarn}. 1029 * This is true if option "-serialwarn" is used. Default value is false to 1030 * suppress excessive warnings about serial tag. 1031 */ 1032 public boolean serialWarn() { 1033 return serialWarn; 1034 } 1035 1036 /** 1037 * Argument for command-line option {@code -author}. 1038 * Generate author specific information for all the classes if @author 1039 * tag is used in the doc comment and if -author option is used. 1040 * <code>showauthor</code> is set to true if -author option is used. 1041 * Default is don't show author information. 1042 */ 1043 public boolean showAuthor() { 1044 return showAuthor; 1045 } 1046 1047 /** 1048 * Argument for command-line option {@code --show-taglets}. 1049 * Show taglets (internal debug switch) 1050 */ 1051 public boolean showTaglets() { 1052 return showTaglets; 1053 } 1054 1055 /** 1056 * Argument for command-line option {@code -version}. 1057 * Generate version specific information for the all the classes 1058 * if @version tag is used in the doc comment and if -version option is 1059 * used. {@code showVersion} is set to true if -version option is 1060 * used. Default is don't show version information. 1061 */ 1062 public boolean showVersion() { 1063 return showVersion; 1064 } 1065 1066 /** 1067 * Arguments for command line option {@code --since}. 1068 */ 1069 public List<String> since() { 1070 return List.copyOf(since); 1071 } 1072 1073 /** 1074 * Arguments for command line option {@code --since-label}. 1075 */ 1076 public String sinceLabel() { 1077 return sinceLabel; 1078 } 1079 1080 /** 1081 * Argument for command-line option {@code -sourcetab}. 1082 * The specified amount of space between tab stops. 1083 */ 1084 public int sourceTabSize() { 1085 return sourceTabSize; 1086 } 1087 1088 /** 1089 * Argument for command-line option {@code --spec-base-url}. 1090 * The base URL for relative URLs in {@code @spec} tags. 1091 */ 1092 public URI specBaseURI() { 1093 return specBaseURI; 1094 } 1095 1096 /** 1097 * Value for command-line option {@code --override-methods summary} 1098 * or {@code --override-methods detail}. 1099 * Specifies whether those methods that override a supertype's method 1100 * with no changes to the API contract should be summarized in the 1101 * footnote section. 1102 */ 1103 public boolean summarizeOverriddenMethods() { 1104 return summarizeOverriddenMethods; 1105 } 1106 1107 /** 1108 * Argument for command-line option {@code -tagletpath}. 1109 * The path to Taglets 1110 */ 1111 public String tagletPath() { 1112 return tagletPath; 1113 } 1114 1115 /** 1116 * Argument for command-line option {@code --snippet-path}. 1117 * The path for external snippets. 1118 */ 1119 public String snippetPath() { 1120 return snippetPath; 1121 } 1122 1123 protected abstract static class Option 1124 implements Doclet.Option, Comparable<Option> { 1125 private final String[] names; 1126 private final String parameters; 1127 private final String description; 1128 private final int argCount; 1129 1130 protected Option(Resources resources, String name, int argCount) { 1131 this(resources, null, name, argCount); 1132 } 1133 1134 protected Option(Resources resources, String keyBase, String name, 1135 int argCount) { 1136 this.names = name.trim().split("\\s+"); 1137 if (keyBase == null) { 1138 keyBase = "doclet.usage." 1139 + Utils.toLowerCase(names[0]).replaceAll("^-+", ""); 1140 } 1141 String desc 1142 = getOptionsMessage(resources, keyBase + ".description"); 1143 if (desc.isEmpty()) { 1144 this.description = "<MISSING KEY>"; 1145 this.parameters = "<MISSING KEY>"; 1146 } else { 1147 this.description = desc; 1148 this.parameters 1149 = getOptionsMessage(resources, keyBase + ".parameters"); 1150 } 1151 this.argCount = argCount; 1152 } 1153 1154 protected Option(Resources resources, String name) { 1155 this(resources, name, 0); 1156 } 1157 1158 private String getOptionsMessage(Resources resources, String key) { 1159 try { 1160 return resources.getText(key); 1161 } catch (MissingResourceException ignore) { 1162 return ""; 1163 } 1164 } 1165 1166 @Override 1167 public String getDescription() { 1168 return description; 1169 } 1170 1171 @Override 1172 public Kind getKind() { 1173 return Kind.STANDARD; 1174 } 1175 1176 @Override 1177 public List<String> getNames() { 1178 return Arrays.asList(names); 1179 } 1180 1181 @Override 1182 public String getParameters() { 1183 return parameters; 1184 } 1185 1186 @Override 1187 public String toString() { 1188 return Arrays.toString(names); 1189 } 1190 1191 @Override 1192 public int getArgumentCount() { 1193 return argCount; 1194 } 1195 1196 public boolean matches(String option) { 1197 for (String name : names) { 1198 boolean matchCase = name.startsWith("--"); 1199 if (option.startsWith("--") && option.contains("=")) { 1200 return name 1201 .equals(option.substring(option.indexOf("=") + 1)); 1202 } else if (matchCase) { 1203 return name.equals(option); 1204 } 1205 return name.equalsIgnoreCase(option); 1206 } 1207 return false; 1208 } 1209 1210 @Override 1211 public int compareTo(Option that) { 1212 return this.getNames().get(0).compareTo(that.getNames().get(0)); 1213 } 1214 } 1215 1216 protected abstract static class XOption extends Option { 1217 1218 public XOption(Resources resources, String prefix, String name, 1219 int argCount) { 1220 super(resources, prefix, name, argCount); 1221 } 1222 1223 public XOption(Resources resources, String name, int argCount) { 1224 super(resources, name, argCount); 1225 } 1226 1227 public XOption(Resources resources, String name) { 1228 this(resources, name, 0); 1229 } 1230 1231 @Override 1232 public Option.Kind getKind() { 1233 return Kind.EXTENDED; 1234 } 1235 } 1236 1237 protected abstract static class Hidden extends Option { 1238 1239 public Hidden(Resources resources, String name, int argCount) { 1240 super(resources, name, argCount); 1241 } 1242 1243 public Hidden(Resources resources, String name) { 1244 this(resources, name, 0); 1245 } 1246 1247 @Override 1248 public Option.Kind getKind() { 1249 return Kind.OTHER; 1250 } 1251 } 1252}