001package javax.visrec.util;
002
003import javax.visrec.ml.ClassifierCreationException;
004import java.lang.reflect.InvocationTargetException;
005import java.lang.reflect.Method;
006import java.util.Map;
007
008/**
009 * Generic builder interface, that all builders for machine learning algorithms implement.
010 *
011 * @author Zoran Sevarac
012 * @author Kevin Berendsen
013 * @param <T> type of the object to be returned by the builder.
014 * @since 1.0
015 */
016public interface Builder<T> {
017
018    /**
019     * Builds and returns an object using properties set using available builder methods.
020     *
021     * @return object specified by the builder to build
022     */
023    T build() throws ClassifierCreationException;
024
025    /**
026     * Builds an object using properties from the specified input argument
027     *
028     * @param configuration properties for the builder, a map of key, value pairs.
029     * @return object specified by the builder to build
030     */
031    default T build(Map<String, Object> configuration) throws ClassifierCreationException {
032        Method[] methods = this.getClass().getDeclaredMethods();
033        for (Method method : methods) {
034            if (!method.getName().equals("build") && method.getParameterCount() == 1
035                    && configuration.containsKey(method.getName())) {
036                try {
037                    method.invoke(this, configuration.get(method.getName()));
038                } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
039                    throw new InvalidBuilderConfigurationException("Couldn't invoke '" + method.getName() + "'", e);
040                }
041            }
042        }
043        return build();
044    }
045
046}