001/* 002 * Copyright (c) 2016 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2016-03-08 00:32:45 +0000 (Tue, 08 Mar 2016) $' 007 * '$Revision: 34450 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029package org.kepler; 030 031import java.util.Collection; 032import java.util.HashMap; 033import java.util.Map; 034 035/** A class to hold command line argument information used when parsing 036 * the Kepler command like arguments. 037 * 038 * @author Daniel Crawl 039 * @version $Id: CommandLineArgument.java 34450 2016-03-08 00:32:45Z crawl $ 040 */ 041public class CommandLineArgument { 042 043 /** Create a new CommandLineArgument for a flag with a description. */ 044 private CommandLineArgument(String flag, String description) { 045 this(flag, 0, description); 046 } 047 048 /** Create a new CommandLineArgument for a flag with following values. */ 049 private CommandLineArgument(String flag, int numArgs, String description, Object... defaultValues) { 050 _flag = flag; 051 _description = description; 052 _numArguments = numArgs; 053 054 if(numArgs != defaultValues.length) { 055 throw new IllegalArgumentException("Number of arguments must match number of default values."); 056 } 057 058 if(_numArguments > 0) { 059 _values = new String[_numArguments]; 060 for(int i = 0; i < _numArguments; i++) { 061 _values[i] = defaultValues[i].toString(); 062 } 063 } 064 } 065 066 /** Add a new CommandLineArgument for a flag with a description. */ 067 public static CommandLineArgument add(String flag, String description) { 068 return add(flag, 0, description); 069 } 070 071 /** Add a new CommandLineArgument for a flag with following values. */ 072 public static CommandLineArgument add(String flag, int numArgs, String description, Object... defaultStr) { 073 CommandLineArgument arg = new CommandLineArgument(flag, numArgs, description, defaultStr); 074 _argsMap.put(flag, arg); 075 return arg; 076 } 077 078 /** Get the CommandLineArgument for a specific flag. */ 079 public static CommandLineArgument get(String flag) { 080 return _argsMap.get(flag); 081 } 082 083 /** Get all the CommandLineArguments registered. */ 084 public static Collection<CommandLineArgument> getAll() { 085 return _argsMap.values(); 086 } 087 088 /** Get the flag. */ 089 public String getFlag() { 090 return _flag; 091 } 092 093 /** Get the action class. */ 094 public String getActionClass() { 095 return _actionClass; 096 } 097 098 /** Get the action method. */ 099 public String getActionMethod() { 100 return _actionMethod; 101 } 102 103 /** Get a string for the command line usage. */ 104 public String getUsage() { 105 StringBuilder buf = new StringBuilder(); 106 buf.append(_flag) 107 // TODO use format() for spaces. 108 .append(" ") 109 .append(_description); 110 111 if(_values != null && _values.length > 0) { 112 buf.append(" (default = "); 113 for(int i = 0; i < _values.length - 1; i++) { 114 buf.append(_values[i]); 115 buf.append(" "); 116 } 117 buf.append(_values[_values.length - 1]); 118 buf.append(")"); 119 } 120 return buf.toString(); 121 } 122 123 /** Get the value of the first argument. */ 124 public String getValue() { 125 return getValue(0); 126 } 127 128 /** Get the value of the argument at a specific index. */ 129 public String getValue(int index) { 130 if(index >= _values.length) { 131 throw new IllegalArgumentException("Index must be less than number of arguments."); 132 } 133 return _values[index]; 134 } 135 136 /** Get the value of the first argument for a flag. */ 137 public static String getValue(String flag) { 138 CommandLineArgument arg = _argsMap.get(flag); 139 if(arg == null) { 140 throw new IllegalArgumentException("No command line argument with flag " + flag); 141 } 142 return arg.getValue(); 143 } 144 145 /** Returns true if this CommandLineArgument is an action to run Kepler. 146 * If true, then run() will be called instead of launching the Kepler 147 * UI or running a workflow from the command line. 148 */ 149 public boolean isAction() { 150 return _actionClass != null; 151 } 152 153 /** Parse one or more of the remaining command line arguments. 154 * @param The command line arguments. 155 * @param The index to the current command line argument yet to be parsed. 156 * @return If one or more of the current command line arguments can be 157 * parsed, the index to the next unparsed argument. Otherwise (no 158 * arguments can be parsed), returns -1. 159 */ 160 public int parseRemainingArgs(String[] args, int i) throws IllegalArgumentException { 161 if(args[i].equals(_flag)) { 162 // increment the index past the flag argument 163 i++; 164 // try to parse the arguments after the flag, if any 165 for(int j = 0; j < _numArguments; j++) { 166 // see if there are not enough arguments. 167 if(i >= args.length) { 168 // TODO 169 throw new IllegalArgumentException(); 170 } 171 // save the argument 172 _values[j] = args[i]; 173 // increment to parse the next argument 174 i++; 175 } 176 _parsed = true; 177 return i; 178 } 179 _parsed = false; 180 return -1; 181 } 182 183 /** Set the class and method to invoke if this argument is seen on the command line. */ 184 public void setAction(String actionClass, String actionMethod) { 185 _actionClass = actionClass; 186 _actionMethod = actionMethod; 187 } 188 189 /** Get a string representation of the command line argument. */ 190 @Override 191 public String toString() { 192 StringBuilder buf = new StringBuilder(_flag + " parsed=" + _parsed); 193 if(_numArguments > 0 && _parsed) { 194 buf.append(" args="); 195 for(int i = 0; i < _numArguments - 1; i++) { 196 buf.append(_values[i]).append(","); 197 } 198 buf.append(_values[_numArguments - 1]); 199 } 200 201 return buf.toString(); 202 } 203 204 /** Returns true if the last call to parseRemainingArgs() succeeded. */ 205 public boolean wasParsed() { 206 return _parsed; 207 } 208 209 /** Returns true if the last call to parseRemainingArgs() succeeded. */ 210 public static boolean wasParsed(String flag) { 211 CommandLineArgument arg = _argsMap.get(flag); 212 if(arg == null) { 213 throw new IllegalArgumentException("No command line argument with flag " + flag); 214 } 215 return arg.wasParsed(); 216 } 217 218 /** The flag for the argmument. */ 219 private String _flag; 220 221 /** The description of the argument. */ 222 private String _description; 223 224 /** The number of arguments after flag on the command line. */ 225 private int _numArguments; 226 227 /** If true, this argument was seen on the command line. */ 228 private boolean _parsed = false; 229 230 /** The values seen on the command line after the flag. */ 231 private String[] _values; 232 233 /** The class to run if this argument was seen on the command line. */ 234 private String _actionClass; 235 236 /** The method to invoke if this argument was seen on the command line. */ 237 private String _actionMethod; 238 239 /** A map of flag to CommandLineArgument containing all the CommandLineArguments registered */ 240 private final static Map<String,CommandLineArgument> _argsMap = new HashMap<String,CommandLineArgument>(); 241}