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     MODULE_SOURCE_PATH("--module-source-path", true) {
 110         @Override
 111         public void process(Helper helper, String arg) {
 112             helper.setFileManagerOpt(Option.MODULE_SOURCE_PATH, arg);
 113         }
 114     },
 115 
 116     UPGRADE_MODULE_PATH("--upgrade-module-path", true) {
 117         @Override
 118         public void process(Helper helper, String arg) {
 119             helper.setFileManagerOpt(Option.UPGRADE_MODULE_PATH, arg);
 120         }
 121     },
 122 
 123     SYSTEM("--system", true) {
 124         @Override
 125         public void process(Helper helper, String arg) {
 126             helper.setFileManagerOpt(Option.SYSTEM, arg);
 127         }
 128     },
 129 
 130     MODULE_PATH("--module-path", true) {
 131         @Override
 132         public void process(Helper helper, String arg) {
 133             helper.setFileManagerOpt(Option.MODULE_PATH, arg);
 134         }
 135     },
 136 
 137     P("-p", true) {
 138         @Override
 139         public void process(Helper helper, String arg) {
 140             helper.setFileManagerOpt(Option.MODULE_PATH, arg);
 141         }
 142     },
 143 
 144     ADD_MODULES("--add-modules", true) {
 145         @Override
 146         public void process(Helper helper, String arg) {
 147             Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
 148         }
 149     },
 150 
 151     LIMIT_MODULES("--limit-modules", true) {
 152         @Override
 153         public void process(Helper helper, String arg) {
 154             Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
 155         }
 156     },
 157 
 158     MODULE("--module", true) {
 159         @Override
 160         public void process(Helper helper, String arg) {
 161             helper.addToList(this, ",", arg);
 162         }
 163     },
 164 
 165     ENCODING("-encoding", true) {
 166         @Override
 167         public void process(Helper helper, String arg) {
 168             helper.setFileManagerOpt(Option.ENCODING, arg);
 169         }
 170     },
 171 
 172     RELEASE("--release", true) {
 173         @Override
 174         public void process(Helper helper, String arg) {
 175             Option.RELEASE.process(helper.getOptionHelper(), opt, arg);
 176         }
 177     },
 178 
 179     SOURCE("-source", true) {
 180         @Override
 181         public void process(Helper helper, String arg) {
 182             Option.SOURCE.process(helper.getOptionHelper(), opt, arg);
 183         }
 184     },
 185 
 186     XMAXERRS("-Xmaxerrs", true) {
 187         @Override
 188         public void process(Helper helper, String arg) {
 189             Option.XMAXERRS.process(helper.getOptionHelper(), opt, arg);
 190         }
 191     },
 192 
 193     XMAXWARNS("-Xmaxwarns", true) {
 194         @Override
 195         public void process(Helper helper, String arg) {
 196             Option.XMAXWARNS.process(helper.getOptionHelper(), opt, arg);
 197         }
 198     },
 199 
 200     ADD_READS("--add-reads", true) {
 201         @Override
 202         public void process(Helper helper, String arg) {
 203             Option.ADD_READS.process(helper.getOptionHelper(), opt, arg);
 204         }
 205     },
 206 
 207     ADD_EXPORTS("--add-exports", true) {
 208         @Override
 209         public void process(Helper helper, String arg) {
 210             Option.ADD_EXPORTS.process(helper.getOptionHelper(), opt, arg);
 211         }
 212     },
 213 
 214     XMODULE("-Xmodule:", false) {
 215         @Override
 216         public void process(Helper helper, String arg) {
 217             Option.XMODULE.process(helper.getOptionHelper(), arg);
 218         }
 219     },
 220 
 221     PATCH_MODULE("--patch-module", true) {
 222         @Override
 223         public void process(Helper helper, String arg) {
 224             Option.PATCH_MODULE.process(helper.getOptionHelper(), opt, arg);
 225         }
 226     },
 227 
 228     // ----- doclet options -----
 229 
 230     DOCLET("-doclet", true), // handled in setDocletInvoker
 231 
 232     DOCLETPATH("-docletpath", true), // handled in setDocletInvoker
 233 
 234     // ----- selection options -----
 235 
 236     SUBPACKAGES("-subpackages", true) {
 237         @Override
 238         public void process(Helper helper, String arg) {
 239             helper.addToList(this, ":", arg);
 240         }
 241     },
 242 
 243     EXCLUDE("-exclude", true) {
 244         @Override
 245         public void process(Helper helper, String arg) {
 246             helper.addToList(this, ":", arg);
 247         }
 248     },
 249 
 250     // ----- filtering options -----
 251 
 252     PACKAGE("-package") {
 253         @Override
 254         public void process(Helper helper) {
 255             helper.setSimpleFilter("package");
 256         }
 257     },
 258 
 259     PRIVATE("-private") {
 260         @Override
 261         public void process(Helper helper) {
 262             helper.setSimpleFilter("private");
 263         }
 264     },
 265 
 266     PROTECTED("-protected") {
 267         @Override
 268         public void process(Helper helper) {
 269             helper.setSimpleFilter("protected");
 270         }
 271     },
 272 
 273     PUBLIC("-public") {
 274         @Override
 275         public void process(Helper helper) {
 276             helper.setSimpleFilter("public");
 277         }
 278     },
 279 
 280     SHOW_MEMBERS("--show-members:") {
 281         @Override
 282         public void process(Helper helper, String arg) {
 283             helper.setFilter(this, arg);
 284         }
 285     },
 286 
 287     SHOW_TYPES("--show-types:") {
 288         @Override
 289         public void process(Helper helper, String arg) {
 290             helper.setFilter(this, arg);
 291         }
 292     },
 293 
 294     SHOW_PACKAGES("--show-packages:") {
 295         @Override
 296         public void process(Helper helper, String arg) {
 297             helper.setShowPackageAccess(SHOW_PACKAGES, helper.getOptionArgumentValue(arg));
 298         }
 299     },
 300 
 301     SHOW_MODULE_CONTENTS("--show-module-contents:") {
 302         @Override
 303         public void process(Helper helper, String arg) {
 304             helper.setShowModuleContents(SHOW_MODULE_CONTENTS, helper.getOptionArgumentValue(arg));
 305         }
 306     },
 307 
 308     EXPAND_REQUIRES("--expand-requires:") {
 309         @Override
 310         public void process(Helper helper, String arg) {
 311             helper.setExpandRequires(EXPAND_REQUIRES, helper.getOptionArgumentValue(arg));
 312         }
 313     },
 314 
 315     // ----- output control options -----
 316 
 317     PROMPT("-prompt") {
 318         @Override
 319         public void process(Helper helper) {
 320             helper.compOpts.put("-prompt", "-prompt");
 321             helper.promptOnError = true;
 322         }
 323     },
 324 
 325     QUIET("-quiet") {
 326         @Override
 327         public void process(Helper helper) {
 328             helper.jdtoolOpts.put(QUIET, true);
 329         }
 330     },
 331 
 332     VERBOSE("-verbose") {
 333         @Override
 334         public void process(Helper helper) {
 335             helper.compOpts.put("-verbose", "");
 336         }
 337     },
 338 
 339     XWERROR("-Xwerror") {
 340         @Override
 341         public void process(Helper helper) {
 342             helper.rejectWarnings = true;
 343 
 344         }
 345     },
 346 
 347     // ----- other options -----
 348 
 349     BREAKITERATOR("-breakiterator") {
 350         @Override
 351         public void process(Helper helper) {
 352             helper.breakiterator = true;
 353         }
 354     },
 355 
 356     LOCALE("-locale", true) {
 357         @Override
 358         public void process(Helper helper, String arg) {
 359             helper.docLocale = arg;
 360         }
 361     },
 362 
 363     XCLASSES("-Xclasses") {
 364         @Override
 365         public void process(Helper helper) {
 366             helper.jdtoolOpts.put(XCLASSES, true);
 367         }
 368     },
 369 
 370     // ----- help options -----
 371 
 372     HELP("-help") {
 373         @Override
 374         public void process(Helper helper) {
 375             helper.usage();
 376         }
 377     },
 378 
 379     X("-X") {
 380         @Override
 381         public void process(Helper helper) {
 382             helper.Xusage();
 383         }
 384     };
 385 
 386     public final String opt;
 387     public final boolean hasArg;
 388     public final boolean hasSuffix; // ex: foo:bar or -foo=bar
 389 
 390     ToolOption(String opt) {
 391         this(opt, false);
 392     }
 393 
 394     ToolOption(String opt, boolean hasArg) {
 395         this.opt = opt;
 396         this.hasArg = hasArg;
 397         char lastChar = opt.charAt(opt.length() - 1);
 398         this.hasSuffix = lastChar == ':' || lastChar == '=';
 399     }
 400 
 401     void process(Helper helper, String arg) { }
 402 
 403     void process(Helper helper) { }
 404 
 405     static ToolOption get(String name) {
 406         String oname = name;
 407         if (name.contains(":")) {
 408             oname = name.substring(0, name.indexOf(':') + 1);
 409         } else if (name.contains("=")) {
 410             oname = name.substring(0, name.indexOf('=') + 1);
 411         }
 412         for (ToolOption o : values()) {
 413             if (oname.equals(o.opt)) {
 414                 return o;
 415             }
 416         }
 417         return null;
 418     }
 419 
 420     static abstract class Helper {
 421 
 422         // File manager options
 423         final Map<Option, String> fileManagerOpts = new LinkedHashMap<>();
 424 
 425         /** javac options, set by various options. */
 426         Options compOpts; // = Options.instance(context)
 427 
 428         /** Javadoc tool options */
 429         final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
 430 
 431         /** Set by -breakiterator. */
 432         boolean breakiterator = false;
 433 
 434         /** Set by -Xwerror. */
 435         boolean rejectWarnings = false;
 436 
 437         /** Set by -prompt. */
 438         boolean promptOnError;
 439 
 440         /** Set by -locale. */
 441         String docLocale = "";
 442 
 443         Helper() {
 444             populateDefaultAccessMap();
 445         }
 446 
 447         abstract void usage();
 448         abstract void Xusage();
 449 
 450         abstract void usageError(String msg, Object... args);
 451         abstract OptionHelper getOptionHelper();
 452 
 453         @SuppressWarnings("unchecked")
 454         void addToList(ToolOption opt, String delimiter, String str) {
 455             List<String> list = (List<String>) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>());
 456             list.addAll(Arrays.asList(str.split(delimiter)));
 457             jdtoolOpts.put(opt, list);
 458         }
 459 
 460         String getOptionArgumentValue(String in) {
 461             String[] values = in.trim().split(":");
 462             return values[1];
 463         }
 464 
 465         void setExpandRequires(ToolOption opt, String arg) {
 466             switch (arg) {
 467                 case "public":
 468                     jdtoolOpts.put(opt, AccessKind.PUBLIC);
 469                     break;
 470                 case "all":
 471                     jdtoolOpts.put(opt, AccessKind.PRIVATE);
 472                     break;
 473                 default:
 474                     usageError("main.illegal_option_value", arg);
 475             }
 476         }
 477 
 478         void setShowModuleContents(ToolOption opt, String arg) {
 479             switch (arg) {
 480                 case "api":
 481                     jdtoolOpts.put(opt, AccessKind.PUBLIC);
 482                     break;
 483                 case "all":
 484                     jdtoolOpts.put(opt, AccessKind.PRIVATE);
 485                     break;
 486                 default:
 487                     usageError("main.illegal_option_value", arg);
 488             }
 489         }
 490 
 491         void setShowPackageAccess(ToolOption opt, String arg) {
 492             switch (arg) {
 493                 case "exported":
 494                     jdtoolOpts.put(opt, AccessKind.PUBLIC);
 495                     break;
 496                 case "all":
 497                     jdtoolOpts.put(opt, AccessKind.PRIVATE);
 498                     break;
 499                 default:
 500                     usageError("main.illegal_option_value", arg);
 501             }
 502         }
 503 
 504 
 505         void setFilter(ToolOption opt, String arg) {
 506             jdtoolOpts.put(opt, getAccessValue(arg));
 507         }
 508 
 509         void setSimpleFilter(String arg) {
 510             handleSimpleOption(arg);
 511         }
 512 
 513         void setFileManagerOpt(Option opt, String arg) {
 514             fileManagerOpts.put(opt, arg);
 515         }
 516 
 517         void handleSimpleOption(String arg) {
 518             populateSimpleAccessMap(getAccessValue(arg));
 519         }
 520 
 521         /*
 522          * This method handles both the simple options -package,
 523          * -private, so on, in addition to the new ones such as
 524          * --show-types:public and so on.
 525          */
 526         private AccessKind getAccessValue(String arg) {
 527             int colon = arg.indexOf(':');
 528             String value = (colon > 0)
 529                     ? arg.substring(colon + 1)
 530                     : arg;
 531             switch (value) {
 532                 case "public":
 533                     return AccessKind.PUBLIC;
 534                 case "protected":
 535                     return AccessKind.PROTECTED;
 536                 case "package":
 537                     return AccessKind.PACKAGE;
 538                 case "private":
 539                     return AccessKind.PRIVATE;
 540                 default:
 541                     usageError("main.illegal_option_value", value);
 542                     return null;
 543             }
 544         }
 545 
 546         /*
 547          * Sets the entire kind map to PROTECTED this is the default.
 548          */
 549         private void populateDefaultAccessMap() {
 550             populateSimpleAccessMap(AccessKind.PROTECTED);
 551         }
 552 
 553         /*
 554          * This sets access to all the allowed kinds in the
 555          * access map.
 556          */
 557         void populateSimpleAccessMap(AccessKind accessValue) {
 558             for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
 559                 switch (kind) {
 560                     case METHOD:
 561                         jdtoolOpts.put(SHOW_MEMBERS, accessValue);
 562                         break;
 563                     case CLASS:
 564                         jdtoolOpts.put(SHOW_TYPES, accessValue);
 565                         break;
 566                     case PACKAGE:
 567                         jdtoolOpts.put(SHOW_PACKAGES, accessValue);
 568                         break;
 569                     case MODULE:
 570                         jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue);
 571                         break;
 572                     default:
 573                         throw new AssertionError("unknown element kind:" + kind);
 574                 }
 575             }
 576         }
 577     }
 578 }