/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.financial.conversion;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.beans.JodaBeanUtils;
import org.joda.convert.StringConvert;
import org.joda.convert.StringConverter;
import org.threeten.bp.ZonedDateTime;
import com.google.common.collect.Lists;
import com.opengamma.financial.security.cds.CDSIndexTerms;
import com.opengamma.financial.security.future.BondFutureDeliverable;
import com.opengamma.financial.security.option.ExerciseType;
import com.opengamma.financial.security.swap.CommodityNotional;
import com.opengamma.financial.security.swap.InterestRateNotional;
import com.opengamma.financial.security.swap.Notional;
import com.opengamma.financial.security.swap.SecurityNotional;
import com.opengamma.financial.security.swap.VarianceSwapNotional;
import com.opengamma.id.ExternalIdBundle;
import com.opengamma.id.UniqueId;
import com.opengamma.util.money.Currency;
import com.opengamma.util.time.Expiry;
import com.opengamma.util.time.Tenor;
/**
* Registers converters with Joda Beans for converting bean fields to and from strings. The registration is
* done in the constructor and after that the instance doesn't do anything.
*/
public final class JodaBeanConverters {
/**
* Singleton instance.
*/
private static final JodaBeanConverters INSTANCE = new JodaBeanConverters();
// TODO map of MetaProperties to converters for fields that cant rely on the default conversion e.g.
// dates that are stored with time info and need the times setting to default values
// ZonedDateTime needs a default zone, based on OpenGammaClock.getTimeZone(), only for certain properties
private JodaBeanConverters() {
StringConvert stringConvert = JodaBeanUtils.stringConverter();
stringConvert.register(ExternalIdBundle.class, new ExternalIdBundleConverter());
stringConvert.register(Expiry.class, new ExpiryConverter());
stringConvert.register(Notional.class, new NotionalConverter());
stringConvert.register(BondFutureDeliverable.class, new BondFutureDeliverableConverter());
stringConvert.register(CDSIndexTerms.class, new CDSIndexTermsConverter());
}
/**
* Gets the singleton instance.
*
* @return the instance, not null
*/
public static JodaBeanConverters getInstance() {
return INSTANCE;
}
private abstract static class AbstractConverter<T> implements StringConverter<T> {
@Override
public String convertToString(T t) {
return t.toString();
}
}
public static class ExternalIdBundleConverter extends AbstractConverter<ExternalIdBundle> {
@Override
public String convertToString(ExternalIdBundle object) {
String str = object.toString();
return str.substring(str.indexOf('[') + 1, str.lastIndexOf(']')).trim();
}
@Override
public ExternalIdBundle convertFromString(Class<? extends ExternalIdBundle> cls, String str) {
if (StringUtils.isEmpty(str)) {
return ExternalIdBundle.EMPTY;
}
List<String> strings = Lists.newArrayList();
for (String s : str.split(",")) {
strings.add(s.trim());
}
return ExternalIdBundle.parse(strings);
}
}
public static class ExpiryConverter extends AbstractConverter<Expiry> {
@Override
public String convertToString(Expiry expiry) {
return expiry.getExpiry().toString();
}
@Override
public Expiry convertFromString(Class<? extends Expiry> cls, String str) {
return new Expiry(ZonedDateTime.parse(str));
}
}
private static class NotionalConverter extends AbstractConverter<Notional> {
@Override
public String convertToString(Notional notional) {
if (notional.getClass().isAssignableFrom(InterestRateNotional.class)) {
return ((InterestRateNotional) notional).getCurrency().getCode()
+ " " + String.format("%f", ((InterestRateNotional) notional).getAmount());
} else if (notional.getClass().isAssignableFrom(CommodityNotional.class)) {
return notional.toString();
} else if (notional.getClass().isAssignableFrom(SecurityNotional.class)) {
return ((SecurityNotional) notional).getNotionalId().toString();
} else if (notional.getClass().isAssignableFrom(VarianceSwapNotional.class)) {
return ((VarianceSwapNotional) notional).getCurrency().getCode()
+ " " + String.format("%f", ((VarianceSwapNotional) notional).getAmount());
}
return notional.toString();
}
@Override
public Notional convertFromString(Class<? extends Notional> cls, String str) {
if (cls.isAssignableFrom(InterestRateNotional.class)) {
String[] s = str.split(" ", 2);
return new InterestRateNotional(Currency.of(s[0].trim()), Double.parseDouble(s[1].trim()));
} else if (cls.isAssignableFrom(CommodityNotional.class)) {
return new CommodityNotional();
} else if (cls.isAssignableFrom(SecurityNotional.class)) {
return new SecurityNotional(UniqueId.parse(str));
} else if (cls.isAssignableFrom(VarianceSwapNotional.class)) {
String[] s = str.split(" ", 2);
return new VarianceSwapNotional(Currency.of(s[0].trim()), Double.parseDouble(s[1].trim()));
}
return null;
}
}
private static class BondFutureDeliverableConverter extends AbstractConverter<BondFutureDeliverable> {
@Override
public String convertToString(BondFutureDeliverable object) {
String ids = object.getIdentifiers().toString();
ids = ids.substring(ids.indexOf("["), ids.indexOf("]") + 1);
return ids + " " + Double.toString(object.getConversionFactor());
}
@Override
public BondFutureDeliverable convertFromString(Class<? extends BondFutureDeliverable> cls, String str) {
List<String> ids = Lists.newArrayList();
for (String s : str.substring(str.indexOf('[') + 1, str.lastIndexOf(']')).trim().split(",")) {
ids.add(s.trim());
}
BondFutureDeliverable result = new BondFutureDeliverable();
result.setIdentifiers(ExternalIdBundle.parse(ids));
result.setConversionFactor(Double.parseDouble(str.substring(str.indexOf(']') + 1).trim()));
return result;
}
}
private static class CDSIndexTermsConverter extends AbstractConverter<CDSIndexTerms> {
@Override
public String convertToString(CDSIndexTerms object) {
Set<Tenor> tenors = object.getTenors();
return tenors.toString();
}
@Override
public CDSIndexTerms convertFromString(Class<? extends CDSIndexTerms> cls, String str) {
String[] tenorStrs = str.split(",");
Tenor[] tenors = new Tenor[tenorStrs.length];
for (int i = 0; i < tenorStrs.length; i++) {
Tenor tenor = Tenor.parse(tenorStrs[i]);
tenors[i] = tenor;
}
return CDSIndexTerms.of(tenors);
}
}
// private static class CDSIndexComponentBundleConverter extends AbstractConverter<CDSIndexComponentBundle> {
//
// @Override
// public String convertToString(CDSIndexComponentBundle object) {
// StringBuilder sb = new StringBuilder();
// Iterable<CreditDefaultSwapIndexComponent> components = object.getComponents();
// for (CreditDefaultSwapIndexComponent component : components) {
// sb.append(JodaBeanUtils.stringConverter().convertToString(component));
// sb.append(",");
// }
// if (sb.length() > 0) {
// sb.deleteCharAt(sb.length() - 1);
// }
// return sb.toString();
// }
// @Override
// public CDSIndexComponentBundle convertFromString(Class<? extends CDSIndexComponentBundle> cls, String str) {
// return null;
// }
//
// }
}