/* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.tools.jimage; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; /** * * JImage tools shared helper. */ public final class TaskHelper { public class BadArgs extends Exception { static final long serialVersionUID = 8765093759964640721L; private BadArgs(String key, Object... args) { super(bundleHelper.getMessage(key, args)); this.key = key; this.args = args; } public BadArgs showUsage(boolean b) { showUsage = b; return this; } public final String key; public final Object[] args; public boolean showUsage; } public static abstract class Option { final boolean hasArg; final String[] aliases; public Option(boolean hasArg, String... aliases) { this.hasArg = hasArg; this.aliases = aliases; } public boolean isHidden() { return false; } public boolean matches(String opt) { for (String a : aliases) { if (a.equals(opt)) { return true; } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) { return true; } } return false; } public boolean ignoreRest() { return false; } protected abstract void process(T task, String opt, String arg) throws BadArgs; } public static abstract class HiddenOption extends Option { public HiddenOption(boolean hasArg, String... aliases) { super(hasArg, aliases); } @Override public boolean isHidden() { return true; } } private class ResourceBundleHelper { private final ResourceBundle bundle; ResourceBundleHelper(String path) { Locale locale = Locale.getDefault(); try { bundle = ResourceBundle.getBundle(path, locale); } catch (MissingResourceException e) { throw new InternalError("Cannot find resource bundle for locale " + locale); } } String getMessage(String key, Object... args) { String val = bundle.getString(key); return MessageFormat.format(val, args); } } public class OptionsHelper { private final List> options; OptionsHelper(List> options) { this.options = options; } public List handleOptions(T task, String[] args) throws BadArgs { List rest = new ArrayList<>(); // process options for (int i = 0; i < args.length; i++) { if (args[i].charAt(0) == '-') { String name = args[i]; Option option = getOption(name); if (option == null) { throw new BadArgs("err.unknown.option", name).showUsage(true); } String param = null; if (option.hasArg) { if (name.startsWith("--") && name.indexOf('=') > 0) { param = name.substring(name.indexOf('=') + 1, name.length()); } else if (i + 1 < args.length) { param = args[++i]; } if (param == null || param.isEmpty() || param.charAt(0) == '-') { throw new BadArgs("err.missing.arg", name).showUsage(true); } } option.process(task, name, param); if (option.ignoreRest()) { i = args.length; } } else { rest.add(args[i]); } } return rest; } private Option getOption(String name) throws BadArgs { for (Option o : options) { if (o.matches(name)) { return o; } } return null; } public void showHelp(String progName, String pluginsHeader) { log.println(bundleHelper.getMessage("main.usage", progName)); for (Option o : options) { String name = o.aliases[0].substring(1); // there must always be at least one name name = name.charAt(0) == '-' ? name.substring(1) : name; if (o.isHidden() || name.equals("h")) { continue; } log.println(bundleHelper.getMessage("main.opt." + name)); } } } private PrintWriter log; private final ResourceBundleHelper bundleHelper; public TaskHelper(String path) { this.bundleHelper = new ResourceBundleHelper(path); } public OptionsHelper newOptionsHelper(Class clazz, Option[] options) { List> optionsList = new ArrayList<>(); for (Option o : options) { @SuppressWarnings("unchecked") Option opt = (Option) o; optionsList.add(opt); } return new OptionsHelper<>(optionsList); } public BadArgs newBadArgs(String key, Object... args) { return new BadArgs(key, args); } public String getMessage(String key, Object... args) { return bundleHelper.getMessage(key, args); } public void setLog(PrintWriter log) { this.log = log; } public void reportError(String key, Object... args) { log.println(bundleHelper.getMessage("error.prefix") + " " + bundleHelper.getMessage(key, args)); } public void warning(String key, Object... args) { log.println(bundleHelper.getMessage("warn.prefix") + " " + bundleHelper.getMessage(key, args)); } public void showVersion(boolean full) { log.println(version(full ? "full" : "release")); } public String version(String key) { return System.getProperty("java.version"); } }