/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.view.compilation; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.threeten.bp.Instant; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.opengamma.DataNotFoundException; import com.opengamma.core.position.Portfolio; import com.opengamma.engine.depgraph.DependencyGraph; import com.opengamma.engine.depgraph.DependencyGraphExplorer; import com.opengamma.engine.depgraph.DependencyNode; import com.opengamma.engine.depgraph.impl.DependencyGraphExplorerImpl; import com.opengamma.engine.function.CompiledFunctionDefinition; import com.opengamma.engine.function.FunctionParameters; import com.opengamma.engine.function.resolver.CompiledFunctionResolver; import com.opengamma.engine.marketdata.manipulator.DistinctMarketDataSelector; import com.opengamma.engine.target.ComputationTargetReference; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.engine.view.ViewDefinition; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.util.ArgumentChecker; /** * Default implementation of {@link CompiledViewDefinitionWithGraphs}. */ public class CompiledViewDefinitionWithGraphsImpl extends CompiledViewDefinitionImpl implements CompiledViewDefinitionWithGraphs { private final Map<String, DependencyGraphExplorer> _graphsByConfiguration; private final long _functionInitId; private final Map<ComputationTargetReference, UniqueId> _resolutions; /** * Constructs an instance. * * @param context the view compilation context, not null * @param identifier the compilation identifier, not null * @param graphs the dependency graphs, not null * @param portfolio the portfolio, possibly null * @return the new instance, not null */ public static CompiledViewDefinitionWithGraphsImpl of(final ViewCompilationContext context, final String identifier, final Collection<DependencyGraph> graphs, final Portfolio portfolio) { final Collection<CompiledViewCalculationConfiguration> calcConfigs = new ArrayList<>(); Instant validFrom = null; Instant validTo = null; final CompiledFunctionResolver functions = context.getCompiledFunctionResolver(); for (DependencyGraph graph : graphs) { calcConfigs.add(CompiledViewCalculationConfigurationImpl.of(graph)); final Iterator<DependencyNode> itr = graph.nodeIterator(); while (itr.hasNext()) { final CompiledFunctionDefinition function = functions.getFunction(itr.next().getFunction().getFunctionId()); if (function != null) { Instant time = function.getEarliestInvocationTime(); if (time != null) { if (validFrom != null) { if (validFrom.isBefore(time)) { validFrom = time; } } else { validFrom = time; } } time = function.getLatestInvocationTime(); if (time != null) { if (validTo != null) { if (validTo.isAfter(time)) { validTo = time; } } else { validTo = time; } } } } } return new CompiledViewDefinitionWithGraphsImpl(context.getResolverVersionCorrection(), identifier, context.getViewDefinition(), graphs, context.getActiveResolutions(), portfolio, context .getServices().getFunctionCompilationContext().getFunctionInitId(), calcConfigs, validFrom, validTo); } public CompiledViewDefinitionWithGraphsImpl(VersionCorrection versionCorrection, String identifier, ViewDefinition viewDefinition, Collection<DependencyGraph> graphs, Map<ComputationTargetReference, UniqueId> resolutions, Portfolio portfolio, long functionInitId, Collection<CompiledViewCalculationConfiguration> compiledCalcConfigs, Instant validFrom, Instant validTo) { super(versionCorrection, identifier, viewDefinition, portfolio, compiledCalcConfigs, validFrom, validTo); ArgumentChecker.notNull(resolutions, "resolutions"); _functionInitId = functionInitId; final Map<String, DependencyGraphExplorer> graphsByConfiguration = Maps.newHashMapWithExpectedSize(graphs.size()); for (DependencyGraph graph : graphs) { graphsByConfiguration.put(graph.getCalculationConfigurationName(), new DependencyGraphExplorerImpl(graph)); } _graphsByConfiguration = Collections.unmodifiableMap(graphsByConfiguration); _resolutions = Collections.unmodifiableMap(resolutions); } private CompiledViewDefinitionWithGraphsImpl(final CompiledViewDefinitionWithGraphsImpl copyFrom, final VersionCorrection versionCorrection) { super(copyFrom, versionCorrection); _graphsByConfiguration = copyFrom._graphsByConfiguration; _functionInitId = copyFrom._functionInitId; _resolutions = copyFrom._resolutions; } private CompiledViewDefinitionWithGraphsImpl(final CompiledViewDefinitionWithGraphsImpl copyFrom, final Map<String, DependencyGraphExplorer> graphsByConfig, final Map<String, Map<DistinctMarketDataSelector, Set<ValueSpecification>>> selectionsByConfig, final Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> paramsByConfig) { super(copyFrom.getResolverVersionCorrection(), copyFrom.getCompilationIdentifier(), copyFrom.getViewDefinition(), copyFrom.getPortfolio(), processCompiledCalculationConfigurations( copyFrom.getCompiledCalculationConfigurationsMap(), graphsByConfig, selectionsByConfig, paramsByConfig), copyFrom.getValidFrom(), copyFrom.getValidTo()); _graphsByConfiguration = graphsByConfig; _functionInitId = copyFrom._functionInitId; _resolutions = copyFrom._resolutions; } @Override public CompiledViewDefinitionWithGraphs withResolverVersionCorrection(final VersionCorrection versionCorrection) { return new CompiledViewDefinitionWithGraphsImpl(this, versionCorrection); } @Override public CompiledViewDefinitionWithGraphs withMarketDataManipulationSelections(final Map<String, DependencyGraph> newGraphsByConfig, final Map<String, Map<DistinctMarketDataSelector, Set<ValueSpecification>>> selectionsByConfig, final Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> paramsByConfig) { final Map<String, DependencyGraphExplorer> graphsByConfig = Maps.newHashMap(_graphsByConfiguration); for (Map.Entry<String, DependencyGraph> graph : newGraphsByConfig.entrySet()) { graphsByConfig.put(graph.getKey(), new DependencyGraphExplorerImpl(graph.getValue())); } return new CompiledViewDefinitionWithGraphsImpl(this, graphsByConfig, selectionsByConfig, paramsByConfig); } @Override public Collection<DependencyGraphExplorer> getDependencyGraphExplorers() { return _graphsByConfiguration.values(); } public static Collection<DependencyGraph> getDependencyGraphs(final CompiledViewDefinitionWithGraphs viewDefinition) { final Collection<DependencyGraphExplorer> explorers = viewDefinition.getDependencyGraphExplorers(); final List<DependencyGraph> graphs = new ArrayList<DependencyGraph>(explorers.size()); for (DependencyGraphExplorer explorer : explorers) { graphs.add(explorer.getWholeGraph()); } return graphs; } /** * Gets the function init ID that was used when creating the dependency graphs * * @return the function init ID that was used when creating the dependency graphs * @deprecated this needs to go */ @Deprecated public long getFunctionInitId() { return _functionInitId; } @Override public Map<ComputationTargetReference, UniqueId> getResolvedIdentifiers() { return _resolutions; } @Override public DependencyGraphExplorer getDependencyGraphExplorer(final String calcConfigName) { ArgumentChecker.notNull(calcConfigName, "calcConfigName"); final DependencyGraphExplorer dependencyGraph = _graphsByConfiguration.get(calcConfigName); if (dependencyGraph == null) { throw new DataNotFoundException("The calculation configuration name " + calcConfigName + " does not exist in the view definition"); } return dependencyGraph; } private static Collection<CompiledViewCalculationConfiguration> processCompiledCalculationConfigurations( final Map<String, CompiledViewCalculationConfiguration> compiledCalculationConfigurations, final Map<String, DependencyGraphExplorer> graphsByConfiguration, final Map<String, Map<DistinctMarketDataSelector, Set<ValueSpecification>>> selectionsByConfig, final Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> paramsByConfig) { ArgumentChecker.notNull(graphsByConfiguration, "graphsByConfiguration"); ArgumentChecker.notNull(selectionsByConfig, "selectionsByGraph"); final Collection<CompiledViewCalculationConfiguration> compiledViewCalculationConfigurations = new ArrayList<>(); for (Map.Entry<String, DependencyGraphExplorer> entry : graphsByConfiguration.entrySet()) { String configName = entry.getKey(); DependencyGraph graph = entry.getValue().getWholeGraph(); CompiledViewCalculationConfiguration cvcc = createCalculationConfiguration(configName, graph, selectionsByConfig, paramsByConfig, compiledCalculationConfigurations); compiledViewCalculationConfigurations.add(cvcc); } return compiledViewCalculationConfigurations; } private static CompiledViewCalculationConfiguration createCalculationConfiguration(String configName, DependencyGraph graph, Map<String, Map<DistinctMarketDataSelector, Set<ValueSpecification>>> selectionsByConfig, Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> paramsByConfig, Map<String, CompiledViewCalculationConfiguration> compiledCalculationConfigurations) { // There is a market data selection in place, create a new configuration with it if (selectionsByConfig.containsKey(configName)) { // Function params will be a subset of the selections, so it is possible we have no entry Map<DistinctMarketDataSelector, FunctionParameters> marketDataSelectionFunctionParameters = paramsByConfig.containsKey(configName) ? paramsByConfig.get(configName) : ImmutableMap .<DistinctMarketDataSelector, FunctionParameters>of(); return CompiledViewCalculationConfigurationImpl.of(graph, selectionsByConfig.get(configName), marketDataSelectionFunctionParameters); } else if (compiledCalculationConfigurations.containsKey(configName)) { // No market data selection, but we have a compiled one already so use it return compiledCalculationConfigurations.get(configName); } else { // Create a new configuration just from the graph return CompiledViewCalculationConfigurationImpl.of(graph); } } }