package org.marketcetera.module; import org.marketcetera.util.misc.ClassVersion; import org.marketcetera.core.Pair; import java.util.Hashtable; import java.util.HashSet; /* $License$ */ /** * A module that emits and receives data. * This module accepts a single string request parameter * that is the class name of the data type to expect. * The module filters all the data it receives and only emits * data that is of the supplied type onward in the data pipe. * * @author anshul@marketcetera.com */ @ClassVersion("$Id: ProcessorModule.java 16154 2012-07-14 16:34:05Z colin $") public class ProcessorModule extends ModuleBase implements DataEmitter, DataReceiver { public ProcessorModule(ModuleURN inModuleURN) { this(inModuleURN, true); } protected ProcessorModule(ModuleURN inModuleURN, boolean inAutoStart) { super(inModuleURN, inAutoStart); } @Override public void receiveData(DataFlowID inFlowID, Object data) throws UnsupportedDataTypeException, StopDataFlowException { if(data == null) { throw new StopDataFlowException(TestMessages.STOP_DATA_FLOW); } //pass thru data is sent right across. if(mPassThru != null) { mPassThru.send(data); return; } //boolean data is transmitted without filtering to all requests if(data instanceof Boolean) { for(Pair<Class,DataEmitterSupport> p:mTable.values()) { p.getSecondMember().send(data); } return; } if(mNumReceive++ % 2 == 0) { //throw an error every other time just for testing error reporting throw new UnsupportedDataTypeException(TestMessages.BAD_DATA); } for(Pair<Class,DataEmitterSupport> p:mTable.values()) { if(p.getFirstMember().isInstance(data)) { p.getSecondMember().send(data); } } } @Override public void requestData( DataRequest inRequest, DataEmitterSupport inSupport) throws RequestDataException { Object obj = inRequest.getData(); if(obj == null) { throw new IllegalRequestParameterValue(getURN(), obj); } if(!(obj instanceof String)) { throw new UnsupportedRequestParameterType(getURN(), obj); } if("passThru".equals(obj)) { if(mPassThru != null) { throw new IllegalRequestParameterValue(getURN(),obj); } mPassThru = inSupport; mPassThruID = inSupport.getRequestID(); } else { try { Class filter = Class.forName(obj.toString()); mTable.put(inSupport.getRequestID(), new Pair<Class,DataEmitterSupport>( filter,inSupport)); mFlows.add(inSupport.getFlowID()); } catch (ClassNotFoundException e) { throw new IllegalRequestParameterValue(getURN(), obj.toString(),e); } } } @Override public void cancel(DataFlowID inFlowID, RequestID inRequestID) { if (inRequestID.equals(mPassThruID)) { mPassThru = null; } Pair<Class, DataEmitterSupport> pair = mTable.remove(inRequestID); if(pair != null) { mFlows.remove(pair.getSecondMember().getFlowID()); } } /** * Number of requests being processed. * * @return number of requests being processed. */ public int getNumRequests() { return mTable.size(); } /** * Set of data flows that this module is particpating in. * * @return the set of data flows. */ public DataFlowID[] getFlows() { return mFlows.toArray(new DataFlowID[mFlows.size()]); } private int mNumReceive = 0; private DataEmitterSupport mPassThru = null; private RequestID mPassThruID; private Hashtable<RequestID, Pair<Class,DataEmitterSupport>> mTable = new Hashtable<RequestID, Pair<Class, DataEmitterSupport>>(); private HashSet<DataFlowID> mFlows = new HashSet<DataFlowID>(); }