com.opengamma.engine.function.FunctionInputsImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.engine.function.FunctionInputsImpl.java

Source

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

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Sets;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.target.ComputationTargetReference;
import com.opengamma.engine.target.ComputationTargetSpecificationResolver;
import com.opengamma.engine.value.ComputedValue;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.id.UniqueId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.Pair;

/**
 * An implementation of {@link FunctionInputs} that stores all inputs in internal maps.
 */
public class FunctionInputsImpl implements FunctionInputs, Serializable {

    private static final long serialVersionUID = 1L;

    private final ComputationTargetSpecificationResolver.AtVersionCorrection _resolver;
    private final Set<ComputedValue> _values;
    private final Map<String, ComputedValue> _valuesByRequirementName = new HashMap<String, ComputedValue>();
    private final Map<Pair<String, Object>, ComputedValue[]> _valuesByRequirement = new HashMap<Pair<String, Object>, ComputedValue[]>();
    private final Collection<ValueSpecification> _missingValues;

    public FunctionInputsImpl(final ComputationTargetSpecificationResolver.AtVersionCorrection resolver,
            final ComputedValue value) {
        _resolver = resolver;
        _missingValues = Collections.emptySet();
        _values = new HashSet<ComputedValue>();
        addValue(value);
    }

    public FunctionInputsImpl(final ComputationTargetSpecificationResolver.AtVersionCorrection resolver,
            final Collection<? extends ComputedValue> values) {
        this(resolver, values, Collections.<ValueSpecification>emptySet());
    }

    public FunctionInputsImpl(final ComputationTargetSpecificationResolver.AtVersionCorrection resolver,
            final Collection<? extends ComputedValue> values, final Collection<ValueSpecification> missingValues) {
        _resolver = resolver;
        _missingValues = missingValues;
        _values = Sets.newHashSetWithExpectedSize(values.size());
        for (final ComputedValue value : values) {
            addValue(value);
        }
    }

    private void targetRefKey(final ComputationTargetReference targetRef, final List<UniqueId> uids) {
        if (targetRef.getParent() != null) {
            targetRefKey(targetRef.getParent(), uids);
        }
        uids.add(_resolver.getTargetSpecification(targetRef).getUniqueId());
    }

    private Object targetSpecKey(final ComputationTargetSpecification targetSpec) {
        if (targetSpec.getParent() == null) {
            return targetSpec.getUniqueId();
        } else {
            final List<UniqueId> uids = new ArrayList<UniqueId>();
            targetRefKey(targetSpec.getParent(), uids);
            uids.add(targetSpec.getUniqueId());
            return uids;
        }
    }

    private void addValue(final ComputedValue value) {
        ArgumentChecker.notNull(value, "Computed Value");
        if (value.getValue() instanceof ComputedValue) {
            throw new IllegalArgumentException("Double-nested value");
        }
        _values.add(value);
        _valuesByRequirementName.put(value.getSpecification().getValueName(), value);
        final Pair<String, Object> key = Pair.of(value.getSpecification().getValueName(),
                targetSpecKey(value.getSpecification().getTargetSpecification()));
        final ComputedValue[] prev = _valuesByRequirement.get(key);
        if (prev == null) {
            _valuesByRequirement.put(key, new ComputedValue[] { value });
        } else {
            final ComputedValue[] values = new ComputedValue[prev.length + 1];
            System.arraycopy(prev, 0, values, 0, prev.length);
            values[prev.length] = value;
            _valuesByRequirement.put(key, values);
        }
    }

    @Override
    public Collection<ComputedValue> getAllValues() {
        return Collections.unmodifiableSet(_values);
    }

    @Override
    public Object getValue(final ValueRequirement requirement) {
        final ComputedValue cv = getComputedValue(requirement);
        if (cv != null) {
            return cv.getValue();
        }
        return null;
    }

    @Override
    public ComputedValue getComputedValue(final ValueRequirement requirement) {
        final Pair<String, Object> key = Pair.of(requirement.getValueName(),
                targetSpecKey(_resolver.getTargetSpecification(requirement.getTargetReference())));
        final ComputedValue[] values = _valuesByRequirement.get(key);
        if (values != null) {
            for (final ComputedValue value : values) {
                // Shortcut to check the properties as we already know the name and target match
                if (requirement.getConstraints().isSatisfiedBy(value.getSpecification().getProperties())) {
                    return value;
                }
            }
        }
        return null;
    }

    @Override
    public Object getValue(final String requirementName) {
        final ComputedValue computedValue = getComputedValue(requirementName);
        return computedValue != null ? computedValue.getValue() : null;
    }

    @Override
    public ComputedValue getComputedValue(final String requirementName) {
        return _valuesByRequirementName.get(requirementName);
    }

    @Override
    public Collection<ValueSpecification> getMissingValues() {
        return Collections.unmodifiableCollection(_missingValues);
    }

    @Override
    public String toString() {
        return "Values = " + _values + ", Missing = " + _missingValues;
    }

}