/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.basics; import java.util.HashMap; import java.util.Map; import java.util.Optional; import com.opengamma.strata.basics.date.HolidayCalendar; import com.opengamma.strata.basics.date.HolidayCalendarId; import com.opengamma.strata.basics.date.HolidayCalendars; import com.opengamma.strata.collect.Messages; /** * Provides access to reference data, such as holiday calendars and securities. * <p> * Reference data is looked up using implementations of {@link ReferenceDataId}. * The identifier is parameterized with the type of the reference data to be returned. * <p> * The standard implementation is {@link ImmutableReferenceData}. */ public interface ReferenceData { /** * Obtains an instance from a map of reference data. * <p> * Each entry in the map is a single piece of reference data, keyed by the matching identifier. * For example, a {@link HolidayCalendar} can be looked up using a {@link HolidayCalendarId}. * The caller must ensure that the each entry in the map corresponds with the parameterized * type on the identifier. * <p> * The resulting {@code ReferenceData} instance will include the {@linkplain #minimal() minimal} * set of reference data that includes non-controversial identifiers that are essential for pricing. * To exclude the minimal set of identifiers, use {@link ImmutableReferenceData#of(Map)}. * * @param values the reference data values * @return the reference data instance containing the values in the map * @throws ClassCastException if a value does not match the parameterized type associated with the identifier */ public static ReferenceData of(Map<? extends ReferenceDataId<?>, ?> values) { // hash map so that keys can overlap, with this instance taking priority Map<ReferenceDataId<?>, Object> combined = new HashMap<>(); combined.putAll(StandardReferenceData.MINIMAL.getValues()); combined.putAll(values); return ImmutableReferenceData.of(combined); } /** * Obtains an instance of standard reference data. * <p> * Standard reference data is built into Strata and provides common holiday calendars and indices. * In most cases, production usage of Strata will not rely on this source of reference data. * * @return standard reference data */ public static ReferenceData standard() { return StandardReferenceData.STANDARD; } /** * Obtains the minimal set of reference data. * <p> * The {@linkplain #standard() standard} reference data contains common holiday calendars * and indices, but may not be suitable for production use. The minimal reference data contains * just those identifiers that are needed by Strata, and that are non-controversial. * These are {@link HolidayCalendars#NO_HOLIDAYS}, {@link HolidayCalendars#SAT_SUN}, * {@link HolidayCalendars#FRI_SAT} and {@link HolidayCalendars#THU_FRI}. * * @return minimal reference data */ public static ReferenceData minimal() { return StandardReferenceData.MINIMAL; } /** * Obtains an instance containing no reference data. * * @return empty reference data */ public static ReferenceData empty() { return ImmutableReferenceData.empty(); } //------------------------------------------------------------------------- /** * Checks if this reference data contains a value for the specified identifier. * * @param id the identifier to find * @return true if the reference data contains a value for the identifier */ public default boolean containsValue(ReferenceDataId<?> id) { return findValue(id).isPresent(); } /** * Gets the reference data value associated with the specified identifier. * <p> * If this reference data instance contains the identifier, the value will be returned. * Otherwise, an exception will be thrown. * * @param <T> the type of the reference data value * @param id the identifier to find * @return the reference data value * @throws ReferenceDataNotFoundException if the identifier is not found */ public default <T> T getValue(ReferenceDataId<T> id) { return findValue(id) .orElseThrow(() -> new ReferenceDataNotFoundException(Messages.format( "Reference data not found for '{}' of type '{}'", id, id.getClass().getSimpleName()))); } /** * Finds the reference data value associated with the specified identifier. * <p> * If this reference data instance contains the identifier, the value will be returned. * Otherwise, an empty optional will be returned. * * @param <T> the type of the reference data value * @param id the identifier to find * @return the reference data value, empty if not found */ public abstract <T> Optional<T> findValue(ReferenceDataId<T> id); /** * Low-level method to query the reference data value associated with the specified identifier, * returning null if not found. * <p> * This is a low-level method that obtains the reference data value, returning null instead of an error. * Applications should use {@link #getValue(ReferenceDataId)} in preference to this method. * * @param <T> the type of the reference data value * @param id the identifier to find * @return the reference data value, null if not found */ public default <T> T queryValueOrNull(ReferenceDataId<T> id) { return findValue(id).orElse(null); } //------------------------------------------------------------------------- /** * Combines this reference data with another. * <p> * The result combines both sets of reference data. * Values are taken from this set of reference data if available, otherwise they are taken * from the other set. * * @param other the other reference data * @return the combined reference data */ public default ReferenceData combinedWith(ReferenceData other) { return new CombinedReferenceData(this, other); } }