package org.tynamo.builder;
import org.slf4j.Logger;
import org.tynamo.exception.TynamoRuntimeException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
/**
* Fulfils the "Director" role in the Tynamo implementation of
* GOF's <a href="http://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>
*
* Constructs an object using the Builder interface
*/
public class BuilderDirector
{
private final Logger logger;
Map<Class, Builder> builders;
public BuilderDirector(Logger logger)
{
this.logger = logger;
builders = new HashMap<Class, Builder>();
}
public BuilderDirector(Logger logger, Map<Class, Builder> builders)
{
this.logger = logger;
this.builders = builders;
}
/**
* Create a new instance of an object of class 'type' using a Builder.
*
* @param type is a class whose instance should be created, it shouldn't be NULL
* @return a newly created object
*/
public <T> T createNewInstance(final Class<T> type)
{
Builder<T> builder = (Builder<T>) builders.get(type);
if (builder != null)
{
return builder.build();
} else
{
return createNewInstanceFromEmptyConstructor(type);
}
}
/**
* Create a new instance of an object of class 'type' using an empty constructor.
*
* @param type is a class whose instance should be created
* @return a newly created object
*/
private <T> T createNewInstanceFromEmptyConstructor(final Class<T> type)
{
try
{
Constructor constructor = type.getDeclaredConstructor();
constructor.setAccessible(true);
return (T) constructor.newInstance();
} catch (Exception ex)
{
logger.error(String.format("Can't create an instance of %s using an empty constructor.", type));
throw new TynamoRuntimeException(ex, type);
}
}
}