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