| /* |
| * Copyright 2006 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.util.tools; |
| |
| import com.google.gwt.dev.About; |
| |
| import java.util.HashSet; |
| import java.util.LinkedHashMap; |
| import java.util.LinkedHashSet; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * A base class for a GWT related command-line application. To use this: |
| * <ol> |
| * <li>Derive a class for this class.</li> |
| * <li>In your constructor, call {@link #registerHandler(ArgHandler)} |
| * repeatedly to register particular command line arguments and options.</li> |
| * <li>Write a main that looks like this: |
| * |
| * <pre> |
| * public static void main(String[] args) { |
| * MyShell myShell = new MyShell(); |
| * if (myShell.processArgs(args)) { |
| * // main program operation |
| * } |
| * System.exit(1); |
| * } |
| * </pre> |
| * |
| * </li> |
| * <li>Create launch config whose main class is MyShell.</li> |
| * </ol> |
| */ |
| public abstract class ToolBase { |
| |
| private static final String PROPERTY_NOWARN_LEGACY_TOOLS = "gwt.nowarn.legacy.tools"; |
| |
| /** |
| * Use a linked hash map to preserve the declaration order. |
| */ |
| private final Map<String, ArgHandler> argHandlers = new LinkedHashMap<String, ArgHandler>(); |
| |
| /** |
| * Log deprecation warning on old JREs. |
| */ |
| protected void checkJdkVersion() { |
| // JDK 1.6 is 50 |
| double classVersion = Double.valueOf(System.getProperty("java.class.version","0.0")); |
| if (classVersion < 50) { |
| System.err.println("WARNING: Use on a JRE prior to version 1.6 is deprecated"); |
| } |
| } |
| |
| protected String getDescription() { |
| return null; |
| } |
| |
| protected String getName() { |
| return getClass().getName(); |
| } |
| |
| protected void printHelp() { |
| printHelp(false); |
| } |
| |
| protected void printHelp(boolean includeUndocumented) { |
| System.err.println(About.getGwtVersion()); |
| |
| Set<ArgHandler> uniqueArgHandlers = new LinkedHashSet<ArgHandler>(argHandlers.values()); |
| |
| ArgHandler nullHandler = null; |
| int widest = 0; |
| for (ArgHandler handler : uniqueArgHandlers) { |
| if (handler.isUndocumented()) { |
| continue; |
| } |
| String helpTag = handler.getHelpTag(); |
| if (helpTag != null) { |
| if (helpTag.length() > widest) { |
| widest = helpTag.length(); |
| } |
| } else { |
| nullHandler = handler; |
| int len = nullHandler.getTagArgs()[0].length(); |
| if (len > widest) { |
| widest = len; |
| } |
| } |
| } |
| |
| // Print the name. |
| // |
| String name = getName(); |
| int i = name.lastIndexOf('.'); |
| if (i != -1) { |
| name = name.substring(i + 1); |
| } |
| System.err.print(name); |
| |
| // Print the command-line template. |
| // |
| for (ArgHandler handler : uniqueArgHandlers) { |
| if (!includeUndocumented && handler.isUndocumented()) { |
| continue; |
| } |
| String helpTag = handler.getHelpTag(); |
| if (helpTag != null) { |
| System.err.print(handler.isRequired() ? " " : " ["); |
| System.err.print(helpTag); |
| String[] tagArgs = handler.getTagArgs(); |
| for (String tagArg : tagArgs) { |
| System.err.print(" " + tagArg); |
| } |
| System.err.print(handler.isRequired() ? "" : "]"); |
| } |
| } |
| |
| // Print the flagless args. |
| // |
| if (nullHandler != null && (!nullHandler.isUndocumented() || includeUndocumented)) { |
| String[] tagArgs = nullHandler.getTagArgs(); |
| for (String element : tagArgs) { |
| System.err.print(nullHandler.isRequired() ? " " : " ["); |
| System.err.print(element); |
| System.err.print(nullHandler.isRequired() ? " " : "]"); |
| } |
| System.err.println(); |
| } |
| |
| System.err.println(); |
| String description = getDescription(); |
| if (description != null) { |
| System.err.println(description); |
| System.err.println(); |
| } |
| |
| System.err.println("where "); |
| |
| // Print the details. |
| // |
| for (ArgHandler handler : uniqueArgHandlers) { |
| if (!includeUndocumented && handler.isUndocumented()) { |
| continue; |
| } |
| String helpTag = handler.getHelpTag(); |
| if (helpTag != null) { |
| int len = helpTag.length(); |
| System.err.print(" "); |
| System.err.print(helpTag); |
| for (i = len; i < widest; ++i) { |
| System.err.print(' '); |
| } |
| System.err.print(" "); |
| System.err.print(handler.getPurpose()); |
| System.err.println(); |
| } |
| } |
| |
| // And details for the "extra" args, if any. |
| // |
| if (nullHandler != null && (!nullHandler.isUndocumented() || includeUndocumented)) { |
| System.err.println("and "); |
| String tagArg = nullHandler.getTagArgs()[0]; |
| int len = tagArg.length(); |
| System.err.print(" "); |
| System.err.print(tagArg); |
| for (i = len; i < widest; ++i) { |
| System.err.print(' '); |
| } |
| System.err.print(" "); |
| System.err.print(nullHandler.getPurpose()); |
| System.err.println(); |
| } |
| } |
| |
| protected boolean processArgs(String... args) { |
| checkJdkVersion(); |
| |
| if (args.length > 0) { |
| boolean help = false; |
| boolean helpUndocumented = false; |
| if ("-help".equalsIgnoreCase(args[0])) { |
| help = true; |
| } else if ("-?".equals(args[0])) { |
| help = true; |
| } else if ("-helpfull".equalsIgnoreCase(args[0])) { |
| help = helpUndocumented = true; |
| } else if ("-??".equals(args[0])) { |
| help = helpUndocumented = true; |
| } |
| |
| if (help) { |
| printHelp(helpUndocumented); |
| return false; |
| } |
| } |
| |
| Set<ArgHandler> defs = new HashSet<ArgHandler>(argHandlers.values()); |
| int extraArgCount = 0; |
| |
| Set<ArgHandler> receivedArg = new HashSet<ArgHandler>(); |
| |
| // Let the args drive the handlers. |
| // |
| ArgHandler nullHandler = argHandlers.get(""); |
| for (int i = 0; i < args.length; i++) { |
| String arg = args[i]; |
| ArgHandler handler; |
| if (arg.startsWith("-")) { |
| // Use the handler registered for this flag. |
| // |
| handler = argHandlers.get(arg); |
| } else { |
| // Use the handler that doesn't have a leading flag. |
| // |
| handler = nullHandler; |
| ++extraArgCount; |
| } |
| |
| if (handler == null) { |
| System.err.println("Unknown argument: " + arg); |
| printHelp(); |
| return false; |
| } |
| |
| int addtlConsumed = handler.handle(args, i); |
| if (addtlConsumed == -1) { |
| printHelp(); |
| return false; |
| } |
| |
| i += addtlConsumed; |
| |
| // We don't need to use this as a default handler. |
| // |
| defs.remove(handler); |
| |
| // Record that this handler saw a value |
| // |
| receivedArg.add(handler); |
| } |
| |
| // See if any handler didn't get its required argument(s). |
| // |
| for (ArgHandler argHandler : argHandlers.values()) { |
| if (argHandler.isRequired() && !receivedArg.contains(argHandler)) { |
| System.err.print("Missing required argument '"); |
| String tag = argHandler.getTag(); |
| if (tag != null) { |
| System.err.print(tag); |
| System.err.print(" "); |
| } |
| |
| String tagArg = argHandler.getTagArgs()[0]; |
| System.err.print(tagArg); |
| System.err.println("'"); |
| |
| printHelp(); |
| return false; |
| } |
| } |
| if (extraArgCount == 0 && nullHandler != null && nullHandler.isRequired()) { |
| System.err.print("Missing required argument '"); |
| String tagArg = nullHandler.getTagArgs()[0]; |
| System.err.print(tagArg); |
| System.err.println("'"); |
| printHelp(); |
| return false; |
| } |
| |
| // Set if there are any remaining unused handlers with default arguments. |
| // Allow the default handlers to pretend there were other arguments. |
| // |
| for (ArgHandler def : defs) { |
| String[] defArgs = def.getDefaultArgs(); |
| if (defArgs != null) { |
| if (def.handle(defArgs, 0) == -1) { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| protected void registerHandler(ArgHandler handler) { |
| for (String tag : handler.getTags()) { |
| tag = tag != null ? tag : ""; |
| argHandlers.put(tag, handler); |
| } |
| } |
| } |