package org.sef4j.core.helpers.ioeventchain;
import java.util.concurrent.TimeUnit;
import org.sef4j.core.api.ioeventchain.InputEventChain;
import org.sef4j.core.api.ioeventchain.InputEventChainFactory;
import org.sef4j.core.helpers.tasks.PeriodicTask;
import org.sef4j.core.helpers.tasks.PeriodicTaskInputEventChainDef;
import org.sef4j.core.helpers.tasks.PollingEventProvider;
import org.sef4j.core.util.AsyncUtils;
import org.sef4j.core.util.IStartableSupport;
import org.sef4j.core.util.factorydef.DependencyObjectCreationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* InputEventChain adapter for polling on tasks and sending corresponding events
*
*/
public class PeriodicTaskInputEventChain<T> extends InputEventChain<T> {
private static final Logger LOG = LoggerFactory.getLogger(PeriodicTaskInputEventChain.class);
protected PollingEventProvider<T> pollingEventProvider;
protected PeriodicTask periodicTask;
// ------------------------------------------------------------------------
public PeriodicTaskInputEventChain(
String displayName,
PollingEventProvider<T> pollingEventProvider,
PeriodicTask.Builder pollingPeriodBuilder) {
super(displayName);
this.pollingEventProvider = pollingEventProvider;
this.periodicTask = pollingPeriodBuilder.build(() -> poll());
pollingEventProvider.addEventListener(innerEventProvider);
}
@Override
public void close() {
super.close();
assert ! isStarted();
this.pollingEventProvider.removeEventListener(innerEventProvider);
this.pollingEventProvider = null;
this.periodicTask = null;
}
// ------------------------------------------------------------------------
protected IStartableSupport startablePollingEventProvider() {
if (pollingEventProvider instanceof IStartableSupport) {
return (IStartableSupport) pollingEventProvider;
}
return null;
}
@Override
public boolean isStarted() {
boolean res = periodicTask.isStarted();
IStartableSupport pollingStartable = startablePollingEventProvider();
if (pollingStartable != null) {
res = pollingStartable.isStarted();
}
return res;
}
@Override
public void start() {
if (isStarted()) {
return;
}
LOG.debug("start " + displayName);
IStartableSupport pollingStartable = startablePollingEventProvider();
if (pollingStartable != null) {
pollingStartable.start();
}
periodicTask.start();
}
@Override
public void stop() {
if (! isStarted()) {
return;
}
LOG.debug("stop " + displayName);
IStartableSupport pollingStartable = startablePollingEventProvider();
if (pollingStartable != null) {
pollingStartable.stop();
}
periodicTask.stop();
}
public void poll() {
if (LOG.isDebugEnabled()) {
LOG.debug("poll " + displayName);
}
pollingEventProvider.poll();
}
// ------------------------------------------------------------------------
@Override
public String toString() {
return "PeriodicTaskInputEventChain [" + displayName + "]";
}
// ------------------------------------------------------------------------
public static class Factory<T>
extends InputEventChainFactory<PeriodicTaskInputEventChainDef,PeriodicTaskInputEventChain<T>> {
@SuppressWarnings("rawtypes")
private static final Factory<?> INSTANCE = new Factory();
@SuppressWarnings("unchecked")
public static <T> Factory<T> instance() { return (Factory<T>) INSTANCE; }
public Factory() {
super("PeriodicTaskInputEventChain", PeriodicTaskInputEventChainDef.class);
}
@Override
public PeriodicTaskInputEventChain<T> create(
PeriodicTaskInputEventChainDef def,
DependencyObjectCreationContext ctx) {
PeriodicTask.Builder pollingPeriodBuilder = new PeriodicTask.Builder()
.withOptionalPeriodicityDef(def.getPeriodicity())
.withDefaults(30, TimeUnit.SECONDS, AsyncUtils.defaultScheduledThreadPool());
PollingEventProvider<T> task = ctx.getOrCreateDependencyByDef("task", def.getTaskDef());
String displayName = ctx.getCurrObjectDisplayName();
PeriodicTaskInputEventChain<T> res = new PeriodicTaskInputEventChain<T>(displayName,
task, pollingPeriodBuilder);
return res;
}
}
}