/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.util.fudgemsg;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.fudgemsg.mapping.FudgeBuilder;
import org.fudgemsg.mapping.FudgeBuilderFactory;
import org.fudgemsg.mapping.FudgeBuilderFactoryAdapter;
import org.fudgemsg.mapping.FudgeMessageBuilder;
import org.fudgemsg.mapping.FudgeObjectBuilder;
import org.fudgemsg.mapping.FudgeObjectDictionary;
import org.joda.beans.Bean;
import org.joda.beans.impl.flexi.FlexiBean;
/**
* Utilities for converting Beans to Fudge and vice versa.
*/
public final class ExtendedFudgeBuilderFactory extends FudgeBuilderFactoryAdapter {
/**
* Map of bean class to builder.
*/
private final ConcurrentMap<Class<?>, FudgeObjectBuilder<?>> _builders =
new ConcurrentHashMap<Class<?>, FudgeObjectBuilder<?>>();
/**
* Initializes an instance of this factory.
* This extracts the existing factory from the dictionary, wraps it, and updates it.
* @param dictionary the object dictionary to install into, not null
*/
public static void init(final FudgeObjectDictionary dictionary) {
FudgeBuilderFactory factory = new ExtendedFudgeBuilderFactory(dictionary.getDefaultBuilderFactory());
dictionary.setDefaultBuilderFactory(factory);
}
/**
* Constructor.
* @param parent the parent factory, not null
*/
private ExtendedFudgeBuilderFactory(final FudgeBuilderFactory parent) {
super(parent);
}
//-------------------------------------------------------------------------
@Override
public <T> FudgeMessageBuilder<T> createMessageBuilder(final Class<T> clazz) {
if (Bean.class.isAssignableFrom(clazz) && clazz != FlexiBean.class) {
FudgeMessageBuilder<T> bld = super.createMessageBuilder(clazz);
if (bld == null || bld.getClass().getSimpleName().equals("JavaBeanBuilder")) { // best we can do
return createBeanBuilder(clazz);
}
return bld;
}
return super.createMessageBuilder(clazz);
}
@Override
public <T> FudgeObjectBuilder<T> createObjectBuilder(final Class<T> clazz) {
if (Bean.class.isAssignableFrom(clazz) && clazz != FlexiBean.class) {
FudgeObjectBuilder<T> bld = super.createObjectBuilder(clazz);
if (bld == null || bld.getClass().getSimpleName().equals("JavaBeanBuilder")) { // best we can do
return createBeanBuilder(clazz);
}
return bld;
}
return super.createObjectBuilder(clazz);
}
/**
* Creates a builder for the specific type of bean.
* @param <T> the bean type
* @param cls the class required, not null
* @return the builder, not null
*/
@SuppressWarnings({"unchecked", "rawtypes" })
private <T> FudgeBuilder<T> createBeanBuilder(final Class<T> cls) {
FudgeBuilder<T> builder = (FudgeBuilder<T>) _builders.get(cls);
if (builder == null) {
builder = DirectBeanFudgeBuilder.of((Class) cls);
_builders.putIfAbsent(cls, builder);
}
return builder;
}
}