blob: 3ae4e9d460c63ca69c41633fde852af5680b946f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.oodt.cas.cli;
//OODT static imports
import static org.apache.oodt.cas.cli.util.CmdLineUtils.asAdvancedOption;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.determineFailedValidation;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.determineRequired;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.findFirstActionOption;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.findHelpOption;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.findPerformAndQuitOptions;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.findPrintSupportedActionsOption;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.handlePerformAndQuitOption;
import static org.apache.oodt.cas.cli.util.CmdLineUtils.isAdvancedOption;
//JDK imports
import java.util.HashSet;
import java.util.List;
import java.util.Set;
//Apache imports
import org.apache.commons.lang.Validate;
//OODT imports
import org.apache.oodt.cas.cli.action.CmdLineAction.ActionMessagePrinter;
import org.apache.oodt.cas.cli.action.store.CmdLineActionStore;
import org.apache.oodt.cas.cli.action.store.spring.SpringCmdLineActionStoreFactory;
import org.apache.oodt.cas.cli.construct.CmdLineConstructor;
import org.apache.oodt.cas.cli.construct.StdCmdLineConstructor;
import org.apache.oodt.cas.cli.exception.CmdLineActionException;
import org.apache.oodt.cas.cli.exception.CmdLineActionExecutionException;
import org.apache.oodt.cas.cli.exception.CmdLineActionStoreException;
import org.apache.oodt.cas.cli.exception.CmdLineConstructionException;
import org.apache.oodt.cas.cli.exception.CmdLineOptionStoreException;
import org.apache.oodt.cas.cli.exception.CmdLineParserException;
import org.apache.oodt.cas.cli.option.ActionCmdLineOption;
import org.apache.oodt.cas.cli.option.CmdLineOption;
import org.apache.oodt.cas.cli.option.CmdLineOptionInstance;
import org.apache.oodt.cas.cli.option.HelpCmdLineOption;
import org.apache.oodt.cas.cli.option.PrintSupportedActionsCmdLineOption;
import org.apache.oodt.cas.cli.option.store.CmdLineOptionStore;
import org.apache.oodt.cas.cli.option.store.spring.SpringCmdLineOptionStoreFactory;
import org.apache.oodt.cas.cli.option.validator.CmdLineOptionValidator;
import org.apache.oodt.cas.cli.parser.CmdLineParser;
import org.apache.oodt.cas.cli.parser.StdCmdLineParser;
import org.apache.oodt.cas.cli.presenter.CmdLinePresenter;
import org.apache.oodt.cas.cli.presenter.StdCmdLinePresenter;
import org.apache.oodt.cas.cli.printer.CmdLinePrinter;
import org.apache.oodt.cas.cli.printer.StdCmdLinePrinter;
import org.apache.oodt.cas.cli.util.CmdLineIterable;
import org.apache.oodt.cas.cli.util.CmdLineUtils;
import org.apache.oodt.cas.cli.util.ParsedArg;
//Google imports
import com.google.common.collect.Lists;
/**
* A highly configurable utility class which supports parsing and handling of
* command line arguments via its action driven design. After parsing the
* command line arguments it will check for required arguments not specified,
* validate the arguments, run the arguments handlers and then invoke the
* specified action. It also supports print out help messages and printing
* supported actions.
*
* @author bfoster (Brian Foster)
*/
public class CmdLineUtility {
private boolean debugMode;
private CmdLineParser parser;
private CmdLineConstructor constructor;
private CmdLineOptionStore optionStore;
private CmdLineActionStore actionStore;
private CmdLinePrinter printer;
private CmdLinePresenter presenter;
public CmdLineUtility() {
parser = new StdCmdLineParser();
constructor = new StdCmdLineConstructor();
optionStore = new SpringCmdLineOptionStoreFactory().createStore();
actionStore = new SpringCmdLineActionStoreFactory().createStore();
printer = new StdCmdLinePrinter();
presenter = new StdCmdLinePresenter();
debugMode = Boolean.getBoolean("org.apache.oodt.cas.cli.debug");
}
public CmdLineOptionStore getOptionStore() {
return optionStore;
}
public void setOptionStore(CmdLineOptionStore optionStore) {
this.optionStore = optionStore;
}
public CmdLineActionStore getActionStore() {
return actionStore;
}
public void setActionStore(CmdLineActionStore actionStore) {
this.actionStore = actionStore;
}
public CmdLinePrinter getPrinter() {
return printer;
}
public void setPrinter(CmdLinePrinter printer) {
this.printer = printer;
}
public CmdLinePresenter getPresenter() {
return presenter;
}
public void setPresenter(CmdLinePresenter presenter) {
this.presenter = presenter;
}
public void printOptionHelp(CmdLineArgs cmdLineArgs) {
presenter.presentOptionHelp(printer.printOptionsHelp(cmdLineArgs
.getSupportedOptions()));
}
public void printActionHelp(CmdLineArgs cmdLineArgs) {
Validate.notEmpty(cmdLineArgs.getHelpOptionInst().getValues());
presenter.presentActionHelp(printer.printActionHelp(
CmdLineUtils.findAction(cmdLineArgs.getHelpOptionInst().getValues()
.get(0), cmdLineArgs.getSupportedActions()),
cmdLineArgs.getSupportedOptions()));
}
public void printActionsHelp(CmdLineArgs cmdLineArgs) {
presenter.presentActionsHelp(printer.printActionsHelp(cmdLineArgs
.getSupportedActions()));
}
public void printActionMessages(List<String> messages) {
presenter.presentActionMessage(printer.printActionMessages(messages));
}
public void printValidationErrors(List<CmdLineOptionValidator.Result> results) {
presenter.presentErrorMessage(printer
.printOptionValidationErrors(results));
}
public void printMissingRequiredOptionsError(
Set<CmdLineOption> missingOptions) {
presenter.presentErrorMessage(printer
.printRequiredOptionsMissingError(missingOptions));
}
public void printErrorMessage(String errorMessage) {
presenter.presentErrorMessage(errorMessage);
}
/**
* Parses given command line arguments, then checks for help and print
* supported actions options, prints them out if found, otherwise performs
* execution on the arguments - see execute(CmdLineArgs).
*
* @param args
* The who will be parsed and executed.
*/
public void run(String[] args) {
try {
CmdLineArgs cmdLineArgs = parse(args);
if (cmdLineArgs.getSpecifiedOptions().isEmpty()) {
printOptionHelp(cmdLineArgs);
} else if (!handleHelp(cmdLineArgs)
&& !handlePrintSupportedActions(cmdLineArgs)) {
execute(cmdLineArgs);
}
} catch (Exception e) {
if (debugMode) {
throw new RuntimeException(e);
}
printErrorMessage(e.getMessage());
}
}
/**
* Parses the given command line arguments and converts it to
* {@link CmdLineArgs}.
*
* @param args
* The command line arguments to parse.
* @return The parsed command line arguments in {@link CmdLineArgs} form.
* @throws IOException
* On error parsing command line arguments.
* @throws CmdLineConstructionException
* On error constructing command line arguments.
* @throws CmdLineOptionStoreException
*/
public CmdLineArgs parse(String[] args) throws CmdLineParserException,
CmdLineActionStoreException, CmdLineConstructionException,
CmdLineOptionStoreException {
Validate.notNull(parser);
Validate.notNull(optionStore);
// Load supported options.
Set<CmdLineOption> validOptions = optionStore.loadSupportedOptions();
initializeHandlers(validOptions);
// Insure help options is present if required.
if (findHelpOption(validOptions) == null) {
validOptions.add(new HelpCmdLineOption());
}
// Insure action options are present if required.
if (findFirstActionOption(validOptions) == null) {
validOptions.add(new ActionCmdLineOption());
}
// Insure print supported actions option is present if required.
if (findPrintSupportedActionsOption(validOptions) == null) {
validOptions.add(new PrintSupportedActionsCmdLineOption());
}
// Parse command line arguments.
return new CmdLineArgs(actionStore.loadSupportedActions(), validOptions,
constructor.construct(
new CmdLineIterable<ParsedArg>(parser.parse(args)),
validOptions));
}
/**
* Initializes each {@link CmdLineOptionHandler} with their assigned
* {@link CmdLineOption}.
*
* @param options
*/
public void initializeHandlers(Set<CmdLineOption> options) {
for (CmdLineOption option : options) {
if (isAdvancedOption(option)
&& asAdvancedOption(option).getHandler() != null) {
asAdvancedOption(option).getHandler().initialize(option);
}
}
}
/**
* Checks if help option was specified and if so prints out help.
*
* @param cmdLineArgs
* The {@link CmdLineArgs} which will be checked for help option
* @return True if help was printed, false otherwise
*/
public boolean handleHelp(CmdLineArgs cmdLineArgs) {
if (cmdLineArgs.getHelpOptionInst() != null) {
if (cmdLineArgs.getHelpOptionInst().getValues().isEmpty()) {
printOptionHelp(cmdLineArgs);
} else {
printActionHelp(cmdLineArgs);
}
return true;
}
return false;
}
/**
* Checks if print supported actions option was specified and if so prints
* out supported actions.
*
* @param cmdLineArgs
* The {@link CmdLineArgs} which will be checked for print
* supported action options
* @return True if supported actions was printed, false otherwise
*/
public boolean handlePrintSupportedActions(CmdLineArgs cmdLineArgs) {
if (cmdLineArgs.getPrintSupportedActionsOptionInst() != null) {
printActionsHelp(cmdLineArgs);
return true;
}
return false;
}
/**
* Checks if required options are set and validation passes, then runs
* handlers and executes its action.
*
* @param cmdLineArgs
* The {@link CmdLineArgs} for which execution processing will be
* run.
*/
public void execute(CmdLineArgs cmdLineArgs)
throws CmdLineActionExecutionException, CmdLineActionException {
Set<CmdLineOptionInstance> performAndQuitOptions = findPerformAndQuitOptions(cmdLineArgs
.getSpecifiedOptions());
if (!performAndQuitOptions.isEmpty()) {
for (CmdLineOptionInstance option : performAndQuitOptions) {
handlePerformAndQuitOption(option);
}
return;
}
if (cmdLineArgs.getActionOptionInst() == null) {
throw new CmdLineActionExecutionException(
"Must specify an action option!");
}
Set<CmdLineOption> requiredOptionsNotSet = check(cmdLineArgs);
if (!requiredOptionsNotSet.isEmpty()) {
printMissingRequiredOptionsError(requiredOptionsNotSet);
return;
}
List<CmdLineOptionValidator.Result> failedValidationResults = determineFailedValidation(validate(cmdLineArgs));
if (!failedValidationResults.isEmpty()) {
printValidationErrors(failedValidationResults);
return;
}
handle(cmdLineArgs);
ActionMessagePrinter printer = new ActionMessagePrinter();
cmdLineArgs.getSpecifiedAction().execute(printer);
printActionMessages(printer.getPrintedMessages());
}
/**
* Checks for required options which are not set and returns the ones it
* finds.
*
* @param cmdLineArgs
* The {@link CmdLineArgs} which will be check for required
* options.
* @return The required {@link CmdLineOption}s not specified.
*/
public static Set<CmdLineOption> check(CmdLineArgs cmdLineArgs) {
Set<CmdLineOption> requiredOptions = determineRequired(
cmdLineArgs.getSpecifiedAction(), cmdLineArgs.getSupportedOptions());
HashSet<CmdLineOption> requiredOptionsNotSet = new HashSet<CmdLineOption>(
requiredOptions);
for (CmdLineOptionInstance specifiedOption : cmdLineArgs
.getSpecifiedOptions()) {
requiredOptionsNotSet.remove(specifiedOption.getOption());
}
return requiredOptionsNotSet;
}
/**
* Runs validation on {@link CmdLineArgs} and returns the validation results.
*
* @param cmdLineArgs
* The {@link CmdLineArgs} which will be validated.
* @return The {@link CmdLineOptionValidator.Result}s generated when running
* {@link CmdLineOptionValidator}s.
*/
public static List<CmdLineOptionValidator.Result> validate(
CmdLineArgs cmdLineArgs) {
Validate.notNull(cmdLineArgs);
List<CmdLineOptionValidator.Result> results = Lists.newArrayList();
for (CmdLineOptionInstance optionInst : cmdLineArgs.getSpecifiedOptions()) {
results.addAll(CmdLineUtils.validate(optionInst));
}
return results;
}
/**
* Runs the {@link CmdLineOptionHandler}s for {@link CmdLineArgs} given.
*
* @param cmdLineArgs
* The {@link CmdLineArgs} whose option handlers will be run.
*/
public static void handle(CmdLineArgs cmdLineArgs) {
for (CmdLineOptionInstance option : cmdLineArgs.getSpecifiedOptions()) {
CmdLineUtils.handle(cmdLineArgs.getSpecifiedAction(), option);
}
}
}