package ru.decipher.extraction.impl;
import org.apache.log4j.Logger;
import ru.decipher.exception.ProcessorTaskExecutionException;
import ru.decipher.extraction.*;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* User: Alexander Paderin (apocarteres@gmail.com)
* Date: 10/21/13
* Time: 9:41 AM
*/
public class GeneralTask<T extends PayloadRequest, U extends ProviderFactory<? extends Provider<T>>> implements PayloadTask<T> {
protected T request;
protected Set<CallbackHandler<T>> handlers;
protected U factory;
private Provider<T> provider;
protected static final Logger log = Logger.getLogger(GeneralTask.class);
public GeneralTask() {
this.handlers = new LinkedHashSet<>();
}
@Override
public T getRequest() {
return request;
}
@Override
public void registerHandler(CallbackHandler<T> handler) {
if (handler == null) {
throw new RuntimeException("can't register null handler");
}
if (!handlers.add(handler)) {
throw new RuntimeException("can't register duplicate handler. Consider don't use same instance of " +
"GeneralTask class to make different requests");
}
}
public void setRequest(T request) {
this.request = request;
}
public void setFactory(U factory) {
this.factory = factory;
}
protected T execute() throws Exception {
if (provider == null) {
throw new ProcessorTaskExecutionException("provider has not been initialized");
}
return provider.fetch(request);
}
protected Provider<T> buildProvider() {
return factory.create();
}
@Override
public T call() throws Exception {
provider = buildProvider();
for (CallbackHandler<T> handler : handlers) {
try {
handler.beforeExecution(request, provider);
} catch (Throwable e) {
log.fatal("handler " + handler + " throws an exception during 'beforeExecution' invocation", e);
}
}
T result;
try {
result = execute();
} catch (Exception e) {
result = request;
log.fatal("exception occurred during processing " + request, e);
}
for (CallbackHandler<T> handler : handlers) {
try {
handler.onProcessorResponse(result);
} catch (Throwable e) {
log.fatal("handler " + handler + " throws an exception during 'onProcessorResponse' invocation", e);
}
}
return result;
}
}