org.jevis.jecalc.CalcJobFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.jevis.jecalc.CalcJobFactory.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.jevis.jecalc;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.logging.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jevis.api.JEVisAttribute;
import org.jevis.api.JEVisClass;
import org.jevis.api.JEVisDataSource;
import org.jevis.api.JEVisException;
import org.jevis.api.JEVisObject;
import org.jevis.api.JEVisSample;
import org.jevis.commons.cli.JEVisServerConnectionCLI;
import org.jevis.commons.database.SampleHandler;
import org.jevis.commons.object.plugin.TargetHelper;
import org.jevis.jeapi.ws.JEVisDataSourceWS;
import org.jevis.jecalc.calculation.SampleMerger.InputType;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;

/**
 *
 * @author broder
 */
class CalcJobFactory {

    private final Stack<JEVisObject> calcObjectStack = new Stack<>();;
    private JEVisDataSource jevisDataSource;
    private final Logger logger = LogManager.getLogger(CalcJobFactory.class);
    private final SampleHandler sampleHandler;

    CalcJobFactory(CalcMode calcMode, String configPath) {
        sampleHandler = new SampleHandler();
        boolean establishConnection = establishConnection(configPath);
        if (!establishConnection) {
            logger.error("Cant connect to the JEVis Service, will terminate");
            System.exit(1);
        }

        addCalculationJobs(calcMode);

    }

    boolean hasNextJob() {
        return !calcObjectStack.isEmpty();
    }

    CalcJob getCurrentCalcJob(SampleHandler sampleHandler) {
        JEVisObject jevisObject = calcObjectStack.pop();

        logger.info("-------------------------------------------");
        logger.info("Create calc job for object with jevis id {}", jevisObject.getID());
        sampleHandler.getLastSample(jevisObject, Calculation.EXPRESSION.getName());
        String expression = sampleHandler.getLastSampleAsString(jevisObject, Calculation.EXPRESSION.getName());

        List<JEVisAttribute> outputAttributes = getAllOutputAttributes(jevisObject);
        logger.debug("{} outputs found", outputAttributes.size());

        DateTime startTime = getStartTimeFromOutputs(outputAttributes);
        logger.debug("start time is", startTime.toString(DateTimeFormat.fullDateTime()));

        List<CalcObject> calcObjects = getInputDataObjects(jevisObject, startTime);
        logger.debug("{} inputs found", calcObjects.size());

        CalcJob calcJob = new CalcJob(calcObjects, expression, outputAttributes);

        return calcJob;
    }

    private List<JEVisObject> getCalcObjects() {
        List<JEVisObject> jevisObjects = new ArrayList<>();
        try {
            JEVisClass calcClass = jevisDataSource.getJEVisClass("Calculation");
            jevisObjects = jevisDataSource.getObjects(calcClass, false);
        } catch (JEVisException ex) {
            logger.error(ex);
        }
        return jevisObjects;
    }

    private boolean establishConnection(String configFile) {
        JEVisServerConnectionCLI con = new JEVisServerConnectionCLI(configFile);
        try {
            //            jevisDataSource = new JEVisDataSourceSQL("openjevis.org", "13306", "jevis", "jevis", "jevistest");
            //            return jevisDataSource.connect("Sys Admin", "OpenJEVis2016");
            //            jevisDataSource = new JEVisDataSourceSQL(con.getDb(), con.getPort(), con.getSchema(), con.getUser(), con.getPw());
            jevisDataSource = new JEVisDataSourceWS("http://" + con.getDb() + ":" + con.getPort());
            return jevisDataSource.connect(con.getJevisUser(), con.getJevisPW());
        } catch (JEVisException ex) {
            logger.error("No Connection to database", ex);
        }
        return false;
    }

    private List<JEVisAttribute> getAllOutputAttributes(JEVisObject jevisObject) {
        List<JEVisAttribute> outputAttributes = new ArrayList<>();
        try {
            JEVisClass outputClass = jevisObject.getDataSource().getJEVisClass(Calculation.OUTPUT_DATA.getName());
            List<JEVisObject> outputs = jevisObject.getChildren(outputClass, false);
            for (JEVisObject output : outputs) {
                JEVisAttribute targetAttr = output.getAttribute(Calculation.OUTPUT_DATA.getName());
                TargetHelper targetHelper = new TargetHelper(output.getDataSource(), targetAttr);
                JEVisAttribute valueAttribute = targetHelper.getAttribute();
                if (valueAttribute == null) {
                    logger.error("Cant find output for id {}", output.getID());
                } else {
                    outputAttributes.add(valueAttribute);
                }
            }
        } catch (JEVisException ex) {
            java.util.logging.Logger.getLogger(CalcJobFactory.class.getName()).log(java.util.logging.Level.SEVERE,
                    null, ex);
        }
        return outputAttributes;
    }

