package org.sef4j.core.helpers.senders.multiplexer;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.sef4j.core.api.EventSender;
import org.sef4j.core.helpers.senders.multiplexer.AbstractDemultiplexerEventSender.UnwrapInfoPair;
/**
* helper class for Mulitplexer/Demultiplexer EventSEnder using function delegates
*
* @see also MultiplexerDefaults, for simpler implementation without using functionnal delegates
*/
public final class FuncMultiplexerUtils {
/* private to force all static */
private FuncMultiplexerUtils() {}
/**
* default implementation of AbstractDemultiplexerEventSender using function delegates
*/
public static class FuncDemultiplexerEventSender<K,T,TDestEvent> extends AbstractDemultiplexerEventSender<K,T,TDestEvent> {
protected Function<T,UnwrapInfoPair<K,TDestEvent>> eventUnwrapperFunc;
protected Function<K,EventSender<TDestEvent>> eventDispatcherFunc;
public FuncDemultiplexerEventSender(
Function<T, UnwrapInfoPair<K, TDestEvent>> eventUnwrapperFunc,
Function<K, EventSender<TDestEvent>> eventDispatcherFunc) {
this.eventUnwrapperFunc = eventUnwrapperFunc;
this.eventDispatcherFunc = eventDispatcherFunc;
}
@Override
protected UnwrapInfoPair<K, TDestEvent> unwrapEventInfo(T event) {
UnwrapInfoPair<K, TDestEvent> unwrapInfo = eventUnwrapperFunc.apply(event);
return unwrapInfo;
}
@Override
protected EventSender<TDestEvent> eventSenderDispatcherFor(K key) {
return eventDispatcherFunc.apply(key);
}
}
// ------------------------------------------------------------------------
/**
* helper class for MultiplexerEventSender: for wrapping key+event into wrappedEvent
*/
public static class EventToMultiplexedEventFunc<K,T> implements BiFunction<K,T,MultiplexedEvent<K,T>> {
@SuppressWarnings("rawtypes")
private static final EventToMultiplexedEventFunc<?,?> INSTANCE = new EventToMultiplexedEventFunc();
@SuppressWarnings("unchecked")
public static final <K,T> EventToMultiplexedEventFunc<K,T> instance() { return (EventToMultiplexedEventFunc<K,T>) INSTANCE; }
@Override
public MultiplexedEvent<K,T> apply(K key, T event) {
return new MultiplexedEvent<K,T>(key, event);
}
}
// ------------------------------------------------------------------------
/**
* helper class for DemultiplexerEventSender : for extracting key+unwrappEvent from wrappedEvent
*/
public static class MultiplexedEventToEventFunc<K,T> implements Function<MultiplexedEvent<K,T>,UnwrapInfoPair<K,T>> {
@SuppressWarnings("rawtypes")
private static final MultiplexedEventToEventFunc<?,?> INSTANCE = new MultiplexedEventToEventFunc();
@SuppressWarnings("unchecked")
public static final <K,T> MultiplexedEventToEventFunc<K,T> instance() { return (MultiplexedEventToEventFunc<K,T>) INSTANCE; }
@Override
public UnwrapInfoPair<K,T> apply(MultiplexedEvent<K, T> event) {
return new UnwrapInfoPair<K,T>(event.getKey(), event.getWrappedEvent());
}
}
// ------------------------------------------------------------------------
/**
* helper class for DemultiplexerEventSender: for selecting an EventDispatcher in a map to dispatch for a given key
*/
public static class EventSenderDispatcherMap<K,T> {
protected Map<K,EventSender<T>> map;
protected EventSender<T> defaultEventSender;
protected final Function<K,EventSender<T>> eventDispatcherFunc;
public EventSenderDispatcherMap(Map<K,EventSender<T>> map, EventSender<T> defaultEventSender) {
this.map = map;
this.defaultEventSender = defaultEventSender;
this.eventDispatcherFunc = key -> getEventSender(key);
}
public Function<K, EventSender<T>> getEventDispatcherFunc() {
return eventDispatcherFunc;
}
protected EventSender<T> getEventSender(K key) {
EventSender<T> res = map.get(key);
if (res == null) {
res = defaultEventSender;
}
return res;
}
}
// ------------------------------------------------------------------------
public static class FuncMultiplexerEventSender<K,TSrcEvent,TDestEvent>
extends AbstractWrapperMultiplexerEventSender<K,TSrcEvent,TDestEvent> {
protected BiFunction<K,TSrcEvent,TDestEvent> eventWrapperFunc;
public FuncMultiplexerEventSender(
EventSender<TDestEvent> target,
BiFunction<K, TSrcEvent, TDestEvent> eventWrapperFunc) {
super(target);
this.eventWrapperFunc = eventWrapperFunc;
}
@Override
protected TDestEvent wrapEvent(K key, TSrcEvent event) {
return eventWrapperFunc.apply(key, event);
}
}
}