Created
July 7, 2014 17:52
-
-
Save gissuebot/ca5305c2abdfb62a3c09 to your computer and use it in GitHub Desktop.
Migrated attachment for Guice issue 22, comment 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: C:/Documents and Settings/Michael.Barker/src/guice/test/com/google/inject/CustomConverterTest.java | |
=================================================================== | |
--- C:/Documents and Settings/Michael.Barker/src/guice/test/com/google/inject/CustomConverterTest.java (revision 0) | |
+++ C:/Documents and Settings/Michael.Barker/src/guice/test/com/google/inject/CustomConverterTest.java (revision 0) | |
@@ -0,0 +1,111 @@ | |
+package com.google.inject; | |
+ | |
+import java.lang.reflect.Member; | |
+import java.net.MalformedURLException; | |
+import java.net.URL; | |
+import java.util.Arrays; | |
+import java.util.HashMap; | |
+import java.util.Map; | |
+ | |
+import junit.framework.TestCase; | |
+ | |
+import com.google.inject.name.Named; | |
+import com.google.inject.name.Names; | |
+ | |
+public class CustomConverterTest extends TestCase { | |
+ | |
+ public void testURLConversion() { | |
+ Injector inj = Guice.createInjector(new AbstractModule() { | |
+ protected void configure() { | |
+ bind(Foo.class).to(FooImpl.class); | |
+ binder().bindConverter(URL.class, new URLConverter()); | |
+ Map<String,String> config = new HashMap<String,String>(); | |
+ config.put("bar", "http://www.google.com"); | |
+ Names.bindProperties(binder(), config); | |
+ } | |
+ }); | |
+ Foo f = inj.getInstance(Foo.class); | |
+ URL url = f.getBar(); | |
+ assertEquals("www.google.com", url.getHost()); | |
+ } | |
+ | |
+ public void testArrayConversion() { | |
+ Injector inj = Guice.createInjector(new AbstractModule() { | |
+ protected void configure() { | |
+ bind(Tee.class).to(TeeImpl.class); | |
+ binder().bindConverter(String[].class, new ArrayConverter()); | |
+ Map<String,String> config = new HashMap<String,String>(); | |
+ config.put("bar", "this,is,a,test,string"); | |
+ Names.bindProperties(binder(), config); | |
+ } | |
+ }); | |
+ Tee tee = inj.getInstance(Tee.class); | |
+ String[] bar = tee.getBar(); | |
+ assertTrue(Arrays.equals(bar, | |
+ new String[] { "this","is","a","test","string" })); | |
+ } | |
+ | |
+ public void testURLConversionError() { | |
+ try { | |
+ Injector inj = Guice.createInjector(new AbstractModule() { | |
+ protected void configure() { | |
+ bind(Foo.class).to(FooImpl.class); | |
+ binder().bindConverter(URL.class, new URLConverter()); | |
+ Map<String,String> config = new HashMap<String,String>(); | |
+ config.put("bar", "www.google.com"); | |
+ Names.bindProperties(binder(), config); | |
+ } | |
+ }); | |
+ inj.getInstance(Foo.class); | |
+ assertFalse("CreationException should be thrown", true); | |
+ } catch (CreationException e) { | |
+ } | |
+ } | |
+ | |
+ static class URLConverter implements Converter<URL> { | |
+ | |
+ public URL convert(Member member, Key<URL> key, String value) | |
+ throws ConstantConversionException { | |
+ try { | |
+ return new URL(value); | |
+ } catch (MalformedURLException e) { | |
+ throw new ConstantConversionException(member, key, value, e); | |
+ } | |
+ } | |
+ | |
+ } | |
+ | |
+ static class ArrayConverter implements Converter<String[]> { | |
+ | |
+ public String[] convert(Member member, Key<String[]> key, String value) | |
+ throws ConstantConversionException { | |
+ return value.split(","); | |
+ } | |
+ | |
+ } | |
+ | |
+ static interface Foo { | |
+ URL getBar(); | |
+ } | |
+ | |
+ static class FooImpl implements Foo { | |
+ @Inject @Named("bar") URL bar; | |
+ | |
+ public URL getBar() { | |
+ return bar; | |
+ } | |
+ } | |
+ | |
+ static interface Tee { | |
+ String[] getBar(); | |
+ } | |
+ | |
+ static class TeeImpl implements Tee { | |
+ @Inject @Named("bar") String[] bar; | |
+ | |
+ public String[] getBar() { | |
+ return bar; | |
+ } | |
+ } | |
+ | |
+} | |
Index: C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/Binder.java | |
=================================================================== | |
--- C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/Binder.java (revision 326) | |
+++ C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/Binder.java (working copy) | |
@@ -16,13 +16,15 @@ | |
package com.google.inject; | |
+import java.lang.annotation.Annotation; | |
+import java.lang.reflect.Method; | |
+ | |
+import org.aopalliance.intercept.MethodInterceptor; | |
+ | |
import com.google.inject.binder.AnnotatedBindingBuilder; | |
import com.google.inject.binder.AnnotatedConstantBindingBuilder; | |
import com.google.inject.binder.LinkedBindingBuilder; | |
import com.google.inject.matcher.Matcher; | |
-import java.lang.annotation.Annotation; | |
-import java.lang.reflect.Method; | |
-import org.aopalliance.intercept.MethodInterceptor; | |
/** | |
* Collects configuration information (primarily <i>bindings</i>) which will be | |
@@ -201,6 +203,11 @@ | |
* Binds a scope to an annotation. | |
*/ | |
void bindScope(Class<? extends Annotation> annotationType, Scope scope); | |
+ | |
+ /** | |
+ * Binds a convertor to a class. | |
+ */ | |
+ <T> void bindConverter(Class<T> type, Converter<? extends T> customConverter); | |
/** | |
* See the EDSL examples at {@link Binder}. | |
Index: C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/Converter.java | |
=================================================================== | |
--- C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/Converter.java (revision 0) | |
+++ C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/Converter.java (revision 0) | |
@@ -0,0 +1,15 @@ | |
+package com.google.inject; | |
+ | |
+import java.lang.reflect.Member; | |
+ | |
+/** | |
+ * Converts a {@code String} to another type. | |
+ */ | |
+public interface Converter<T> { | |
+ | |
+ /** | |
+ * Converts {@code String} value. | |
+ */ | |
+ T convert(Member member, Key<T> key, String value) | |
+ throws ConstantConversionException; | |
+} | |
\ No newline at end of file | |
Index: C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/InjectorImpl.java | |
=================================================================== | |
--- C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/InjectorImpl.java (revision 326) | |
+++ C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/InjectorImpl.java (working copy) | |
@@ -86,16 +86,20 @@ | |
final Map<Key<?>, BindingImpl<?>> bindings; | |
final BindingsMultimap bindingsMultimap = new BindingsMultimap(); | |
final Map<Class<? extends Annotation>, Scope> scopes; | |
+ final Map<Class<?>, Converter<?>> customConverters; | |
ErrorHandler errorHandler = new InvalidErrorHandler(); | |
Object defaultSource = SourceProviders.UNKNOWN_SOURCE; | |
+ | |
InjectorImpl(ConstructionProxyFactory constructionProxyFactory, | |
Map<Key<?>, BindingImpl<?>> bindings, | |
- Map<Class<? extends Annotation>, Scope> scopes) { | |
+ Map<Class<? extends Annotation>, Scope> scopes, | |
+ Map<Class<?>, Converter<?>> customConverters) { | |
this.constructionProxyFactory = constructionProxyFactory; | |
this.bindings = bindings; | |
this.scopes = scopes; | |
+ this.customConverters = customConverters; | |
} | |
/** | |
@@ -220,6 +224,18 @@ | |
// TODO: Generalize everything below here and enable users to plug in | |
// their own converters. | |
+ // Do we need a custom conversion? | |
+ Converter<T> custom = (Converter<T>) customConverters.get(rawType); | |
+ if (custom != null) { | |
+ try { | |
+ T t = custom.convert(member, key, value); | |
+ return new ConstantFactory<T>(t); | |
+ } | |
+ catch (ConstantConversionException e) { | |
+ return handleConstantConversionError( | |
+ member, stringBinding, rawType, e); | |
+ } | |
+ } | |
// Do we need a primitive? | |
Converter<T> converter = (Converter<T>) PRIMITIVE_CONVERTERS.get(rawType); | |
@@ -861,18 +877,6 @@ | |
} | |
} | |
- /** | |
- * Converts a {@code String} to another type. | |
- */ | |
- interface Converter<T> { | |
- | |
- /** | |
- * Converts {@code String} value. | |
- */ | |
- T convert(Member member, Key<T> key, String value) | |
- throws ConstantConversionException; | |
- } | |
- | |
Map<Class<?>, InternalFactory<?>> implicitBindings = | |
new HashMap<Class<?>, InternalFactory<?>>(); | |
Index: C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/BinderImpl.java | |
=================================================================== | |
--- C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/BinderImpl.java (revision 326) | |
+++ C:/Documents and Settings/Michael.Barker/src/guice/src/com/google/inject/BinderImpl.java (working copy) | |
@@ -61,6 +61,8 @@ | |
= new ArrayList<ConstantBindingBuilderImpl>(); | |
final Map<Class<? extends Annotation>, Scope> scopes = | |
new HashMap<Class<? extends Annotation>, Scope>(); | |
+ final Map<Class<?>, Converter<?>> customConverters = | |
+ new HashMap<Class<?>, Converter<?>>(); | |
final List<StaticInjection> staticInjections | |
= new ArrayList<StaticInjection>(); | |
@@ -168,6 +170,13 @@ | |
scopes.put(annotationType, nonNull(scope, "scope")); | |
} | |
} | |
+ | |
+ /* (non-Javadoc) | |
+ * @see com.google.inject.Binder#bindConverter(java.lang.Class, com.google.inject.Converter) | |
+ */ | |
+ public <T> void bindConverter(Class<T> type, Converter<? extends T> customConverter) { | |
+ customConverters.put(type, customConverter); | |
+ } | |
public <T> BindingBuilderImpl<T> bind(Key<T> key) { | |
BindingBuilderImpl<T> builder = | |
@@ -245,7 +254,7 @@ | |
Map<Key<?>, BindingImpl<?>> bindings = new HashMap<Key<?>, BindingImpl<?>>(); | |
injector = new InjectorImpl( | |
- proxyFactoryBuilder.create(), bindings, scopes); | |
+ proxyFactoryBuilder.create(), bindings, scopes, customConverters); | |
injector.setErrorHandler(configurationErrorHandler); | |
createConstantBindings(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment