/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.analytics.fudgemsg;
import java.util.ArrayList;
import org.apache.commons.lang.ArrayUtils;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.MutableFudgeMsg;
import org.fudgemsg.mapping.FudgeBuilderFor;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.threeten.bp.Period;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.math.curve.ConstantDoublesCurve;
import com.opengamma.analytics.math.curve.FunctionalDoublesCurve;
import com.opengamma.analytics.math.curve.InterpolatedDoublesCurve;
import com.opengamma.analytics.math.curve.NodalDoublesCurve;
import com.opengamma.analytics.math.curve.NodalObjectsCurve;
import com.opengamma.analytics.math.curve.NodalTenorDoubleCurve;
import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.util.time.Tenor;
/**
* Fudge builders for com.opengamma.analytics.math.curve.* classes
*/
final class MathCurve {
private MathCurve() {
}
/**
* Fudge builder for {@link ConstantDoublesCurve}
*/
@FudgeBuilderFor(ConstantDoublesCurve.class)
public static final class ConstantDoublesCurveBuilder extends AbstractFudgeBuilder<ConstantDoublesCurve> {
private static final String Y_VALUE_FIELD_NAME = "y value";
private static final String CURVE_NAME_FIELD_NAME = "curve name";
@Override
protected void buildMessage(final FudgeSerializer serializer, final MutableFudgeMsg message, final ConstantDoublesCurve object) {
message.add(Y_VALUE_FIELD_NAME, null, object.getYValue(0.));
message.add(CURVE_NAME_FIELD_NAME, null, object.getName());
}
@Override
public ConstantDoublesCurve buildObject(final FudgeDeserializer deserializer, final FudgeMsg message) {
return ConstantDoublesCurve.from(message.getFieldValue(Double.class, message.getByName(Y_VALUE_FIELD_NAME)), message.getFieldValue(String.class, message.getByName(CURVE_NAME_FIELD_NAME)));
}
}
/**
* Fudge builder for {@link InterpolatedDoublesCurve}
*/
@FudgeBuilderFor(InterpolatedDoublesCurve.class)
public static final class InterpolatedDoublesCurveBuilder extends AbstractFudgeBuilder<InterpolatedDoublesCurve> {
private static final String X_DATA_FIELD_NAME = "x data";
private static final String Y_DATA_FIELD_NAME = "y data";
private static final String INTERPOLATOR_FIELD_NAME = "interpolator";
private static final String CURVE_NAME_FIELD_NAME = "curve name";
@Override
protected void buildMessage(final FudgeSerializer serializer, final MutableFudgeMsg message, final InterpolatedDoublesCurve object) {
serializer.addToMessage(message, X_DATA_FIELD_NAME, null, object.getXDataAsPrimitive());
serializer.addToMessage(message, Y_DATA_FIELD_NAME, null, object.getYDataAsPrimitive());
serializer.addToMessage(message, INTERPOLATOR_FIELD_NAME, null, object.getInterpolator());
serializer.addToMessage(message, CURVE_NAME_FIELD_NAME, null, object.getName());
}
@Override
public InterpolatedDoublesCurve buildObject(final FudgeDeserializer deserializer, final FudgeMsg message) {
final double[] x = deserializer.fieldValueToObject(double[].class, message.getByName(X_DATA_FIELD_NAME));
final double[] y = deserializer.fieldValueToObject(double[].class, message.getByName(Y_DATA_FIELD_NAME));
final Interpolator1D interpolator = deserializer.fieldValueToObject(Interpolator1D.class, message.getByName(INTERPOLATOR_FIELD_NAME));
final String name = deserializer.fieldValueToObject(String.class, message.getByName(CURVE_NAME_FIELD_NAME));
return InterpolatedDoublesCurve.fromSorted(x, y, interpolator, name);
}
}
/**
* Fudge builder for {@link FunctionalDoublesCurve}
*/
@FudgeBuilderFor(FunctionalDoublesCurve.class)
public static final class FunctionalDoublesCurveBuilder extends AbstractFudgeBuilder<FunctionalDoublesCurve> {
private static final String CURVE_FUNCTION_FIELD_NAME = "function";
private static final String CURVE_NAME_FIELD_NAME = "name";
@SuppressWarnings({"unchecked", "rawtypes" })
@Override
public FunctionalDoublesCurve buildObject(final FudgeDeserializer deserializer, final FudgeMsg message) {
final String name = deserializer.fieldValueToObject(String.class, message.getByName(CURVE_NAME_FIELD_NAME));
final Object function = deserializer.fieldValueToObject(message.getByName(CURVE_FUNCTION_FIELD_NAME));
if (function instanceof Function1D) {
return FunctionalDoublesCurve.from((Function1D) function, name);
}
throw new OpenGammaRuntimeException("Expected serialized function, got " + function);
}
@Override
protected void buildMessage(final FudgeSerializer serializer, final MutableFudgeMsg message, final FunctionalDoublesCurve object) {
serializer.addToMessage(message, CURVE_NAME_FIELD_NAME, null, object.getName());
serializer.addToMessage(message, CURVE_FUNCTION_FIELD_NAME, null, substituteObject(object.getFunction()));
return;
}
}
/**
* Fudge builder for {@link NodalDoublesCurve}
*/
@FudgeBuilderFor(NodalDoublesCurve.class)
public static final class NodalDoublesCurveBuilder extends AbstractFudgeBuilder<NodalDoublesCurve> {
private static final String X_DATA_FIELD_NAME = "x data";
private static final String Y_DATA_FIELD_NAME = "y data";
private static final String CURVE_NAME_FIELD_NAME = "curve name";
@Override
protected void buildMessage(final FudgeSerializer serializer, final MutableFudgeMsg message, final NodalDoublesCurve object) {
serializer.addToMessage(message, X_DATA_FIELD_NAME, null, object.getXDataAsPrimitive());
serializer.addToMessage(message, Y_DATA_FIELD_NAME, null, object.getYDataAsPrimitive());
serializer.addToMessage(message, CURVE_NAME_FIELD_NAME, null, object.getName());
}
@Override
public NodalDoublesCurve buildObject(final FudgeDeserializer deserializer, final FudgeMsg message) {
final double[] x = deserializer.fieldValueToObject(double[].class, message.getByName(X_DATA_FIELD_NAME));
final double[] y = deserializer.fieldValueToObject(double[].class, message.getByName(Y_DATA_FIELD_NAME));
final String name = deserializer.fieldValueToObject(String.class, message.getByName(CURVE_NAME_FIELD_NAME));
return NodalDoublesCurve.fromSorted(x, y, name);
}
}
/**
* Fudge builder for {@link NodalTenorDoubleCurve}
*/
@FudgeBuilderFor(NodalTenorDoubleCurve.class)
public static final class NodalTenorDoubleCurveBuilder extends AbstractFudgeBuilder<NodalTenorDoubleCurve> {
//FIXME: Use the Tenor fudge builder
private static final String X_DATA_FIELD_NAME = "x data";
private static final String Y_DATA_FIELD_NAME = "y data";
private static final String CURVE_NAME_FIELD_NAME = "curve name";
@Override
protected void buildMessage(final FudgeSerializer serializer, final MutableFudgeMsg message, final NodalTenorDoubleCurve object) {
final ArrayList<String> tenorStrings = new ArrayList<>();
for (final Tenor tenor : object.getXData()) {
tenorStrings.add(tenor.getPeriod().toString());
}
serializer.addToMessage(message, X_DATA_FIELD_NAME, null, tenorStrings.toArray(new String[tenorStrings.size()]));
serializer.addToMessage(message, Y_DATA_FIELD_NAME, null, ArrayUtils.toPrimitive(object.getYData()));
serializer.addToMessage(message, CURVE_NAME_FIELD_NAME, null, object.getName());
}
@Override
public NodalTenorDoubleCurve buildObject(final FudgeDeserializer deserializer, final FudgeMsg message) {
final String[] tenorStrings = deserializer.fieldValueToObject(String[].class, message.getByName(X_DATA_FIELD_NAME));
final ArrayList<Tenor> tenors = new ArrayList<>();
for (final String tenorString : tenorStrings) {
tenors.add(Tenor.of(Period.parse(tenorString)));
}
final double[] y = deserializer.fieldValueToObject(double[].class, message.getByName(Y_DATA_FIELD_NAME));
final Double[] yObjects = ArrayUtils.toObject(y);
final String name = deserializer.fieldValueToObject(String.class, message.getByName(CURVE_NAME_FIELD_NAME));
return NodalTenorDoubleCurve.fromSorted(tenors.toArray(new Tenor[tenors.size()]), yObjects, name);
}
}
/**
* Fudge builder for {@link NodalObjectCurve}
*/
@FudgeBuilderFor(NodalObjectsCurve.class)
public static final class NodalObjectsCurveBuilder extends AbstractFudgeBuilder<NodalObjectsCurve<?, ?>> {
private static final String X_DATA_FIELD_NAME = "x data";
private static final String Y_DATA_FIELD_NAME = "y data";
private static final String CURVE_NAME_FIELD_NAME = "curve name";
@Override
public NodalObjectsCurve<?, ?> buildObject(final FudgeDeserializer deserializer, final FudgeMsg message) {
final Comparable[] xs = deserializer.fieldValueToObject(Comparable[].class, message.getByName(X_DATA_FIELD_NAME));
final Object[] ys = deserializer.fieldValueToObject(Object[].class, message.getByName(Y_DATA_FIELD_NAME));
final String curveName = message.getString(CURVE_NAME_FIELD_NAME);
return NodalObjectsCurve.from(xs, ys, curveName);
}
@Override
protected void buildMessage(final FudgeSerializer serializer, final MutableFudgeMsg message, final NodalObjectsCurve<?, ?> object) {
final Object[] xs = object.getXData();
final Object[] ys = object.getYData();
final String curveName = object.getName();
serializer.addToMessage(message, X_DATA_FIELD_NAME, null, xs);
serializer.addToMessage(message, Y_DATA_FIELD_NAME, null, ys);
message.add(CURVE_NAME_FIELD_NAME, curveName);
}
}
}