diff --git a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/AbstractStage.java b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/AbstractStage.java index ad33e815be84b88cf588b3c5cf44f4ae16060726..80bfd8df443e5773328216c776845a4d0d653e43 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/AbstractStage.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/AbstractStage.java @@ -18,7 +18,7 @@ public abstract class AbstractStage implements StageWithPort { /** * A unique logger instance per stage instance */ - protected final Logger logger; // BETTER use SLF4J as interface and logback as impl + protected final Logger logger; private StageWithPort parentStage; @@ -131,14 +131,14 @@ public abstract class AbstractStage implements StageWithPort { protected <T> InputPort<T> createInputPort() { InputPort<T> inputPort = new InputPort<T>(this); - // inputPort.setType(type); // TODO set type for input port + // inputPort.setType(portType); this.inputPortList.add(inputPort); return inputPort; } protected <T> OutputPort<T> createOutputPort() { OutputPort<T> outputPort = new OutputPort<T>(); - // outputPort.setType(type); // TODO set type for output port + // outputPort.setType(portType); this.outputPortList.add(outputPort); return outputPort; } diff --git a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/ConsumerStage.java b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/ConsumerStage.java index 046395a5f0873884fb323788347c6681d48d658d..f64c50f3fc485409f628533876626fc9e618002d 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/ConsumerStage.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/ConsumerStage.java @@ -10,7 +10,7 @@ public abstract class ConsumerStage<I> extends AbstractStage { @Override public void executeWithPorts() { - I element = this.inputPort.receive(); + I element = this.getInputPort().receive(); boolean isReschedulable = this.determineReschedulability(); this.setReschedulable(isReschedulable); @@ -24,7 +24,7 @@ public abstract class ConsumerStage<I> extends AbstractStage { } protected boolean determineReschedulability() { - return this.inputPort.getPipe().size() > 0; + return this.getInputPort().getPipe().size() > 0; } protected abstract void execute(I element); diff --git a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/StageWithPort.java b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/StageWithPort.java index 15733038a7566d2a5eb6cbb7ade4213af023aba7..9753bcdf0bc4819e798317e3bbae88abb150fb82 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/StageWithPort.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/StageWithPort.java @@ -23,6 +23,7 @@ public interface StageWithPort { */ boolean isReschedulable(); + // BETTER remove this method since it will be replaced by onTerminating() void onIsPipelineHead(); void onSignal(Signal signal, InputPort<?> inputPort); diff --git a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/pipe/IPipe.java b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/pipe/IPipe.java index 0bedb314592d62abcd5b8a2917cca130444cb5a2..a5f2519919e54b6915f010a9cdc6f7caa432038b 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/framework/core/pipe/IPipe.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/framework/core/pipe/IPipe.java @@ -26,6 +26,7 @@ public interface IPipe<T> { void setSignal(Signal signal); + // BETTER change signature to allow {OutputPort<T>, OutputPort<A0 extends T>, OutputPort<A1 extends T>, ...} void connectPorts(OutputPort<T> sourcePort, InputPort<T> targetPort); } diff --git a/src/main/java/teetime/variant/methodcallWithPorts/stage/CollectorSink.java b/src/main/java/teetime/variant/methodcallWithPorts/stage/CollectorSink.java index 82f2ec8d81e1e226eb31bfdb3b07e5dc5a017e8c..6af3d421f4d30a73c0289960b94ecb033d587ec0 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/stage/CollectorSink.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/stage/CollectorSink.java @@ -21,11 +21,17 @@ import teetime.variant.methodcallWithPorts.framework.core.ConsumerStage; /** * @author Christian Wulf - * + * * @since 1.10 */ public class CollectorSink<T> extends ConsumerStage<T> { + // private final InputPort<T> inputPort = this.createInputPort(); + // + // public final InputPort<T> getInputPort() { + // return this.inputPort; + // } + private final List<T> elements; private final int threshold; diff --git a/src/main/java/teetime/variant/methodcallWithPorts/stage/PortTypeConfiguration.java b/src/main/java/teetime/variant/methodcallWithPorts/stage/PortTypeConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..59790ddd8fb52c24687d4e1f469837c045fd64bf --- /dev/null +++ b/src/main/java/teetime/variant/methodcallWithPorts/stage/PortTypeConfiguration.java @@ -0,0 +1,19 @@ +package teetime.variant.methodcallWithPorts.stage; + +import teetime.variant.explicitScheduling.examples.throughput.TimestampObject; + +public class PortTypeConfiguration { + + public static <T> void setPortTypes(final ObjectProducer<T> stage, final Class<T> clazz) { + stage.getOutputPort().setType(clazz); + } + + public static <T> void setPortTypes(final CollectorSink<T> stage, final Class<T> clazz) { + stage.getInputPort().setType(clazz); + } + + public static <T> void setPortTypes(final StartTimestampFilter stage) { + stage.getInputPort().setType(TimestampObject.class); + stage.getOutputPort().setType(TimestampObject.class); + } +} diff --git a/src/main/java/teetime/variant/methodcallWithPorts/stage/StartTimestampFilter.java b/src/main/java/teetime/variant/methodcallWithPorts/stage/StartTimestampFilter.java index 2b10cdf378e44363780aa52790485d50ce3d1f9d..0ba688d7f3da6f214189e5e7d5e1e39e8d241f69 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/stage/StartTimestampFilter.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/stage/StartTimestampFilter.java @@ -21,7 +21,7 @@ import teetime.variant.methodcallWithPorts.framework.core.OutputPort; /** * @author Christian Wulf - * + * * @since 1.10 */ public class StartTimestampFilter extends ConsumerStage<TimestampObject> { @@ -35,6 +35,6 @@ public class StartTimestampFilter extends ConsumerStage<TimestampObject> { } public OutputPort<TimestampObject> getOutputPort() { - return outputPort; + return this.outputPort; } } diff --git a/src/main/java/teetime/variant/methodcallWithPorts/stage/StopTimestampFilter.java b/src/main/java/teetime/variant/methodcallWithPorts/stage/StopTimestampFilter.java index 220780e787dd9e03c2d4e82bc73b446fd8d24750..c8454c2f35bfb2ec49fe9bb8a8028c2e88585035 100644 --- a/src/main/java/teetime/variant/methodcallWithPorts/stage/StopTimestampFilter.java +++ b/src/main/java/teetime/variant/methodcallWithPorts/stage/StopTimestampFilter.java @@ -21,7 +21,7 @@ import teetime.variant.methodcallWithPorts.framework.core.OutputPort; /** * @author Christian Wulf - * + * * @since 1.10 */ public class StopTimestampFilter extends ConsumerStage<TimestampObject> { diff --git a/src/test/java/teetime/variant/methodcallWithPorts/runtime/typeCheck/ConnectionTypeTest.java b/src/test/java/teetime/variant/methodcallWithPorts/runtime/typeCheck/ConnectionTypeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..25719d739103fa5b94f5cab5f27df7cbd2f9384a --- /dev/null +++ b/src/test/java/teetime/variant/methodcallWithPorts/runtime/typeCheck/ConnectionTypeTest.java @@ -0,0 +1,109 @@ +package teetime.variant.methodcallWithPorts.runtime.typeCheck; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.TypeVariable; + +import org.junit.Test; + +import teetime.util.ConstructorClosure; +import teetime.variant.explicitScheduling.examples.throughput.TimestampObject; +import teetime.variant.methodcallWithPorts.framework.core.OutputPort; +import teetime.variant.methodcallWithPorts.framework.core.pipe.IPipe; +import teetime.variant.methodcallWithPorts.framework.core.pipe.PipeFactory; +import teetime.variant.methodcallWithPorts.framework.core.pipe.PipeFactory.ThreadCommunication; +import teetime.variant.methodcallWithPorts.stage.ObjectProducer; +import teetime.variant.methodcallWithPorts.stage.PortTypeConfiguration; +import teetime.variant.methodcallWithPorts.stage.StartTimestampFilter; +import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter; +import teetime.variant.methodcallWithPorts.stage.basic.Sink; + +public class ConnectionTypeTest { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testDynamicPortConnection() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, ClassNotFoundException { + ConstructorClosure<TimestampObject> constructorClosure = new ConstructorClosure<TimestampObject>() { + @Override + public TimestampObject create() { + return new TimestampObject(); + } + + }; + + Constructor<ObjectProducer> constructor = ObjectProducer.class.getConstructor(long.class, ConstructorClosure.class); + + ObjectProducer objectProducer = constructor.newInstance(1, constructorClosure); + StartTimestampFilter startTimestampFilter = StartTimestampFilter.class.newInstance(); + StopTimestampFilter stopTimestampFilter = StopTimestampFilter.class.newInstance(); + Sink sink = Sink.class.newInstance(); + + PipeFactory pipeFactory = new PipeFactory(); + + IPipe pipe = pipeFactory.create(ThreadCommunication.INTRA); + pipe.connectPorts(objectProducer.getOutputPort(), startTimestampFilter.getInputPort()); + pipe = pipeFactory.create(ThreadCommunication.INTRA); + pipe.connectPorts(startTimestampFilter.getOutputPort(), stopTimestampFilter.getInputPort()); + pipe = pipeFactory.create(ThreadCommunication.INTRA); + pipe.connectPorts(stopTimestampFilter.getOutputPort(), sink.getInputPort()); + + /* + * requirements: + * <ul> + * <li>when selecting a stage class to create one instance, the user is prompted to declare each type argument + * <li> + * </ul> + */ + + TypeVariable<Class<ObjectProducer>>[] objectProducerTypeParameters = ObjectProducer.class.getTypeParameters(); + for (TypeVariable<Class<ObjectProducer>> typeVariable : objectProducerTypeParameters) { + System.out.println(typeVariable.getBounds()); // ->[Ljava.lang.reflect.Type;@13a65d1f + System.out.println(typeVariable.getBounds().length); // ->1 + System.out.println(typeVariable.getBounds()[0]); // ->class java.lang.Object + System.out.println(typeVariable.getName()); // ->T + System.out.println(typeVariable.getClass()); // ->class sun.reflect.generics.reflectiveObjects.TypeVariableImpl + System.out.println(typeVariable.getGenericDeclaration()); // ->class teetime.variant.methodcallWithPorts.stage.ObjectProducer + } + + // TypeVariable<?>[] objectProducerOutputPortTypeParameters = objectProducer.getOutputPort().getClass().getTypeParameters(); + // for (TypeVariable<?> typeVariable : objectProducerOutputPortTypeParameters) { + // System.out.println(typeVariable.getBounds()); // ->[Ljava.lang.reflect.Type;@20a12d8f + // System.out.println(typeVariable.getBounds().length); // ->1 + // System.out.println(typeVariable.getBounds()[0]); // ->class java.lang.Object + // System.out.println(typeVariable.getName()); // ->T + // System.out.println(typeVariable.getClass()); // ->class sun.reflect.generics.reflectiveObjects.TypeVariableImpl + // System.out.println(typeVariable.getGenericDeclaration()); // ->class teetime.variant.methodcallWithPorts.framework.core.OutputPort + // } + // + // TypeVariable<?>[] startTimestampFilterOutputPortTypeParameters = startTimestampFilter.getOutputPort().getClass().getTypeParameters(); + // for (TypeVariable<?> typeVariable : startTimestampFilterOutputPortTypeParameters) { + // System.out.println(typeVariable.getBounds()); // ->[Ljava.lang.reflect.Type;@7b365f02 + // System.out.println(typeVariable.getBounds().length); // ->1 + // System.out.println(typeVariable.getBounds()[0]); // ->class java.lang.Object + // System.out.println(typeVariable.getName()); // ->T + // System.out.println(typeVariable.getClass()); // ->class sun.reflect.generics.reflectiveObjects.TypeVariableImpl + // System.out.println(typeVariable.getGenericDeclaration()); // ->class teetime.variant.methodcallWithPorts.framework.core.OutputPort + // } + + Class<?> currentClass = objectProducer.getClass(); + while (currentClass.getSuperclass() != null) { // we don't want to process Object.class + Field[] fields = currentClass.getDeclaredFields(); + for (Field field : fields) { + // System.out.println("Field: " + field.getType()); + if (OutputPort.class.equals(field.getType())) { + System.out.println("Field.name: " + field.getName()); + System.out.println("Field.type: " + field.getType()); + // field.getType() + } + } + + currentClass = currentClass.getSuperclass(); + } + + System.out.println(objectProducer.getOutputPort().getType()); + PortTypeConfiguration.setPortTypes(objectProducer, Class.forName("teetime.variant.explicitScheduling.examples.throughput.TimestampObject")); + System.out.println(objectProducer.getOutputPort().getType()); + } +} diff --git a/submodules/JCTools b/submodules/JCTools index 88e1e25f9519b250258c7e5ada30935975ab2d10..75998aa20b7ec897ec321c1f94192de888f2dc6e 160000 --- a/submodules/JCTools +++ b/submodules/JCTools @@ -1 +1 @@ -Subproject commit 88e1e25f9519b250258c7e5ada30935975ab2d10 +Subproject commit 75998aa20b7ec897ec321c1f94192de888f2dc6e