/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.depgraph;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.engine.function.ParameterizedFunction;
import com.opengamma.engine.function.exclusion.FunctionExclusionGroup;
import com.opengamma.engine.function.exclusion.FunctionExclusionGroups;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.util.test.Profiler;
import com.opengamma.util.tuple.Triple;
/* package */class ResolvedFunctionStep extends FunctionIterationStep.IterationBaseStep {
private static final Logger s_logger = LoggerFactory.getLogger(ResolvedFunctionStep.class);
private final Iterator<Triple<ParameterizedFunction, ValueSpecification, Collection<ValueSpecification>>> _functions;
public ResolvedFunctionStep(final ResolveTask task, final Iterator<Triple<ParameterizedFunction, ValueSpecification, Collection<ValueSpecification>>> functions) {
super(task);
assert functions != null;
_functions = functions;
}
protected Iterator<Triple<ParameterizedFunction, ValueSpecification, Collection<ValueSpecification>>> getFunctions() {
return _functions;
}
@Override
protected boolean run(final GraphBuildingContext context) {
if (!getFunctions().hasNext()) {
s_logger.info("No more functions for {}", getValueRequirement());
setTaskStateFinished(context);
return true;
}
final Triple<ParameterizedFunction, ValueSpecification, Collection<ValueSpecification>> resolvedFunction = getFunctions().next();
final Collection<FunctionExclusionGroup> groups = getTask().getFunctionExclusion();
if (groups != null) {
final FunctionExclusionGroups util = context.getFunctionExclusionGroups();
final FunctionExclusionGroup exclusion = util.getExclusionGroup(resolvedFunction.getFirst().getFunction().getFunctionDefinition());
if ((exclusion != null) && util.isExcluded(exclusion, groups)) {
s_logger.debug("Ignoring {} from exclusion group {}", resolvedFunction, exclusion);
getTask().setRecursionDetected();
setRunnableTaskState(this, context);
return true;
}
}
s_logger.debug("Considering {} for {}", resolvedFunction, getValueRequirement());
final ValueSpecification originalOutput = resolvedFunction.getSecond();
ValueSpecification resolvedOutput = originalOutput.compose(getValueRequirement());
if (resolvedOutput != originalOutput) {
resolvedOutput = context.simplifyType(resolvedOutput);
s_logger.debug("Composed original output of {} to {}", originalOutput, resolvedOutput);
}
functionApplication(context, resolvedOutput, resolvedFunction);
return true;
}
@Override
protected ValueRequirement getDesiredValue() {
return getValueRequirement();
}
@Override
protected ValueSpecification getResolvedOutputs(final GraphBuildingContext context, final Set<ValueSpecification> newOutputValues, final Set<ValueSpecification> resolvedOutputValues) {
final ValueRequirement desiredValue = getValueRequirement();
ValueSpecification resolvedOutput = null;
for (ValueSpecification outputValue : newOutputValues) {
if ((resolvedOutput == null) && (desiredValue.getValueName() == outputValue.getValueName()) && desiredValue.getConstraints().isSatisfiedBy(outputValue.getProperties())) {
resolvedOutput = context.simplifyType(outputValue.compose(desiredValue));
s_logger.debug("Raw output {} resolves to {}", outputValue, resolvedOutput);
resolvedOutputValues.add(resolvedOutput);
} else {
resolvedOutputValues.add(context.simplifyType(outputValue));
}
}
return resolvedOutput;
}
@Override
public String toString() {
return "RESOLVED_FUNCTION" + getObjectId();
}
private static final Profiler s_profiler = Profiler.create(ResolvedFunctionStep.class);
@Override
protected void reportResult() {
s_profiler.tick();
}
}