/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.server.conversion; import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.fudgemsg.FudgeContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.analytics.financial.forex.method.PresentValueForexBlackVolatilitySensitivity; import com.opengamma.analytics.financial.greeks.BucketedGreekResultCollection; import com.opengamma.analytics.financial.model.interestrate.curve.ForwardCurve; import com.opengamma.analytics.financial.model.interestrate.curve.YieldCurve; import com.opengamma.analytics.financial.model.volatility.local.LocalVolatilitySurfaceMoneyness; import com.opengamma.analytics.financial.model.volatility.surface.BlackVolatilitySurfaceMoneyness; import com.opengamma.analytics.financial.model.volatility.surface.VolatilitySurface; import com.opengamma.analytics.math.curve.DoublesCurve; import com.opengamma.core.historicaltimeseries.HistoricalTimeSeries; import com.opengamma.core.marketdatasnapshot.VolatilityCubeData; import com.opengamma.core.marketdatasnapshot.VolatilitySurfaceData; import com.opengamma.engine.cache.MissingInput; import com.opengamma.financial.analytics.LabelledMatrix1D; import com.opengamma.financial.analytics.LabelledMatrix2D; import com.opengamma.financial.analytics.LabelledMatrix3D; import com.opengamma.financial.analytics.volatility.surface.FunctionalVolatilitySurfaceData; import com.opengamma.timeseries.date.localdate.LocalDateDoubleTimeSeries; import com.opengamma.util.ClassMap; import com.opengamma.util.money.CurrencyAmount; import com.opengamma.util.money.MultipleCurrencyAmount; import com.opengamma.util.time.Tenor; /** * Manages a set of converters and provides access to the most appropriate converter for a given type. */ public class ResultConverterCache { private static final Logger s_logger = LoggerFactory.getLogger(ResultConverterCache.class); private final DoubleConverter _doubleConverter; private final ResultConverter<Object> _genericConverter; private final ClassMap<ResultConverter<?>> _converterMap; private final Map<String, ResultConverter<?>> _valueNameConverterCache = new ConcurrentHashMap<String, ResultConverter<?>>(); public ResultConverterCache(final FudgeContext fudgeContext) { _genericConverter = new ToStringConverter(); _doubleConverter = new DoubleConverter(); final ResultConverter<Object> primitiveConverter = new PrimitiveConverter(); // Add standard custom converters here _converterMap = new ClassMap<ResultConverter<?>>(); registerConverter(Boolean.class, primitiveConverter); registerConverter(String.class, primitiveConverter); registerConverter(Double.class, _doubleConverter); registerConverter(BigDecimal.class, _doubleConverter); registerConverter(CurrencyAmount.class, _doubleConverter); registerConverter(YieldCurve.class, new YieldCurveConverter()); registerConverter(VolatilityCubeData.class, new VolatilityCubeDataConverter()); registerConverter(VolatilitySurfaceData.class, new VolatilitySurfaceDataConverter()); registerConverter(VolatilitySurface.class, new VolatilitySurfaceConverter()); registerConverter(LabelledMatrix1D.class, new LabelledMatrix1DConverter()); registerConverter(LabelledMatrix2D.class, new LabelledMatrix2DConverter()); registerConverter(LabelledMatrix3D.class, new LabelledMatrix3DConverter()); registerConverter(Tenor.class, new TenorConverter()); registerConverter(MultipleCurrencyAmount.class, new MultipleCurrencyAmountConverter(_doubleConverter)); registerConverter(MissingInput.class, new StaticStringConverter("Missing market data")); registerConverter(ForwardCurve.class, new ForwardCurveConverter()); registerConverter(BlackVolatilitySurfaceMoneyness.class, new BlackVolatilitySurfaceMoneynessConverter()); registerConverter(LocalVolatilitySurfaceMoneyness.class, new LocalVolatilitySurfaceMoneynessConverter()); registerConverter(BucketedGreekResultCollection.class, new BucketedVegaConverter()); registerConverter(DoublesCurve.class, new CurveConverter()); registerConverter(LocalDateDoubleTimeSeries.class, new LocalDateDoubleTimeSeriesConverter()); registerConverter(HistoricalTimeSeries.class, new HistoricalTimeSeriesConverter()); registerConverter(double[][].class, new DoubleArrayConverter()); registerConverter(Double[][].class, new DoubleObjectArrayConverter()); registerConverter(List.class, new ListDoubleArrayConverter()); registerConverter(PresentValueForexBlackVolatilitySensitivity.class, new PresentValueVolatilitySensitivityConverter(_doubleConverter)); registerConverter(FunctionalVolatilitySurfaceData.class, new FunctionalVolatilitySurfaceDataConverter()); } private <T> void registerConverter(final Class<T> clazz, final ResultConverter<? super T> converter) { _converterMap.put(clazz, converter); } public <T> ResultConverter<? super T> getAndCacheConverter(final String valueName, final Class<T> valueType) { @SuppressWarnings("unchecked") ResultConverter<? super T> converter = (ResultConverter<? super T>) _valueNameConverterCache.get(valueName); if (converter == null) { converter = getConverterForType(valueType); _valueNameConverterCache.put(valueName, converter); s_logger.info("'{}' {}", valueName, valueType.getName()); } return converter; } public <T> ResultConverter<? super T> getConverterForType(final Class<T> type) { @SuppressWarnings("unchecked") final ResultConverter<? super T> converter = (ResultConverter<? super T>) _converterMap.get(type); if (converter == null) { return _genericConverter; } return converter; } public <T> Object convert(final T value, final ConversionMode mode) { @SuppressWarnings("unchecked") final ResultConverter<? super T> converter = getConverterForType((Class<T>) value.getClass()); return converter.convertForDisplay(this, null, value, mode); } public DoubleConverter getDoubleConverter() { return _doubleConverter; } public String getKnownResultTypeName(final String valueName) { final ResultConverter<?> converter = _valueNameConverterCache.get(valueName); return converter != null ? converter.getFormatterName() : null; } public ResultConverter<Object> getFudgeConverter() { return _genericConverter; } }