package org.marketcetera.core.instruments; import org.marketcetera.util.misc.ClassVersion; import org.marketcetera.util.log.SLF4JLoggerProxy; import org.apache.commons.lang.Validate; import java.util.ServiceLoader; import java.util.LinkedList; import java.util.List; import com.google.common.collect.ImmutableList; /* $License$ */ /** * A Instrument function selector that selects an appropriate instance * of {@link DynamicInstrumentHandler} given an instance of * type <code>T</code> by dynamically querying the handlers. * <p> * Since creation of an instance of the selector is an expensive operation, * it's recommended that a singleton instance of this selector be created * for processing. * * @param <T> The type of objects that are used to dynamically select an * {@link DynamicInstrumentHandler} instance. * @param <S> The type of function handler selected by this instance. * * @author anshul@marketcetera.com * @version $Id: DynamicInstrumentFunctionSelector.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ @ClassVersion("$Id: DynamicInstrumentFunctionSelector.java 16154 2012-07-14 16:34:05Z colin $") public class DynamicInstrumentFunctionSelector<T,S extends DynamicInstrumentHandler<T>> { /** * Creates an instance. * * @param inClass the class of dynamic functions that are selected * by this instance. Cannot be null. */ public DynamicInstrumentFunctionSelector(Class<S> inClass) { Validate.notNull(inClass, "class"); //$NON-NLS-1$ List<S> list = new LinkedList<S>(); ServiceLoader<S> loader = ServiceLoader.load(inClass); for(S s : loader) { list.add(s); } SLF4JLoggerProxy.debug(this, "Available handlers {}", list); //$NON-NLS-1$ mClass = inClass; mHandlers = ImmutableList.copyOf(list); } /** * Selects an appropriate handler for the specified value. * <p> * The first handler whose {@link DynamicInstrumentHandler#isHandled(Object)} * returns true is returned back. * * @param inValue the value * * @return the appropriate handler for the specified value. * * @throws IllegalArgumentException if a selectable could not be * found for the specified object. */ public S forValue(T inValue) { Validate.notNull(inValue, "value"); //$NON-NLS-1$ for(S s: mHandlers) { if(s.isHandled(inValue)) { return s; } } throw new IllegalArgumentException(Messages.NO_HANDLER_FOR_VALUE. getText(inValue,mClass.getName())); } /** * Returns the immutable list of handlers that are available * to the selector. * * @return the list of handlers available. */ public List<S> getHandlers() { return mHandlers; } private final Class<S> mClass; private final List<S> mHandlers; }