Updated to Guice 3.0.

Use the new FactoryModuleBuilder everywhere, instead of FactoryProvider.

Updated the OptionHandlers to be generic, instead of ignoring the type
parameter.

Removed the GuiceHelper and refactored the HttpLog implementation to
depend on a request attribute for passing the current user.

Change-Id: Ic7d94118c7ab6c46fa784b88acefd7434bb58a44
This commit is contained in:
Colby Ranger
2012-03-06 11:39:45 -08:00
parent d386bb2f6e
commit 7820803a0d
23 changed files with 171 additions and 209 deletions

View File

@@ -37,7 +37,6 @@ limitations under the License.
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
</dependency>
<dependency>

View File

@@ -25,6 +25,7 @@ import com.google.gerrit.httpd.WebModule;
import com.google.gerrit.httpd.WebSshGlueModule;
import com.google.gerrit.httpd.auth.openid.OpenIdModule;
import com.google.gerrit.lifecycle.LifecycleManager;
import com.google.gerrit.pgm.http.jetty.GetUserFilter;
import com.google.gerrit.pgm.http.jetty.JettyEnv;
import com.google.gerrit.pgm.http.jetty.JettyModule;
import com.google.gerrit.pgm.http.jetty.ProjectQoSFilter;
@@ -274,6 +275,7 @@ public class Daemon extends SiteProgram {
if (authConfig.getAuthType() == AuthType.OPENID) {
modules.add(new OpenIdModule());
}
modules.add(sysInjector.getInstance(GetUserFilter.Module.class));
return sysInjector.createChildInjector(modules);
}

View File

@@ -0,0 +1,88 @@
// Copyright (C) 2012 The Android Open Source Project
//
// 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.gerrit.pgm.http.jetty;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.servlet.ServletModule;
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
import java.net.URI;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Stores as a request attribute, so the {@link HttpLog} can include the the
* user for the request outside of the request scope.
*
* @author cranger@google.com (Colby Ranger)
*/
@Singleton
public class GetUserFilter implements Filter {
static final String REQ_ATTR_KEY = CurrentUser.class.toString();
public static class Module extends ServletModule {
private boolean loggingEnabled;
@Inject
Module(@GerritServerConfig final Config cfg) {
URI[] urls = JettyServer.listenURLs(cfg);
boolean reverseProxy = JettyServer.isReverseProxied(urls);
this.loggingEnabled = cfg.getBoolean("httpd", "requestlog", !reverseProxy);
}
@Override
protected void configureServlets() {
if (loggingEnabled) {
filter("/*").through(GetUserFilter.class);
}
}
}
private final Provider<CurrentUser> userProvider;
@Inject
GetUserFilter(final Provider<CurrentUser> userProvider) {
this.userProvider = userProvider;
}
@Override
public void doFilter(
ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
req.setAttribute(REQ_ATTR_KEY, userProvider.get());
chain.doFilter(req, resp);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) {
}
}

View File

