package tc.oc.pgm.features; import javax.annotation.Nullable; import com.google.inject.Key; import com.google.inject.TypeLiteral; import tc.oc.commons.core.inject.KeyedManifest; import tc.oc.commons.core.reflect.ResolvableType; import tc.oc.commons.core.reflect.TypeArgument; import tc.oc.commons.core.reflect.Types; import tc.oc.pgm.map.inject.MapBinders; import tc.oc.pgm.map.inject.MapScoped; import tc.oc.pgm.xml.parser.ReflectiveParserManifest; /** * Configures a reflectively parsed feature {@link T}, which must be an interface. * * @see tc.oc.pgm.xml.Parseable for details on reflective parsing */ public class ReflectiveFeatureManifest<T extends FeatureDefinition> extends KeyedManifest implements MapBinders { private final TypeLiteral<T> type; private final TypeArgument<T> typeArg; private final Key<FeatureDefinitionParser<T>> definitionParserKey; protected ReflectiveFeatureManifest() { this(null); } public ReflectiveFeatureManifest(@Nullable TypeLiteral<T> type) { this.type = type != null ? Types.assertFullySpecified(type) : new ResolvableType<T>(){}.in(getClass()); this.typeArg = new TypeArgument<T>(this.type){}; this.definitionParserKey = Key.get(new ResolvableType<FeatureDefinitionParser<T>>(){}.with(typeArg)); } @Override protected Object manifestKey() { return type; } @Override protected void configure() { // Generate the reflective parser and bind it to ReflectiveParser<T> install(new ReflectiveParserManifest<>(type, FeatureDefinition.Impl.class)); // Bind ReflectiveFeatureParser<T> as the definition parser for T bind(definitionParserKey).to(new ResolvableType<ReflectiveFeatureParser<T>>(){}.with(typeArg)) .in(MapScoped.class); } }