Skip to content

Commit

Permalink
Allow binding to satisfactions (grouplens#79)
Browse files Browse the repository at this point in the history
This adds the `toSatisfaction` method to `Binding`, allowing
clients (particularly extending code or language bindings)
to bind directly to a satisfaction.
  • Loading branch information
mdekstrand committed Nov 25, 2013
1 parent 8da3577 commit 515e3ac
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/main/java/org/grouplens/grapht/Binding.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.grouplens.grapht;

import org.grouplens.grapht.solver.BindRule;
import org.grouplens.grapht.spi.Satisfaction;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -186,4 +187,19 @@ public interface Binding<T> {
* @see #toNull()
*/
void toNull(Class<? extends T> type);

/**
* Bind this binding directly to a satisfaction.
*
* <p><strong>Note:</strong> this method is intended for use by applications that extend Grapht,
* or for bindings to other JVM languages. Most applications will have no use for this method,
* and developers consider if one of the other methods is more applicable for their situation.
* </p>
*
* <p>Bindings to satisfactions are always {@linkplain org.grouplens.grapht.solver.BindRule#isTerminal() terminal}.
* </p>
*
* @param sat The satisfaction to bind to.
*/
void toSatisfaction(@Nonnull Satisfaction sat);
}
21 changes: 21 additions & 0 deletions src/main/java/org/grouplens/grapht/BindingImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,27 @@ public void toNull(Class<? extends T> type) {
BindRules.toSatisfaction(sourceType, qualifier, s, cachePolicy, true));
}
}

@Override
public void toSatisfaction(@Nonnull Satisfaction sat) {
Preconditions.notNull("satisfaction", sat);

ElementChainContextMatcher matcher = context.getContextChain();
BindingFunctionBuilder config = context.getBuilder();

if (config.getGenerateRules()) {
Map<Class<?>, RuleSet> bindPoints = generateBindPoints(sat.getErasedType());
for (Entry<Class<?>, RuleSet> e: bindPoints.entrySet()) {
config.addBindRule(e.getValue(), matcher,
BindRules.toSatisfaction(e.getKey(), qualifier,
sat, cachePolicy, true));
}
} else {
config.addBindRule(RuleSet.EXPLICIT, matcher,
BindRules.toSatisfaction(sourceType, qualifier,
sat, cachePolicy, true));
}
}

private Object coerce(Object in) {
Class<?> boxedSource = Types.box(sourceType);
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/org/grouplens/grapht/BindingFunctionBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ public void testBindToProviderInstance() throws Exception {
assertEqualBindings(expected, ((RuleBasedBindingFunction) builder.build(RuleSet.EXPLICIT)).getRules());
}

@Test
public void testBindToSatisfaction() throws Exception {
// Test that the fluent api creates type-to-type bind rules in
// the root context
BindingFunctionBuilder builder = new BindingFunctionBuilder(spi, false);

builder.getRootContext().bind(InterfaceA.class).toSatisfaction(spi.satisfy(TypeA.class));

// expected
Map<ContextMatcher, Collection<BindRule>> expected = new HashMap<ContextMatcher, Collection<BindRule>>();
expected.put(new ElementChainContextMatcher(new ArrayList<ContextElementMatcher>()),
Arrays.asList(BindRules.toSatisfaction(InterfaceA.class, spi.matchDefault(), spi.satisfy(TypeA.class), CachePolicy.NO_PREFERENCE, true)));

assertEqualBindings(expected, ((RuleBasedBindingFunction) builder.build(RuleSet.EXPLICIT)).getRules());
}

@SuppressWarnings("unchecked")
@Test
public void testBindToWrongProvider() throws Exception {
Expand Down

0 comments on commit 515e3ac

Please sign in to comment.