@@ -17,8 +17,6 @@ package com.google.gerrit.pgm.http.jetty;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Provider;
import com.google.inject.servlet.GuiceHelper;
import org.apache.log4j.Appender;
import org.apache.log4j.AsyncAppender;
@@ -55,11 +53,8 @@ class HttpLog extends AbstractLifeCycle implements RequestLog {
private static final String P_USER_AGENT = "User-Agent";
private final AsyncAppender async;
private final Provider<CurrentUser> userProvider;
HttpLog(final SitePaths site, final Provider<CurrentUser> userProvider) {
this.userProvider = userProvider;
HttpLog(final SitePaths site) {
final DailyRollingFileAppender dst = new DailyRollingFileAppender();
dst.setName(LOG_NAME);
dst.setLayout(new MyLayout());
@@ -91,15 +86,11 @@ class HttpLog extends AbstractLifeCycle implements RequestLog {
@Override
public void log(final Request req, final Response rsp) {
GuiceHelper.runInContext(req, rsp, new Runnable() {
@Override
public void run() {
doLog(req, rsp);
}
});
CurrentUser user = (CurrentUser) req.getAttribute(GetUserFilter.REQ_ATTR_KEY);
doLog(req, rsp, user);
}
private void doLog(Request req, Response rsp) {
private void doLog(Request req, Response rsp, CurrentUser user) {
final LoggingEvent event = new LoggingEvent( //
Logger.class.getName(), // fqnOfCategoryClass
null, // logger (optional)
@@ -119,7 +110,6 @@ class HttpLog extends AbstractLifeCycle implements RequestLog {
uri = uri + "?" + qs;
}
CurrentUser user = userProvider.get();
if (user instanceof IdentifiedUser) {
IdentifiedUser who = (IdentifiedUser) user;
if (who.getUserName() != null && !who.getUserName().isEmpty()) {

View File

@@ -20,16 +20,13 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.lifecycle.LifecycleListener;
import com.google.gerrit.reviewdb.AuthType;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.servlet.GuiceFilter;
import com.google.inject.servlet.GuiceHelper;
import com.google.inject.servlet.GuiceServletContextListener;
import org.eclipse.jetty.io.EndPoint;
@@ -68,10 +65,6 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Singleton
public class JettyServer {
static class Lifecycle implements LifecycleListener {
@@ -112,7 +105,7 @@ public class JettyServer {
@Inject
JettyServer(@GerritServerConfig final Config cfg, final SitePaths site,
final JettyEnv env, final Provider<CurrentUser> userProvider)
final JettyEnv env)
throws MalformedURLException, IOException {
this.site = site;
@@ -122,24 +115,8 @@ public class JettyServer {
Handler app = makeContext(env, cfg);
if (cfg.getBoolean("httpd", "requestlog", !reverseProxy)) {
RequestLogHandler handler = new RequestLogHandler() {
@Override
public void handle(String target, Request baseRequest,
final HttpServletRequest req, final HttpServletResponse rsp)
throws IOException, ServletException {
// Force the user to construct, so it's available to our HttpLog
// later on when the request gets logged out to the access file.
//
GuiceHelper.runInContext(req, rsp, new Runnable() {
@Override
public void run() {
userProvider.get();
}
});
super.handle(target, baseRequest, req, rsp);
}
};
handler.setRequestLog(new HttpLog(site, userProvider));
RequestLogHandler handler = new RequestLogHandler();
handler.setRequestLog(new HttpLog(site));
handler.setHandler(app);
app = handler;
}
@@ -164,7 +141,7 @@ public class JettyServer {
final int acceptors = cfg.getInt("httpd", "acceptorThreads", 2);
final AuthType authType = ConfigUtil.getEnum(cfg, "auth", null, "type", AuthType.OPENID);
reverseProxy = true;
reverseProxy = isReverseProxied(listenUrls);
final Connector[] connectors = new Connector[listenUrls.length];
for (int idx = 0; idx < listenUrls.length; idx++) {
final URI u = listenUrls[idx];
@@ -179,7 +156,6 @@ public class JettyServer {
}
if ("http".equals(u.getScheme())) {
reverseProxy = false;
defaultPort = 80;
c = new SelectChannelConnector();
} else if ("https".equals(u.getScheme())) {
@@ -198,7 +174,6 @@ public class JettyServer {
ssl.setNeedClientAuth(true);
}
reverseProxy = false;
defaultPort = 443;
c = ssl;
@@ -256,7 +231,16 @@ public class JettyServer {
return connectors;
}
private URI[] listenURLs(final Config cfg) {
static boolean isReverseProxied(final URI[] listenUrls) {
for (URI u : listenUrls) {
if ("http".equals(u.getScheme()) || "https".equals(u.getScheme())) {
return false;
}
}
return true;
}
static URI[] listenURLs(final Config cfg) {
String[] urls = cfg.getStringList("httpd", null, "listenurl");
if (urls.length == 0) {
urls = new String[] {"http://*:8080/"};

View File

@@ -1,36 +0,0 @@
// Copyright (C) 2010 The Android Open Source Project
//
// 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.inject.servlet;
import com.google.inject.servlet.GuiceFilter.Context;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GuiceHelper {
public static void runInContext(HttpServletRequest req,
HttpServletResponse rsp, Runnable thunk) {
Context previous = GuiceFilter.localContext.get();
try {
GuiceFilter.localContext.set(new Context(req, rsp));
thunk.run();
} finally {
GuiceFilter.localContext.set(previous);
}
}
private GuiceHelper() {
}
}

View File

@@ -90,17 +90,17 @@ limitations under the License.
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-assistedinject</artifactId>
</dependency>

View File

@@ -15,11 +15,7 @@
package com.google.gerrit.server.config;
import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.inject.assistedinject.FactoryProvider;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import com.google.inject.assistedinject.FactoryModuleBuilder;
public abstract class FactoryModule extends AbstractModule {
/**
@@ -42,63 +38,9 @@ public abstract class FactoryModule extends AbstractModule {
* Just pass {@code Foo.Factory.class} to this method. The factory will be
* generated to return its one return type as declared in the creation method.
*
* @param <F>
* @param factory interface which specifies the bean factory method.
*/
protected <F> void factory(final Class<F> factory) {
factory(Key.get(factory), factory);
}
/**
* Register an assisted injection factory.
* <p>
* This function provides an automatic way to define a factory that creates a
* concrete type through assited injection. For example to configure the
* following assisted injection case:
*
* <pre>
* public class Foo {
* public interface Factory {
* Foo create(int a);
* }
* &#064;Inject
* Foo(Logger log, @Assisted int a) {...}
* }
* </pre>
*
* Just pass {@code Foo.Factory.class} to this method. The factory will be
* generated to return its one return type as declared in the creation method.
*
* @param <F>
* @param key key to bind with in Guice bindings.
* @param factory interface which specifies the bean factory method.
*/
protected <F> void factory(final Key<F> key, final Class<F> factory) {
final Method[] methods = factory.getDeclaredMethods();
switch (methods.length) {
case 1: {
final Class<?> result = methods[0].getReturnType();
if (isAbstract(result)) {
addError("Factory " + factory.getName() + " returns abstract result.");
} else {
bind(key).toProvider(FactoryProvider.newFactory(factory, result));
}
break;
}
case 0:
addError("Factory " + factory.getName() + " has no create method.");
break;
default:
addError("Factory " + factory.getName()
+ " has more than one create method.");
break;
}
}
private static boolean isAbstract(final Class<?> result) {
return result.isInterface()
|| (result.getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
protected void factory(final Class<?> factory) {
install(new FactoryModuleBuilder().build(factory));
}
}

View File

@@ -2,15 +2,13 @@
package com.google.gerrit.server.contact;
import static com.google.inject.Scopes.SINGLETON;
import com.google.gerrit.server.contact.ContactStoreConnection;
import com.google.gerrit.server.contact.HttpContactStoreConnection;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryProvider;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import org.eclipse.jgit.util.IO;
@@ -27,11 +25,9 @@ public class HttpContactStoreConnection implements ContactStoreConnection {
return new AbstractModule() {
@Override
protected void configure() {
bind(ContactStoreConnection.Factory.class)
.toProvider(FactoryProvider.newFactory(
ContactStoreConnection.Factory.class,
HttpContactStoreConnection.class))
.in(SINGLETON);
install(new FactoryModuleBuilder()
.implement(ContactStoreConnection.class, HttpContactStoreConnection.class)
.build(ContactStoreConnection.Factory.class));
}
};
}

View File

@@ -20,6 +20,7 @@ import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.ReplicationUser;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.FactoryModule;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.PerRequestProjectControlCache;
@@ -29,7 +30,6 @@ import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryProvider;
import com.google.inject.servlet.RequestScoped;
import com.jcraft.jsch.Session;
@@ -430,14 +430,12 @@ public class PushReplication implements ReplicationQueue {
}
}).getInstance(ProjectControl.Factory.class);
opFactory = injector.createChildInjector(new AbstractModule() {
opFactory = injector.createChildInjector(new FactoryModule() {
@Override
protected void configure() {
bind(PushReplication.ReplicationConfig.class).toInstance(
ReplicationConfig.this);
bind(PushReplication.ReplicationConfig.class).toInstance(ReplicationConfig.this);
bind(RemoteConfig.class).toInstance(remote);
bind(PushOp.Factory.class).toProvider(
FactoryProvider.newFactory(PushOp.Factory.class, PushOp.class));
factory(PushOp.Factory.class);
}
}).getInstance(PushOp.Factory.class);
}

View File

@@ -37,14 +37,13 @@ import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.cache.ConcurrentHashMapCache;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.FactoryModule;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gwtorm.client.SchemaFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.assistedinject.FactoryProvider;
import junit.framework.TestCase;
@@ -294,18 +293,14 @@ public class RefControlTest extends TestCase {
}
};
Injector injector = Guice.createInjector(new AbstractModule() {
Injector injector = Guice.createInjector(new FactoryModule() {
@Override
protected void configure() {
bind(Config.class) //
.annotatedWith(GerritServerConfig.class) //
bind(Config.class)
.annotatedWith(GerritServerConfig.class)
.toInstance(new Config());
bind(CapabilityControl.Factory.class)
.toProvider(FactoryProvider.newFactory(
CapabilityControl.Factory.class,
CapabilityControl.class));
factory(CapabilityControl.Factory.class);
bind(ProjectCache.class).toInstance(projectCache);
}
});

View File

@@ -42,11 +42,7 @@ import com.google.gerrit.sshd.commands.DefaultCommandModule;
import com.google.gerrit.sshd.commands.ProjectNode;
import com.google.gerrit.sshd.commands.QueryShell;
import com.google.gerrit.util.cli.CmdLineParser;
import com.google.gerrit.util.cli.OptionHandlerFactory;
import com.google.gerrit.util.cli.OptionHandlerUtil;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.assistedinject.FactoryProvider;
import com.google.inject.servlet.RequestScoped;
import org.apache.sshd.common.KeyPairProvider;
@@ -129,14 +125,6 @@ public class SshModule extends FactoryModule {
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));
install(OptionHandlerUtil.moduleFor(type, impl));
}
}

View File

@@ -29,11 +29,10 @@ import org.kohsuke.args4j.spi.Setter;
public class AccountGroupIdHandler extends OptionHandler<AccountGroup.Id> {
private final GroupCache groupCache;
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public AccountGroupIdHandler(final GroupCache groupCache,
@Assisted final CmdLineParser parser, @Assisted final OptionDef option,
@Assisted final Setter setter) {
@Assisted final Setter<AccountGroup.Id> setter) {
super(parser, option, setter);
this.groupCache = groupCache;
}

View File

@@ -29,11 +29,10 @@ import org.kohsuke.args4j.spi.Setter;
public class AccountGroupUUIDHandler extends OptionHandler<AccountGroup.UUID> {
private final GroupCache groupCache;
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public AccountGroupUUIDHandler(final GroupCache groupCache,
@Assisted final CmdLineParser parser, @Assisted final OptionDef option,
@Assisted final Setter setter) {
@Assisted final Setter<AccountGroup.UUID> setter) {
super(parser, option, setter);
this.groupCache = groupCache;
}

View File

@@ -37,13 +37,12 @@ public class AccountIdHandler extends OptionHandler<Account.Id> {
private final AccountManager accountManager;
private final AuthType authType;
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public AccountIdHandler(final AccountResolver accountResolver,
final AccountManager accountManager,
final AuthConfig authConfig,
@Assisted final CmdLineParser parser, @Assisted final OptionDef option,
@Assisted final Setter setter) {
@Assisted final Setter<Account.Id> setter) {
super(parser, option, setter);
this.accountResolver = accountResolver;
this.accountManager = accountManager;

View File

@@ -26,10 +26,10 @@ import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
public class PatchSetIdHandler extends OptionHandler<PatchSet.Id> {
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public PatchSetIdHandler(@Assisted final CmdLineParser parser,
@Assisted final OptionDef option, @Assisted final Setter setter) {
@Assisted final OptionDef option, @Assisted final Setter<PatchSet.Id> setter) {
super(parser, option, setter);
}

View File

@@ -30,12 +30,11 @@ import org.kohsuke.args4j.spi.Setter;
public class ProjectControlHandler extends OptionHandler<ProjectControl> {
private final ProjectControl.Factory projectControlFactory;
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public ProjectControlHandler(
final ProjectControl.Factory projectControlFactory,
@Assisted final CmdLineParser parser, @Assisted final OptionDef option,
@Assisted final Setter setter) {
@Assisted final Setter<ProjectControl> setter) {
super(parser, option, setter);
this.projectControlFactory = projectControlFactory;
}

View File

@@ -28,10 +28,10 @@ import org.kohsuke.args4j.spi.Setter;
import java.net.SocketAddress;
public class SocketAddressHandler extends OptionHandler<SocketAddress> {
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public SocketAddressHandler(@Assisted final CmdLineParser parser,
@Assisted final OptionDef option, @Assisted final Setter setter) {
@Assisted final OptionDef option, @Assisted final Setter<SocketAddress> setter) {
super(parser, option, setter);
}

View File

@@ -25,10 +25,10 @@ import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
public class SubcommandHandler extends OptionHandler<String> {
@SuppressWarnings({"unchecked", "rawtypes"})
@Inject
public SubcommandHandler(@Assisted final CmdLineParser parser,
@Assisted final OptionDef option, @Assisted final Setter setter) {
@Assisted final OptionDef option, @Assisted final Setter<String> setter) {
super(parser, option, setter);
}

View File

@@ -39,12 +39,12 @@ limitations under the License.
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-assistedinject</artifactId>
</dependency>
</dependencies>

View File

@@ -20,7 +20,6 @@ import org.kohsuke.args4j.spi.Setter;
/** Creates an args4j OptionHandler through a Guice Injector. */
public interface OptionHandlerFactory<T> {
@SuppressWarnings("rawtypes")
OptionHandler create(org.kohsuke.args4j.CmdLineParser cmdLineParser,
OptionDef optionDef, Setter setter);
OptionHandler<T> create(org.kohsuke.args4j.CmdLineParser cmdLineParser,
OptionDef optionDef, Setter<T> setter);
}

View File

@@ -15,8 +15,13 @@
package com.google.gerrit.util.cli;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.internal.MoreTypes.ParameterizedTypeImpl;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.util.Types;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Setter;
import java.lang.reflect.Type;
@@ -25,10 +30,21 @@ public class OptionHandlerUtil {
/** Generate a key for an {@link OptionHandlerFactory} in Guice. */
@SuppressWarnings("unchecked")
public static <T> Key<OptionHandlerFactory<T>> keyFor(final Class<T> valueType) {
final Type factoryType =
new ParameterizedTypeImpl(null, OptionHandlerFactory.class, valueType);
final Type factoryType = Types.newParameterizedType(OptionHandlerFactory.class, valueType);
return (Key<OptionHandlerFactory<T>>) Key.get(factoryType);
}
return (Key<OptionHandlerFactory<T>>) Key.get(TypeLiteral.get(factoryType));
@SuppressWarnings("unchecked")
private static <T> Key<OptionHandler<T>> handlerOf(Class<T> type) {
final Type handlerType = Types.newParameterizedTypeWithOwner(null, OptionHandler.class, type);
return (Key<OptionHandler<T>>) Key.get(handlerType);
}
@SuppressWarnings("unchecked")
public static <T> Module moduleFor(final Class<T> type, Class<? extends OptionHandler<T>> impl) {
return new FactoryModuleBuilder()
.implement(handlerOf(type), impl)
.build(keyFor(type));
}
private OptionHandlerUtil() {

13
pom.xml
View File

@@ -52,7 +52,7 @@ limitations under the License.
<gwtexpuiVersion>1.2.5</gwtexpuiVersion>
<gwtVersion>2.3.0</gwtVersion>
<slf4jVersion>1.6.1</slf4jVersion>
<guiceVersion>2.0</guiceVersion>
<guiceVersion>3.0</guiceVersion>
<jettyVersion>7.2.1.v20101111</jettyVersion>
<gwt.compileReport>false</gwt.compileReport>
@@ -485,6 +485,11 @@ limitations under the License.
<version>0.9.6</version>
<type>pom</type>
<exclusions>
<exclusion>
<!-- conflicts with our use of guice 3.0 -->
<groupId>com.google.code.guice</groupId>
<artifactId>guice</artifactId>
</exclusion>
<exclusion>
<!-- jug-1.1 is LGPL, and the source has been lost -->
<groupId>jug</groupId>
@@ -557,19 +562,19 @@ limitations under the License.
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guiceVersion}</version>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>${guiceVersion}</version>
</dependency>
<dependency>
<groupId>com.google.code.guice</groupId>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-assistedinject</artifactId>
<version>${guiceVersion}</version>
</dependency>