org.apache.sqoop.shell.SqoopCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sqoop.shell.SqoopCommand.java

Source

/**
 * 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.sqoop.shell;

import groovy.lang.GroovyShell;
import groovy.lang.MissingPropertyException;
import groovy.lang.Script;

import java.util.*;

import org.apache.commons.lang.StringUtils;
import org.apache.sqoop.shell.core.Constants;
import org.apache.sqoop.common.SqoopException;
import org.apache.sqoop.shell.core.ShellError;
import org.apache.sqoop.utils.ClassUtils;
import org.codehaus.groovy.tools.shell.ComplexCommandSupport;
import org.codehaus.groovy.tools.shell.Shell;

import static org.apache.sqoop.shell.ShellEnvironment.*;

/**
 * Sqoop shell command.
 *
 * Every command should define following resource properties:
 *
 * $command.description
 *    One sentence describing purpose of the command, displayed on "help" command.
 */
public abstract class SqoopCommand extends ComplexCommandSupport {

    /**
     * Command name
     */
    private String name;

    /**
     * Function map given by concrete implementation.
     *
     * Key: Name of the function as is present in the shell
     * Value: Class name implementing the function
     */
    private final Map<String, Class<? extends SqoopFunction>> functionNames;

    /**
     * Instantiated functions for reuse. Built lazily.
     */
    private final Map<String, SqoopFunction> functionInstances;

    protected SqoopCommand(Shell shell, String name, String shortcut,
            Map<String, Class<? extends SqoopFunction>> funcs) {
        super(shell, name, shortcut);

        this.name = name;
        this.functionNames = funcs;
        this.functionInstances = new HashMap<String, SqoopFunction>();

        this.functions = new LinkedList<String>();
        this.functions.addAll(funcs.keySet());
    }

    @Override
    public String getDescription() {
        return resourceString(name + ".description");
    }

    @Override
    public String getUsage() {
        return new StringBuilder().append("[").append(StringUtils.join(functionNames.keySet(), "|")).append("]")
                .toString();
    }

    @Override
    public String getHelp() {
        return getDescription() + ".";
    }

    /**
     * Override execute method
     */
    @Override
    public Object execute(List args) {
        resolveVariables(args);
        return executeCommand(args);
    }

    /**
     * Abstract executeCommand
     * @param args list
     * @return Object
     */
    public Object executeCommand(List args) {
        if (args.size() == 0) {
            printlnResource(Constants.RES_SHARED_USAGE, name, getUsage());
            return null;
        }

        String func = (String) args.get(0);

        // Unknown function
        if (!functionNames.containsKey(func)) {
            printlnResource(Constants.RES_SHARED_UNKNOWN_FUNCTION, func);
            return null;
        }

        // If we already do have the instance, execute it
        if (functionInstances.containsKey(func)) {
            return functionInstances.get(func).execute(args);
        }

        // Otherwise create new instance
        Class klass = functionNames.get(func);
        SqoopFunction instance = (SqoopFunction) ClassUtils.instantiate(klass);
        if (instance == null) {
            // This is pretty much a developer error as it shouldn't happen without changing and testing code
            throw new SqoopException(ShellError.SHELL_0000, "Can't instantiate class " + klass);
        }

        functionInstances.put(func, instance);

        // And return the function execution
        return instance.execute(args);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected void resolveVariables(List arg) {
        List temp = new ArrayList();
        GroovyShell gs = new GroovyShell(getBinding());
        for (Object obj : arg) {
            Script scr = gs.parse("\"" + (String) obj + "\"");
            try {
                temp.add(scr.run().toString());
            } catch (MissingPropertyException e) {
                throw new SqoopException(ShellError.SHELL_0004, e.getMessage(), e);
            }
        }
        Collections.copy(arg, temp);
    }
}