package de.unihd.dbs.uima.annotator.heideltime; import java.util.EnumMap; import java.util.Iterator; import java.util.Map.Entry; import org.apache.uima.UimaContext; import org.apache.uima.jcas.JCas; import de.unihd.dbs.uima.annotator.heideltime.processors.GenericProcessor; import de.unihd.dbs.uima.annotator.heideltime.utilities.Logger; /** * This class implements a singleton "Addon Manager". Any subroutine (Processor) that * may be added to HeidelTime's code to achieve a specific goal which is self-sufficient, * i.e. creates new Timexes by itself and without the use of HeidelTime's non-resource * related functionality should be registered in an instance of this class. HeidelTime's * annotator will then execute every registered "Processor"'s process() function. * Note that these Processes will be instantiated and processed after the resource * collection and before HeidelTime's cleanup methods. * @author julian zell * */ public class ProcessorManager { // singleton instance private static final ProcessorManager INSTANCE = new ProcessorManager(); // list of processes' package names private EnumMap<Priority, String> processorNames; // array of instantiated processors private EnumMap<Priority, GenericProcessor> processors; // self-identifying component for logging purposes private Class<?> component; // flag for whether the processors have been initialized private boolean initialized = false; /** * Private constructor, only to be called by the getInstance() method. */ private ProcessorManager() { this.processorNames = new EnumMap<Priority, String>(Priority.class); this.component = this.getClass(); this.processors = new EnumMap<Priority, GenericProcessor>(Priority.class); } /** * method to register a processor * @param processor processor to be registered in the processormanager's list * @param p priority for the process to take */ public void registerProcessor(String processor, Priority prio) { this.processorNames.put(prio, processor); } /** * method to register a processor without priority * @param processor processor to be registered in the processormanager's list */ public void registerProcessor(String processor) { registerProcessor(processor, Priority.POSTPROCESSING); } /** * Based on reflection, this method instantiates and initializes all of the * registered Processors. * @param jcas */ public void initializeAllProcessors(UimaContext aContext) { Iterator<Entry<Priority, String>> it = processorNames.entrySet().iterator(); Entry<Priority, String> e; while(it.hasNext()) { e = it.next(); try { Class<?> c = Class.forName(e.getValue()); GenericProcessor p = (GenericProcessor) c.newInstance(); p.initialize(aContext); processors.put(e.getKey(), p); } catch (Exception exception) { exception.printStackTrace(); Logger.printError(component, "Unable to initialize registered Processor "+e.getValue()+", got: "+exception.toString()); System.exit(-1); } } this.initialized = true; } /** * Based on reflection, this method instantiates and executes all of the * registered Processors. * @param jcas */ public void executeProcessors(JCas jcas, ProcessorManager.Priority prio) { if(!this.initialized) { Logger.printError(component, "Unable to execute Processors; initialization was not concluded successfully."); System.exit(-1); } Iterator<Entry<Priority, GenericProcessor>> it = processors.entrySet().iterator(); Entry<Priority, GenericProcessor> e; while(it.hasNext()) { e = it.next(); if(prio.equals(e.getKey())) { try { e.getValue().process(jcas); } catch (Exception exception) { exception.printStackTrace(); Logger.printError(component, "Unable to process registered Processor "+e.getValue().getClass().getName()+", got: "+exception.toString()); System.exit(-1); } } } } /** * getInstance method of the singleton pattern * @return ProcessorManager */ public static ProcessorManager getInstance() { return ProcessorManager.INSTANCE; } public enum Priority { PREPROCESSING, POSTPROCESSING, ARBITRARY } }