    private DateTime getStartTimeFromOutputs(List<JEVisAttribute> outputAttributes) {
        DateTime startTime = null;
        for (JEVisAttribute valueAttribute : outputAttributes) {
            //if a attribute is without date -> start whole calculation
            if (valueAttribute != null && valueAttribute.getTimestampFromLastSample() == null) {
                startTime = new DateTime(0);
                break;
            }

            //else take the earliest last timestamp
            if (startTime == null || startTime.isAfter(valueAttribute.getTimestampFromLastSample())) {
                startTime = valueAttribute.getTimestampFromLastSample().plusMillis(1);
            }
        }
        if (startTime == null) {
            throw new IllegalStateException("Cant calculate a start date");
        }
        return startTime;
    }

    private List<CalcObject> getInputDataObjects(JEVisObject jevisObject, DateTime startTime) {
        List<CalcObject> calcObjects = new ArrayList<>();
        try {
            JEVisClass inputClass = jevisObject.getDataSource().getJEVisClass(Calculation.INPUT.getName());
            List<JEVisObject> inputDataObjects = jevisObject.getChildren(inputClass, false);
            for (JEVisObject child : inputDataObjects) { //Todo differenciate based on input type
                JEVisAttribute targetAttr = child.getAttribute(Calculation.INPUT_DATA.getName());
                TargetHelper targetHelper = new TargetHelper(jevisDataSource, targetAttr);
                JEVisAttribute valueAttribute = targetHelper.getAttribute();

                if (valueAttribute == null) {
                    throw new IllegalStateException(
                            "Cant find valid values for input data with id " + child.getID());
                }

                String identifier = child.getAttribute(Calculation.IDENTIFIER.getName()).getLatestSample()
                        .getValueAsString();
                String inputTypeString = child.getAttribute(Calculation.INPUT_TYPE.getName()).getLatestSample()
                        .getValueAsString();
                InputType inputType = InputType.valueOf(inputTypeString);
                List<JEVisSample> samples = getSamplesFromInputType(valueAttribute, inputType, startTime);
                CalcObject calcObject = new CalcObject(samples, identifier, inputType);
                calcObjects.add(calcObject);
            }
        } catch (JEVisException ex) {
            java.util.logging.Logger.getLogger(CalcJobFactory.class.getName()).log(java.util.logging.Level.SEVERE,
                    null, ex);
        }
        return calcObjects;
    }

    private void addCalculationJobs(CalcMode calcMode) {
        if (calcMode == CalcMode.ALL) {
            List<JEVisObject> jevisCalcObjects = getCalcObjects();
            logger.info("{} calc jobs found", jevisCalcObjects.size());
            List<JEVisObject> filterForEnabledCalcObjects = getEnabledCalcJobs(jevisCalcObjects);
            logger.info("{} enabled calc jobs found", filterForEnabledCalcObjects.size());
            calcObjectStack.addAll(filterForEnabledCalcObjects);
        } else if (calcMode == CalcMode.SINGLE) {
            Long singleObject = CommandLineParser.getInstance().getSingleObject();
            try {
                JEVisObject calcObject = jevisDataSource.getObject(singleObject);
                calcObjectStack.add(calcObject);
            } catch (JEVisException ex) {
                java.util.logging.Logger.getLogger(CalcJobFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private List<JEVisSample> getSamplesFromInputType(JEVisAttribute valueAttribute, InputType inputType,
            DateTime startTime) {
        List<JEVisSample> returnSamples = new ArrayList<>();
        switch (inputType) {
        case PERIODIC:
            returnSamples = valueAttribute.getSamples(startTime, new DateTime());
            break;
        case STATIC:
            JEVisSample constant = valueAttribute.getLatestSample();
            if (constant != null) {
                returnSamples.add(constant);
            } else {
                throw new IllegalArgumentException(
                        "Constant with id " + valueAttribute.getObject().getID() + " has no value");
            }
            break;
        case NON_PERIODIC:
            returnSamples = valueAttribute.getAllSamples();
            break;
        }
        return returnSamples;
    }

    private List<JEVisObject> getEnabledCalcJobs(List<JEVisObject> jevisCalcObjects) {
        List<JEVisObject> enabledObjects = new ArrayList<>();
        for (JEVisObject curObj : jevisCalcObjects) {
            Boolean valueAsBoolean = sampleHandler.getLastSampleAsBoolean(curObj, Calculation.ENABLED.getName(),
                    false);
            if (valueAsBoolean) {
                enabledObjects.add(curObj);
            }
        }
        return enabledObjects;
    }

    public enum CalcMode {

        ALL, SINGLE;
    }

    public enum Calculation {

        CLASS("Calculation"), EXPRESSION("Expression"), ENABLED("Enabled"), INPUT("Input"), INPUT_DATA(
                "Input Data"), OUTPUT_DATA("Output"), IDENTIFIER("Identifier"), INPUT_TYPE("Input Data Type");

        String name;

        private Calculation(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

}