package com.zillabyte.motherbrain.flow.operations.multilang.builder; import com.zillabyte.motherbrain.flow.App; import com.zillabyte.motherbrain.flow.Component; import com.zillabyte.motherbrain.flow.Flow; import com.zillabyte.motherbrain.flow.FlowCompilationException; import com.zillabyte.motherbrain.flow.components.ComponentInput; import com.zillabyte.motherbrain.flow.components.ComponentOutput; import com.zillabyte.motherbrain.flow.operations.Operation; import com.zillabyte.motherbrain.flow.operations.Sink; import com.zillabyte.motherbrain.flow.operations.Source; public class FlowValidator { public static void validateComponent(Component flow) throws FlowCompilationException{ validateNotEmpty(flow); validateTotallySunk(flow); } public static void validateApp(App flow) throws FlowCompilationException { validateNotEmpty(flow); validateTotallySunk(flow); } public static void validateNotEmpty(Flow flow) throws FlowCompilationException { if (flow.getOperations().size() == 0) { throw (FlowCompilationException) new FlowCompilationException().setAllMessages("The app does not declare any operations."); } } public static void validateTotallySunk(Component flow) throws FlowCompilationException { // Init int sources = 0; for(Operation op : flow.getOperations()) { // An unsunk branch is simply an operation that doesn't have any successors, and is not a sink, or a join if (op.nextOperations().size() == 0 && op instanceof ComponentOutput == false) { throw (FlowCompilationException) new FlowCompilationException().setAllMessages("The stream originating from '" + op.namespaceName() + "' does not end in an output. All streams must end in output."); } if (op instanceof ComponentInput) { sources++; } if (op instanceof Source) { sources++; } } if (sources == 0) { throw (FlowCompilationException) new FlowCompilationException().setAllMessages("The component does not declare any sources."); } } public static void validateTotallySunk(App flow) throws FlowCompilationException { // Init int sources = 0; for(Operation op : flow.getOperations()) { // An unsunk branch is simply an operation that doesn't have any successors, and is // not a sink, or a join if (op.nextOperations().size() == 0 && op instanceof Sink == false) { throw (FlowCompilationException) new FlowCompilationException().setAllMessages("The stream originating from " + op.namespaceName() + " does not end in a sink. All streams must be sunk."); } if (op instanceof Source) { sources++; } } if (sources == 0) { throw (FlowCompilationException) new FlowCompilationException().setAllMessages("The app does not declare any sources."); } } public void validate(Flow flow) throws FlowCompilationException { if (flow instanceof App) { validateApp((App) flow); } else { validateComponent((Component) flow); } } }