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