Skip to content

Instantly share code, notes, and snippets.

@codyaray
Created January 3, 2013 06:54
Show Gist options
  • Save codyaray/4441348 to your computer and use it in GitHub Desktop.
Save codyaray/4441348 to your computer and use it in GitHub Desktop.
Basic AbstractInjectableProvider for building RESTful web services with Jersey using reflection to find the Super Type Tokens. See http://codyaray.com/2013/01/finding-generic-type-parameters-with-guava for details.
package com.mydomain.myapp.resources;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import javax.ws.rs.core.Context;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;
/**
* Abstract class for making Jersey injectable providers.
*
* @param <T> the type of the injectable value.
* @author codyaray
* @since 2/01/2012
* @see http://codahale.com/what-makes-jersey-interesting-injection-providers/
*/
public abstract class AbstractInjectableProvider<T> extends AbstractHttpContextInjectable<T>
implements InjectableProvider<Context, Type> {
// The type of T
private final Type type;
public AbstractInjectableProvider() {
/*
* Use reflection to get the "Super Type Token"
* See http://gafter.blogspot.com/2006/12/super-type-tokens.html
*/
// Because this class is abstract, getClass() must return a sub-class of it.
// Traverse the hierarchy from the instantiated subclass to a direct subclass of this one
Class<?> klass = getClass();
while (!klass.getSuperclass().equals(AbstractInjectableProvider.class)) {
klass = klass.getSuperclass();
}
// This operation is safe. Because klass is a direct sub-class, getGenericSuperclass() will
// always return the Type of this class. Because this class is parameterized, the cast is safe
ParameterizedType superclass = (ParameterizedType) klass.getGenericSuperclass();
this.type = superclass.getActualTypeArguments()[0];
}
@Override
public Injectable<T> getInjectable(ComponentContext componentContext, Context context, Type type) {
return type.equals(this.type) ? getInjectable(componentContext, context) : null;
}
protected Injectable<T> getInjectable(ComponentContext componentContext, Context context) {
return this;
}
@Override
public ComponentScope getScope() {
return ComponentScope.PerRequest;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment