assertEquals(2, getResultsInvoked.get());
}
public void twoLevelConversion() {
final DepGraphTestHelper helper = helper();
final ComputationTarget target1 = new ComputationTarget(ComputationTargetType.PRIMITIVE, UniqueId.of("Target", "1"));
final ComputationTarget target2 = new ComputationTarget(ComputationTargetType.PRIMITIVE, UniqueId.of("Target", "2"));
final ComputationTarget target3 = new ComputationTarget(ComputationTargetType.PRIMITIVE, UniqueId.of("Target", "3"));
final String property = "Constraint";
MockFunction source = new MockFunction("source1", target1);
source.addResult(new ComputedValue(new ValueSpecification("A", target1.toSpecification(), ValueProperties.with(ValuePropertyNames.FUNCTION, "1").with(property, "Foo").get()), 1.0));
helper.getFunctionRepository().addFunction(source);
source = new MockFunction("source2", target2);
source.addResult(new ComputedValue(new ValueSpecification("A", target2.toSpecification(), ValueProperties.with(ValuePropertyNames.FUNCTION, "1").with(property, "Bar").get()), 2.0));
helper.getFunctionRepository().addFunction(source);
// Constraint preserving A->B
helper.getFunctionRepository().addFunction(new TestFunction() {
@Override
public String getShortName() {
return "AtoB";
}
@Override
public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, ValueRequirement desiredValue) {
return Collections.singleton(new ValueRequirement("A", target.toSpecification(), ValueProperties.withAny(property).get()));
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) {
return Collections.singleton(new ValueSpecification("B", target.toSpecification(), createValueProperties().withAny(property).get()));
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target, Map<ValueSpecification, ValueRequirement> inputs) {
return Collections.singleton(new ValueSpecification("B", target.toSpecification(), createValueProperties().with(property, inputs.keySet().iterator().next().getProperty(property)).get()));
}
@Override
public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) {
return null;
}
});
// Constraint converting B->B
helper.getFunctionRepository().addFunction(new TestFunction() {
@Override
public String getShortName() {
return "BConv";
}
@Override
public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) {
return null;
}
@Override
public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, ValueRequirement desiredValue) {
return Collections.singleton(new ValueRequirement("B", target.toSpecification(), ValueProperties.withAny(property).get()));
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) {
return Collections.singleton(new ValueSpecification("B", target.toSpecification(), ValueProperties.all()));
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target, Map<ValueSpecification, ValueRequirement> inputs) {
final Set<ValueSpecification> result = Sets.newHashSetWithExpectedSize(inputs.size());
for (ValueSpecification input : inputs.keySet()) {
result.add(new ValueSpecification(input.getValueName(), input.getTargetSpecification(), input.getProperties().copy().withAny(property).get()));
}
return result;
}
@Override
public int getPriority() {
return -1;
}
});
// Combining B->C; any constraint but must be the same
helper.getFunctionRepository().addFunction(new TestFunction() {
@Override
public String getShortName() {
return "BtoC";
}
@Override
public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) {
return null;
}
@Override
public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, ValueRequirement desiredValue) {
final Set<ValueRequirement> req = new HashSet<ValueRequirement>();
Set<String> props = desiredValue.getConstraints().getValues(property);
if (props == null) {
if (target.equals(target3)) {
req.add(new ValueRequirement("B", target1.toSpecification(), ValueProperties.withAny(property).get()));
req.add(new ValueRequirement("B", target2.toSpecification(), ValueProperties.withAny(property).get()));
} else {
req.add(new ValueRequirement("B", target.toSpecification(), ValueProperties.withAny(property).get()));
}
} else {
if (target.equals(target3)) {
req.add(new ValueRequirement("B", target1.toSpecification(), ValueProperties.with(property, props).get()));
req.add(new ValueRequirement("B", target2.toSpecification(), ValueProperties.with(property, props).get()));
} else {
req.add(new ValueRequirement("B", target.toSpecification(), ValueProperties.with(property, props).get()));
}
}
return req;
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) {
return Collections.singleton(new ValueSpecification("C", target.toSpecification(), createValueProperties().withAny(property).get()));
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target, Map<ValueSpecification, ValueRequirement> inputs) {
String propValue = null;
for (ValueSpecification input : inputs.keySet()) {
if (propValue == null) {
propValue = input.getProperty(property);
} else {
if (!propValue.equals(input.getProperty(property))) {
throw new IllegalArgumentException("property mismatch - " + propValue + " vs " + input.getProperty(property));
}
}
}
return Collections.singleton(new ValueSpecification("C", target.toSpecification(), createValueProperties().with(property, propValue).get()));
}
});
// Converting C->C; constraint omitted implies default
helper.getFunctionRepository().addFunction(new TestFunction() {
@Override
public String getShortName() {
return "CConv";
}
@Override
public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) {
return null;
}
@Override
public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, ValueRequirement desiredValue) {
final Set<String> props = desiredValue.getConstraints().getValues(property);
if (props == null) {
return Collections.singleton(new ValueRequirement("C", target.toSpecification(), ValueProperties.with(property, "Default").get()));
} else {
return Collections.singleton(new ValueRequirement("C", target.toSpecification(), ValueProperties.withAny(property).get()));
}
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) {
return Collections.singleton(new ValueSpecification("C", target.toSpecification(), ValueProperties.all()));
}
@Override
public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target, Map<ValueSpecification, ValueRequirement> inputs) {
final Set<ValueSpecification> result = Sets.newHashSetWithExpectedSize(inputs.size());
for (ValueSpecification input : inputs.keySet()) {
result.add(new ValueSpecification(input.getValueName(), input.getTargetSpecification(), input.getProperties().copy().withAny(property).get()));
}
return result;
}
@Override
public int getPriority() {
return -1;
}
});
final DependencyGraphBuilder builder = helper.createBuilder(new FunctionPriority() {
@Override
public int getPriority(CompiledFunctionDefinition function) {
if (function instanceof TestFunction) {
return ((TestFunction) function).getPriority();
}
return 0;
}
});
((MapComputationTargetResolver) builder.getCompilationContext().getRawComputationTargetResolver()).addTarget(target1);
((MapComputationTargetResolver) builder.getCompilationContext().getRawComputationTargetResolver()).addTarget(target2);
((MapComputationTargetResolver) builder.getCompilationContext().getRawComputationTargetResolver()).addTarget(target3);
builder.addTarget(new ValueRequirement("C", target3.toSpecification()));
builder.addTarget(new ValueRequirement("C", target2.toSpecification()));
builder.addTarget(new ValueRequirement("C", target1.toSpecification()));
builder.addTarget(new ValueRequirement("B", target1.toSpecification()));
builder.addTarget(new ValueRequirement("B", target2.toSpecification()));
DependencyGraph graph = builder.getDependencyGraph();