forked from google/guice
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Big change - changing BinderImpl to use commands/
git-svn-id: https://google-guice.googlecode.com/svn/trunk@420 d779f126-a31b-0410-b53b-1d3aecad763e
- Loading branch information
limpbizkit
committed
Mar 8, 2008
1 parent
947540b
commit 3d58d6b
Showing
54 changed files
with
2,045 additions
and
943 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,8 @@ | |
|
||
package com.google.inject.commands; | ||
|
||
import static com.google.inject.internal.Objects.nonNull; | ||
|
||
import java.util.Arrays; | ||
import static java.util.Collections.unmodifiableList; | ||
import java.util.List; | ||
|
@@ -26,14 +28,20 @@ | |
* @author [email protected] (Jesse Wilson) | ||
*/ | ||
public final class AddMessageErrorCommand implements Command { | ||
private final Object source; | ||
private final String message; | ||
private final List<Object> arguments; | ||
|
||
AddMessageErrorCommand(String message, Object[] arguments) { | ||
this.message = message; | ||
AddMessageErrorCommand(Object source, String message, Object[] arguments) { | ||
this.source = nonNull(source, "source"); | ||
this.message = nonNull(message, "message"); | ||
this.arguments = unmodifiableList(Arrays.asList(arguments.clone())); | ||
} | ||
|
||
public Object getSource() { | ||
return source; | ||
} | ||
|
||
public <T> T acceptVisitor(Visitor<T> visitor) { | ||
return visitor.visitAddMessageError(this); | ||
} | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,16 +16,24 @@ | |
|
||
package com.google.inject.commands; | ||
|
||
import static com.google.inject.internal.Objects.nonNull; | ||
|
||
/** | ||
* Immutable snapshot of a request to add a throwable message. | ||
* | ||
* @author [email protected] (Jesse Wilson) | ||
*/ | ||
public final class AddThrowableErrorCommand implements Command { | ||
private final Object source; | ||
private final Throwable throwable; | ||
|
||
AddThrowableErrorCommand(Throwable throwable) { | ||
this.throwable = throwable; | ||
AddThrowableErrorCommand(Object source, Throwable throwable) { | ||
this.source = nonNull(source, "source"); | ||
this.throwable = nonNull(throwable, "throwable"); | ||
} | ||
|
||
public Object getSource() { | ||
return source; | ||
} | ||
|
||
public <T> T acceptVisitor(Visitor<T> visitor) { | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,10 +16,8 @@ | |
|
||
package com.google.inject.commands; | ||
|
||
import com.google.inject.Key; | ||
import com.google.inject.Provider; | ||
import com.google.inject.Scope; | ||
import com.google.inject.TypeLiteral; | ||
import com.google.inject.*; | ||
import com.google.inject.spi.SourceProviders; | ||
import com.google.inject.binder.AnnotatedBindingBuilder; | ||
import com.google.inject.binder.ConstantBindingBuilder; | ||
import com.google.inject.binder.LinkedBindingBuilder; | ||
|
@@ -34,14 +32,44 @@ | |
* @author [email protected] (Jesse Wilson) | ||
*/ | ||
public final class BindCommand<T> implements Command { | ||
|
||
static { | ||
SourceProviders.skip(BindCommand.BindingBuilder.class); | ||
} | ||
|
||
private static final BindTarget<Object> EMPTY_BIND_TARGET = new AbstractTarget<Object>() { | ||
public ScopedBindingBuilder execute(LinkedBindingBuilder<Object> linkedBindingBuilder) { | ||
return linkedBindingBuilder; | ||
} | ||
public <V> V acceptVisitor(Visitor<Object, V> visitor) { | ||
return visitor.visitUntargetted(); | ||
} | ||
}; | ||
|
||
private static final BindScoping EMPTY_SCOPING = new AbstractScoping() { | ||
public void execute(ScopedBindingBuilder scopedBindingBuilder) { | ||
// do nothing | ||
} | ||
public <V> V acceptVisitor(Visitor<V> visitor) { | ||
return visitor.visitNoScoping(); | ||
} | ||
}; | ||
|
||
private final Object source; | ||
private Key<T> key; | ||
private BindTarget<T> bindTarget; | ||
private BindScoping bindScoping; | ||
@SuppressWarnings({"unchecked"}) | ||
private BindTarget<T> bindTarget = (BindTarget<T>) EMPTY_BIND_TARGET; | ||
private BindScoping bindScoping = EMPTY_SCOPING; | ||
|
||
BindCommand(Key<T> key) { | ||
BindCommand(Object source, Key<T> key) { | ||
this.source = nonNull(source, "source"); | ||
this.key = nonNull(key, "key"); | ||
} | ||
|
||
public Object getSource() { | ||
return source; | ||
} | ||
|
||
public <V> V acceptVisitor(Visitor<V> visitor) { | ||
return visitor.visitBind(this); | ||
} | ||
|
@@ -60,52 +88,57 @@ public BindScoping getScoping() { | |
|
||
@Override public String toString() { | ||
return "bind " + key | ||
+ (bindTarget == null ? "" : (" to " + bindTarget)) | ||
+ (bindScoping == null ? "" : (" in " + bindScoping)); | ||
+ (bindTarget == EMPTY_BIND_TARGET ? "" : (" to " + bindTarget)) | ||
+ (bindScoping == EMPTY_SCOPING ? "" : (" in " + bindScoping)); | ||
} | ||
|
||
private static abstract class AbstractTarget<T> implements BindTarget<T> { | ||
public void execute(ConstantBindingBuilder builder) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
public T get(T defaultValue) { | ||
return defaultValue; | ||
public T get() { | ||
return null; | ||
} | ||
public Key<? extends Provider<? extends T>> getProviderKey( | ||
Key<Provider<? extends T>> defaultValue) { | ||
return defaultValue; | ||
public Key<? extends Provider<? extends T>> getProviderKey() { | ||
return null; | ||
} | ||
public Provider<? extends T> getProvider(Provider<? extends T> defaultValue) { | ||
return defaultValue; | ||
public Provider<? extends T> getProvider() { | ||
return null; | ||
} | ||
public Key<? extends T> getKey(Key<? extends T> defaultValue) { | ||
return defaultValue; | ||
public Key<? extends T> getKey() { | ||
return null; | ||
} | ||
} | ||
|
||
private static abstract class AbstractScoping implements BindScoping { | ||
public boolean isEagerSingleton() { | ||
return false; | ||
} | ||
public Scope getScope(Scope defaultValue) { | ||
return defaultValue; | ||
public Scope getScope() { | ||
return null; | ||
} | ||
public Class<? extends Annotation> getScopeAnnotation( | ||
Class<? extends Annotation> defaultValue) { | ||
return defaultValue; | ||
public Class<? extends Annotation> getScopeAnnotation() { | ||
return null; | ||
} | ||
} | ||
|
||
BindingBuilder bindingBuilder() { | ||
return new BindingBuilder(); | ||
BindingBuilder bindingBuilder(Binder binder) { | ||
return new BindingBuilder(binder); | ||
} | ||
|
||
/** | ||
* Package-private write access to the internal state of this command. | ||
*/ | ||
class BindingBuilder implements AnnotatedBindingBuilder<T> { | ||
private final Binder binder; | ||
|
||
BindingBuilder(Binder binder) { | ||
this.binder = binder; | ||
} | ||
|
||
public LinkedBindingBuilder<T> annotatedWith( | ||
Class<? extends Annotation> annotationType) { | ||
nonNull(annotationType, "annotationType"); | ||
assertNotAnnotated(); | ||
key = Key.get(key.getTypeLiteral(), annotationType); | ||
return this; | ||
|
@@ -134,9 +167,12 @@ public ScopedBindingBuilder to(final Key<? extends T> targetKey) { | |
public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) { | ||
return linkedBindingBuilder.to(targetKey); | ||
} | ||
@Override public Key<? extends T> getKey(Key<? extends T> defaultValue) { | ||
@Override public Key<? extends T> getKey() { | ||
return targetKey; | ||
} | ||
public <V> V acceptVisitor(Visitor<T, V> visitor) { | ||
return visitor.visitToKey(targetKey); | ||
} | ||
@Override public String toString() { | ||
return String.valueOf(targetKey); | ||
} | ||
|
@@ -145,16 +181,23 @@ public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder | |
} | ||
|
||
public void toInstance(final T instance) { | ||
nonNull(instance, "instance"); // might someday want to tolerate null here | ||
// might someday want to tolerate null here, probably by setting up a | ||
// Provider<null> rather than trying to distinguish between null and | ||
// not set | ||
nonNull(instance, "instance"); | ||
|
||
assertNoTarget(); | ||
bindTarget = new AbstractTarget<T>() { | ||
public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) { | ||
linkedBindingBuilder.toInstance(instance); | ||
return null; | ||
} | ||
@Override public T get(T defaultValue) { | ||
@Override public T get() { | ||
return instance; | ||
} | ||
public <V> V acceptVisitor(Visitor<T, V> visitor) { | ||
return visitor.visitToInstance(instance); | ||
} | ||
@Override public String toString() { | ||
return "instance " + instance; | ||
} | ||
|
@@ -168,9 +211,12 @@ public ScopedBindingBuilder toProvider(final Provider<? extends T> provider) { | |
public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) { | ||
return linkedBindingBuilder.toProvider(provider); | ||
} | ||
@Override public Provider<? extends T> getProvider(Provider<? extends T> defaultValue) { | ||
@Override public Provider<? extends T> getProvider() { | ||
return provider; | ||
} | ||
public <V> V acceptVisitor(Visitor<T, V> visitor) { | ||
return visitor.visitToProvider(provider); | ||
} | ||
@Override public String toString() { | ||
return "provider " + provider; | ||
} | ||
|
@@ -191,10 +237,12 @@ public ScopedBindingBuilder toProvider( | |
public ScopedBindingBuilder execute(LinkedBindingBuilder<T> linkedBindingBuilder) { | ||
return linkedBindingBuilder.toProvider(providerKey); | ||
} | ||
@Override public Key<? extends Provider<? extends T>> getProviderKey( | ||
Key<Provider<? extends T>> defaultValue) { | ||
@Override public Key<? extends Provider<? extends T>> getProviderKey() { | ||
return providerKey; | ||
} | ||
public <V> V acceptVisitor(Visitor<T, V> visitor) { | ||
return visitor.visitToProviderKey(providerKey); | ||
} | ||
@Override public String toString() { | ||
return "provider " + providerKey; | ||
} | ||
|
@@ -210,10 +258,12 @@ public void in(final Class<? extends Annotation> scopeAnnotation) { | |
public void execute(ScopedBindingBuilder scopedBindingBuilder) { | ||
scopedBindingBuilder.in(scopeAnnotation); | ||
} | ||
@Override public Class<? extends Annotation> getScopeAnnotation( | ||
Class<? extends Annotation> defaultValue) { | ||
@Override public Class<? extends Annotation> getScopeAnnotation() { | ||
return scopeAnnotation; | ||
} | ||
public <V> V acceptVisitor(Visitor<V> visitor) { | ||
return visitor.visitScopeAnnotation(scopeAnnotation); | ||
} | ||
@Override public String toString() { | ||
return scopeAnnotation.getName(); | ||
} | ||
|
@@ -224,12 +274,16 @@ public void in(final Scope scope) { | |
nonNull(scope, "scope"); | ||
assertNoScope(); | ||
bindScoping = new AbstractScoping() { | ||
|
||
public void execute(ScopedBindingBuilder scopedBindingBuilder) { | ||
scopedBindingBuilder.in(scope); | ||
} | ||
@Override public Scope getScope(Scope defaultValue) { | ||
@Override public Scope getScope() { | ||
return scope; | ||
} | ||
public <V> V acceptVisitor(Visitor<V> visitor) { | ||
return visitor.visitScope(scope); | ||
} | ||
@Override public String toString() { | ||
return String.valueOf(scope); | ||
} | ||
|
@@ -245,27 +299,44 @@ public void execute(ScopedBindingBuilder scopedBindingBuilder) { | |
@Override public boolean isEagerSingleton() { | ||
return true; | ||
} | ||
public <V> V acceptVisitor(Visitor<V> visitor) { | ||
return visitor.visitEagerSingleton(); | ||
} | ||
@Override public String toString() { | ||
return "eager singleton"; | ||
} | ||
}; | ||
} | ||
|
||
static final String IMPLEMENTATION_ALREADY_SET | ||
= "Implementation is set more than once."; | ||
static final String SINGLE_INSTANCE_AND_SCOPE = "Setting the scope is not" | ||
+ " permitted when binding to a single instance."; | ||
static final String SCOPE_ALREADY_SET = "Scope is set more than once."; | ||
static final String ANNOTATION_ALREADY_SPECIFIED = "More than one annotation" | ||
+ " is specified for this binding."; | ||
|
||
private void assertNoTarget() { | ||
if (bindTarget != null) { | ||
throw new IllegalStateException("Already targetted to " + bindTarget); | ||
if (bindTarget != EMPTY_BIND_TARGET) { | ||
binder.addError(IMPLEMENTATION_ALREADY_SET); | ||
} | ||
} | ||
|
||
private void assertNotAnnotated() { | ||
if (BindCommand.this.key.getAnnotationType() != null) { | ||
throw new IllegalStateException("Already annotated with " + key.getAnnotationType()); | ||
binder.addError(ANNOTATION_ALREADY_SPECIFIED); | ||
} | ||
} | ||
|
||
private void assertNoScope() { | ||
if (bindScoping != null) { | ||
throw new IllegalStateException("Already scoped by " + bindScoping); | ||
// Scoping isn't allowed when we have only one instance. | ||
if (bindTarget.get() != null) { | ||
binder.addError(SINGLE_INSTANCE_AND_SCOPE); | ||
return; | ||
} | ||
|
||
if (bindScoping != EMPTY_SCOPING) { | ||
binder.addError(SCOPE_ALREADY_SET); | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.