1 /*
   2  * Copyright (c) 2012, 2016, 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.tool;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.EnumMap;
  31 import java.util.LinkedHashMap;
  32 import java.util.List;
  33 import java.util.Map;
  34 
  35 import javax.lang.model.element.ElementKind;
  36 
  37 import com.sun.tools.javac.main.Option;
  38 import com.sun.tools.javac.main.OptionHelper;
  39 import com.sun.tools.javac.util.Options;
  40 
  41 /**
  42  * javadoc tool options.
  43  *
  44  *  <p><b>This is NOT part of any supported API.
  45  *  If you write code that depends on this, you do so at your own risk.
  46  *  This code and its internal interfaces are subject to change or
  47  *  deletion without notice.</b>
  48  */
  49 public enum ToolOption {
  50 
  51     // ----- options for underlying compiler -----
  52 
  53     BOOTCLASSPATH("-bootclasspath", true) {
  54         @Override
  55         public void process(Helper helper, String arg) {
  56             helper.setFileManagerOpt(Option.BOOT_CLASS_PATH, arg);
  57         }
  58     },
  59 
  60     CLASSPATH("-classpath", true) {
  61         @Override
  62         public void process(Helper helper, String arg) {
  63             helper.setFileManagerOpt(Option.CLASS_PATH, arg);
  64         }
  65     },
  66 
  67     CP("-cp", true) {
  68         @Override
  69         public void process(Helper helper, String arg) {
  70             helper.setFileManagerOpt(Option.CLASS_PATH, arg);
  71         }
  72     },
  73 
  74     CLASS_PATH("--class-path", true) {
  75         @Override
  76         public void process(Helper helper, String arg) {
  77             helper.setFileManagerOpt(Option.CLASS_PATH, arg);
  78         }
  79     },
  80 
  81     EXTDIRS("-extdirs", true) {
  82         @Override
  83         public void process(Helper helper, String arg) {
  84             helper.setFileManagerOpt(Option.EXTDIRS, arg);
  85         }
  86     },
  87 
  88     SOURCEPATH("-sourcepath", true) {
  89         @Override
  90         public void process(Helper helper, String arg) {
  91             helper.setFileManagerOpt(Option.SOURCE_PATH, arg);
  92         }
  93     },
  94 
  95     SOURCE_PATH("--source-path", true) {
  96         @Override
  97         public void process(Helper helper, String arg) {
  98             helper.setFileManagerOpt(Option.SOURCE_PATH, arg);
  99         }
 100     },
 101 
 102     SYSCLASSPATH("-sysclasspath", true) {
 103         @Override
 104         public void process(Helper helper, String arg) {
 105             helper.setFileManagerOpt(Option.BOOT_CLASS_PATH, arg);
 106         }
 107     },
 108 
 109     MODULESOURCEPATH("-modulesourcepath", true) {
 110         @Override
 111         public void process(Helper helper, String arg) {
 112             helper.setFileManagerOpt(Option.MODULE_SOURCE_PATH, arg);
 113         }
 114     },
 115 
 116     MODULE_SOURCE_PATH("--module-source-path", true) {
 117         @Override
 118         public void process(Helper helper, String arg) {
 119             helper.setFileManagerOpt(Option.MODULE_SOURCE_PATH, arg);
 120         }
 121     },
 122 
 123     UPGRADEMODULEPATH("-upgrademodulepath", true) {
 124         @Override
 125         public void process(Helper helper, String arg) {
 126             helper.setFileManagerOpt(Option.UPGRADE_MODULE_PATH, arg);
 127         }
 128     },
 129 
 130     UPGRADE_MODULE_PATH("--upgrade-module-path", true) {
 131         @Override
 132         public void process(Helper helper, String arg) {
 133             helper.setFileManagerOpt(Option.UPGRADE_MODULE_PATH, arg);
 134         }
 135     },
 136 
 137     SYSTEM("-system", true) {
 138         @Override
 139         public void process(Helper helper, String arg) {
 140             helper.setFileManagerOpt(Option.SYSTEM, arg);
 141         }
 142     },
 143 
 144     SYSTEM_("--system", true) {
 145         @Override
 146         public void process(Helper helper, String arg) {
 147             helper.setFileManagerOpt(Option.SYSTEM, arg);
 148         }
 149     },
 150 
 151     MODULEPATH("-modulepath", true) {
 152         @Override
 153         public void process(Helper helper, String arg) {
 154             helper.setFileManagerOpt(Option.MODULE_PATH, arg);
 155         }
 156     },
 157 
 158     MODULE_PATH("--module-path", true) {
 159         @Override
 160         public void process(Helper helper, String arg) {
 161             helper.setFileManagerOpt(Option.MODULE_PATH, arg);
 162         }
 163     },
 164 
 165     P("-p", true) {
 166         @Override
 167         public void process(Helper helper, String arg) {
 168             helper.setFileManagerOpt(Option.MODULE_PATH, arg);
 169         }
 170     },
 171 
 172     ADDMODS("-addmods", true) {
 173         @Override
 174         public void process(Helper helper, String arg) {
 175             Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
 176         }
 177     },
 178 
 179     ADD_MODULES("--add-modules", true) {
 180         @Override
 181         public void process(Helper helper, String arg) {
 182             Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
 183         }
 184     },
 185 
 186     LIMITMODS("-limitmods", true) {
 187         @Override
 188         public void process(Helper helper, String arg) {
 189             Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
 190         }
 191     },
 192 
 193     LIMIT_MODULES("--limit-modules", true) {
 194         @Override
 195         public void process(Helper helper, String arg) {
 196             Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
 197         }
 198     },
 199 
 200     MODULE("--module", true) {
 201         @Override
 202         public void process(Helper helper, String arg) {
 203             helper.addToList(this, ",", arg);
 204         }
 205     },
 206 
 207     ENCODING("-encoding", true) {
 208         @Override
 209         public void process(Helper helper, String arg) {
 210             helper.setFileManagerOpt(Option.ENCODING, arg);
 211         }
 212     },
 213 
 214     RELEASE("--release", true) {
 215         @Override
 216         public void process(Helper helper, String arg) {
 217             Option.RELEASE.process(helper.getOptionHelper(), opt, arg);
 218         }
 219     },
 220 
 221     RELEASE_OLD("-release", true) {
 222         @Override
 223         public void process(Helper helper, String arg) {
 224             Option.RELEASE.process(helper.getOptionHelper(), opt, arg);
 225         }
 226     },
 227 
 228     SOURCE("-source", true) {
 229         @Override
 230         public void process(Helper helper, String arg) {
 231             Option.SOURCE.process(helper.getOptionHelper(), opt, arg);
 232         }
 233     },
 234 
 235     XMAXERRS("-Xmaxerrs", true) {
 236         @Override
 237         public void process(Helper helper, String arg) {
 238             Option.XMAXERRS.process(helper.getOptionHelper(), opt, arg);
 239         }
 240     },
 241 
 242     XMAXWARNS("-Xmaxwarns", true) {
 243         @Override
 244         public void process(Helper helper, String arg) {
 245             Option.XMAXWARNS.process(helper.getOptionHelper(), opt, arg);
 246         }
 247     },
 248 
 249     XADDREADS("-XaddReads:", false) {
 250         @Override
 251         public void process(Helper helper, String arg) {
 252             Option.ADD_READS.process(helper.getOptionHelper(), arg);
 253         }
 254     },
 255 
 256     ADD_READS("--add-reads", true) {
 257         @Override
 258         public void process(Helper helper, String arg) {
 259             Option.ADD_READS.process(helper.getOptionHelper(), opt, arg);
 260         }
 261     },
 262 
 263     ADDEXPORTS("-XaddExports:", false) {
 264         @Override
 265         public void process(Helper helper, String arg) {
 266             Option.ADD_EXPORTS.process(helper.getOptionHelper(), arg);
 267         }
 268     },
 269 
 270     ADD_EXPORTS("--add-exports", true) {
 271         @Override
 272         public void process(Helper helper, String arg) {
 273             Option.ADD_EXPORTS.process(helper.getOptionHelper(), opt, arg);
 274         }
 275     },
 276 
 277     XMODULE("-Xmodule:", false) {
 278         @Override
 279         public void process(Helper helper, String arg) {
 280             Option.XMODULE.process(helper.getOptionHelper(), arg);
 281         }
 282     },
 283 
 284     XPATCH("-Xpatch:", false) {
 285         @Override
 286         public void process(Helper helper, String arg) {
 287             Option.XMODULE.process(helper.getOptionHelper(), arg);
 288         }
 289     },
 290 
 291     PATCH_MODULE("--patch-module", true) {
 292         @Override
 293         public void process(Helper helper, String arg) {
 294             Option.PATCH_MODULE.process(helper.getOptionHelper(), opt, arg);
 295         }
 296     },
 297 
 298     // ----- doclet options -----
 299 
 300     DOCLET("-doclet", true), // handled in setDocletInvoker
 301 
 302     DOCLETPATH("-docletpath", true), // handled in setDocletInvoker
 303 
 304     // ----- selection options -----
 305 
 306     SUBPACKAGES("-subpackages", true) {
 307         @Override
 308         public void process(Helper helper, String arg) {
 309             helper.addToList(this, ":", arg);
 310         }
 311     },
 312 
 313     EXCLUDE("-exclude", true) {
 314         @Override
 315         public void process(Helper helper, String arg) {
 316             helper.addToList(this, ":", arg);
 317         }
 318     },
 319 
 320     // ----- filtering options -----
 321 
 322     PACKAGE("-package") {
 323         @Override
 324         public void process(Helper helper) {
 325             helper.setSimpleFilter("package");
 326         }
 327     },
 328 
 329     PRIVATE("-private") {
 330         @Override
 331         public void process(Helper helper) {
 332             helper.setSimpleFilter("private");
 333         }
 334     },
 335 
 336     PROTECTED("-protected") {
 337         @Override
 338         public void process(Helper helper) {
 339             helper.setSimpleFilter("protected");
 340         }
 341     },
 342 
 343     PUBLIC("-public") {
 344         @Override
 345         public void process(Helper helper) {
 346             helper.setSimpleFilter("public");
 347         }
 348     },
 349 
 350     SHOW_MEMBERS("--show-members:") {
 351         @Override
 352         public void process(Helper helper, String arg) {
 353             helper.setFilter(this, arg);
 354         }
 355     },
 356 
 357     SHOW_TYPES("--show-types:") {
 358         @Override
 359         public void process(Helper helper, String arg) {
 360             helper.setFilter(this, arg);
 361         }
 362     },
 363 
 364     SHOW_PACKAGES("--show-packages:") {
 365         @Override
 366         public void process(Helper helper, String arg) {
 367             helper.setShowPackageAccess(SHOW_PACKAGES, helper.getOptionArgumentValue(arg));
 368         }
 369     },
 370 
 371     SHOW_MODULE_CONTENTS("--show-module-contents:") {
 372         @Override
 373         public void process(Helper helper, String arg) {
 374             helper.setShowModuleContents(SHOW_MODULE_CONTENTS, helper.getOptionArgumentValue(arg));
 375         }
 376     },
 377 
 378     EXPAND_REQUIRES("--expand-requires:") {
 379         @Override
 380         public void process(Helper helper, String arg) {
 381             helper.setExpandRequires(EXPAND_REQUIRES, helper.getOptionArgumentValue(arg));
 382         }
 383     },
 384 
 385     // ----- output control options -----
 386 
 387     PROMPT("-prompt") {
 388         @Override
 389         public void process(Helper helper) {
 390             helper.compOpts.put("-prompt", "-prompt");
 391             helper.promptOnError = true;
 392         }
 393     },
 394 
 395     QUIET("-quiet") {
 396         @Override
 397         public void process(Helper helper) {
 398             helper.jdtoolOpts.put(QUIET, true);
 399         }
 400     },
 401 
 402     VERBOSE("-verbose") {
 403         @Override
 404         public void process(Helper helper) {
 405             helper.compOpts.put("-verbose", "");
 406         }
 407     },
 408 
 409     XWERROR("-Xwerror") {
 410         @Override
 411         public void process(Helper helper) {
 412             helper.rejectWarnings = true;
 413 
 414         }
 415     },
 416 
 417     // ----- other options -----
 418 
 419     BREAKITERATOR("-breakiterator") {
 420         @Override
 421         public void process(Helper helper) {
 422             helper.breakiterator = true;
 423         }
 424     },
 425 
 426     LOCALE("-locale", true) {
 427         @Override
 428         public void process(Helper helper, String arg) {
 429             helper.docLocale = arg;
 430         }
 431     },
 432 
 433     XCLASSES("-Xclasses") {
 434         @Override
 435         public void process(Helper helper) {
 436             helper.jdtoolOpts.put(XCLASSES, true);
 437         }
 438     },
 439 
 440     // ----- help options -----
 441 
 442     HELP("-help") {
 443         @Override
 444         public void process(Helper helper) {
 445             helper.usage();
 446         }
 447     },
 448 
 449     X("-X") {
 450         @Override
 451         public void process(Helper helper) {
 452             helper.Xusage();
 453         }
 454     };
 455 
 456     public final String opt;
 457     public final boolean hasArg;
 458     public final boolean hasSuffix; // ex: foo:bar or -foo=bar
 459 
 460     ToolOption(String opt) {
 461         this(opt, false);
 462     }
 463 
 464     ToolOption(String opt, boolean hasArg) {
 465         this.opt = opt;
 466         this.hasArg = hasArg;
 467         char lastChar = opt.charAt(opt.length() - 1);
 468         this.hasSuffix = lastChar == ':' || lastChar == '=';
 469     }
 470 
 471     void process(Helper helper, String arg) { }
 472 
 473     void process(Helper helper) { }
 474 
 475     static ToolOption get(String name) {
 476         String oname = name;
 477         if (name.contains(":")) {
 478             oname = name.substring(0, name.indexOf(':') + 1);
 479         } else if (name.contains("=")) {
 480             oname = name.substring(0, name.indexOf('=') + 1);
 481         }
 482         for (ToolOption o : values()) {
 483             if (oname.equals(o.opt)) {
 484                 return o;
 485             }
 486         }
 487         return null;
 488     }
 489 
 490     static abstract class Helper {
 491 
 492         // File manager options
 493         final Map<Option, String> fileManagerOpts = new LinkedHashMap<>();
 494 
 495         /** javac options, set by various options. */
 496         Options compOpts; // = Options.instance(context)
 497 
 498         /** Javadoc tool options */
 499         final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
 500 
 501         /** Set by -breakiterator. */
 502         boolean breakiterator = false;
 503 
 504         /** Set by -Xwerror. */
 505         boolean rejectWarnings = false;
 506 
 507         /** Set by -prompt. */
 508         boolean promptOnError;
 509 
 510         /** Set by -locale. */
 511         String docLocale = "";
 512 
 513         Helper() {
 514             populateDefaultAccessMap();
 515         }
 516 
 517         abstract void usage();
 518         abstract void Xusage();
 519 
 520         abstract void usageError(String msg, Object... args);
 521         abstract OptionHelper getOptionHelper();
 522 
 523         @SuppressWarnings("unchecked")
 524         void addToList(ToolOption opt, String delimiter, String str) {
 525             List<String> list = (List<String>) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>());
 526             list.addAll(Arrays.asList(str.split(delimiter)));
 527             jdtoolOpts.put(opt, list);
 528         }
 529 
 530         String getOptionArgumentValue(String in) {
 531             String[] values = in.trim().split(":");
 532             return values[1];
 533         }
 534 
 535         void setExpandRequires(ToolOption opt, String arg) {
 536             switch (arg) {
 537                 case "public":
 538                     jdtoolOpts.put(opt, AccessKind.PUBLIC);
 539                     break;
 540                 case "all":
 541                     jdtoolOpts.put(opt, AccessKind.PRIVATE);
 542                     break;
 543                 default:
 544                     usageError("main.illegal_option_value", arg);
 545             }
 546         }
 547 
 548         void setShowModuleContents(ToolOption opt, String arg) {
 549             switch (arg) {
 550                 case "api":
 551                     jdtoolOpts.put(opt, AccessKind.PUBLIC);
 552                     break;
 553                 case "all":
 554                     jdtoolOpts.put(opt, AccessKind.PRIVATE);
 555                     break;
 556                 default:
 557                     usageError("main.illegal_option_value", arg);
 558             }
 559         }
 560 
 561         void setShowPackageAccess(ToolOption opt, String arg) {
 562             switch (arg) {
 563                 case "exported":
 564                     jdtoolOpts.put(opt, AccessKind.PUBLIC);
 565                     break;
 566                 case "all":
 567                     jdtoolOpts.put(opt, AccessKind.PRIVATE);
 568                     break;
 569                 default:
 570                     usageError("main.illegal_option_value", arg);
 571             }
 572         }
 573 
 574 
 575         void setFilter(ToolOption opt, String arg) {
 576             jdtoolOpts.put(opt, getAccessValue(arg));
 577         }
 578 
 579         void setSimpleFilter(String arg) {
 580             handleSimpleOption(arg);
 581         }
 582 
 583         void setFileManagerOpt(Option opt, String arg) {
 584             fileManagerOpts.put(opt, arg);
 585         }
 586 
 587         void handleSimpleOption(String arg) {
 588             populateSimpleAccessMap(getAccessValue(arg));
 589         }
 590 
 591         /*
 592          * This method handles both the simple options -package,
 593          * -private, so on, in addition to the new ones such as
 594          * --show-types:public and so on.
 595          */
 596         private AccessKind getAccessValue(String arg) {
 597             int colon = arg.indexOf(':');
 598             String value = (colon > 0)
 599                     ? arg.substring(colon + 1)
 600                     : arg;
 601             switch (value) {
 602                 case "public":
 603                     return AccessKind.PUBLIC;
 604                 case "protected":
 605                     return AccessKind.PROTECTED;
 606                 case "package":
 607                     return AccessKind.PACKAGE;
 608                 case "private":
 609                     return AccessKind.PRIVATE;
 610                 default:
 611                     usageError("main.illegal_option_value", value);
 612                     return null;
 613             }
 614         }
 615 
 616         /*
 617          * Sets the entire kind map to PROTECTED this is the default.
 618          */
 619         private void populateDefaultAccessMap() {
 620             populateSimpleAccessMap(AccessKind.PROTECTED);
 621         }
 622 
 623         /*
 624          * This sets access to all the allowed kinds in the
 625          * access map.
 626          */
 627         void populateSimpleAccessMap(AccessKind accessValue) {
 628             for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
 629                 switch (kind) {
 630                     case METHOD:
 631                         jdtoolOpts.put(SHOW_MEMBERS, accessValue);
 632                         break;
 633                     case CLASS:
 634                         jdtoolOpts.put(SHOW_TYPES, accessValue);
 635                         break;
 636                     case PACKAGE:
 637                         jdtoolOpts.put(SHOW_PACKAGES, accessValue);
 638                         break;
 639                     case MODULE:
 640                         jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue);
 641                         break;
 642                     default:
 643                         throw new AssertionError("unknown element kind:" + kind);
 644                 }
 645             }
 646         }
 647     }
 648 }