package org.apache.ode.spi.work;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import javax.xml.namespace.QName;
public interface ExecutionUnit {
//Fluent API
//New ExecutionUnits
public <S extends Execution, D extends Execution> ExecutionUnit sequential(S supExecUnit, D depExecUnit) throws ExecutionUnitException;
public Execution jobCmd(QName commandName) throws ExecutionUnitException;
public InExecution inCmd(QName commandName) throws ExecutionUnitException;
public OutExecution outCmd(QName commandName) throws ExecutionUnitException;
public InOutExecution inOutCmd(QName commandName) throws ExecutionUnitException;
public Execution jobOp(QName operationName) throws ExecutionUnitException;
public InExecution inOp(QName operationName) throws ExecutionUnitException;
public OutExecution outOp(QName operationName) throws ExecutionUnitException;
public InOutExecution inOutOp(QName operationName) throws ExecutionUnitException;
public Execution run(Job job) throws ExecutionUnitException;
public InExecution run(In<?> in) throws ExecutionUnitException;
public OutExecution run(Out<?> out) throws ExecutionUnitException;
public InOutExecution run(InOut<?, ?> inout) throws ExecutionUnitException;
public <I extends InBuffer> BufferInput<I> newInput(I struct) throws ExecutionUnitException;
public <O extends OutBuffer> BufferOutput<O> newOutput(O struct) throws ExecutionUnitException;
public ArrayInput newInput(Object... input) throws ExecutionUnitException;
public ArrayOutput newOutput(Object... output) throws ExecutionUnitException;
//public <V> ExecutionUnit setEnvironment(QName name, V value) throws ExecutionUnitException;;
//public <V> V getEnvironment(QName name) throws ExecutionUnitException;;
//public ExecutionUnit unsetEnvironment(QName name) throws ExecutionUnitException;;
public <E extends Throwable> void handle(Class<E> e, QName handlerOperationName) throws ExecutionUnitException;;
public <E extends Throwable> void handle(Class<E> e, Aborted aborted) throws ExecutionUnitException;
//Transforms should be associative, i.e. order of the transform does not matter
public static interface Transform {
}
public static interface OneToOne extends Transform {
public void transform(Object[] from, Object[] to);
}
public static interface OneToMany extends Transform {
public void transform(Object[] from, Object[][] to);
}
public static interface ManyToOne extends Transform {
public void transform(Object[][] from, Object[] to);
}
public static enum ExecutionState {
READY, BLOCK_IN, BLOCK_SEQ, RUN, BLOCK_RUN, BLOCK_OUT, CANCEL, ABORT, COMPLETE;
}
public static interface Execution {
//public void initializer();
//public void finalizer();
public ExecutionState state() throws ExecutionUnitException;
}
public static interface InExecution extends Execution {
public InExecution pipeIn(Output output, Transform... transforms) throws ExecutionUnitException;
public OutExecution pipeIn(OutExecution execUnit, Transform... transforms) throws ExecutionUnitException;
public InOutExecution pipeIn(InOutExecution execUnit, Transform... transforms) throws ExecutionUnitException;
}
public static interface OutExecution extends Execution {
public OutExecution pipeOut(Input input, Transform... transforms) throws ExecutionUnitException;
public InExecution pipeOut(InExecution execUnit, Transform... transforms) throws ExecutionUnitException;
public InOutExecution pipeOut(InOutExecution execUnit, Transform... transforms) throws ExecutionUnitException;
}
public static interface InOutExecution extends InExecution, OutExecution {
}
public static enum ExecutionUnitState {
BUILD, SUBMIT, READY, RUN, BLOCK, CANCEL, COMPLETE;
}
public interface Work extends ExecutionUnit {
//termination methods
public void submit() throws ExecutionUnitException;
ExecutionUnitState state(long timeout, TimeUnit unit, ExecutionUnitState... expected) throws ExecutionUnitException;
public void cancel() throws ExecutionUnitException;
}
public interface WorkItem extends ExecutionUnit {
//termination methods
public void submit() throws ExecutionUnitException;
public Semaphore block() throws ExecutionUnitException;
public void abort(Throwable t) throws ExecutionUnitException;
public <O extends Output> O input() throws ExecutionUnitException;
public <I extends Input> I output() throws ExecutionUnitException;
}
public static class ExecutionUnitException extends Exception {
public ExecutionUnitException() {
}
public ExecutionUnitException(String msg) {
super(msg);
}
public ExecutionUnitException(Throwable t) {
super(t);
}
}
public static interface Aborted {
public void abort(Throwable t);
}
public static interface Input {
}
public static interface Output {
}
//Using a buffer pattern data is passed by order in the buffer
//implements InStream or OutStream
//no methods, only fields
//read data in
public static interface InBuffer {
}
public static interface OutBuffer {
}
public static interface BufferInput<I extends InBuffer> extends Input {
I buffer();
}
public static interface BufferOutput<O extends OutBuffer> extends Output {
O buffer();
}
public static interface ArrayInput extends Input {
Object[] array();
}
public static interface ArrayOutput extends Output {
Object[] array();
}
//While operations are static and modeled at DI discovery time these interfaces allow any instance to participate in execution.
public static interface Job {
public void run(WorkItem execUnit);
}
public static interface In<I extends InBuffer> {
public void in(WorkItem execUnit, I in);
}
public static interface Out<O extends OutBuffer> {
public void out(WorkItem execUnit, O out);
}
public static interface InOut<I extends InBuffer, O extends OutBuffer> {
public void inOut(WorkItem execUnit, I in, O out);
}
/*
zero arg constructor or single element array instead
public static final class H<T> {
public final T value;
public H(T value) {
this.value = value;
}
}*/
}