com.opengamma.engine.view.client.ViewDeltaResultCalculator.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.engine.view.client.ViewDeltaResultCalculator.java

Source

/**
 * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.engine.view.client;

import java.util.Map;

import org.apache.commons.lang.ObjectUtils;

import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.value.ComputedValueResult;
import com.opengamma.engine.value.ValueProperties;
import com.opengamma.engine.view.DeltaDefinition;
import com.opengamma.engine.view.ViewCalculationResultModel;
import com.opengamma.engine.view.ViewComputationResultModel;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.engine.view.ViewDeltaResultModel;
import com.opengamma.engine.view.ViewResultModel;
import com.opengamma.engine.view.impl.InMemoryViewDeltaResultModel;
import com.opengamma.util.tuple.Pair;

/**
 * Produces {@link ViewDeltaResultModel} instances by comparing two {@link ViewComputationResultModel}.
 */
public class ViewDeltaResultCalculator {

    /**
     * Computes the delta between and old and new results.
     * 
     * @param viewDefinition the view definition to which the results apply
     * @param previousResult the previous result
     * @param result the new result
     * @return the delta between the two results, not null
     */
    public static ViewDeltaResultModel computeDeltaModel(ViewDefinition viewDefinition,
            ViewResultModel previousResult, ViewResultModel result) {
        InMemoryViewDeltaResultModel deltaModel = new InMemoryViewDeltaResultModel();
        deltaModel.setViewCycleExecutionOptions(result.getViewCycleExecutionOptions());
        deltaModel.setCalculationTime(result.getCalculationTime());
        deltaModel.setCalculationDuration(result.getCalculationDuration());
        deltaModel.setVersionCorrection(result.getVersionCorrection());
        deltaModel.setViewCycleId(result.getViewCycleId());
        deltaModel.setViewProcessId(result.getViewProcessId());
        if (previousResult != null) {
            deltaModel.setPreviousCalculationTime(previousResult.getCalculationTime());
        }
        for (String calcConfigName : result.getCalculationConfigurationNames()) {
            final DeltaDefinition deltaDefinition = viewDefinition.getCalculationConfiguration(calcConfigName)
                    .getDeltaDefinition();
            final ViewCalculationResultModel resultCalcModel = result.getCalculationResult(calcConfigName);
            final ViewCalculationResultModel previousCalcModel = previousResult != null
                    ? previousResult.getCalculationResult(calcConfigName)
                    : null;
            for (ComputationTargetSpecification targetSpec : resultCalcModel.getAllTargets()) {
                computeDeltaModel(deltaDefinition, deltaModel, targetSpec, calcConfigName, previousCalcModel,
                        resultCalcModel);
            }
        }
        return deltaModel;
    }

    private static void computeDeltaModel(DeltaDefinition deltaDefinition, InMemoryViewDeltaResultModel deltaModel,
            ComputationTargetSpecification targetSpec, String calcConfigName,
            ViewCalculationResultModel previousCalcModel, ViewCalculationResultModel resultCalcModel) {
        final Map<Pair<String, ValueProperties>, ComputedValueResult> resultValues = resultCalcModel
                .getValues(targetSpec);
        if (resultValues != null) {
            if (previousCalcModel == null) {
                // Everything is new/delta because this is a new calculation context.
                for (Map.Entry<Pair<String, ValueProperties>, ComputedValueResult> resultEntry : resultValues
                        .entrySet()) {
                    deltaModel.addValue(calcConfigName, resultEntry.getValue());
                }
            } else {
                final Map<Pair<String, ValueProperties>, ComputedValueResult> previousValues = previousCalcModel
                        .getValues(targetSpec);
                if (previousValues == null) {
                    // Everything is new/delta because this is a new target.
                    for (ComputedValueResult result : resultValues.values()) {
                        deltaModel.addValue(calcConfigName, result);
                    }
                } else {
                    // Have to individual delta.
                    for (Map.Entry<Pair<String, ValueProperties>, ComputedValueResult> resultEntry : resultValues
                            .entrySet()) {
                        ComputedValueResult resultValue = resultEntry.getValue();
                        ComputedValueResult previousValue = previousValues.get(resultEntry.getKey());
                        // REVIEW jonathan 2010-05-07 -- The previous value that we're comparing with is the value from the last
                        // computation cycle, not the value that we last emitted as a delta. It is therefore important that the
                        // DeltaComparers take this into account in their implementation of isDelta. E.g. they should compare the
                        // values after truncation to the required decimal place, rather than testing whether the difference of the
                        // full values is greater than some threshold; this way, there will always be a point beyond which a change
                        // is detected, even in the event of gradual creep.
                        if (deltaDefinition.isDelta(previousValue, resultValue)
                                || !ObjectUtils.equals(previousValue.getAggregatedExecutionLog(),
                                        resultValue.getAggregatedExecutionLog())) {
                            deltaModel.addValue(calcConfigName, resultEntry.getValue());
                        }
                    }
                }
            }
        }
    }

}