All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.algorithmia.development.Handler Maven / Gradle / Ivy

There is a newer version: 2.0.2
Show newest version
package com.algorithmia.development;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;


public class Handler {

    private ReflectionHelper.DebuggableBifunction applyWState;
    private ReflectionHelper.DebuggableFunction apply;
    private Supplier loadFunc;

    private STATE state;
    private RequestHandler in;
    private ResponseHandler out = new ResponseHandler();


    public Handler(Class algorithmClass, ReflectionHelper.DebuggableBifunction applyWState, Supplier loadFunc) {
        this.applyWState = applyWState;
        this.loadFunc = loadFunc;
        Class inputClass = getInputClass(algorithmClass);
        this.in = new RequestHandler<>(inputClass);
    }

    public Handler(Class algorithmClass, ReflectionHelper.DebuggableBifunction applyWState) {
        this.applyWState = applyWState;
        Class inputClass = getInputClass(algorithmClass);
        this.in = new RequestHandler<>(inputClass);
    }

    public Handler(Class algorithmClass, ReflectionHelper.DebuggableFunction apply) {
        this.apply = apply;
        Class inputClass = getInputClass(algorithmClass);
        this.in = new RequestHandler<>(inputClass);
    }

    private void load() {
        if (this.loadFunc != null) {
            state = this.loadFunc.get();
            System.out.println("PIPE_INIT_COMPLETE");
            System.out.flush();
        }
    }

    private void executeWithoutState(Function func, Stream buffer) {

        buffer.forEach((line) -> {
            INPUT input = in.processRequest(line);
            OUTPUT output = func.apply(input);
            out.writeToPipe(output);
        });
    }

    private void executeWithState(BiFunction func, Stream buffer) {
        buffer.forEach((line) -> {
            INPUT input = in.processRequest(line);
            OUTPUT output = func.apply(input, state);
            out.writeToPipe(output);
        });
    }

    private void execute() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Stream buffer = reader.lines();
        if (this.applyWState != null && this.loadFunc != null) {
            load();
            executeWithState(this.applyWState, buffer);
        } else if (this.apply != null) {
            executeWithoutState(this.apply, buffer);
        } else {
            throw new RuntimeException("If using an load function with state, a load function must be defined as well.");
        }
    }

    private Class getInputClass(Class algoClass) {
        String methodName;
        if (this.applyWState != null) {
            methodName = ReflectionHelper.getMethodName(this.applyWState);
        } else if (this.apply != null) {
            methodName = ReflectionHelper.getMethodName(this.apply);
        } else {
            throw new RuntimeException("Either Apply(INPUT t) or Apply(INPUT t STATE s) must be defined.");
        }
        Method[] methods = algoClass.getMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] parameters = method.getParameterTypes();
                return (Class) parameters[0];
            }
        }
        throw new RuntimeException("Unable to find the 'public' method reference called " + methodName + " in the provided class.");
    }

    public void setLoad(Supplier func) {
        loadFunc = func;
    }

    public void serve() {
        try {
            execute();
        } catch (RuntimeException e) {
            out.writeErrorToPipe(e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy