LibraryExecutorLoader.java

package edu.udel.cis.vsl.tass.library.impl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedHashMap;
import java.util.Map;

import edu.udel.cis.vsl.tass.config.RunConfiguration;
import edu.udel.cis.vsl.tass.dynamic.IF.DynamicFactoryIF;
import edu.udel.cis.vsl.tass.semantics.Semantics;
import edu.udel.cis.vsl.tass.semantics.IF.EvaluatorIF;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutorIF;
import edu.udel.cis.vsl.tass.semantics.IF.LibraryExecutorIF;
import edu.udel.cis.vsl.tass.semantics.IF.LibraryExecutorLoaderIF;
import edu.udel.cis.vsl.tass.semantics.IF.LogIF;
import edu.udel.cis.vsl.tass.util.Strings;
import edu.udel.cis.vsl.tass.util.TASSInternalException;

public class LibraryExecutorLoader implements LibraryExecutorLoaderIF {

	private RunConfiguration configuration;

	private DynamicFactoryIF dynamicFactory;

	private LogIF log;

	private Map<String, LibraryExecutorIF> libraryExecutorCache = new LinkedHashMap<String, LibraryExecutorIF>();

	private static String classPrefix = "edu.udel.cis.vsl.tass.library.";

	private static Class<EvaluatorIF> evaluatorClass = EvaluatorIF.class;

	private static Class<ExecutorIF> executorClass = ExecutorIF.class;

	public LibraryExecutorLoader(RunConfiguration configuration,
			DynamicFactoryIF dynamicFactory, LogIF log) {
		this.configuration = configuration;
		this.dynamicFactory = dynamicFactory;
		this.log = log;
	}

	@SuppressWarnings("unchecked")
	@Override
	public LibraryExecutorIF getLibraryExecutor(String name,
			ExecutorIF primaryExecutor) {
		LibraryExecutorIF result = libraryExecutorCache.get(name);

		if (result == null) {
			String aClassName = classPrefix + name + "."
					+ Strings.capitalizeFirstLetter(name) + "Executor";
			EvaluatorIF evaluator = Semantics.newEvaluator(dynamicFactory,
					configuration.bufferBound(), log);

			try {
				Class<? extends LibraryExecutorIF> aClass = (Class<? extends LibraryExecutorIF>) Class
						.forName(aClassName);
				Constructor<? extends LibraryExecutorIF> constructor = aClass
						.getConstructor(executorClass, evaluatorClass);

				result = constructor.newInstance(primaryExecutor, evaluator);
			} catch (ClassNotFoundException e) {
				result = null;
			} catch (NoSuchMethodException e) {
				throw new TASSInternalException("Class " + aClassName
						+ " must provide a constructor "
						+ "that takes one argument of type EvaluatorIF");
			} catch (IllegalArgumentException e) {
				throw new TASSInternalException(e.toString());
			} catch (InstantiationException e) {
				throw new TASSInternalException(e.toString());
			} catch (IllegalAccessException e) {
				throw new TASSInternalException(e.toString());
			} catch (InvocationTargetException e) {
				throw new TASSInternalException(e.toString());
			}
			libraryExecutorCache.put(name, result);
		}
		return result;
	}
}