com.opengamma.engine.marketdata.MarketDataSnapshotWithOverride.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.engine.marketdata.MarketDataSnapshotWithOverride.java

Source

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

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.threeten.bp.Instant;

import com.google.common.collect.Maps;
import com.opengamma.engine.value.ValueRequirement;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.id.UniqueId;

/**
 * Combines an underlying {@link MarketDataSnapshot} with one designed to provide overrides for certain requirements.
 * <p>
 * Note that the overriding snapshot can provide instances of {@link OverrideOperation} instead of (or as well as) actual values for this to return. In this case the operation is applied to the
 * underlying.
 */
public class MarketDataSnapshotWithOverride extends AbstractMarketDataSnapshot {

    private final MarketDataSnapshot _underlying;
    private final MarketDataInjectorImpl.Snapshot _override;

    public MarketDataSnapshotWithOverride(final MarketDataSnapshot underlying,
            final MarketDataInjectorImpl.Snapshot override) {
        _underlying = underlying;
        _override = override;
    }

    @Override
    public UniqueId getUniqueId() {
        assertInitialized();
        if (getOverride() == null) {
            // NOTE jonathan 2013-03-08 -- important for batch to have access to the real underlying snapshot ID when possible
            return getUnderlying().getUniqueId();
        }
        // REVIEW 2013-02-04 Andrew -- This is not a good unique id, it should be allocated by whatever persists or creates these snapshots
        return UniqueId.of(MARKET_DATA_SNAPSHOT_ID_SCHEME, "MarketDataSnapshotWithOverride:" + getSnapshotTime());
    }

    @Override
    public Instant getSnapshotTimeIndication() {
        return getUnderlying().getSnapshotTimeIndication();
    }

    @Override
    public void init() {
        getUnderlying().init();
        if (getOverride() != null) {
            getOverride().init();
        }
    }

    @Override
    public void init(final Set<ValueSpecification> values, final long timeout, final TimeUnit unit) {
        getUnderlying().init(values, timeout, unit);
        if (getOverride() != null) {
            getOverride().init();
        }
    }

    @Override
    public boolean isInitialized() {
        return getUnderlying().isInitialized();
    }

    @Override
    public boolean isEmpty() {
        assertInitialized();
        return getUnderlying().isEmpty() && (getOverride() == null);
    }

    @Override
    public Instant getSnapshotTime() {
        return getUnderlying().getSnapshotTime();
    }

    @Override
    public Object query(final ValueSpecification value) {
        if (getOverride() != null) {
            Object result = getOverride().query(value);
            if (result != null) {
                if (result instanceof OverrideOperation) {
                    final OverrideOperation operation = (OverrideOperation) result;
                    result = getUnderlying().query(value);
                    if (result != null) {
                        return operation.apply(getOverrideValueRequirement(value), result);
                    } else {
                        return null;
                    }
                } else {
                    return result;
                }
            }
        }
        return getUnderlying().query(value);
    }

    @Override
    public Map<ValueSpecification, Object> query(final Set<ValueSpecification> values) {
        if (getOverride() != null) {
            final Set<ValueSpecification> unresolved = new HashSet<ValueSpecification>(values);
            final Map<ValueSpecification, Object> result = Maps.newHashMapWithExpectedSize(values.size());
            final Map<ValueSpecification, OverrideOperation> overrideOperations = Maps
                    .newHashMapWithExpectedSize(values.size());
            for (ValueSpecification value : values) {
                Object response = getOverride().query(value);
                if (response == null) {
                    continue;
                } else if (response instanceof OverrideOperation) {
                    overrideOperations.put(value, (OverrideOperation) response);
                } else {
                    result.put(value, response);
                    unresolved.remove(value);
                }
            }
            if (!unresolved.isEmpty()) {
                final Map<ValueSpecification, Object> response = getUnderlying().query(unresolved);
                if (response != null) {
                    for (final Map.Entry<ValueSpecification, Object> underlyingEntry : response.entrySet()) {
                        final OverrideOperation overrideOperation = overrideOperations
                                .get(underlyingEntry.getKey());
                        if (overrideOperation != null) {
                            result.put(underlyingEntry.getKey(),
                                    overrideOperation.apply(getOverrideValueRequirement(underlyingEntry.getKey()),
                                            underlyingEntry.getValue()));
                        } else {
                            result.put(underlyingEntry.getKey(), underlyingEntry.getValue());
                        }
                    }
                }
            }
            return result;
        } else {
            return getUnderlying().query(values);
        }
    }

    private ValueRequirement getOverrideValueRequirement(final ValueSpecification subscription) {
        // TODO: Converting a value specification to a requirement like this is probably going to be wrong
        return new ValueRequirement(subscription.getValueName(), subscription.getTargetSpecification(),
                subscription.getProperties());
    }

    //-------------------------------------------------------------------------
    private MarketDataSnapshot getUnderlying() {
        return _underlying;
    }

    private MarketDataInjectorImpl.Snapshot getOverride() {
        return _override;
    }

}