/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.sesame.engine;
import java.util.List;
import java.util.Objects;
import org.threeten.bp.LocalDate;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.sesame.Environment;
import com.opengamma.sesame.cache.CacheInvalidator;
import com.opengamma.sesame.cache.ValuationTimeCacheEntry;
import com.opengamma.sesame.function.scenarios.FilteredScenarioDefinition;
import com.opengamma.sesame.function.scenarios.ScenarioArgument;
import com.opengamma.sesame.function.scenarios.ScenarioFunction;
import com.opengamma.sesame.marketdata.MarketDataBundle;
import com.opengamma.util.ArgumentChecker;
/**
* {@link Environment} implementation created and managed by the engine.
* This allows the engine to monitor what data from the environment is used
* by each function and invalidate cache entries when the data changes. This
* class is package-private because it is only intended to be used by the
* engine itself, not user code.
*
* TODO can this be retired? might not need a cache or any cache invalidation after MarketDataEnvironment
* could use SimpleEnvironment for everything
*/
final class EngineEnvironment implements Environment {
// TODO an inner class used by all environment impls that is used for hashCode and equals
// makes it explicit which parts of the environment are part of the cache key and which ones are ignored
// TODO how should equality of MarketDataEnvironment be handled? requires some thought.
/** The valuation time. */
private final ZonedDateTime _valuationTime;
/** The source of market data. */
private final MarketDataBundle _marketDataBundle;
/** Scenario arguments, keyed by the type of function implementation that uses them. */
private final FilteredScenarioDefinition _scenarioDefinition;
private final CacheInvalidator _cacheInvalidator;
EngineEnvironment(ZonedDateTime valuationTime,
MarketDataBundle marketDataBundle,
CacheInvalidator cacheInvalidator) {
this(valuationTime, marketDataBundle, FilteredScenarioDefinition.EMPTY, cacheInvalidator);
}
private EngineEnvironment(ZonedDateTime valuationTime,
MarketDataBundle marketDataBundle,
FilteredScenarioDefinition scenarioDefinition,
CacheInvalidator cacheInvalidator) {
_valuationTime = ArgumentChecker.notNull(valuationTime, "valuationTime");
_scenarioDefinition = ArgumentChecker.notNull(scenarioDefinition, "scenarioDefinition");
_marketDataBundle = ArgumentChecker.notNull(marketDataBundle, "marketDataBundle");
_cacheInvalidator = ArgumentChecker.notNull(cacheInvalidator, "cacheInvalidator");
}
@Override
public LocalDate getValuationDate() {
LocalDate valuationDate = _valuationTime.toLocalDate();
_cacheInvalidator.register(new ValuationTimeCacheEntry.ValidOnCalculationDay(valuationDate));
return valuationDate;
}
@Override
public ZonedDateTime getValuationTime() {
_cacheInvalidator.register(new ValuationTimeCacheEntry.ValidAtCalculationInstant(_valuationTime));
return _valuationTime;
}
// TODO wrap bundle to do cache invalidation?
@Override
public MarketDataBundle getMarketDataBundle() {
return _marketDataBundle;
}
@Override
public <A extends ScenarioArgument<A, F>, F extends ScenarioFunction<A, F>> List<A> getScenarioArguments(
ScenarioFunction<A, F> scenarioFunction) {
return _scenarioDefinition.getArguments(scenarioFunction);
}
@Override
public FilteredScenarioDefinition getScenarioDefinition() {
return _scenarioDefinition;
}
@Override
public Environment withValuationTime(ZonedDateTime valuationTime) {
return new EngineEnvironment(valuationTime,
_marketDataBundle.withTime(valuationTime),
_scenarioDefinition,
_cacheInvalidator);
}
@Override
public Environment withValuationTimeAndFixedMarketData(ZonedDateTime valuationTime) {
return new EngineEnvironment(valuationTime, _marketDataBundle, _scenarioDefinition, _cacheInvalidator);
}
// TODO do we still need this?
@Override
public Environment withMarketData(MarketDataBundle marketDataBundle) {
return new EngineEnvironment(_valuationTime, marketDataBundle, _scenarioDefinition, _cacheInvalidator);
}
// TODO do we still need this?
@Override
public Environment withScenarioDefinition(FilteredScenarioDefinition scenarioDefinition) {
return new EngineEnvironment(_valuationTime, _marketDataBundle, scenarioDefinition, _cacheInvalidator);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
EngineEnvironment that = (EngineEnvironment) o;
return _valuationTime.equals(that._valuationTime) &&
_marketDataBundle.equals(that._marketDataBundle) &&
_scenarioDefinition.equals(that._scenarioDefinition);
}
@Override
public int hashCode() {
return Objects.hash(_valuationTime, _marketDataBundle, _scenarioDefinition);
}
}