001    package org.trails.builder;
002    
003    import org.trails.exception.TrailsRuntimeException;
004    
005    import java.lang.reflect.Constructor;
006    import java.util.HashMap;
007    import java.util.Map;
008    
009    /**
010     * Fulfils the "Director" role in the Trails implementation of
011     * GOF's <a href="http://en.wikipedia.org/wiki/Builder_pattern">Builder pattern</a>
012     *
013     * Constructs an object using the Builder interface 
014     */
015    public class BuilderDirector
016    {
017    
018            Map<Class, Builder> map = new HashMap<Class, Builder>();
019    
020            /**
021             * Create a new instance of an object of class 'type' using a Builder.
022             *
023             * @param type is a class whose instance should be created
024             * @return a newly created object
025             */
026            public <T> T createNewInstance(final Class<T> type)
027            {
028                    Builder<T> builder = (Builder<T>) map.get(type);
029                    if (builder != null)
030                    {
031                            return builder.build();
032                    } else
033                    {
034                            return createNewInstanceFromEmptyConstructor(type);
035                    }
036            }
037    
038            /**
039             * Create a new instance of an object of class 'type' using an empty constructor.
040             *
041             * @param type is a class whose instance should be created
042             * @return a newly created object
043             */
044            private <T> T createNewInstanceFromEmptyConstructor(final Class<T> type)
045            {
046                    try
047                    {
048                            Constructor constructor = type.getDeclaredConstructor();
049                            constructor.setAccessible(true);
050                            return (T) constructor.newInstance();
051    
052                    } catch (Exception ex)
053                    {
054                            throw new TrailsRuntimeException(ex, type);
055                    }
056            }
057    }