edu.stanford.slac.archiverappliance.PB.data.BoundaryConditionsSimulationValueGenerator.java Source code

Java tutorial

Introduction

Here is the source code for edu.stanford.slac.archiverappliance.PB.data.BoundaryConditionsSimulationValueGenerator.java

Source

/*******************************************************************************
 * Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University
 * as Operator of the SLAC National Accelerator Laboratory.
 * Copyright (c) 2011 Brookhaven National Laboratory.
 * EPICS archiver appliance is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution.
 *******************************************************************************/
package edu.stanford.slac.archiverappliance.PB.data;

import java.nio.ByteBuffer;
import java.util.Collections;

import org.apache.commons.lang3.ArrayUtils;
import org.epics.archiverappliance.common.TimeUtils;
import org.epics.archiverappliance.config.ArchDBRTypes;
import org.epics.archiverappliance.data.ByteBufSampleValue;
import org.epics.archiverappliance.data.SampleValue;
import org.epics.archiverappliance.data.ScalarStringSampleValue;
import org.epics.archiverappliance.data.ScalarValue;
import org.epics.archiverappliance.data.VectorStringSampleValue;
import org.epics.archiverappliance.data.VectorValue;
import org.epics.archiverappliance.utils.simulation.SimulationValueGenerator;

import gov.aps.jca.dbr.DBR;
import gov.aps.jca.dbr.DBR_TIME_Byte;
import gov.aps.jca.dbr.DBR_TIME_Double;
import gov.aps.jca.dbr.DBR_TIME_Enum;
import gov.aps.jca.dbr.DBR_TIME_Float;
import gov.aps.jca.dbr.DBR_TIME_Int;
import gov.aps.jca.dbr.DBR_TIME_Short;
import gov.aps.jca.dbr.DBR_TIME_String;

/**
 * Generates a sample value based on secondsintoyear for each DBR_type. 
 * The value generated is predictable; therefore, it can be used for unit tests. 
 * @author mshankar
 *
 */
public class BoundaryConditionsSimulationValueGenerator implements SimulationValueGenerator {

