Move command line parsing to BaseCommand

The parsing is optional, and must be explicitly invoked by the
implementor in order to have the injection of values occur.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-07-31 09:56:42 -07:00
parent 5013c9c133
commit 4eb678dba6
2 changed files with 76 additions and 69 deletions

View File

@@ -20,7 +20,6 @@ import com.google.gerrit.client.reviewdb.AccountGroup;
import com.google.gerrit.client.reviewdb.ApprovalCategory;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.pgm.CmdLineParser;
import com.google.gerrit.server.BaseServiceImplementation;
import com.google.gerrit.server.GerritServer;
import com.google.gerrit.server.IdentifiedUser;
@@ -29,20 +28,12 @@ import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.SchemaFactory;
import com.google.inject.Inject;
import org.apache.sshd.common.SshException;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.Option;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public abstract class AbstractCommand extends BaseCommand {
@@ -65,9 +56,6 @@ public abstract class AbstractCommand extends BaseCommand {
private Set<AccountGroup.Id> userGroups;
@Option(name = "--help", usage = "display this help text", aliases = {"-h"})
private boolean help;
protected PrintWriter toPrintWriter(final OutputStream o)
throws UnsupportedEncodingException {
return new PrintWriter(new BufferedWriter(new OutputStreamWriter(o, ENC)));
@@ -119,68 +107,12 @@ public abstract class AbstractCommand extends BaseCommand {
}
}
private void parseArguments() throws Failure {
final List<String> list = new ArrayList<String>();
boolean inquote = false;
StringBuilder r = new StringBuilder();
for (int ip = 0; ip < commandLine.length();) {
final char b = commandLine.charAt(ip++);
switch (b) {
case '\t':
case ' ':
if (inquote)
r.append(b);
else if (r.length() > 0) {
list.add(r.toString());
r = new StringBuilder();
}
continue;
case '\'':
inquote = !inquote;
continue;
case '\\':
if (inquote || ip == commandLine.length())
r.append(b); // literal within a quote
else
r.append(commandLine.charAt(ip++));
continue;
default:
r.append(b);
continue;
}
}
if (r.length() > 0) {
list.add(r.toString());
}
final CmdLineParser clp = new CmdLineParser(this);
try {
clp.parseArgument(list.toArray(new String[list.size()]));
} catch (CmdLineException err) {
if (!help) {
throw new UnloggedFailure(1, "fatal: " + err.getMessage());
}
}
if (help) {
final StringWriter msg = new StringWriter();
msg.write(commandPrefix);
clp.printSingleLineUsage(msg, null);
msg.write('\n');
msg.write('\n');
clp.printUsage(msg, null);
msg.write('\n');
throw new UnloggedFailure(1, msg.toString());
}
}
public void start() {
startThread(new CommandRunnable() {
public void run() throws Exception {
try {
preRun();
parseArguments();
parseCommandLine();
AbstractCommand.this.run();
} finally {
postRun();

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.ssh;
import com.google.gerrit.client.reviewdb.Account;
import com.google.gerrit.pgm.CmdLineParser;
import com.google.gerrit.server.ssh.SshScopes.Context;
import org.apache.sshd.common.SshException;
@@ -22,17 +23,25 @@ import org.apache.sshd.server.CommandFactory.Command;
import org.apache.sshd.server.CommandFactory.ExitCallback;
import org.apache.sshd.server.CommandFactory.SessionAware;
import org.apache.sshd.server.session.ServerSession;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseCommand implements Command, SessionAware {
private static final Logger log = LoggerFactory.getLogger(BaseCommand.class);
@Option(name = "--help", usage = "display this help text", aliases = {"-h"})
private boolean help;
protected InputStream in;
protected OutputStream out;
protected OutputStream err;
@@ -101,6 +110,72 @@ public abstract class BaseCommand implements Command, SessionAware {
cmd.setExitCallback(exit);
}
/**
* Parses the command line argument, injecting parsed values into fields.
* <p>
* This method must be explicitly invoked to cause a parse. When parsing,
* arguments are split out of and read from the {@link #commandLine} field.
*
* @throws Failure if the command line arguments were invalid.
* @see Option
* @see Argument
*/
protected void parseCommandLine() throws Failure {
final List<String> list = new ArrayList<String>();
boolean inquote = false;
StringBuilder r = new StringBuilder();
for (int ip = 0; ip < commandLine.length();) {
final char b = commandLine.charAt(ip++);
switch (b) {
case '\t':
case ' ':
if (inquote)
r.append(b);
else if (r.length() > 0) {
list.add(r.toString());
r = new StringBuilder();
}
continue;
case '\'':
inquote = !inquote;
continue;
case '\\':
if (inquote || ip == commandLine.length())
r.append(b); // literal within a quote
else
r.append(commandLine.charAt(ip++));
continue;
default:
r.append(b);
continue;
}
}
if (r.length() > 0) {
list.add(r.toString());
}
final CmdLineParser clp = new CmdLineParser(this);
try {
clp.parseArgument(list.toArray(new String[list.size()]));
} catch (CmdLineException err) {
if (!help) {
throw new UnloggedFailure(1, "fatal: " + err.getMessage());
}
}
if (help) {
final StringWriter msg = new StringWriter();
msg.write(commandPrefix);
clp.printSingleLineUsage(msg, null);
msg.write('\n');
msg.write('\n');
clp.printUsage(msg, null);
msg.write('\n');
throw new UnloggedFailure(1, msg.toString());
}
}
/**
* Spawn a function into its own thread.
* <p>