package org.sef4j.core.api.ioeventchain; import java.io.Closeable; import java.util.Collection; import org.sef4j.core.api.EventSender; import org.sef4j.core.api.def.ioevenchain.OutputEventChainDef; import org.sef4j.core.util.Handle; import org.sef4j.core.util.factorydef.AbstractSharedStartableObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * chain of EventProvider (EventProvider<-EventProvider<-EventProvider) * * instance of this class are managed by ObjectByDefRepository * and are unique for the given corresponding InputEventChainDef * * to output events to this chain; * <code> * OutputEventChain<T> outputChain = ... // repository.register(def); * * OutputEventChainPublication<T> subscr = outputChain.addOutputSender(); * ... * ... // send events: * subscr.sendEvents(..) * * ... * subscr.close(); * </code> * */ public abstract class OutputEventChain<T> extends AbstractSharedStartableObject<OutputEventChainDef> { private static final Logger LOG = LoggerFactory.getLogger(OutputEventChain.class); // ------------------------------------------------------------------------ public OutputEventChain(String displayName) { super(displayName); } // ------------------------------------------------------------------------ protected abstract EventSender<T> getInnerEventSender(); public SenderHandle<T> registerSender() { Handle handle = registerStart(); return new SenderHandle<T>(this, handle); } public void unregisterSender(SenderHandle<T> handle) { handle.close(); } // ------------------------------------------------------------------------ public static class SenderHandle<T> implements EventSender<T>, Closeable { private OutputEventChain<T> target; private Handle handle; private SenderHandle(OutputEventChain<T> target, Handle handle) { this.target = target; this.handle = handle; } @Override protected void finalize() throws Throwable { if (target != null) { LOG.warn("detected unreleased resource ... force close()!"); try { close(); } catch(Exception ex) { LOG.error("Failed ... ignore, no rethrow!", ex); } } super.finalize(); } @Override public void close() { if (target != null) { target.unregisterStop(handle); this.target = null; this.handle = null; } } @Override public void sendEvent(T event) { if (target == null) return; EventSender<T> innerSender = target.getInnerEventSender(); innerSender.sendEvent(event); } @Override public void sendEvents(Collection<T> events) { if (target == null) return; EventSender<T> innerSender = target.getInnerEventSender(); innerSender.sendEvents(events); } } }