/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.financial.aggregation; import java.util.Collections; import java.util.List; import java.util.Set; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.function.FunctionExecutionContext; import com.opengamma.engine.function.FunctionInputs; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.value.ComputedValue; import com.opengamma.engine.value.ValueProperties; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.engine.value.ValueSpecification; /** * Function for producing a slice of outputs from all positions underneath a node based on the sorted results. The values are sorted * in the "compareTo" order and returned in value descending order (as reported by {@link Comparable#compareTo}. The values must * implement the comparable interface for the result to be calculated. * <p> * See {@link SortedPositionValues} for further details of how the sort takes place. */ public abstract class SlicedPositionValues extends AbstractSortedPositionValues { /** * Property name giving the number of results in the slice. */ public static final String COUNT_PROPERTY = "Count"; /** * Property name identifying the value that was produced from the positions. */ public static final String VALUE_NAME_PROPERTY = "Value"; protected abstract boolean validateConstraints(ValueProperties constraints); protected abstract List<ComputedValue> sliceResults(List<ComputedValue> sortedAscending, ValueProperties constraints, ValueProperties.Builder properties); private static void composePrefixedProperties(final ValueProperties.Builder builder, final ValueProperties source, final String prefix) { for (String property : source.getProperties()) { if (property.startsWith(prefix)) { final Set<String> propertyValues = source.getValues(property); if (propertyValues.isEmpty()) { builder.withAny(property); } else { builder.with(property, propertyValues); } } } } // AbstractSortedPositionValues @Override protected Set<ValueRequirement> getRequirements(final String valueName, final ComputationTarget target, final ValueProperties constraints) { if (!validateConstraints(constraints)) { return null; } final ValueProperties.Builder requirementConstraints = ValueProperties.with(VALUE_NAME_PROPERTY, valueName); composePrefixedProperties(requirementConstraints, constraints, valueName + "."); return Collections.singleton(new ValueRequirement(SortedPositionValues.VALUE_NAME, target.toSpecification(), requirementConstraints.get())); } @Override protected void composeValueProperties(final ValueProperties.Builder builder, final ValueSpecification inputValue) { final String valueName = inputValue.getProperty(SortedPositionValues.VALUE_NAME_PROPERTY); builder.with(VALUE_NAME_PROPERTY, valueName); composePrefixedProperties(builder, inputValue.getProperties(), valueName + "."); } // AbstractFunction @SuppressWarnings("unchecked") @Override public Set<ComputedValue> execute(final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final ComputedValue input = inputs.getAllValues().iterator().next(); final ValueProperties constraints = desiredValues.iterator().next().getConstraints(); final ValueProperties.Builder properties = createValueProperties(); composeValueProperties(properties, input.getSpecification()); final List<ComputedValue> values = sliceResults((List<ComputedValue>) input.getValue(), constraints, properties); return Collections.singleton(new ComputedValue(ValueSpecification.of(getValueName(), ComputationTargetType.PORTFOLIO_NODE, target.getUniqueId(), properties.get()), values)); } }