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