package scs.event_service.servant; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.omg.CORBA.Any; import scs.core.ConnectionDescription; import scs.core.IReceptacles; import scs.core.IReceptaclesHelper; import scs.event_service.EventSink; import scs.event_service.EventSinkPOA; /** * Classe que cont�m as funcionalidades da interface EventSink suportada pelo * canal de eventos. * * @author Eduardo Fonseca/Luiz Marques * */ public class EventSinkChannelServant extends EventSinkPOA { /** * Inner class responsavel por enviar assincronamente os * eventos para os consumidores. Consiste basicamente de * uma thread que fica sempre tentando ler de uma fila de * eventos aqueles que est�o pendentes para envio. */ private class EventDispatcher extends Thread { BlockingQueue<Any> eventQueue = null; EventChannelServant channel = null; /** * @param channel canal que � "pai" deste dispatcher * @param queue fila que cont�m os eventos prontos para serem enviados */ public EventDispatcher( EventChannelServant channel, BlockingQueue<Any> queue ) { this.eventQueue = queue; this.channel = channel; } /* (non-Javadoc) * @see java.lang.Thread#run() */ @Override public void run() { while(true){ Any event; try { /* * Remove um elemento da fila de forma bloqueante * S� acorda quando tiver um elemento ou quando a aplica��o * estiver terminando */ event = this.eventQueue.take(); } catch (InterruptedException e) { System.err.println("Dispatcher interrupted ! Exiting ..."); break; } synchronized(this) { IReceptacles source = IReceptaclesHelper.narrow(this.channel.getFacet("scs::core::IReceptacles")); ConnectionDescription[] connections=null; try { connections = source.getConnections("EventSource"); } catch (scs.core.InvalidName e) { e.printStackTrace(); } /* * Tenta despachar para todos os EventSinks registrados no EventSource */ for (int i = 0; i < connections.length; i++) { ConnectionDescription description = connections[i]; ((EventSink)description.objref).push(event); //System.out.println("Dispatcher despachou evento para o destino apropriado"); } } } } } private EventChannelServant evtChn = null; private BlockingQueue<Any> eventQueue = null; private EventDispatcher eventDisp = null; /* * Construtor recebe o event channel associado ao EventSink */ public EventSinkChannelServant(EventChannelServant ev) { this.evtChn = ev; this.eventQueue = new LinkedBlockingQueue<Any>(); this.eventDisp = new EventDispatcher(this.evtChn, this.eventQueue); this.eventDisp.start(); } /* * (non-Javadoc) * @see EventService.EventSinkOperations#disconnect() */ public void disconnect() { IReceptacles source = IReceptaclesHelper.narrow(this.evtChn.getFacet("scs::core::IReceptacles")); ConnectionDescription[] connections=null; try { connections = source.getConnections("EventSource"); } catch (scs.core.InvalidName e) { e.printStackTrace(); } for (int i = 0; i < connections.length; i++) { ConnectionDescription description = connections[i]; ((EventSink)description.objref).disconnect(); } } /* * (non-Javadoc) * @see EventService.EventSinkOperations#push(org.omg.CORBA.Any) */ public void push(Any event) { //String s = event.extract_string(); //System.out.println("EventSinkChannelServant.push: " + s); this.eventQueue.offer(event); //System.out.println("EventSinkChannelServant.push: evento enfileirado"); } }