/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.test; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.commons.lang.ObjectUtils; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.function.AbstractFunction; import com.opengamma.engine.function.FunctionCompilationContext; import com.opengamma.engine.function.FunctionExecutionContext; import com.opengamma.engine.function.FunctionInputs; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.value.ComputedValue; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.engine.value.ValueSpecification; /** * A function suitable for use in mock environments. * */ public class MockFunction extends AbstractFunction.NonCompiledInvoker { /** * default unique id */ public static final String UNIQUE_ID = "mock"; private final ComputationTarget _target; private final Set<ValueRequirement> _requirements = new HashSet<ValueRequirement>(); private final Set<ValueSpecification> _resultSpecs = new HashSet<ValueSpecification>(); private final Set<ComputedValue> _results = new HashSet<ComputedValue>(); /** * @param uniqueId identifier of the function * @param target Target mock function applies to * @param output What the mock function outputs * @return A mock function with one input and one output */ public static MockFunction getMockFunction(String uniqueId, ComputationTarget target, Object output) { MockFunction fn = new MockFunction(uniqueId, target); fn.addResult(new ValueSpecification("OUTPUT", target.toSpecification(), fn.createValueProperties().get()), output); return fn; } public static MockFunction getMockFunction(ComputationTarget target, Object output) { return getMockFunction(UNIQUE_ID, target, output); } public static MockFunction getMockFunction(final ComputationTarget target, final ValueSpecification spec, final Object value) { final MockFunction fn = new MockFunction(UNIQUE_ID, target); fn.addResult(new ComputedValue(spec, value)); return fn; } public static MockFunction getMockFunction(String uniqueId, ComputationTarget target, Object output, ValueRequirement input) { MockFunction fn = getMockFunction(uniqueId, target, output); fn.addRequirement(input); return fn; } public static MockFunction getMockFunction(String uniqueId, ComputationTarget target, Object output, MockFunction inputFunction) { MockFunction fn = getMockFunction(uniqueId, target, output); for (ValueSpecification resultSpec : inputFunction.getResultSpecs()) { fn.addRequirement(resultSpec.toRequirementSpecification()); } return fn; } public MockFunction(String uniqueId, ComputationTarget target) { _target = target; setUniqueId(uniqueId); } public MockFunction(ComputationTarget target) { this(UNIQUE_ID, target); } public void addRequirement(ValueRequirement requirement) { addRequirements(Collections.singleton(requirement)); } public void addRequirements(Collection<ValueRequirement> requirements) { _requirements.addAll(requirements); } public Set<ValueRequirement> getRequirements() { return Collections.unmodifiableSet(_requirements); } public void addResult(ValueSpecification valueSpec, Object result) { addResult(new ComputedValue(valueSpec, result)); } public void addResult(ComputedValue result) { addResults(Collections.singleton(result)); } public void addResults(Collection<ComputedValue> results) { _results.addAll(results); for (ComputedValue result : _results) { _resultSpecs.add(result.getSpecification()); } } @Override public boolean canApplyTo(FunctionCompilationContext context, ComputationTarget target) { return ObjectUtils.equals(target.getUniqueId(), _target.getUniqueId()); } @Override public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, final ValueRequirement desiredValue) { return Collections.unmodifiableSet(_requirements); } @Override public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) { return getResultSpecs(); } public Set<ValueSpecification> getResultSpecs() { return _resultSpecs; } public ValueSpecification getResultSpec() { if (_resultSpecs.size() != 1) { throw new IllegalStateException("Result count must be 1: " + _resultSpecs.toString()); } return _resultSpecs.iterator().next(); } public Set<ComputedValue> getResults() { return _results; } public ComputedValue getResult() { if (_results.size() != 1) { throw new IllegalStateException("Result count must be 1: " + _results.toString()); } return _results.iterator().next(); } @Override public String getShortName() { return getUniqueId() + " for " + _target; } @Override public ComputationTargetType getTargetType() { return _target.getType(); } public ComputationTarget getTarget() { return _target; } @Override public Set<ComputedValue> execute(FunctionExecutionContext executionContext, FunctionInputs inputs, ComputationTarget target, Set<ValueRequirement> desiredValues) { Set<ComputedValue> results = new HashSet<ComputedValue>(); for (ValueRequirement desiredValue : desiredValues) { for (ComputedValue result : _results) { // PLAT-2290; desiredValue is really a ValueSpecification so can do an equality test if ((desiredValue.getValueName() == result.getSpecification().getValueName()) && desiredValue.getTargetReference().equals(result.getSpecification().getTargetSpecification()) && desiredValue.getConstraints().equals(result.getSpecification().getProperties())) { results.add(result); } } } return results; } @Override public String toString() { return getShortName() + " (" + getUniqueId() + ")"; } }