All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cloudbees.sdk.commands.Command Maven / Gradle / Ivy

There is a newer version: 1.3.8
Show newest version
/*
 * Copyright 2010-2013, CloudBees 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.cloudbees.sdk.commands;

import com.cloudbees.api.BeesClientBase;
import com.cloudbees.sdk.cli.BeesClientFactory;
import com.cloudbees.sdk.cli.ACommand;
import com.cloudbees.sdk.cli.Verbose;
import com.staxnet.repository.LocalRepository;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author Fabian Donze
 */
public abstract class Command extends ACommand {
    private String commandName;

    private String[] args;

    private String help;

    private String output;

    private Boolean showAll;

    private CommandLineParser parser;

    private List options;

    private CommandLine line;

    private boolean addDefaultOptions;

    private File localRepository;

    private String description;

    private List parameters;

    private int argumentExpected;
    
    @Inject
    BeesClientFactory beesClientFactory;

    @Inject
    private Verbose verbose;

    public Command() {
        addDefaultOptions = true;
        LocalRepository lr = new LocalRepository();
        localRepository = new File(lr.getRepositoryPath());
        argumentExpected = 0;
    }

    @Override
    public int run(List args) throws Exception {
        init("bees"/*TODO:get rid of this*/, args.get(0), args.toArray(new String[args.size()]));

        // Add shutdown hook
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                Command.this.stop();
            }
        });

        return run();
    }

    @Override
    public void printHelp(List args) {
        try {
            init("bees"/*TODO:get rid of this*/, args.get(0), args.toArray(new String[args.size()]));
        } catch (Exception e) {
            // the use of the exception in the init method doesn't differentiate anticipated problems
            // (such as user error on parameter values) from unanticipated bugs in code. The former
            // should be handled without stack trace, later should result in a stack trace.
            // since we can' differentiate them here, I'm err-ing on the ease of diagnostics and
            // reporting it as unanticipated bug in code
            throw new Error(e);
        }
        printHelp();
    }

    public void init(String commandPrefix, String commandName, String[] args) throws Exception {
        parameters = new ArrayList();
        this.commandName = commandName;
        this.args = new String[args.length-1];
        System.arraycopy(args, 1, this.args, 0, this.args.length);
        help = commandPrefix + " " + commandName;

        // create the command line parser
        parser = new GnuParser();

        // create the Options
        options = new ArrayList();
        addOption("all", "showAll", false, "Show all options", true);
        if (addDefaultOptions) {
            addOption("k", "key", true, "CloudBees API key");
            addOption("s", "secret", true, "CloudBees API secret");
            addOption(null, "server", true, "API server", true);
            addOption(null, "proxyHost", true, "API server proxy host", true);
            addOption(null, "proxyPort", true, "API server proxy port", true);
            addOption(null, "proxyUser", true, "API server proxy user name", true);
            addOption(null, "proxyPassword", true, "API server proxy password", true);
            addOption("v", "verbose", false, "verbose output");
            addOption("o", "output", true, "output format [txt | json | xml]  (Default: 'txt')");
            addOption("ep", "endPoint", true, "CloudBes API end point [us | eu]", true);
        }

        boolean success;
        try {
            success = preParseCommandLine();
        } catch (Exception e) {
            printHelp(help);
            throw e;
        }
        if (!success) {
            printHelp(help);
            return;
        }

        try {
            success = parseCommandLine();
        } catch (Exception e) {
            printHelp(help);
            throw e;
        }
        if (!success) {
            printHelp(help);
            return;
        }

        if (!isHelp(args))
            initDefaults(getConfigProperties());

    }

    public int run() throws Exception {
        boolean success = false;
        try {
            if (postParseCommandLine()) {
                success = postParseCheck();
            }
        } catch (Exception e) {
            printHelp(help);
            throw e;
        }
        if (!success) {
            printHelp(help);
            return 0;
        }

        if (!execute()) {
            printHelp(help);
        }

        return getResultCode();
    }

    public void printHelp() {
        printHelp(help);
    }

    public void stop() {
    }

    /**
     * This method is call before parsing the command line.
     * This is the place to add command line options
     * @return true if successful, false otherwise
     */
    protected boolean preParseCommandLine() {
        return true;
    }

    /**
     * This method is the main command execution method.
     * @return true if successful, false otherwise
     */
    protected abstract boolean execute() throws Exception;

    /**
     * This method is call by the help command.
     * This is the place to define the command arguments usage.
     * No need to return the options, they will be automatically added to the help message
     * @return usage String
     */
    protected String getUsageMessage() {
        return "";
    }

    /**
     * This method is call after parsing the command line.
     * This is the place to parse additional command arguments
     * @return true if successful, false otherwise
     */
    protected boolean postParseCommandLine() {
        List otherArgs = getCommandLine().getArgList();
        if (otherArgs.size() > 0) {
            for (int i=0; i= argumentExpected;
        if (!ok)
            throw new IllegalArgumentException("Expected parameters: " + argumentExpected + " found: " + parameters.size());
        return ok;
    }

    protected void setArgumentExpected(int argumentExpected) {
        this.argumentExpected = argumentExpected;
    }

    protected int getArgumentExpected() {
        return argumentExpected;
    }

    protected boolean parseCommandLine() throws Exception {
        boolean ok = true;
        // parse the command line arguments
        line = getParser().parse(getOptions(true), getArgs());
        for (Option option: line.getOptions()) {
//                System.out.println("Option: " + option);
            String str = option.getLongOpt();
            if (str == null)
                str = option.getOpt();
            str = str.replace("-","");
            if (option.hasArg()) {
                Class[] types = {String.class};
                Method method = getMethod(str, "", types);
                if (method == null) {
                    method = getMethod(str, "Option", types);
                }
                method.invoke(this, option.getValue());
            } else {
                Class[] types = {Boolean.class};
                Method method = getMethod(str, "", types);
                if (method == null) {
                    method = getMethod(str, "Option", types);
                }
                method.invoke(this, Boolean.TRUE);
            }
        }
        return ok;
    }

    protected List getParameters() {
        return parameters != null ? parameters : Collections.emptyList();
    }

    protected void addParameter(String parameter) {
        int length=parameter.length();
        if (parameter.charAt(0) == '"' && parameter.charAt(length-1) == '"')
            parameter = parameter.substring(1, length-1);
        parameters.add(parameter);
    }

    protected int isParameter(String str) {
        boolean endQuote = true;
        int length = str.length();
        for (int i=0; i


© 2015 - 2024 Weber Informatics LLC | Privacy Policy