com.shopzilla.hadoop.repl.HadoopREPL.java Source code

Java tutorial

Introduction

Here is the source code for com.shopzilla.hadoop.repl.HadoopREPL.java

Source

/**
 * Copyright 2012 Shopzilla.com
 *
 *  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.
 *
 *  http://tech.shopzilla.com
 *
 */

package com.shopzilla.hadoop.repl;

import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.*;
import com.shopzilla.hadoop.repl.commands.*;
import com.shopzilla.hadoop.repl.commands.completers.DeferredStringsCompleter;
import jline.console.completer.AggregateCompleter;
import jline.console.completer.ArgumentCompleter;
import jline.console.completer.Completer;
import jline.console.completer.StringsCompleter;
import org.apache.hadoop.conf.Configuration;

import java.io.File;
import java.util.Map;
import java.util.TreeSet;

import static com.shopzilla.hadoop.repl.commands.Call.call;

/**
 * @author Jeremy Lucas
 * @since 9/12/12
 */
public class HadoopREPL extends REPL {

    protected static final Splitter ARG_SPLITTER = Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings();

    protected final Configuration configuration;

    protected SessionState sessionState;

    protected final Map<Call, Command> commandMappings;

    public HadoopREPL(final Configuration configuration) throws ExitSignal {
        this.configuration = configuration;
        this.sessionState = new SessionState(configuration, this);
        this.commandMappings = buildCommandMappings();
        resetCompletors();
    }

    public HadoopREPL(final Configuration configuration, final SessionState sessionState) throws ExitSignal {
        this.configuration = configuration;
        this.sessionState = sessionState;
        this.commandMappings = buildCommandMappings();
        resetCompletors();
    }

    public HadoopREPL(final Configuration configuration, final SessionState sessionState,
            final Map<Call, Command> commandMappings) throws ExitSignal {
        this.configuration = configuration;
        this.sessionState = sessionState;
        this.commandMappings = commandMappings;
        resetCompletors();
    }

    protected Map<Call, Command> buildCommandMappings() {
        final Map<Call, Command> commands = ImmutableMap.<Call, Command>builder()
                .putAll(new SessionCommandProvider().apply(sessionState))
                .putAll(new FSShellCommandProvider().apply(sessionState)).build();
        return ImmutableMap.<Call, Command>builder().putAll(commands)
                .put(call("help", new DeferredStringsCompleter<Map<Call, Command>>(commandMappings,
                        new Function<Map<Call, Command>, TreeSet<String>>() {
                            @Override
                            public TreeSet<String> apply(final Map<Call, Command> calls) {
                                return Sets.newTreeSet(Maps.transformEntries(commandMappings,
                                        new Maps.EntryTransformer<Call, Command, String>() {
                                            @Override
                                            public String transformEntry(final Call key, final Command value) {
                                                return key.commandName();
                                            }
                                        }).values());
                            }
                        })), new Command() {
                            @Override
                            public void execute(final CommandInvocation call, final SessionState sessionState)
                                    throws REPL.ExitSignal {
                                if (call.args().length != 1) {
                                    sessionState.output("Usage: help [command]");
                                } else {
                                    final String command = call.args()[0];
                                    if (commandMappings.containsKey(call(command))) {
                                        final Usage usage = commandMappings.get(call(command)).usage(sessionState);
                                        sessionState.output("Displaying help for \"%s\":\n", command);
                                        sessionState.outputUsage(usage);
                                    } else {
                                        sessionState.error("Unknown command \"%s\"", command);
                                    }
                                }
                            }

                            @Override
                            public Usage usage(final SessionState sessionState) {
                                return new Usage("help", "Displays help / usage information for the given command ",
                                        "<command>");
                            }
                        })
                .build();
    }

    protected void resetCompletors() {
        removeAllcompleters();
        addcompleters(new AggregateCompleter(
                Collections2.transform(commandMappings.keySet(), new Function<Call, Completer>() {
                    @Override
                    public Completer apply(final Call input) {
                        return new ArgumentCompleter(ImmutableList.<Completer>builder()
                                .add(new StringsCompleter(input.commandName())).add(input.completers()).build());
                    }
                })));
    }

    @Override
    protected void evaluate(final String input) throws ExitSignal {
        popHistory();
        final Iterable<String> inputParts = ARG_SPLITTER.limit(2).split(input);
        if (Iterables.isEmpty(inputParts)) {
            // Do nothing
        } else {
            final String command = Iterables.get(inputParts, 0).toLowerCase();
            if (commandMappings.containsKey(call(command))) {
                commandMappings.get(call(command)).execute(
                        new CommandInvocation(command, Iterables
                                .toArray(ARG_SPLITTER.split(Iterables.get(inputParts, 1, "")), String.class)),
                        sessionState);
            } else {
                sessionState.output("Unknown command \"%s\"", command);
            }
            pushHistory(input);
        }
    }

    protected SessionState sessionState() {
        return sessionState;
    }

    protected Map<Call, Command> commandMappings() {
        return commandMappings;
    }

    public static void main(final String[] args) {
        int exitCode = 0;

        try {
            final Configuration configuration = new Configuration(true);
            if (args.length == 1) {
                configuration.addResource(new File(args[0]).toURI().toURL());
            } else if (args.length > 1) {
                throw new ExitSignal(1, "Usage: ./hadoop-repl <path-to-hadoop-core-site-file>");
            }
            new HadoopREPL(configuration).loop("hadoop> ");
        } catch (final ExitSignal ex) {
            System.err.println(ex.getMessage());
            exitCode = ex.getExitCode();
        } catch (final Exception ex) {
            System.err.println(ex);
            exitCode = 1;
        }

        System.exit(exitCode);
    }
}