/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.integration.tool.config; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.threeten.bp.LocalDate; import com.opengamma.core.config.ConfigSource; import com.opengamma.core.config.impl.ConfigItem; import com.opengamma.core.convention.Convention; import com.opengamma.core.convention.ConventionSource; import com.opengamma.core.id.ExternalSchemes; import com.opengamma.core.region.Region; import com.opengamma.core.region.RegionSource; import com.opengamma.core.security.SecuritySource; import com.opengamma.financial.analytics.curve.AbstractCurveDefinition; import com.opengamma.financial.analytics.curve.ConstantCurveDefinition; import com.opengamma.financial.analytics.curve.CurveConstructionConfiguration; import com.opengamma.financial.analytics.curve.CurveDefinition; import com.opengamma.financial.analytics.curve.CurveGroupConfiguration; import com.opengamma.financial.analytics.curve.CurveNodeIdMapper; import com.opengamma.financial.analytics.curve.CurveTypeConfiguration; import com.opengamma.financial.analytics.curve.DiscountingCurveTypeConfiguration; import com.opengamma.financial.analytics.curve.FixedDateInterpolatedCurveDefinition; import com.opengamma.financial.analytics.curve.IborCurveTypeConfiguration; import com.opengamma.financial.analytics.curve.InflationCurveTypeConfiguration; import com.opengamma.financial.analytics.curve.InflationIssuerCurveTypeConfiguration; import com.opengamma.financial.analytics.curve.InterpolatedCurveDefinition; import com.opengamma.financial.analytics.curve.IssuerCurveTypeConfiguration; import com.opengamma.financial.analytics.curve.OvernightCurveTypeConfiguration; import com.opengamma.financial.analytics.curve.SpreadCurveDefinition; import com.opengamma.financial.analytics.curve.exposure.ExposureFunctions; import com.opengamma.financial.analytics.ircurve.strips.CurveNode; import com.opengamma.id.ExternalId; import com.opengamma.master.config.ConfigMaster; import com.opengamma.master.config.ConfigSearchRequest; import com.opengamma.master.config.ConfigSearchResult; import com.opengamma.master.convention.ManageableConvention; import com.opengamma.master.holiday.HolidayMaster; import com.opengamma.util.money.Currency; import com.opengamma.util.time.Tenor; /** * Class to validate third generation curve configurations */ public class CurveValidator { private static final Logger s_logger = LoggerFactory.getLogger(CurveValidator.class); private final ConfigMaster _configMaster; private final ConfigSource _configSource; private ConfigValidationUtils _configValidationUtils; private List<ValidationNode> _curveConstructionConfigNodes = new ArrayList<>(); private List<ValidationNode> _exposureConfigNodes = new ArrayList<>(); private final RegionSource _regionSource; private final LocalDate _curveDate; private final SecuritySource _securitySource; /** * Constructor * @param configMaster the config master * @param configSource the config source * @param conventionSource the convention source * @param regionSource the region source * @param secSource the security source * @param holidayMaster the holiday master */ public CurveValidator(final ConfigMaster configMaster, final ConfigSource configSource, final ConventionSource conventionSource, final RegionSource regionSource, final SecuritySource secSource, final HolidayMaster holidayMaster) { _configMaster = configMaster; _configSource = configSource; _configValidationUtils = new ConfigValidationUtils(conventionSource, holidayMaster); _regionSource = regionSource; _securitySource = secSource; _curveDate = LocalDate.now(); } /** * Not re-entrant. * @return */ public void validateNewCurveSetup() { _curveConstructionConfigNodes = new ArrayList<>(); _exposureConfigNodes = new ArrayList<>(); final ConfigSearchRequest<CurveConstructionConfiguration> searchReq = new ConfigSearchRequest<>(CurveConstructionConfiguration.class); ConfigSearchResult<CurveConstructionConfiguration> searchResult; try { searchResult = _configMaster.search(searchReq); final Set<String> curveConstructionConfigNames = new HashSet<>(); for (final ConfigItem<CurveConstructionConfiguration> curveConstructionConfigItem : searchResult.getValues()) { final CurveConstructionConfiguration curveConstructionConfig = curveConstructionConfigItem.getValue(); curveConstructionConfigNames.add(curveConstructionConfig.getName()); final ValidationNode validationNode = new ValidationNode(); validationNode.setName(curveConstructionConfig.getName()); validationNode.setType(CurveConstructionConfiguration.class); checkCurveConstructionConfiguration(curveConstructionConfig, validationNode); _curveConstructionConfigNodes.add(validationNode); } try { validateExposureFunctionsConfigurations(curveConstructionConfigNames, _exposureConfigNodes); } catch (final Exception e) { s_logger.error("Error while searching config master", e); final ValidationNode validationNode = new ValidationNode(); validationNode.setType(ExposureFunctions.class); validationNode.setName("Config query error"); validationNode.setError(true); validationNode.getErrors().add(e.getMessage()); } } catch (final Exception e) { s_logger.error("Error while searching config master", e); final ValidationNode validationNode = new ValidationNode(); validationNode.setType(CurveConstructionConfiguration.class); validationNode.setName("Config query error"); validationNode.setError(true); validationNode.getErrors().add(e.getMessage()); _curveConstructionConfigNodes.add(validationNode); } } public List<ValidationNode> getCurveConstructionConfigResults() { return _curveConstructionConfigNodes; } public List<ValidationNode> getExposureFunctionsConfigResults() { return _exposureConfigNodes; } private void validateExposureFunctionsConfigurations(final Set<String> curveConstructionConfigurationNames, final List<ValidationNode> rootNodes) { final ConfigSearchRequest<ExposureFunctions> searchReq = new ConfigSearchRequest<>(ExposureFunctions.class); final ConfigSearchResult<ExposureFunctions> searchResult = _configMaster.search(searchReq); if (searchResult.getValues().size() == 0) { final ValidationNode node = new ValidationNode(); node.setName("Empty Configuration"); node.setType(ExposureFunctions.class); node.getErrors().add("No ExposuresFunctions could be found"); node.setError(true); rootNodes.add(node); } for (final ConfigItem<ExposureFunctions> configItem : searchResult.getValues()) { final ValidationNode node = checkExposureFunctionsConfiguration(configItem.getValue(), curveConstructionConfigurationNames); rootNodes.add(node); } } private ValidationNode checkExposureFunctionsConfiguration(final ExposureFunctions configuration, final Set<String> curveConstructionConfigurationNames) { final ValidationNode node = new ValidationNode(); node.setName(configuration.getName()); node.setType(ExposureFunctions.class); if (configuration.getIdsToNames() != null) { final Map<ExternalId, String> idsToNames = configuration.getIdsToNames(); for (final Map.Entry<ExternalId, String> entry : idsToNames.entrySet()) { final ValidationNode mapEntry = new ValidationNode(); mapEntry.setName(entry.getKey().toString()); mapEntry.setType(Map.Entry.class); final String name = entry.getValue(); if (!curveConstructionConfigurationNames.contains(name)) { mapEntry.getErrors().add("Entry in idsToNames map " + entry.getKey() + " => " + name + " points to non-existent CurveConstructionConfiguration"); mapEntry.setError(true); } node.getSubNodes().add(mapEntry); } } return node; } private void checkCurveConstructionConfiguration(final CurveConstructionConfiguration curveConstructionConfig, final ValidationNode validationNode) { for (final CurveGroupConfiguration curveGroupConfig : curveConstructionConfig.getCurveGroups()) { for (final Entry<String, List<? extends CurveTypeConfiguration>> curveForTypeEntry : curveGroupConfig.getTypesForCurves().entrySet()) { if (!curveDefinitionOrSubclassExists(curveForTypeEntry.getKey())) { validationNode.getErrors().add("Could not find CurveDefinition or subclass called " + curveForTypeEntry.getKey() + " in type for curves entry"); validationNode.setError(true); } validateCurveTypeConfigrations(curveForTypeEntry.getKey(), curveForTypeEntry.getValue(), validationNode); } } } private void validateCurveTypeConfigrations(final String name, final List<? extends CurveTypeConfiguration> curveTypeConfigurations, final ValidationNode parentNode) { for (final CurveTypeConfiguration curveTypeConfig : curveTypeConfigurations) { final ValidationNode curveTypeConfigNode = new ValidationNode(); curveTypeConfigNode.setName(name); curveTypeConfigNode.setType(CurveTypeConfiguration.class); validateCurveTypeConfiguration(name, curveTypeConfig, curveTypeConfigNode); parentNode.getSubNodes().add(curveTypeConfigNode); } } private void validateCurveTypeConfiguration(final String name, final CurveTypeConfiguration curveTypeConfig, final ValidationNode curveTypeConfigNode) { if (curveTypeConfig instanceof DiscountingCurveTypeConfiguration) { final DiscountingCurveTypeConfiguration discountingCurveTypeConfig = (DiscountingCurveTypeConfiguration) curveTypeConfig; validateDiscountingCurveTypeConfiguration(name, discountingCurveTypeConfig, curveTypeConfigNode); } else if (curveTypeConfig instanceof IborCurveTypeConfiguration) { final IborCurveTypeConfiguration iborCurveTypeConfiguration = (IborCurveTypeConfiguration) curveTypeConfig; validateIborCurveTypeConfiguration(name, iborCurveTypeConfiguration, curveTypeConfigNode); } else if (curveTypeConfig instanceof InflationCurveTypeConfiguration) { final InflationCurveTypeConfiguration inflationCurveTypeConfiguration = (InflationCurveTypeConfiguration) curveTypeConfig; validateInflationCurveTypeConfiguration(name, inflationCurveTypeConfiguration, curveTypeConfigNode); } else if (curveTypeConfig instanceof InflationIssuerCurveTypeConfiguration) { final InflationIssuerCurveTypeConfiguration inflationIssuerCurveTypeConfiguration = (InflationIssuerCurveTypeConfiguration) curveTypeConfig; validateInflationIssuerCurveTypeConfiguration(name, inflationIssuerCurveTypeConfiguration, curveTypeConfigNode); } else if (curveTypeConfig instanceof IssuerCurveTypeConfiguration) { final IssuerCurveTypeConfiguration issuerCurveTypeConfiguration = (IssuerCurveTypeConfiguration) curveTypeConfig; validateIssuerCurveTypeConfiguration(name, issuerCurveTypeConfiguration, curveTypeConfigNode); } else if (curveTypeConfig instanceof OvernightCurveTypeConfiguration) { final OvernightCurveTypeConfiguration overnightCurveTypeConfiguration = (OvernightCurveTypeConfiguration) curveTypeConfig; validateOvernightCurveTypeConfiguration(name, overnightCurveTypeConfiguration, curveTypeConfigNode); } else { curveTypeConfigNode.getErrors().add("Unknown type of CurveTypeConfiguration: " + curveTypeConfig.getClass().getSimpleName()); curveTypeConfigNode.setError(true); } } private void validateDiscountingCurveTypeConfiguration(final String name, final DiscountingCurveTypeConfiguration curveTypeConfiguration, final ValidationNode curveTypeConfigNode) { final boolean regionDryRun = checkRegion(curveTypeConfiguration.getReference(), curveTypeConfigNode, true); final boolean currencyDryRun = checkCurrency(curveTypeConfiguration.getReference(), curveTypeConfigNode, true); if (regionDryRun || currencyDryRun) { final ValidationNode validationNode = new ValidationNode(); validationNode.setName(curveTypeConfiguration.getReference()); if (regionDryRun) { validationNode.setType(Region.class); } else if (currencyDryRun) { validationNode.setType(Currency.class); } // config is good. } else { // record both errors checkRegion(curveTypeConfiguration.getReference(), curveTypeConfigNode, false); checkCurrency(curveTypeConfiguration.getReference(), curveTypeConfigNode, false); } final AbstractCurveDefinition abstractCurveDefinition = getCurveDefinitionOrSubclass(name); if (abstractCurveDefinition instanceof CurveDefinition) { final CurveDefinition curveDefinition = (CurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateCurveDefinition(curveDefinition, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof SpreadCurveDefinition) { final SpreadCurveDefinition curveDefinition = (SpreadCurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateDiscountingCurveTypeConfiguration(curveDefinition.getFirstCurve(), curveTypeConfiguration, validationNode); validateDiscountingCurveTypeConfiguration(curveDefinition.getSecondCurve(), curveTypeConfiguration, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof ConstantCurveDefinition) { final ConstantCurveDefinition curveDefinition = (ConstantCurveDefinition) abstractCurveDefinition; // assume this is fine? final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validationNode.getErrors().add("Using IborCurveTypeConfiguration with constant curve definition: check this is okay."); validationNode.setError(true); curveTypeConfigNode.getSubNodes().add(validationNode); } } private void validateIborCurveTypeConfiguration(String name, IborCurveTypeConfiguration curveTypeConfiguration, ValidationNode curveTypeConfigNode) { if (!_configValidationUtils.conventionExists(curveTypeConfiguration.getConvention())) { ValidationNode validationNode = new ValidationNode(); validationNode.setName(curveTypeConfiguration.getConvention().getValue()); validationNode.setType(Convention.class); validationNode.getErrors().add("Could not find convention " + curveTypeConfiguration.getConvention()); validationNode.setError(true); } else { final ValidationNode validationNode = new ValidationNode(); validationNode.setName(curveTypeConfiguration.getConvention().getValue()); validationNode.setType(Convention.class); validationNode.getErrors().add("Could not find convention " + curveTypeConfiguration.getConvention()); validationNode.setError(true); } final AbstractCurveDefinition abstractCurveDefinition = getCurveDefinitionOrSubclass(name); if (abstractCurveDefinition instanceof CurveDefinition) { final CurveDefinition curveDefinition = (CurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateCurveDefinition(curveDefinition, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof SpreadCurveDefinition) { final SpreadCurveDefinition curveDefinition = (SpreadCurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateIborCurveTypeConfiguration(curveDefinition.getFirstCurve(), curveTypeConfiguration, validationNode); validateIborCurveTypeConfiguration(curveDefinition.getSecondCurve(), curveTypeConfiguration, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof ConstantCurveDefinition) { final ConstantCurveDefinition curveDefinition = (ConstantCurveDefinition) abstractCurveDefinition; // assume this is fine? final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validationNode.getErrors().add("Using IborCurveTypeConfiguration with constant curve definition: check this is okay."); validationNode.setError(true); curveTypeConfigNode.getSubNodes().add(validationNode); } } private void validateInflationCurveTypeConfiguration(final String name, final InflationCurveTypeConfiguration curveTypeConfiguration, final ValidationNode curveTypeConfigNode) { final boolean regionDryRun = checkRegion(curveTypeConfiguration.getReference(), curveTypeConfigNode, true); final boolean currencyDryRun = checkCurrency(curveTypeConfiguration.getReference(), curveTypeConfigNode, true); if (regionDryRun || currencyDryRun) { final ValidationNode validationNode = new ValidationNode(); validationNode.setName(curveTypeConfiguration.getReference()); if (regionDryRun) { validationNode.setType(Region.class); } else if (currencyDryRun) { validationNode.setType(Currency.class); } // config is good. } else { // record both errors checkRegion(curveTypeConfiguration.getReference(), curveTypeConfigNode, false); checkCurrency(curveTypeConfiguration.getReference(), curveTypeConfigNode, false); } final AbstractCurveDefinition abstractCurveDefinition = getCurveDefinitionOrSubclass(name); if (abstractCurveDefinition instanceof CurveDefinition) { final CurveDefinition curveDefinition = (CurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateCurveDefinition(curveDefinition, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof SpreadCurveDefinition) { final SpreadCurveDefinition curveDefinition = (SpreadCurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateInflationCurveTypeConfiguration(curveDefinition.getFirstCurve(), curveTypeConfiguration, validationNode); validateInflationCurveTypeConfiguration(curveDefinition.getSecondCurve(), curveTypeConfiguration, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof ConstantCurveDefinition) { final ConstantCurveDefinition curveDefinition = (ConstantCurveDefinition) abstractCurveDefinition; // assume this is fine? final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validationNode.getErrors().add("Using IborCurveTypeConfiguration with constant curve definition: check this is okay."); validationNode.setError(true); curveTypeConfigNode.getSubNodes().add(validationNode); } } private void validateInflationIssuerCurveTypeConfiguration(final String name, final InflationIssuerCurveTypeConfiguration curveTypeConfiguration, final ValidationNode curveTypeConfigNode) { final boolean regionDryRun = checkRegion(curveTypeConfiguration.getReference(), curveTypeConfigNode, true); final boolean currencyDryRun = checkCurrency(curveTypeConfiguration.getReference(), curveTypeConfigNode, true); if (regionDryRun || currencyDryRun) { final ValidationNode validationNode = new ValidationNode(); validationNode.setName(curveTypeConfiguration.getReference()); if (regionDryRun) { validationNode.setType(Region.class); } else if (currencyDryRun) { validationNode.setType(Currency.class); } // config is good. } else { // record both errors checkRegion(curveTypeConfiguration.getReference(), curveTypeConfigNode, false); checkCurrency(curveTypeConfiguration.getReference(), curveTypeConfigNode, false); } final AbstractCurveDefinition abstractCurveDefinition = getCurveDefinitionOrSubclass(name); if (abstractCurveDefinition instanceof CurveDefinition) { final CurveDefinition curveDefinition = (CurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateCurveDefinition(curveDefinition, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof SpreadCurveDefinition) { final SpreadCurveDefinition curveDefinition = (SpreadCurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateInflationIssuerCurveTypeConfiguration(curveDefinition.getFirstCurve(), curveTypeConfiguration, validationNode); validateInflationIssuerCurveTypeConfiguration(curveDefinition.getSecondCurve(), curveTypeConfiguration, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof ConstantCurveDefinition) { final ConstantCurveDefinition curveDefinition = (ConstantCurveDefinition) abstractCurveDefinition; // assume this is fine? final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validationNode.getErrors().add("Using IborCurveTypeConfiguration with constant curve definition: check this is okay."); validationNode.setError(true); curveTypeConfigNode.getSubNodes().add(validationNode); } } private void validateIssuerCurveTypeConfiguration(final String name, final IssuerCurveTypeConfiguration curveTypeConfiguration, final ValidationNode curveTypeConfigNode) { // currency a no-op final AbstractCurveDefinition abstractCurveDefinition = getCurveDefinitionOrSubclass(name); if (abstractCurveDefinition instanceof CurveDefinition) { final CurveDefinition curveDefinition = (CurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateCurveDefinition(curveDefinition, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof SpreadCurveDefinition) { final SpreadCurveDefinition curveDefinition = (SpreadCurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateIssuerCurveTypeConfiguration(curveDefinition.getFirstCurve(), curveTypeConfiguration, validationNode); validateIssuerCurveTypeConfiguration(curveDefinition.getSecondCurve(), curveTypeConfiguration, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof ConstantCurveDefinition) { final ConstantCurveDefinition curveDefinition = (ConstantCurveDefinition) abstractCurveDefinition; // assume this is fine? final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validationNode.getErrors().add("Using IborCurveTypeConfiguration with constant curve definition: check this is okay."); validationNode.setError(true); curveTypeConfigNode.getSubNodes().add(validationNode); } } private void validateOvernightCurveTypeConfiguration(final String name, final OvernightCurveTypeConfiguration curveTypeConfiguration, final ValidationNode curveTypeConfigNode) { final ValidationNode onValidationNode = new ValidationNode(); onValidationNode.setName(curveTypeConfiguration.getConvention().getValue()); if (_configValidationUtils.conventionExists(curveTypeConfiguration.getConvention())) { ManageableConvention convention = _configValidationUtils.getConvention(curveTypeConfiguration.getConvention()); onValidationNode.setType(convention.getClass()); } else { onValidationNode.setType(Convention.class); onValidationNode.getErrors().add("Can't find overnight convention using ID " + curveTypeConfiguration.getConvention()); onValidationNode.setError(true); } curveTypeConfigNode.getSubNodes().add(onValidationNode); final AbstractCurveDefinition abstractCurveDefinition = getCurveDefinitionOrSubclass(name); if (abstractCurveDefinition instanceof CurveDefinition) { final CurveDefinition curveDefinition = (CurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateCurveDefinition(curveDefinition, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof SpreadCurveDefinition) { final SpreadCurveDefinition curveDefinition = (SpreadCurveDefinition) abstractCurveDefinition; final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validateOvernightCurveTypeConfiguration(curveDefinition.getFirstCurve(), curveTypeConfiguration, validationNode); validateOvernightCurveTypeConfiguration(curveDefinition.getSecondCurve(), curveTypeConfiguration, validationNode); curveTypeConfigNode.getSubNodes().add(validationNode); } else if (abstractCurveDefinition instanceof ConstantCurveDefinition) { final ConstantCurveDefinition curveDefinition = (ConstantCurveDefinition) abstractCurveDefinition; // assume this is fine? final ValidationNode validationNode = new ValidationNode(); validationNode.setName(name); validationNode.setType(curveDefinition.getClass()); validationNode.getErrors().add("Using IborCurveTypeConfiguration with constant curve definition: check this is okay."); validationNode.setError(true); curveTypeConfigNode.getSubNodes().add(validationNode); } } private void validateCurveDefinition(final CurveDefinition curveDefinition, final ValidationNode curveDefinitionNode) { // check for an empty curve def if (curveDefinition.getNodes().size() == 0) { curveDefinitionNode.getErrors().add("Curve definition " + curveDefinition.getName() + " has zero nodes"); curveDefinitionNode.setError(true); } // otherwise process the nodes for (CurveNode node : curveDefinition.getNodes()) { validateCurveNode(node, curveDefinitionNode); } } private ValidationNode createInvalidCurveNodeValidationNode(final Tenor tenor, final Class<? extends CurveNode> curveNodeType, final ValidationNode parentNode, final String message) { final ValidationNode validationNode = new ValidationNode(); validationNode.setName(tenor.toFormattedString()); validationNode.setType(curveNodeType); if (message != null) { validationNode.getErrors().add(message); validationNode.setError(true); } parentNode.getSubNodes().add(validationNode); return validationNode; } private void validateCurveNode(CurveNode curveNode, final ValidationNode validationNode) { final CurveNodeIdMapper curveNodeIdMapper = getCurveNodeIdMapper(curveNode.getCurveNodeIdMapperName()); if (curveNodeIdMapper == null) { createInvalidCurveNodeValidationNode(curveNode.getResolvedMaturity(), curveNode.getClass(), validationNode, "CurveNodeIdMapper " + curveNode.getCurveNodeIdMapperName() + " is missing"); } else { curveNode.accept(new CurveNodeValidator(_curveDate, _configValidationUtils, _securitySource, validationNode, curveNodeIdMapper, _configSource)); } } private CurveNodeIdMapper getCurveNodeIdMapper(final String curveNodeIdMapperName) { return _configSource.getLatestByName(CurveNodeIdMapper.class, curveNodeIdMapperName); } /** * Check the string region ISO code (2-character) for validity against the RegionSource. Records error in node object if dryRun is not set. * @param regionStr the potential region code. Will add a warning but return true if region is not a country (e.g. EU). * @param node a node to record errors in * @param dryRun whether to omit writing an error * @return true, if this is a valid region code */ private boolean checkRegion(final String regionStr, final ValidationNode node, final boolean dryRun) { final Region highestLevelRegion = _regionSource.getHighestLevelRegion(ExternalId.of(ExternalSchemes.ISO_COUNTRY_ALPHA2, regionStr)); if (highestLevelRegion != null) { if (highestLevelRegion.getCountry() == null && !dryRun) { node.getWarnings().add("Warning: Region string " + regionStr + " was region but not country"); } return true; } else { if (!dryRun) { node.getWarnings().add("Region string " + regionStr + " was not found as a region or country"); } return false; } } /** * Check the string currency valid and record error if not dryRun. Also adds warning if valid lexigraphically but not contained * in Currency class as a constant. * @param currencyStr the currency in string format (3-character ISO), not null * @param node the error recording node, not null * @param dryRun doesn't record an error if true * @return true if valid currency */ private boolean checkCurrency(final String currencyStr, final ValidationNode node, final boolean dryRun) { try { final Currency currency = Currency.of(currencyStr); if (!checkCurrencyClass(currency)) { if (dryRun) { return false; } else { node.getWarnings().add("Warning: String expected to be currency parses, but is not in Currency class as constant"); return true; } } } catch (final IllegalArgumentException iae) { if (dryRun) { return false; } else { node.getWarnings().add("String expected to be currency " + currencyStr + " will not parse"); } } return true; } /** * Check the Currency class for a constant matching this currency instance * @param currency a currency instance, not null * @return true if there is a constant matching the supplied currency */ private boolean checkCurrencyClass(final Currency currency) { final Field[] fields = Currency.class.getFields(); for (final Field field : fields) { if (field.getName().equals(currency.getCode())) { return true; } } return false; } private boolean curveDefinitionOrSubclassExists(final String nameOfCurveDefinition) { return getCurveDefinitionOrSubclass(nameOfCurveDefinition) != null; } private AbstractCurveDefinition getCurveDefinitionOrSubclass(final String nameOfCurveDefinition) { final CurveDefinition curveDefinition = _configSource.getLatestByName(CurveDefinition.class, nameOfCurveDefinition); if (curveDefinition != null) { return curveDefinition; } final InterpolatedCurveDefinition interpolatedCurveDefinition = _configSource.getLatestByName(InterpolatedCurveDefinition.class, nameOfCurveDefinition); if (interpolatedCurveDefinition != null) { return interpolatedCurveDefinition; } final FixedDateInterpolatedCurveDefinition fixedDateInterpolatedCurveDefinition = _configSource.getLatestByName(FixedDateInterpolatedCurveDefinition.class, nameOfCurveDefinition); if (fixedDateInterpolatedCurveDefinition != null) { return fixedDateInterpolatedCurveDefinition; } final ConstantCurveDefinition constantCurveDefinition = _configSource.getLatestByName(ConstantCurveDefinition.class, nameOfCurveDefinition); if (constantCurveDefinition != null) { return constantCurveDefinition; } final SpreadCurveDefinition spreadCurveDefinition = _configSource.getLatestByName(SpreadCurveDefinition.class, nameOfCurveDefinition); if (spreadCurveDefinition != null) { return spreadCurveDefinition; } return null; } }