Package com.google.enterprise.connector.manager

Source Code of com.google.enterprise.connector.manager.CommandDispatcher

// Copyright 2009 Google 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.google.enterprise.connector.manager;

import com.google.enterprise.connector.common.AbstractCommandLineApp;
import com.google.enterprise.connector.encryptpassword.EncryptPassword;
import com.google.enterprise.connector.importexport.DumpConnectors;
import com.google.enterprise.connector.importexport.ImportExport;
import com.google.enterprise.connector.persist.MigrateStore;
import com.google.enterprise.connector.servlet.ServletUtil;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

import java.util.TreeMap;

/**
* The Connector Manager Command Processor.  This is thean entry point
* for command line access to Connector Manager features.  It is
* typically invoked from {@link ManagerMain} when that Jar Main class
* is called with command line arguments, while avoiding ManagerMain direct
* dependence on external libraries (specifically Apache Commons CLI).
* <p>
* There are shell scripts, {@code Manager} and {@code Manager.bat}, that
* may be used to more conveniently invoke the command processor.
* <p>
* <pre>
* Usage: Manager [-?] [-v] [command] [options] [arguments]
*        -?, --help     Display the set of available commands
*        -v, --version  Display the Connector Manager version
*
* To get help for a command, specify the command along with -? or --help
* For instance:
*   Manager MigrateStore --help
* </pre>
*/
public class CommandDispatcher extends AbstractCommandLineApp {

  // TODO: The command implementations should really register themselves.
  private static TreeMap<String, Command> commands;
  {
    commands = new TreeMap<String, Command>();
    addCommand(new DumpConnectors(), false);
    addCommand(new EncryptPassword(), false);
    addCommand(new MigrateStore(), false);
    addCommand(new ImportExport(), true);
  }

  /**
   * Adds a new command line app to the set of supported commands.
   *
   * @param app the command line application.
   * @param hidden if true, do not list the command in help.
   */
  private static void addCommand(AbstractCommandLineApp app, boolean hidden) {
    Command command = new Command(app, hidden);
    commands.put(command.name.toLowerCase(), command);
  }

  /**
   * Represents a Command Line application.
   */
  private static class Command {
    String name;
    String description;
    boolean hidden;
    Class<? extends AbstractCommandLineApp> appClass;

    public Command(AbstractCommandLineApp app, boolean hidden) {
      this.name = app.getName().trim();
      this.appClass = app.getClass();
      this.hidden = hidden;
      if (!hidden) {
        this.description = app.getDescription();
      }
    }
  }

  private final String[] originalArgs;

  /**
   * Construct a new CommandDispatcher, preserving the original args.
   */
  public CommandDispatcher(String[] args) {
    this.originalArgs = args;
  }

  @Override
  public String getName() {
    return ServletUtil.MANAGER_NAME;
  }

  @Override
  public String getDescription() {
    return ServletUtil.MANAGER_NAME + " command processor.";
  }

  @Override
  public String getCommandLineSyntax() {
    return "Manager [-?] [-v]";
  }

  @Override
  public String getUsageHeader() {
    return "or     Manager [command] [options] [arguments]";
  }


  @Override
  protected void printUsage() {
    super.printUsage();
    System.err.print(getAdditionalUsage());
  }

  // Doesn't override getUsageFooter() because HelpFormatter
  // strips the leading whitespace from my lines.
  private String getAdditionalUsage() {
    StringBuilder builder = new StringBuilder();
    // Figure out the longest command name for formatting output.
    int longestCommand = 0;
    for (Command command : commands.values()) {
      if (command.name.length() > longestCommand) {
        longestCommand = command.name.length();
      }
    }

    // Now add the descriptions of the available commands.
    builder.append("Available commands:").append(NL);
    for (Command command : commands.values()) {
      addDescription(command, builder, longestCommand);
    }

    builder.append(NL);
    builder.append("To get help for a command, specify the command along");
    builder.append(" with -? or --help").append(NL);
    builder.append("For instance:").append(NL);
    builder.append("  Manager MigrateStore --help").append(NL).append(NL);
    return builder.toString();
  }

  private void addDescription(Command command, StringBuilder builder,
                              int longestCommand) {
    if (!command.hidden) {
      builder.append("  ").append(command.name);
      for (int i = command.name.length(); i < longestCommand; i++) {
        builder.append(' ');
      }
      builder.append("  ").append(command.description).append(NL);
    }
  }

  @Override
  public CommandLine parseArgs(String[] args) {
    try {
      // Stop parsing at first non-option, so we don't accidently try
      // to interperet options intended for the commands themselves.
      commandLine = new PosixParser().parse(getOptions(), args, true);
      return commandLine;
    } catch (ParseException pe) {
      printUsageAndExit(-1);
    }
    return null;
  }

  @Override
  public void run(CommandLine commandLine) throws Exception {
    String[] args = commandLine.getArgs();
    if (args.length > 0) {
      Command command = commands.get(args[0].toLowerCase());
      if (command != null) {
        AbstractCommandLineApp app = command.appClass.newInstance();
        app.run(app.parseArgs(shift(originalArgs)));
        return;
      }
      printUsageAndExit(-1);
    }
    if (commandLine.hasOption(HELP_OPTION.getLongOpt())) {
      printUsageAndExit(0);
    }

    // The default behavior is to display the product version.
    printVersion();
  }

  /**
   * Returns a subarray of the supplied array.  This performs the equivalent of
   * the 'shift' shell command.
   *
   * @param args An array of String arguments
   * @return args[1..n] subarray
   */
  private static String[] shift(String[] args) {
    String[] shifted = new String[args.length - 1];
    System.arraycopy(args, 1, shifted, 0, shifted.length);
    return shifted;
  }

  /**
   * Proper main() in case this is called directly.
   */
  public static void main(String[] args) throws Exception {
    CommandDispatcher app = new CommandDispatcher(args);
    app.run(app.parseArgs(args));
    System.exit(0);
  }
}
TOP

Related Classes of com.google.enterprise.connector.manager.CommandDispatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.