package org.sef4j.core.api.session;
import java.util.Collection;
import org.sef4j.core.api.EventProvider;
import org.sef4j.core.api.EventSender;
import org.sef4j.core.helpers.senders.DefaultEventProvider;
import org.sef4j.core.helpers.senders.MutableInMemoryOrDelegateEventSender;
/**
* class for Client Session supporting input-output events
* between hosted Application listener/sender <--- to/from---> SessionTransport listener/sender
*/
public class InOutEventsClientSession {
private InOutEventsClientSessionManager ownerSessionManager;
private final String id;
private String sessionDisplayName;
/**
* event redirector from hosted application provider to client session transport(s)
* Notice there should be only 1 session listener in general
* ... otherwise client will receive multiple occurrences of each event, one per transport
*
* <PRE>
* addSessionTransportEventListener
* <---
*
* (appSender1) clientSession Transport (example: JMS, WebSocket, ..)
* sendEvent(e1) +--------------+ sendEvent(e1)
* -----> | appToSession | -------> +---> transport1
* | | \--> transport2
* (appSender2) +--------------+ ...
* sendEvent(e2) sendEvent(e2)
* -----> ------> +---> transport1
* \--> transport2
* ...
* removeSessionTransportEventListener()
* <---
* </PRE>
*
* Notice that appSender(s) should generally be wrapped with a MultiplexerEventSender
*/
protected MutableInMemoryOrDelegateEventSender<Object> appToSessionTransportsEventSender = new MutableInMemoryOrDelegateEventSender<Object>(null, 100);
// TODO ... may redispatch to only 1 TransportSession (by priority / round robin, ...)
protected DefaultEventProvider<Object> sessionTransportsRedispatcher = new DefaultEventProvider<Object>();
/**
* event redirector from client session transport(s) to hosted application event listener
*
* <PRE>
* addAppEventListener(appListener1)
* --->
* addAppEventListener(appListener2)
* --->
* clientSession Transport (example: JMS, WebSocket, ..)
* sendEvent(e1) +--------------+ sendEvent(e1)
* appListener1 <---+ <----- | appToSession | <------
* appListener2 <--/ | |
* +--------------+
* sendEvent(e2) sendEvent(e2)
* appListener1 <---+ <----- <------
* appListener2 <--/
*
* removeAppEventListener(appListener1)
* --->
* </PRE>
*
*/
protected DefaultEventProvider<Object> sessionTransportsToAppListenersEventSender = new DefaultEventProvider<Object>();
/**
* <PRE> inner inner
* AppService +--------+ SessionTransportService
* ---> +----+ | this | +----+ <---
* ---> | |--| |--| | <---
* ---> +----+ | | +----+ <---
* /\ +--------+ /\
* | |
* +----+ +----+
* ---> | | | | <---
* +----+ +----+
* InputEventChain OutputEventChain
* Subscriptions Publications
* </PRE>
*/
private SessionTransportService sessionTransportService = new SessionTransportService();
private AppService appService = new AppService();
private ClientSessionInputEventChainSubscriptions inputEventChainSubscriptions =
new ClientSessionInputEventChainSubscriptions(this);
// ------------------------------------------------------------------------
public InOutEventsClientSession(InOutEventsClientSessionManager ownerSessionManager, String id,
String sessionDisplayName) {
this.id = id;
this.sessionDisplayName = sessionDisplayName;
}
// ------------------------------------------------------------------------
public InOutEventsClientSessionManager getOwnerSessionManager() {
return ownerSessionManager;
}
public String getId() {
return id;
}
public SessionTransportService getSessionTransportService() {
return sessionTransportService ;
}
public String getSessionDisplayName() {
return sessionDisplayName;
}
public AppService getAppService() {
return appService;
}
public ClientSessionInputEventChainSubscriptions getInputEventChainSubscriptions() {
return inputEventChainSubscriptions;
}
// ------------------------------------------------------------------------
/**
* inner api service for SessionTransports side
* <PRE>
* addSessionTransportListener() ...example: on WebSocket connect
* <---
* +----+ removeSessionTransportListener() ...example: on WebSocket disconnect
* | | <---
* +----+
* sendSessionTransportEvent() ...example: on WebSocket receive event
* <--
* </PRE>
*/
public class SessionTransportService {
// public EventProvider<Object> getSessionTransportsEventProvider() {
// return appToSessionTransportsEventSender;
// }
/** helper for <code>getSessionTransportsEventProvider().addEventListener()</code> */
public void addSessionTransportsEventListener(EventSender<Object> listener) {
sessionTransportsRedispatcher.addEventListener(listener);
if (sessionTransportsRedispatcher.getEventListenerCount() > 0
&& appToSessionTransportsEventSender.getDelegate() == null
) {
appToSessionTransportsEventSender.setDelegate(sessionTransportsRedispatcher);
}
}
/** helper for <code>getSessionTransportsEventProvider().removeEventListener()</code> */
public void removeSessionTransportsEventListener(EventSender<Object> listener) {
sessionTransportsRedispatcher.removeEventListener(listener);
if (sessionTransportsRedispatcher.getEventListenerCount() == 0
&& appToSessionTransportsEventSender.getDelegate() != null
) {
appToSessionTransportsEventSender.setDelegate(null);
}
}
public EventSender<Object> getSessionTransportsEventReceiver() {
return sessionTransportsToAppListenersEventSender;
}
/** helper for <code>getSessionTransportsEventSender().sendEvent()</code> */
public void sendSessionTransportsEvent(Object event) {
sessionTransportsToAppListenersEventSender.sendEvent(event);
}
/** helper for <code>getSessionTransportsEventSender().sendEvents()</code> */
public void sendSessionTransportsEvents(Collection<Object> events) {
sessionTransportsToAppListenersEventSender.sendEvents(events);
}
}
/**
* inner api service for appListener side
* <PRE>
* addAppEventListener()
* ---> +------+
* removeAppEventListener() | |
* ---> +------+
*
* sendEvent()
* --->
* </PRE>
*/
public class AppService {
public EventProvider<Object> getAppEventProvider() {
return sessionTransportsToAppListenersEventSender;
}
/** helper for <code>getSessionTransportsEventProvider().addEventListener()</code> */
public void addAppEventListener(EventSender<Object> listener) {
sessionTransportsToAppListenersEventSender.addEventListener(listener);
}
/** helper for <code>getSessionTransportsEventProvider().removeEventListener()</code> */
public void removeAppEventListener(EventSender<Object> listener) {
sessionTransportsToAppListenersEventSender.removeEventListener(listener);
}
public EventSender<Object> getAppEventSender() {
return appToSessionTransportsEventSender;
}
/** helper for <code>sessionTransportsToAppListenersEventSender.sendEvent()</code> */
public void sendAppEvent(Object event) {
appToSessionTransportsEventSender.sendEvent(event);
}
/** helper for <code>getSessionTransportsEventSender().sendEvents()</code> */
public void sendAppEvents(Collection<Object> events) {
appToSessionTransportsEventSender.sendEvents(events);
}
}
// ------------------------------------------------------------------------
public void close() {
// TODO ...
}
}