1 /* 2 * Copyright (c) 1998, 2018, 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.formats.html; 27 28 import java.net.*; 29 import java.util.*; 30 import java.util.stream.Collectors; 31 32 import javax.lang.model.element.Element; 33 import javax.lang.model.element.PackageElement; 34 import javax.lang.model.element.TypeElement; 35 import javax.tools.JavaFileManager; 36 import javax.tools.JavaFileObject; 37 import javax.tools.StandardJavaFileManager; 38 39 import com.sun.source.util.DocTreePath; 40 import com.sun.tools.doclint.DocLint; 41 42 import jdk.javadoc.doclet.Doclet; 43 import jdk.javadoc.doclet.DocletEnvironment; 44 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; 45 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 46 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlVersion; 47 import jdk.javadoc.internal.doclets.formats.html.markup.Links; 48 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; 49 import jdk.javadoc.internal.doclets.toolkit.Content; 50 import jdk.javadoc.internal.doclets.toolkit.DocletException; 51 import jdk.javadoc.internal.doclets.toolkit.Messages; 52 import jdk.javadoc.internal.doclets.toolkit.Resources; 53 import jdk.javadoc.internal.doclets.toolkit.WriterFactory; 54 import jdk.javadoc.internal.doclets.toolkit.util.DocFile; 55 import jdk.javadoc.internal.doclets.toolkit.util.DocPath; 56 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 57 import jdk.javadoc.internal.doclets.toolkit.util.Utils; 58 59 import static javax.tools.Diagnostic.Kind.*; 60 61 /** 62 * Configure the output based on the command line options. 63 * <p> 64 * Also determine the length of the command line option. For example, 65 * for a option "-header" there will be a string argument associated, then the 66 * the length of option "-header" is two. But for option "-nohelp" no argument 67 * is needed so it's length is 1. 68 * </p> 69 * <p> 70 * Also do the error checking on the options used. For example it is illegal to 71 * use "-helpfile" option when already "-nohelp" option is used. 72 * </p> 73 * 74 * <p><b>This is NOT part of any supported API. 75 * If you write code that depends on this, you do so at your own risk. 76 * This code and its internal interfaces are subject to change or 77 * deletion without notice.</b> 78 * 79 * @author Robert Field. 80 * @author Atul Dambalkar. 81 * @author Jamie Ho 82 * @author Bhavesh Patel (Modified) 83 */ 84 public class HtmlConfiguration extends BaseConfiguration { 85 86 /** 87 * Argument for command line option "-header". 88 */ 89 public String header = ""; 90 91 /** 92 * Argument for command line option "-packagesheader". 93 */ 94 public String packagesheader = ""; 95 96 /** 97 * Argument for command line option "-footer". 98 */ 99 public String footer = ""; 100 101 /** 102 * Argument for command line option "-doctitle". 103 */ 104 public String doctitle = ""; 105 106 /** 107 * Argument for command line option "-windowtitle". 108 */ 109 public String windowtitle = ""; 110 111 /** 112 * Argument for command line option "-top". 113 */ 114 public String top = ""; 115 116 /** 117 * Argument for command line option "-bottom". 118 */ 119 public String bottom = ""; 120 121 /** 122 * Argument for command line option "-helpfile". 123 */ 124 public String helpfile = ""; 125 126 /** 127 * Argument for command line option "-stylesheetfile". 128 */ 129 public String stylesheetfile = ""; 130 131 /** 132 * Argument for command line option "--add-stylesheet". 133 */ 134 public List<String> additionalStylesheets = new ArrayList<>(); 135 136 /** 137 * Argument for command line option "-Xdocrootparent". 138 */ 139 public String docrootparent = ""; 140 141 /** 142 * True if command line option "-nohelp" is used. Default value is false. 143 */ 144 public boolean nohelp = false; 145 146 /** 147 * True if command line option "-splitindex" is used. Default value is 148 * false. 149 */ 150 public boolean splitindex = false; 151 152 /** 153 * False if command line option "-noindex" is used. Default value is true. 154 */ 155 public boolean createindex = true; 156 157 /** 158 * True if command line option "-use" is used. Default value is false. 159 */ 160 public boolean classuse = false; 161 162 /** 163 * False if command line option "-notree" is used. Default value is true. 164 */ 165 public boolean createtree = true; 166 167 /** 168 * The META charset tag used for cross-platform viewing. 169 */ 170 public String charset = null; 171 172 /** 173 * True if command line option "-nodeprecated" is used. Default value is 174 * false. 175 */ 176 public boolean nodeprecatedlist = false; 177 178 /** 179 * True if command line option "-nonavbar" is used. Default value is false. 180 */ 181 public boolean nonavbar = false; 182 183 /** 184 * True if command line option "-nooverview" is used. Default value is 185 * false 186 */ 187 private boolean nooverview = false; 188 189 /** 190 * The overview path specified with "-overview" flag. 191 */ 192 public String overviewpath = null; 193 194 /** 195 * This is true if option "-overview" is used or option "-overview" is not 196 * used and number of packages is more than one. 197 */ 198 public boolean createoverview = false; 199 200 /** 201 * Specifies whether or not frames should be generated. 202 * Defaults to true; can be set by --frames; can be set to false by --no-frames; last one wins. 203 */ 204 public boolean frames = true; 205 206 /** 207 * This is the HTML version of the generated pages. 208 * The default value is determined later. 209 */ 210 public HtmlVersion htmlVersion = null; 211 212 /** 213 * Flag to enable/disable use of module directories when generating docs for modules 214 * Default: on (module directories are enabled). 215 */ 216 public boolean useModuleDirectories = true; 217 218 /** 219 * Collected set of doclint options 220 */ 221 public Map<Doclet.Option, String> doclintOpts = new LinkedHashMap<>(); 222 223 public final Resources resources; 224 225 /** 226 * First file to appear in the right-hand frame in the generated 227 * documentation. 228 */ 229 public DocPath topFile = DocPath.empty; 230 231 /** 232 * The TypeElement for the class file getting generated. 233 */ 234 public TypeElement currentTypeElement = null; // Set this TypeElement in the ClassWriter. 235 236 protected List<SearchIndexItem> memberSearchIndex = new ArrayList<>(); 237 238 protected List<SearchIndexItem> moduleSearchIndex = new ArrayList<>(); 239 240 protected List<SearchIndexItem> packageSearchIndex = new ArrayList<>(); 241 242 protected SortedSet<SearchIndexItem> tagSearchIndex = new TreeSet<>(makeSearchTagComparator()); 243 244 protected List<SearchIndexItem> typeSearchIndex = new ArrayList<>(); 245 246 protected Map<Character,List<SearchIndexItem>> tagSearchIndexMap = new HashMap<>(); 247 248 protected Set<Character> tagSearchIndexKeys; 249 250 protected final Contents contents; 251 252 protected final Messages messages; 253 254 protected DocPaths docPaths; 255 256 /** 257 * Creates an object to hold the configuration for a doclet. 258 * 259 * @param doclet the doclet 260 */ 261 public HtmlConfiguration(Doclet doclet) { 262 super(doclet); 263 resources = new Resources(this, 264 BaseConfiguration.sharedResourceBundleName, 265 "jdk.javadoc.internal.doclets.formats.html.resources.standard"); 266 267 messages = new Messages(this); 268 contents = new Contents(this); 269 270 String v; 271 try { 272 ResourceBundle rb = ResourceBundle.getBundle(versionBundleName, getLocale()); 273 try { 274 v = rb.getString("release"); 275 } catch (MissingResourceException e) { 276 v = defaultDocletVersion; 277 } 278 } catch (MissingResourceException e) { 279 v = defaultDocletVersion; 280 } 281 docletVersion = v; 282 } 283 284 private static final String versionBundleName = "jdk.javadoc.internal.tool.resources.version"; 285 private static final String defaultDocletVersion = System.getProperty("java.version"); 286 public final String docletVersion; 287 288 @Override 289 public String getDocletVersion() { 290 return docletVersion; 291 } 292 293 @Override 294 public Resources getResources() { 295 return resources; 296 } 297 298 @Override 299 public Messages getMessages() { 300 return messages; 301 } 302 303 protected boolean validateOptions() { 304 // check shared options 305 if (!generalValidOptions()) { 306 return false; 307 } 308 309 if (htmlVersion == null) { 310 reporter.print(WARNING, getText("doclet.HTML_version_not_specified", helpfile)); 311 htmlVersion = HtmlVersion.HTML4; 312 } 313 314 // check if helpfile exists 315 if (!helpfile.isEmpty()) { 316 DocFile help = DocFile.createFileForInput(this, helpfile); 317 if (!help.exists()) { 318 reporter.print(ERROR, getText("doclet.File_not_found", helpfile)); 319 return false; 320 } 321 } 322 // check if stylesheetfile exists 323 if (!stylesheetfile.isEmpty()) { 324 DocFile stylesheet = DocFile.createFileForInput(this, stylesheetfile); 325 if (!stylesheet.exists()) { 326 reporter.print(ERROR, getText("doclet.File_not_found", stylesheetfile)); 327 return false; 328 } 329 } 330 // check if additional stylesheets exists 331 for (String ssheet : additionalStylesheets) { 332 DocFile ssfile = DocFile.createFileForInput(this, ssheet); 333 if (!ssfile.exists()) { 334 reporter.print(ERROR, getText("doclet.File_not_found", ssheet)); 335 return false; 336 } 337 } 338 339 // In a more object-oriented world, this would be done by methods on the Option objects. 340 // Note that -windowtitle silently removes any and all HTML elements, and so does not need 341 // to be handled here. 342 utils.checkJavaScriptInOption("-header", header); 343 utils.checkJavaScriptInOption("-footer", footer); 344 utils.checkJavaScriptInOption("-top", top); 345 utils.checkJavaScriptInOption("-bottom", bottom); 346 utils.checkJavaScriptInOption("-doctitle", doctitle); 347 utils.checkJavaScriptInOption("-packagesheader", packagesheader); 348 349 return true; 350 } 351 352 353 @Override 354 public boolean finishOptionSettings() { 355 if (!validateOptions()) { 356 return false; 357 } 358 if (!getSpecifiedTypeElements().isEmpty()) { 359 Map<String, PackageElement> map = new HashMap<>(); 360 PackageElement pkg; 361 for (TypeElement aClass : getIncludedTypeElements()) { 362 pkg = utils.containingPackage(aClass); 363 if (!map.containsKey(utils.getPackageName(pkg))) { 364 map.put(utils.getPackageName(pkg), pkg); 365 } 366 } 367 } 368 docPaths = new DocPaths(utils, useModuleDirectories); 369 setCreateOverview(); 370 setTopFile(docEnv); 371 workArounds.initDocLint(doclintOpts.values(), tagletManager.getCustomTagNames(), 372 Utils.toLowerCase(htmlVersion.name())); 373 return true; 374 } 375 376 /** 377 * Return true if the generated output is HTML5. 378 */ 379 public boolean isOutputHtml5() { 380 return htmlVersion == HtmlVersion.HTML5; 381 } 382 383 /** 384 * Return true if the tag is allowed for this specific version of HTML. 385 */ 386 public boolean allowTag(HtmlTag htmlTag) { 387 return htmlTag.allowTag(this.htmlVersion); 388 } 389 390 public Comparator<SearchIndexItem> makeSearchTagComparator() { 391 return (SearchIndexItem sii1, SearchIndexItem sii2) -> { 392 int result = (sii1.getLabel()).compareTo(sii2.getLabel()); 393 if (result == 0) { 394 result = (sii1.getHolder()).compareTo(sii2.getHolder()); 395 } 396 return result; 397 }; 398 } 399 400 /** 401 * Decide the page which will appear first in the right-hand frame. It will 402 * be "overview-summary.html" if "-overview" option is used or no 403 * "-overview" but the number of packages is more than one. It will be 404 * "package-summary.html" of the respective package if there is only one 405 * package to document. It will be a class page(first in the sorted order), 406 * if only classes are provided on the command line. 407 * 408 * @param docEnv the doclet environment 409 */ 410 protected void setTopFile(DocletEnvironment docEnv) { 411 if (!checkForDeprecation(docEnv)) { 412 return; 413 } 414 if (createoverview) { 415 topFile = DocPaths.overviewSummary(frames); 416 } else { 417 if (showModules) { 418 topFile = DocPath.empty.resolve(docPaths.moduleSummary(modules.first())); 419 } else if (packages.size() == 1 && packages.first().isUnnamed()) { 420 List<TypeElement> classes = new ArrayList<>(getIncludedTypeElements()); 421 if (!classes.isEmpty()) { 422 TypeElement te = getValidClass(classes); 423 topFile = docPaths.forClass(te); 424 } 425 } else if (!packages.isEmpty()) { 426 topFile = docPaths.forPackage(packages.first()).resolve(DocPaths.PACKAGE_SUMMARY); 427 } 428 } 429 } 430 431 protected TypeElement getValidClass(List<TypeElement> classes) { 432 if (!nodeprecated) { 433 return classes.get(0); 434 } 435 for (TypeElement te : classes) { 436 if (!utils.isDeprecated(te)) { 437 return te; 438 } 439 } 440 return null; 441 } 442 443 protected boolean checkForDeprecation(DocletEnvironment docEnv) { 444 for (TypeElement te : getIncludedTypeElements()) { 445 if (isGeneratedDoc(te)) { 446 return true; 447 } 448 } 449 return false; 450 } 451 452 /** 453 * Generate "overview.html" page if option "-overview" is used or number of 454 * packages is more than one. Sets {@link #createoverview} field to true. 455 */ 456 protected void setCreateOverview() { 457 if ((overviewpath != null || packages.size() > 1) && !nooverview) { 458 createoverview = true; 459 } 460 } 461 462 /** 463 * {@inheritDoc} 464 */ 465 @Override 466 public WriterFactory getWriterFactory() { 467 return new WriterFactoryImpl(this); 468 } 469 470 /** 471 * {@inheritDoc} 472 */ 473 @Override 474 public Locale getLocale() { 475 if (locale == null) 476 return Locale.getDefault(); 477 return locale; 478 } 479 480 /** 481 * Return the path of the overview file or null if it does not exist. 482 * 483 * @return the path of the overview file or null if it does not exist. 484 */ 485 @Override 486 public JavaFileObject getOverviewPath() { 487 if (overviewpath != null && getFileManager() instanceof StandardJavaFileManager) { 488 StandardJavaFileManager fm = (StandardJavaFileManager) getFileManager(); 489 return fm.getJavaFileObjects(overviewpath).iterator().next(); 490 } 491 return null; 492 } 493 494 public DocFile getMainStylesheet() { 495 return stylesheetfile.isEmpty() ? null : DocFile.createFileForInput(this, stylesheetfile); 496 } 497 498 public List<DocFile> getAdditionalStylesheets() { 499 return additionalStylesheets.stream() 500 .map(ssf -> DocFile.createFileForInput(this, ssf)) 501 .collect(Collectors.toList()); 502 } 503 504 /** 505 * {@inheritDoc} 506 */ 507 @Override 508 public JavaFileManager getFileManager() { 509 return docEnv.getJavaFileManager(); 510 } 511 512 @Override 513 public boolean showMessage(DocTreePath path, String key) { 514 return (path == null || workArounds.haveDocLint()); 515 } 516 517 @Override 518 public boolean showMessage(Element e, String key) { 519 return (e == null || workArounds.haveDocLint()); 520 } 521 522 @Override 523 public String getText(String key) { 524 return resources.getText(key); 525 } 526 527 @Override 528 public String getText(String key, String... args) { 529 return resources.getText(key, (Object[]) args); 530 } 531 532 /** 533 * {@inheritdoc} 534 */ 535 @Override 536 public Content getContent(String key) { 537 return contents.getContent(key); 538 } 539 540 /** 541 * Get the configuration string as a content. 542 * 543 * @param key the key to look for in the configuration file 544 * @param o string or content argument added to configuration text 545 * @return a content tree for the text 546 */ 547 @Override 548 public Content getContent(String key, Object o) { 549 return contents.getContent(key, o); 550 } 551 552 /** 553 * Get the configuration string as a content. 554 * 555 * @param key the key to look for in the configuration file 556 * @param o1 resource argument 557 * @param o2 resource argument 558 * @return a content tree for the text 559 */ 560 @Override 561 public Content getContent(String key, Object o1, Object o2) { 562 return contents.getContent(key, o1, o2); 563 } 564 565 /** 566 * Get the configuration string as a content. 567 * 568 * @param key the key to look for in the configuration file 569 * @param o0 string or content argument added to configuration text 570 * @param o1 string or content argument added to configuration text 571 * @param o2 string or content argument added to configuration text 572 * @return a content tree for the text 573 */ 574 @Override 575 public Content getContent(String key, Object o0, Object o1, Object o2) { 576 return contents.getContent(key, o0, o1, o2); 577 } 578 579 protected void buildSearchTagIndex() { 580 for (SearchIndexItem sii : tagSearchIndex) { 581 String tagLabel = sii.getLabel(); 582 Character unicode = (tagLabel.length() == 0) 583 ? '*' 584 : Character.toUpperCase(tagLabel.charAt(0)); 585 List<SearchIndexItem> list = tagSearchIndexMap.get(unicode); 586 if (list == null) { 587 list = new ArrayList<>(); 588 tagSearchIndexMap.put(unicode, list); 589 } 590 list.add(sii); 591 } 592 tagSearchIndexKeys = tagSearchIndexMap.keySet(); 593 } 594 595 @Override 596 public Set<Doclet.Option> getSupportedOptions() { 597 Resources resources = getResources(); 598 Doclet.Option[] options = { 599 new Option(resources, "--add-stylesheet", 1) { 600 @Override 601 public boolean process(String opt, List<String> args) { 602 additionalStylesheets.add(args.get(0)); 603 return true; 604 } 605 }, 606 new Option(resources, "-bottom", 1) { 607 @Override 608 public boolean process(String opt, List<String> args) { 609 bottom = args.get(0); 610 return true; 611 } 612 }, 613 new Option(resources, "-charset", 1) { 614 @Override 615 public boolean process(String opt, List<String> args) { 616 charset = args.get(0); 617 return true; 618 } 619 }, 620 new Option(resources, "-doctitle", 1) { 621 @Override 622 public boolean process(String opt, List<String> args) { 623 doctitle = args.get(0); 624 return true; 625 } 626 }, 627 new Option(resources, "-footer", 1) { 628 @Override 629 public boolean process(String opt, List<String> args) { 630 footer = args.get(0); 631 return true; 632 } 633 }, 634 new Option(resources, "-header", 1) { 635 @Override 636 public boolean process(String opt, List<String> args) { 637 header = args.get(0); 638 return true; 639 } 640 }, 641 new Option(resources, "-helpfile", 1) { 642 @Override 643 public boolean process(String opt, List<String> args) { 644 if (nohelp == true) { 645 reporter.print(ERROR, getText("doclet.Option_conflict", 646 "-helpfile", "-nohelp")); 647 return false; 648 } 649 if (!helpfile.isEmpty()) { 650 reporter.print(ERROR, getText("doclet.Option_reuse", 651 "-helpfile")); 652 return false; 653 } 654 helpfile = args.get(0); 655 return true; 656 } 657 }, 658 new Option(resources, "-html4") { 659 @Override 660 public boolean process(String opt, List<String> args) { 661 htmlVersion = HtmlVersion.HTML4; 662 return true; 663 } 664 }, 665 new Option(resources, "-html5") { 666 @Override 667 public boolean process(String opt, List<String> args) { 668 htmlVersion = HtmlVersion.HTML5; 669 return true; 670 } 671 }, 672 new Option(resources, "-nohelp") { 673 @Override 674 public boolean process(String opt, List<String> args) { 675 nohelp = true; 676 if (!helpfile.isEmpty()) { 677 reporter.print(ERROR, getText("doclet.Option_conflict", 678 "-nohelp", "-helpfile")); 679 return false; 680 } 681 return true; 682 } 683 }, 684 new Option(resources, "-nodeprecatedlist") { 685 @Override 686 public boolean process(String opt, List<String> args) { 687 nodeprecatedlist = true; 688 return true; 689 } 690 }, 691 new Option(resources, "-noindex") { 692 @Override 693 public boolean process(String opt, List<String> args) { 694 createindex = false; 695 if (splitindex == true) { 696 reporter.print(ERROR, getText("doclet.Option_conflict", 697 "-noindex", "-splitindex")); 698 return false; 699 } 700 return true; 701 } 702 }, 703 new Option(resources, "-nonavbar") { 704 @Override 705 public boolean process(String opt, List<String> args) { 706 nonavbar = true; 707 return true; 708 } 709 }, 710 new Hidden(resources, "-nooverview") { 711 @Override 712 public boolean process(String opt, List<String> args) { 713 nooverview = true; 714 if (overviewpath != null) { 715 reporter.print(ERROR, getText("doclet.Option_conflict", 716 "-nooverview", "-overview")); 717 return false; 718 } 719 return true; 720 } 721 }, 722 new Option(resources, "-notree") { 723 @Override 724 public boolean process(String opt, List<String> args) { 725 createtree = false; 726 return true; 727 } 728 }, 729 new Option(resources, "-overview", 1) { 730 @Override 731 public boolean process(String opt, List<String> args) { 732 overviewpath = args.get(0); 733 if (nooverview == true) { 734 reporter.print(ERROR, getText("doclet.Option_conflict", 735 "-overview", "-nooverview")); 736 return false; 737 } 738 return true; 739 } 740 }, 741 new Option(resources, "--frames") { 742 @Override 743 public boolean process(String opt, List<String> args) { 744 frames = true; 745 return true; 746 } 747 }, 748 new Option(resources, "--no-frames") { 749 @Override 750 public boolean process(String opt, List<String> args) { 751 frames = false; 752 return true; 753 } 754 }, 755 new Hidden(resources, "-packagesheader", 1) { 756 @Override 757 public boolean process(String opt, List<String> args) { 758 packagesheader = args.get(0); 759 return true; 760 } 761 }, 762 new Option(resources, "-splitindex") { 763 @Override 764 public boolean process(String opt, List<String> args) { 765 splitindex = true; 766 if (createindex == false) { 767 reporter.print(ERROR, getText("doclet.Option_conflict", 768 "-splitindex", "-noindex")); 769 return false; 770 } 771 return true; 772 } 773 }, 774 new Option(resources, "--main-stylesheet -stylesheetfile", 1) { 775 @Override 776 public boolean process(String opt, List<String> args) { 777 stylesheetfile = args.get(0); 778 return true; 779 } 780 }, 781 new Option(resources, "-top", 1) { 782 @Override 783 public boolean process(String opt, List<String> args) { 784 top = args.get(0); 785 return true; 786 } 787 }, 788 new Option(resources, "-use") { 789 @Override 790 public boolean process(String opt, List<String> args) { 791 classuse = true; 792 return true; 793 } 794 }, 795 new Option(resources, "-windowtitle", 1) { 796 @Override 797 public boolean process(String opt, List<String> args) { 798 windowtitle = args.get(0).replaceAll("\\<.*?>", ""); 799 return true; 800 } 801 }, 802 new XOption(resources, "-Xdoclint") { 803 @Override 804 public boolean process(String opt, List<String> args) { 805 doclintOpts.put(this, DocLint.XMSGS_OPTION); 806 return true; 807 } 808 }, 809 new XOption(resources, "-Xdocrootparent", 1) { 810 @Override 811 public boolean process(String opt, List<String> args) { 812 docrootparent = args.get(0); 813 try { 814 URL ignored = new URL(docrootparent); 815 } catch (MalformedURLException e) { 816 reporter.print(ERROR, getText("doclet.MalformedURL", docrootparent)); 817 return false; 818 } 819 return true; 820 } 821 }, 822 new XOption(resources, "doclet.usage.xdoclint-extended", "-Xdoclint:", 0) { 823 @Override 824 public boolean process(String opt, List<String> args) { 825 String dopt = opt.replace("-Xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX); 826 doclintOpts.put(this, dopt); 827 if (dopt.contains("/")) { 828 reporter.print(ERROR, getText("doclet.Option_doclint_no_qualifiers")); 829 return false; 830 } 831 if (!DocLint.isValidOption(dopt)) { 832 reporter.print(ERROR, getText("doclet.Option_doclint_invalid_arg")); 833 return false; 834 } 835 return true; 836 } 837 }, 838 new XOption(resources, "doclet.usage.xdoclint-package", "-Xdoclint/package:", 0) { 839 @Override 840 public boolean process(String opt, List<String> args) { 841 String dopt = opt.replace("-Xdoclint/package:", DocLint.XCHECK_PACKAGE); 842 doclintOpts.put(this, dopt); 843 if (!DocLint.isValidOption(dopt)) { 844 reporter.print(ERROR, getText("doclet.Option_doclint_package_invalid_arg")); 845 return false; 846 } 847 return true; 848 } 849 }, 850 new XOption(resources, "--no-module-directories") { 851 @Override 852 public boolean process(String option, List<String> args) { 853 useModuleDirectories = false; 854 return true; 855 } 856 } 857 }; 858 Set<Doclet.Option> oset = new TreeSet<>(); 859 oset.addAll(Arrays.asList(options)); 860 oset.addAll(super.getSupportedOptions()); 861 return oset; 862 } 863 864 @Override 865 protected boolean finishOptionSettings0() throws DocletException { 866 if (docencoding == null) { 867 if (charset == null) { 868 docencoding = charset = (encoding == null) ? HtmlConstants.HTML_DEFAULT_CHARSET : encoding; 869 } else { 870 docencoding = charset; 871 } 872 } else { 873 if (charset == null) { 874 charset = docencoding; 875 } else if (!charset.equals(docencoding)) { 876 reporter.print(ERROR, getText("doclet.Option_conflict", "-charset", "-docencoding")); 877 return false; 878 } 879 } 880 return super.finishOptionSettings0(); 881 } 882 }