/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.analytics;
import com.opengamma.engine.view.cycle.ComputationCycleQuery;
import com.opengamma.engine.view.cycle.ComputationResultsResponse;
import com.opengamma.engine.view.cycle.ViewCycle;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.Pair;
/**
* Viewport on a grid displaying the dependency graph showing how a value is calculated. This class isn't thread safe.
*/
public class DependencyGraphViewport implements Viewport {
/** The calculation configuration used when calculating the value and its ancestor values. */
private final String _calcConfigName;
/** The row and column structure of the underlying grid. */
private final DependencyGraphGridStructure _gridStructure;
/** The ID that is sent to the client to notify it that the viewport's data has been updated. */
private final String _callbackId;
/** The ID that is sent to the client to notify it that the viewport's structure has been updated. */
private final String _structureCallbackId;
/** Defines the extent of the viewport. */
private ViewportDefinition _viewportDefinition;
/** The current viewport data. */
private ViewportResults _latestResults;
/** The current state. Dep graph viewports are never empty, they will always have structure and metadata. */
private State _state = State.STALE_DATA;
/**
* Creates an instance.
*
* @param calcConfigName the calculation configuration used to calculate the dependency graph
* @param gridStructure the row and column structure of the grid
* @param callbackId the ID that's passed to listeners when the viewport's data changes
* @param structureCallbackId the ID that's passed to listeners when the viewport's structure changes
* TODO not used currently
* @param viewportDefinition the viewport definition
* @param cycle the view cycle from the previous calculation cycle
* @param cache the current results TODO should this be a new cache?
* if all depgraphs share the main cache it won't get cleaned up when they close. is there a good reason to share
* the cache? could this just be a new instance?
*/
/* package */ DependencyGraphViewport(String calcConfigName,
DependencyGraphGridStructure gridStructure,
String callbackId,
String structureCallbackId,
ViewportDefinition viewportDefinition,
ViewCycle cycle,
ResultsCache cache) {
_structureCallbackId = structureCallbackId;
ArgumentChecker.notEmpty(calcConfigName, "calcConfigName");
ArgumentChecker.notNull(gridStructure, "gridStructure");
ArgumentChecker.notEmpty(callbackId, "callbackId");
_calcConfigName = calcConfigName;
_gridStructure = gridStructure;
_callbackId = callbackId;
update(viewportDefinition, cycle, cache);
}
/**
* Updates the viewport, e.g. in response to the user scrolling the grid.
*
* @param viewportDefinition the definition of the viewport, not null
* @param cycle the cycle used to calculate the latest set of results, not null
* @param cache the cache of results for the grid, not null
*/
@Override
public void update(ViewportDefinition viewportDefinition, ViewCycle cycle, ResultsCache cache) {
ArgumentChecker.notNull(viewportDefinition, "viewportSpec");
ArgumentChecker.notNull(cycle, "cycle");
ArgumentChecker.notNull(cache, "cache");
if (!viewportDefinition.isValidFor(_gridStructure)) {
throw new IllegalArgumentException("Viewport contains cells outside the bounds of the grid. Viewport: " +
viewportDefinition + ", grid: " + _gridStructure);
}
_viewportDefinition = viewportDefinition;
updateResults(cycle, cache);
}
/**
* Updates the data in the viewport when a new set of results arrives from the calculation engine.
*
* @param cycle the view cycle, not null
* @param cache the cache of results, not null
*/
/* package */void updateResults(ViewCycle cycle, ResultsCache cache) {
ComputationCycleQuery query = new ComputationCycleQuery();
query.setCalculationConfigurationName(_calcConfigName);
query.setValueSpecifications(_gridStructure.getValueSpecifications());
ComputationResultsResponse resultsResponse = cycle.queryResults(query);
cache.put(_calcConfigName, resultsResponse.getResults(), cycle.getDuration());
Pair<ViewportResults, State> resultsAndState = _gridStructure.createResults(_viewportDefinition, cache, _latestResults);
_latestResults = resultsAndState.getFirst();
_state = resultsAndState.getSecond();
}
@Override
public GridStructure getGridStructure() {
return _gridStructure;
}
@Override
public ViewportResults getData() {
return _latestResults;
}
@Override
public ViewportDefinition getDefinition() {
return _viewportDefinition;
}
@Override
public String getCallbackId() {
return _callbackId;
}
@Override
public State getState() {
return _state;
}
@Override
public String getStructureCallbackId() {
return _structureCallbackId;
}
}