2014-09-04 2 views
1

Voici comment mon interface StatusMapper ressemble à:Comment faire Guice MapBinder vraiment typesafe?

public interface StatusMapper<T extends Throwable> { 
    Status map(final T exception); 
} 

Et voici mon MapBinder:

TypeLiteral<Class<? extends Throwable>> exceptionType = new TypeLiteral<Class<? extends Throwable>>() { }; 
    TypeLiteral<StatusMapper<? extends Throwable>> mapperType = new TypeLiteral<StatusMapper<? extends Throwable>>() { }; 

    MapBinder<Class<? extends Throwable>, StatusMapper<? extends Throwable>> exceptionBinder = MapBinder.newMapBinder(binder(), exceptionType, mapperType); 

    exceptionBinder.addBinding(IOException.class).to(IOExceptionMapper.class); 
    exceptionBinder.addBinding(SQLException.class).to(SQLExceptionMapper.class); 
    ... 

Voici comment l'un de ces ExceptionMappers ressemble à: (simplifié)

public class IOExceptionMapper implements StatusMapper<IOException> { 
    @SuppressWarnings("unused") 
    private static final Logger logger = LoggerFactory.getLogger(IOExceptionMapper.class); 

    @Override 
    public Status map(final IOException exception) { 
     return new Status(100); 
    } 
} 

Cela fonctionne très bien jusqu'à présent, mais je dois faire attention à ce que IOException se lie à IOExceptionMapper. Si je lie exceptionBinder.addBinding(IOException.class).to(SQLExceptionMapper.class); le typechecker (compilateur) ne se plaint pas, mais il casse toute l'application - des conseils?

[Mise à jour] Selon la réponse de The111 J'ai créé ExceptionBinder

public class ExceptionBinder { 
    private final MapBinder<Class<? extends Throwable>, StatusMapper<? extends Throwable>> exceptionBinder; 

    public ExceptionBinder(final Binder binder) { 
     final TypeLiteral<Class<? extends Throwable>> exceptionType; 
     final TypeLiteral<StatusMapper<? extends Throwable>> mapperType; 

     exceptionType = new TypeLiteral<Class<? extends Throwable>>() {}; 
     mapperType = new TypeLiteral<StatusMapper<? extends Throwable>>() {}; 

     exceptionBinder = MapBinder.newMapBinder(binder, exceptionType, mapperType); 
    } 

    public <T extends Throwable> void bind(Class<T> exceptionClass, Class<? extends StatusMapper<T>> mapperClass) { 
     exceptionBinder.addBinding(exceptionClass).to(mapperClass); 
    } 
} 

Et voilà comment mon Guice-Module ressemble:

final ExceptionBinder eb = new ExceptionBinder(binder()); 
eb.bind(IOException.class,IOExceptionMapper.class); 
eb.bind(SQLException.class,SQLExceptionMapper.class); 

Répondre

1

Votre question semble peut-être liée à celle-ci : Java map with values limited by key's type parameter

Quoi si vous le Guice enveloppé MapBinder dans votre propre TypeSafeMapBinder et a donné cette classe comme une méthode:

void addToBinder(Class<T extends Throwable> eClass, 
       Class<? extends StatusMapper<T>> mClass) { 
    getWrappedBinder().addBinding(eClass, mClass); 
} 

Je ne l'ai pas testé ce donc s'il vous plaît laissez-moi savoir vos résultats.

+0

Cool homme - thx! Seul le était manquant. J'ai mis à jour ma question avec la solution. –