Use Guice to create custom arg4j OptionHandler instances
This permits us to inject Guice managed objects into any ObjectHandler via assisted factory injection, which permits them to perform database queries during option parsing by accessing the per-request ReviewDb. Change-Id: I14a6b5296d8d77b5e3966846bbaa58f6e8ebb09a Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
		| @@ -54,6 +54,9 @@ public abstract class BaseCommand implements Command { | ||||
|  | ||||
|   private ExitCallback exit; | ||||
|  | ||||
|   @Inject | ||||
|   private CmdLineParser.Factory cmdLineParserFactory; | ||||
|  | ||||
|   @Inject | ||||
|   private RequestCleanup cleanup; | ||||
|  | ||||
| @@ -180,7 +183,7 @@ public abstract class BaseCommand implements Command { | ||||
|  | ||||
|   /** Construct a new parser for this command's received command line. */ | ||||
|   protected CmdLineParser newCmdLineParser() { | ||||
|     return new CmdLineParser(this); | ||||
|     return cmdLineParserFactory.create(this); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -16,13 +16,21 @@ package com.google.gerrit.server.ssh; | ||||
|  | ||||
| import static com.google.inject.Scopes.SINGLETON; | ||||
|  | ||||
| import com.google.gerrit.client.reviewdb.PatchSet; | ||||
| import com.google.gerrit.pgm.CmdLineParser; | ||||
| import com.google.gerrit.pgm.OptionHandlerFactory; | ||||
| import com.google.gerrit.pgm.OptionHandlerUtil; | ||||
| import com.google.gerrit.server.CurrentUser; | ||||
| import com.google.gerrit.server.IdentifiedUser; | ||||
| import com.google.gerrit.server.RemotePeer; | ||||
| import com.google.gerrit.server.config.FactoryModule; | ||||
| import com.google.gerrit.server.config.GerritRequestModule; | ||||
| import com.google.gerrit.server.ssh.commands.DefaultCommandModule; | ||||
| import com.google.gerrit.server.ssh.commands.PatchSetIdHandler; | ||||
| import com.google.inject.Key; | ||||
| import com.google.inject.Provider; | ||||
| import com.google.inject.TypeLiteral; | ||||
| import com.google.inject.assistedinject.FactoryProvider; | ||||
| import com.google.inject.servlet.RequestScoped; | ||||
| import com.google.inject.servlet.SessionScoped; | ||||
|  | ||||
| @@ -31,6 +39,7 @@ import org.apache.sshd.common.session.AbstractSession; | ||||
| import org.apache.sshd.server.CommandFactory; | ||||
| import org.apache.sshd.server.PublickeyAuthenticator; | ||||
| import org.apache.sshd.server.session.ServerSession; | ||||
| import org.kohsuke.args4j.spi.OptionHandler; | ||||
|  | ||||
| import java.net.SocketAddress; | ||||
|  | ||||
| @@ -45,6 +54,7 @@ public class SshModule extends FactoryModule { | ||||
|  | ||||
|     configureSessionScope(); | ||||
|     configureRequestScope(); | ||||
|     configureCmdLineParser(); | ||||
|  | ||||
|     bind(SshInfo.class).to(SshDaemon.class).in(SINGLETON); | ||||
|     factory(DispatchCommand.Factory.class); | ||||
| @@ -85,4 +95,23 @@ public class SshModule extends FactoryModule { | ||||
|         SshScopes.REQUEST); | ||||
|     bind(CurrentUser.class).to(IdentifiedUser.class); | ||||
|   } | ||||
|  | ||||
|   private void configureCmdLineParser() { | ||||
|     factory(CmdLineParser.Factory.class); | ||||
|  | ||||
|     registerOptionHandler(PatchSet.Id.class, PatchSetIdHandler.class); | ||||
|   } | ||||
|  | ||||
|   private <T> void registerOptionHandler(Class<T> type, | ||||
|       Class<? extends OptionHandler<T>> impl) { | ||||
|     final Key<OptionHandlerFactory<T>> key = OptionHandlerUtil.keyFor(type); | ||||
|  | ||||
|     final TypeLiteral<OptionHandlerFactory<T>> factoryType = | ||||
|         new TypeLiteral<OptionHandlerFactory<T>>() {}; | ||||
|  | ||||
|     final TypeLiteral<? extends OptionHandler<T>> implType = | ||||
|         TypeLiteral.get(impl); | ||||
|  | ||||
|     bind(key).toProvider(FactoryProvider.newFactory(factoryType, implType)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -46,13 +46,9 @@ import java.util.Collections; | ||||
| import java.util.List; | ||||
|  | ||||
| public class ApproveCommand extends BaseCommand { | ||||
|   static { | ||||
|     CmdLineParser.registerHandler(PatchSet.Id.class, PatchSetIdHandler.class); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   protected final CmdLineParser newCmdLineParser() { | ||||
|     final CmdLineParser parser = new CmdLineParser(this); | ||||
|     final CmdLineParser parser = super.newCmdLineParser(); | ||||
|     for (CmdOption c : optionList) { | ||||
|       parser.addOption(c, c); | ||||
|     } | ||||
|   | ||||
| @@ -15,6 +15,8 @@ | ||||
| package com.google.gerrit.server.ssh.commands; | ||||
|  | ||||
| import com.google.gerrit.client.reviewdb.PatchSet; | ||||
| import com.google.inject.Inject; | ||||
| import com.google.inject.assistedinject.Assisted; | ||||
|  | ||||
| import org.kohsuke.args4j.CmdLineException; | ||||
| import org.kohsuke.args4j.CmdLineParser; | ||||
| @@ -24,8 +26,10 @@ import org.kohsuke.args4j.spi.Parameters; | ||||
| import org.kohsuke.args4j.spi.Setter; | ||||
|  | ||||
| public class PatchSetIdHandler extends OptionHandler<PatchSet.Id> { | ||||
|   public PatchSetIdHandler(final CmdLineParser parser, final OptionDef option, | ||||
|       final Setter<? super PatchSet.Id> setter) { | ||||
|   @SuppressWarnings("unchecked") | ||||
|   @Inject | ||||
|   public PatchSetIdHandler(@Assisted final CmdLineParser parser, | ||||
|       @Assisted final OptionDef option, @Assisted final Setter setter) { | ||||
|     super(parser, option, setter); | ||||
|   } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Shawn O. Pearce
					Shawn O. Pearce