/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.depgraph.ambiguity; import java.util.Collection; import com.google.common.collect.ImmutableSet; import com.opengamma.engine.depgraph.DependencyNodeFunction; import com.opengamma.engine.depgraph.impl.DependencyNodeFunctionImpl; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.util.ArgumentChecker; /** * Representation of a single resolution to a requirement. If ambiguities exist in a view definition or the resolution rules then there may be multiple resolutions possible. These can be held in a * {@link FullRequirementResolution} instance. */ public final class RequirementResolution { // TODO: Any changes to this structure need to be reflected in the Fudge builder /** * The resolved value specification. */ private final ValueSpecification _specification; /** * The selected function. Note that the function identifier property in the value specification may not match that of the function in the repository. */ private final DependencyNodeFunction _function; /** * The resolution(s) of any inputs to the function. If there is ambiguity such that alternative resolutions are possible, then additional instances of {@link RequirementResolution} will be created * that refer to these same inputs and referenced from the containing {@link FullRequirementResolution}. */ private final Collection<FullRequirementResolution> _inputs; /** * The cached hash code. */ private final int _hashCode; public RequirementResolution(final ValueSpecification specification, final DependencyNodeFunction function, final Collection<FullRequirementResolution> inputs) { ArgumentChecker.notNull(specification, "specification"); ArgumentChecker.notNull(function, "function"); ArgumentChecker.notNull(inputs, "inputs"); _specification = specification; _function = function; _inputs = ImmutableSet.copyOf(inputs); int hc = getClass().hashCode(); hc = (hc * 31) + _specification.hashCode(); hc = (hc * 31) + DependencyNodeFunctionImpl.HASHING_STRATEGY.hashCode(_function); hc = (hc * 31) + _inputs.hashCode(); _hashCode = hc; } public ValueSpecification getSpecification() { return _specification; } public DependencyNodeFunction getFunction() { return _function; } public Collection<FullRequirementResolution> getInputs() { return _inputs; } /** * Tests whether the given resolution is present in any of the inputs to this resolution. This prevents recursive structures from being constructed. */ /* package */boolean contains(final FullRequirementResolution parent) { for (FullRequirementResolution input : _inputs) { if ((input == parent) || input.contains(parent)) { return true; } } return false; } /** * Tests whether any of the inputs to this resolution contain any ambiguity. */ /* package */boolean isAmbiguous() { for (FullRequirementResolution input : _inputs) { if (input.isDeeplyAmbiguous()) { return true; } } return false; } // Object @Override public boolean equals(final Object o) { if (o == this) { return true; } if (!(o instanceof RequirementResolution)) { return false; } final RequirementResolution other = (RequirementResolution) o; return (hashCode() == other.hashCode()) && getSpecification().equals(other.getSpecification()) && DependencyNodeFunctionImpl.HASHING_STRATEGY.equals(getFunction(), other.getFunction()) && getInputs().equals(other.getInputs()); } @Override public int hashCode() { return _hashCode; } @Override public String toString() { return _specification.toString(); } }