    /**
     * Get a value based on the DBR type. 
     * We should check for boundary conditions here and make sure PB does not throw exceptions when we come close to MIN_ and MAX_ values 
     * @param type
     * @param secondsIntoYear
     * @return
     */
    public SampleValue getSampleValue(ArchDBRTypes type, int secondsIntoYear) {
        switch (type) {
        case DBR_SCALAR_STRING:
            return new ScalarStringSampleValue(Integer.toString(secondsIntoYear));
        case DBR_SCALAR_SHORT:
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                return new ScalarValue<Short>((short) (Short.MIN_VALUE + secondsIntoYear));
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                return new ScalarValue<Short>((short) (Short.MAX_VALUE - (secondsIntoYear - 1000)));
            } else {
                // Check for some numbers around 0
                return new ScalarValue<Short>((short) (secondsIntoYear - 2000));
            }
        case DBR_SCALAR_FLOAT:
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                return new ScalarValue<Float>(Float.MIN_VALUE + secondsIntoYear);
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                return new ScalarValue<Float>(Float.MAX_VALUE - (secondsIntoYear - 1000));
            } else {
                // Check for some numbers around 0. Divide by a large number to make sure we cater to the number of precision digits
                return new ScalarValue<Float>((secondsIntoYear - 2000.0f) / secondsIntoYear);
            }
        case DBR_SCALAR_ENUM:
            return new ScalarValue<Short>((short) secondsIntoYear);
        case DBR_SCALAR_BYTE:
            return new ScalarValue<Byte>(((byte) (secondsIntoYear % 255)));
        case DBR_SCALAR_INT:
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                return new ScalarValue<Integer>(Integer.MIN_VALUE + secondsIntoYear);
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                return new ScalarValue<Integer>(Integer.MAX_VALUE - (secondsIntoYear - 1000));
            } else {
                // Check for some numbers around 0
                return new ScalarValue<Integer>(secondsIntoYear - 2000);
            }
        case DBR_SCALAR_DOUBLE:
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                return new ScalarValue<Double>(Double.MIN_VALUE + secondsIntoYear);
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                return new ScalarValue<Double>(Double.MAX_VALUE - (secondsIntoYear - 1000));
            } else {
                // Check for some numbers around 0. Divide by a large number to make sure we cater to the number of precision digits
                return new ScalarValue<Double>((secondsIntoYear - 2000.0) / (secondsIntoYear * 1000000));
            }
        case DBR_WAVEFORM_STRING:
            // Varying number of copies of a typical value
            return new VectorStringSampleValue(
                    Collections.nCopies(secondsIntoYear, Integer.toString(secondsIntoYear)));
        case DBR_WAVEFORM_SHORT:
            return new VectorValue<Short>(Collections.nCopies(1, (short) secondsIntoYear));
        case DBR_WAVEFORM_FLOAT:
            // Varying number of copies of a typical value
            return new VectorValue<Float>(
                    Collections.nCopies(secondsIntoYear, (float) Math.cos(secondsIntoYear * Math.PI / 3600)));
        case DBR_WAVEFORM_ENUM:
            return new VectorValue<Short>(Collections.nCopies(1024, (short) secondsIntoYear));
        case DBR_WAVEFORM_BYTE:
            // Large number of elements in the array
            return new VectorValue<Byte>(
                    Collections.nCopies(65536 * secondsIntoYear, ((byte) (secondsIntoYear % 255))));
        case DBR_WAVEFORM_INT:
            // Varying number of copies of a typical value
            return new VectorValue<Integer>(
                    Collections.nCopies(secondsIntoYear, secondsIntoYear * secondsIntoYear));
        case DBR_WAVEFORM_DOUBLE:
            // Varying number of copies of a typical value
            return new VectorValue<Double>(
                    Collections.nCopies(secondsIntoYear, Math.sin(secondsIntoYear * Math.PI / 3600)));
        case DBR_V4_GENERIC_BYTES:
            // Varying number of copies of a typical value
            ByteBuffer buf = ByteBuffer.allocate(1024 * 10);
            buf.put(Integer.toString(secondsIntoYear).getBytes());
            buf.flip();
            return new ByteBufSampleValue(buf);
        default:
            throw new RuntimeException("We seemed to have missed a DBR type when generating sample data");
        }
    }

    public int getNumberOfSamples(ArchDBRTypes type) {
        switch (type) {
        case DBR_SCALAR_STRING:
            return 10000;
        case DBR_SCALAR_SHORT:
            return 4000;
        case DBR_SCALAR_FLOAT:
            return 4000;
        case DBR_SCALAR_ENUM:
            return 10;
        case DBR_SCALAR_BYTE:
            return 255;
        case DBR_SCALAR_INT:
            return 4000;
        case DBR_SCALAR_DOUBLE:
            return 4000;
        case DBR_WAVEFORM_STRING:
            return 10;
        case DBR_WAVEFORM_SHORT:
            return 4000;
        case DBR_WAVEFORM_FLOAT:
            return 4000;
        case DBR_WAVEFORM_ENUM:
            return 10;
        case DBR_WAVEFORM_BYTE:
            return 16;
        case DBR_WAVEFORM_INT:
            return 4000;
        case DBR_WAVEFORM_DOUBLE:
            return 4000;
        case DBR_V4_GENERIC_BYTES:
            return 1000;
        default:
            return 24 * 60 * 60;
        }
    }

    public DBR getJCASampleValue(ArchDBRTypes type, int secondsIntoYear) {
        switch (type) {
        case DBR_SCALAR_STRING:
            DBR_TIME_String retvalss = new DBR_TIME_String(new String[] { Integer.toString(secondsIntoYear) });
            retvalss.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvalss.setSeverity(1);
            retvalss.setStatus(0);
            return retvalss;
        case DBR_SCALAR_SHORT:
            DBR_TIME_Short retvalsh;
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                retvalsh = new DBR_TIME_Short(new short[] { (short) (Short.MIN_VALUE + secondsIntoYear) });
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                retvalsh = new DBR_TIME_Short(new short[] { (short) (Short.MAX_VALUE - (secondsIntoYear - 1000)) });
            } else {
                // Check for some numbers around 0
                retvalsh = new DBR_TIME_Short(new short[] { (short) (secondsIntoYear - 2000) });
            }
            retvalsh.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvalsh.setSeverity(1);
            retvalsh.setStatus(0);
            return retvalsh;
        case DBR_SCALAR_FLOAT:
            DBR_TIME_Float retvalfl;
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                retvalfl = new DBR_TIME_Float(new float[] { Float.MIN_VALUE + secondsIntoYear });
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                retvalfl = new DBR_TIME_Float(new float[] { Float.MAX_VALUE - (secondsIntoYear - 1000) });
            } else {
                // Check for some numbers around 0. Divide by a large number to make sure we cater to the number of precision digits
                retvalfl = new DBR_TIME_Float(new float[] { (secondsIntoYear - 2000.0f) / secondsIntoYear });
            }
            retvalfl.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvalfl.setSeverity(1);
            retvalfl.setStatus(0);
            return retvalfl;
        case DBR_SCALAR_ENUM:
            DBR_TIME_Enum retvalen;
            retvalen = new DBR_TIME_Enum(new short[] { (short) (secondsIntoYear) });
            retvalen.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvalen.setSeverity(1);
            retvalen.setStatus(0);
            return retvalen;
        case DBR_SCALAR_BYTE:
            DBR_TIME_Byte retvalby;
            retvalby = new DBR_TIME_Byte(new byte[] { ((byte) (secondsIntoYear % 255)) });
            retvalby.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvalby.setSeverity(1);
            retvalby.setStatus(0);
            return retvalby;
        case DBR_SCALAR_INT:
            DBR_TIME_Int retvalint;
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                retvalint = new DBR_TIME_Int(new int[] { Integer.MIN_VALUE + secondsIntoYear });
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                retvalint = new DBR_TIME_Int(new int[] { Integer.MAX_VALUE - (secondsIntoYear - 1000) });
            } else {
                // Check for some numbers around 0
                retvalint = new DBR_TIME_Int(new int[] { (secondsIntoYear - 2000) });
            }
            retvalint.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvalint.setSeverity(1);
            retvalint.setStatus(0);
            return retvalint;
        case DBR_SCALAR_DOUBLE:
            DBR_TIME_Double retvaldb;
            if (0 <= secondsIntoYear && secondsIntoYear < 1000) {
                // Check for some numbers around the minimum value
                retvaldb = new DBR_TIME_Double(new double[] { (Double.MIN_VALUE + secondsIntoYear) });
            } else if (1000 <= secondsIntoYear && secondsIntoYear < 2000) {
                // Check for some numbers around the maximum value
                retvaldb = new DBR_TIME_Double(new double[] { (Double.MAX_VALUE - (secondsIntoYear - 1000)) });
            } else {
                // Check for some numbers around 0. Divide by a large number to make sure we cater to the number of precision digits
                retvaldb = new DBR_TIME_Double(
                        new double[] { ((secondsIntoYear - 2000.0) / (secondsIntoYear * 1000000)) });
            }
            retvaldb.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvaldb.setSeverity(1);
            retvaldb.setStatus(0);
            return retvaldb;
        case DBR_WAVEFORM_STRING:
            DBR_TIME_String retvst;
            // Varying number of copies of a typical value
            retvst = new DBR_TIME_String(
                    Collections.nCopies(secondsIntoYear, Integer.toString(secondsIntoYear)).toArray(new String[0]));
            retvst.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvst.setSeverity(1);
            retvst.setStatus(0);
            return retvst;
        case DBR_WAVEFORM_SHORT:
            DBR_TIME_Short retvsh;
            retvsh = new DBR_TIME_Short(
                    ArrayUtils.toPrimitive(Collections.nCopies(1, (short) secondsIntoYear).toArray(new Short[0])));
            retvsh.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvsh.setSeverity(1);
            retvsh.setStatus(0);
            return retvsh;
        case DBR_WAVEFORM_FLOAT:
            DBR_TIME_Float retvf;
            // Varying number of copies of a typical value
            retvf = new DBR_TIME_Float(ArrayUtils.toPrimitive(
                    Collections.nCopies(secondsIntoYear, (float) Math.cos(secondsIntoYear * Math.PI / 3600))
                            .toArray(new Float[0])));
            retvf.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvf.setSeverity(1);
            retvf.setStatus(0);
            return retvf;
        case DBR_WAVEFORM_ENUM:
            DBR_TIME_Enum retven;
            retven = new DBR_TIME_Enum(ArrayUtils
                    .toPrimitive(Collections.nCopies(1024, (short) secondsIntoYear).toArray(new Short[0])));
            retven.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retven.setSeverity(1);
            retven.setStatus(0);
            return retven;
        case DBR_WAVEFORM_BYTE:
            DBR_TIME_Byte retvb;
            // Large number of elements in the array
            retvb = new DBR_TIME_Byte(ArrayUtils.toPrimitive(Collections
                    .nCopies(65536 * secondsIntoYear, ((byte) (secondsIntoYear % 255))).toArray(new Byte[0])));
            retvb.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvb.setSeverity(1);
            retvb.setStatus(0);
            return retvb;
        case DBR_WAVEFORM_INT:
            DBR_TIME_Int retvint;
            // Varying number of copies of a typical value
            retvint = new DBR_TIME_Int(ArrayUtils.toPrimitive(Collections
                    .nCopies(secondsIntoYear, secondsIntoYear * secondsIntoYear).toArray(new Integer[0])));
            retvint.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvint.setSeverity(1);
            retvint.setStatus(0);
            return retvint;
        case DBR_WAVEFORM_DOUBLE:
            DBR_TIME_Double retvd;
            // Varying number of copies of a typical value
            retvd = new DBR_TIME_Double(ArrayUtils.toPrimitive(Collections
                    .nCopies(secondsIntoYear, Math.sin(secondsIntoYear * Math.PI / 3600)).toArray(new Double[0])));
            retvd.setTimeStamp(convertSecondsIntoYear2JCATimeStamp(secondsIntoYear));
            retvd.setSeverity(1);
            retvd.setStatus(0);
            return retvd;
        case DBR_V4_GENERIC_BYTES:
            throw new RuntimeException("Currently don't support " + type + " when generating sample data");
        default:
            throw new RuntimeException("We seemed to have missed a DBR type when generating sample data");
        }
    }

    private static gov.aps.jca.dbr.TimeStamp convertSecondsIntoYear2JCATimeStamp(int secondsintoYear) {
        return new gov.aps.jca.dbr.TimeStamp(TimeUtils.getStartOfCurrentYearInSeconds() + secondsintoYear);
    }
}