}
// Implementation note: the work listener is notified prior to release
// the start lock. This behavior is intentional and seems to be the
// more conservative.
workListener.workStarted(new WorkEvent(this, WorkEvent.WORK_STARTED, adaptee, null));
startLatch.countDown();
//Implementation note: we assume this is being called without an interesting TransactionContext,
//and ignore/replace whatever is associated with the current thread.
try {
List<WorkContext> workContexts = NO_INFLOW_CONTEXT;
if (executionContext != null) {
TransactionContext txWorkContext = new TransactionContext();
try {
txWorkContext.setTransactionTimeout(executionContext.getTransactionTimeout());
} catch (NotSupportedException e) {
//not set, continue to not set it.
}
txWorkContext.setXid(executionContext.getXid());
workContexts = Collections.<WorkContext>singletonList(txWorkContext);
log.info("Translated ExecutionContext to TransactionContext");
} else if (adaptee instanceof WorkContextProvider) {
workContexts = ((WorkContextProvider) adaptee).getWorkContexts();
}
List<WorkContextHandler> sortedHandlers = new ArrayList<WorkContextHandler>(workContexts.size());
for (WorkContext workContext : workContexts) {
boolean found = false;
for (Iterator<WorkContextHandler> it = workContextHandlers.iterator(); it.hasNext();) {
WorkContextHandler workContextHandler = it.next();
log.info("sorting WorkContextHandler: " + workContextHandler + " for work context: " + workContext);
if (workContextHandler.supports(workContext.getClass())) {
it.remove();
log.info("adding sorted WorkContextHandler: " + workContextHandler);
sortedHandlers.add(workContextHandler);
found = true;
break;
}
}
if (!found) {
for (WorkContextHandler workContextHandler: sortedHandlers) {
if (workContextHandler.supports(workContext.getClass())) {
throw new WorkCompletedException("Duplicate WorkContext: " + workContext, WorkContextErrorCodes.DUPLICATE_CONTEXTS);
}
}
throw new WorkCompletedException("Unhandled WorkContext: " + workContext, WorkContextErrorCodes.UNSUPPORTED_CONTEXT_TYPE);
}
}
for (Iterator<WorkContextHandler> it = workContextHandlers.iterator(); it.hasNext();) {
WorkContextHandler workContextHandler = it.next();
if (!workContextHandler.required()) {
log.info("Removing non-required WorkContextHandler with no context: " + workContextHandler);
it.remove();
}
}
// TODO use a WorkContextLifecycleListener
int i = 0;
for (WorkContext workContext : workContexts) {
WorkContextHandler contextHandler = sortedHandlers.get(i++);
log.info("calling before on WorkContextHandler: " + contextHandler + " with workContext: " + workContext);
contextHandler.before(workContext);
}
for (WorkContextHandler workContextHandler: workContextHandlers) {
log.info("calling before on WorkContextHandler: " + workContextHandler + " with null workContext");
workContextHandler.before(null);
}
try {
adaptee.run();
} finally {
int j = 0;
for (WorkContext workContext : workContexts) {
WorkContextHandler contextHandler = sortedHandlers.get(j++);
log.info("calling after on WorkContextHandler: " + contextHandler + " with workContext: " + workContext);
contextHandler.after(workContext);
}
for (WorkContextHandler workContextHandler: workContextHandlers) {
log.info("calling after on WorkContextHandler: " + workContextHandler + " with null workContext");
workContextHandler.after(null);
}
}
workListener.workCompleted(new WorkEvent(this, WorkEvent.WORK_COMPLETED, adaptee, null));
} catch (Throwable e) {
workException = (WorkException) (e instanceof WorkCompletedException ? e : new WorkCompletedException("Unknown error", WorkCompletedException.UNDEFINED).initCause(e));
workListener.workCompleted(new WorkEvent(this, WorkEvent.WORK_REJECTED, adaptee,
workException));
} finally {
endLatch.countDown();
}
}