/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.marketdata.manipulator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import com.opengamma.engine.depgraph.DependencyNode; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.tuple.Pair; /** * Responsible for extracting structured objects from a dependency graph. * E.g. yield curve, volatility surface etc. The caller is able to specify what types of structure they are * interested in to avoid extraction of. */ public class DependencyGraphStructureExtractor { private final String _calcConfigName; private final MarketDataSelector _selector; private final SelectorResolver _selectorResolver; private final Map<ValueSpecification, DependencyNode> _graphValues = new HashMap<>(); private final List<Pair<ValueSpecification, ValueSpecification>> _terminalValueRename = new LinkedList<>(); private final Map<DistinctMarketDataSelector, Set<ValueSpecification>> _selectorMapping; private int _nodeDelta; /** * Create an extractor which will extract all structures matching the passed name. * * @param calcConfigName the calculation configuration name, not null * @param selector the structures to be extracted, not null * @param selectorResolver the selector resolver, not null * @param selectorMapping populated with details of the manipulations inserted into the graph, not null */ public DependencyGraphStructureExtractor(final String calcConfigName, final MarketDataSelector selector, final SelectorResolver selectorResolver, final Map<DistinctMarketDataSelector, Set<ValueSpecification>> selectorMapping) { ArgumentChecker.notNull(calcConfigName, "calcConfigName"); ArgumentChecker.notNull(selector, "selectors"); ArgumentChecker.notNull(selectorResolver, "selectorResolver"); _calcConfigName = calcConfigName; _selector = selector; _selectorResolver = selectorResolver; _selectorMapping = selectorMapping; } /** * Tests if structure extraction is required for the given value specification. * * @param valueSpecification the original value specification, not null * @return the set of value specifications associated with the manipulator; this should be updated with the rewritten value from the proxy node */ // REVIEW Chris 2014-01-14 - Mutating the return value outside this class isn't great design. too obscure public Set<ValueSpecification> extractStructure(final ValueSpecification valueSpecification) { final DistinctMarketDataSelector matchingSelector = _selector.findMatchingSelector(valueSpecification, _calcConfigName, _selectorResolver); if (matchingSelector == null) { return null; } Set<ValueSpecification> values = _selectorMapping.get(matchingSelector); if (values == null) { values = new HashSet<>(); _selectorMapping.put(matchingSelector, values); } return values; } public void storeProduction(final ValueSpecification valueSpec, final DependencyNode node) { _graphValues.put(valueSpec, node); } public DependencyNode getProduction(final ValueSpecification valueSpec) { return _graphValues.get(valueSpec); } public void addProxyValue(final ValueSpecification originalValue, final ValueSpecification proxyValue) { _terminalValueRename.add(Pair.of(originalValue, proxyValue)); _nodeDelta++; } public void removeProxyValue(final ValueSpecification originalValue, final ValueSpecification proxyValue) { _terminalValueRename.remove(Pair.of(proxyValue, originalValue)); _nodeDelta--; } public Iterable<Pair<ValueSpecification, ValueSpecification>> getTerminalValueRenames() { return _terminalValueRename; } public boolean hasTerminalValueRenames() { return !_terminalValueRename.isEmpty(); } public int getNodeDelta() { return _nodeDelta; } }