/******************************************************************************* * 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 org.epics.archiverappliance.utils.imprt; import java.io.IOException; import java.io.StringWriter; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import org.epics.archiverappliance.ByteArray; import org.epics.archiverappliance.Event; import org.epics.archiverappliance.common.TimeUtils; import org.epics.archiverappliance.config.ArchDBRTypes; import org.epics.archiverappliance.data.DBRTimeEvent; 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; /** * * @author mshankar * */ public class CSVEvent implements DBRTimeEvent { Timestamp timestamp; int status; int severity; SampleValue sampleValue; private ArchDBRTypes type; public CSVEvent(String[] line, ArchDBRTypes type) throws Exception { this.type = type; // This line is of this format epochseconds, nanos, value, status, severity // Example: 1301986801,446452000,5.55269,0,0 // Waveforms are pipe escaped.... if(line == null || line.length < 5) throw new Exception("We need at least five columns in the CSV - epochseconds, nanos, value, status, severity. Example: - 1301986801,446452000,5.55269,0,0"); // Per Bob, the epochseconds here is EPICS epoch seconds. We need to convert to Java epoch seconds; so we add the offset. long epochSeconds = Long.parseLong(line[0]) + TimeUtils.EPICS_EPOCH_2_JAVA_EPOCH_OFFSET; int nanos = Integer.parseInt(line[1]); timestamp = TimeUtils.convertFromEpochSeconds(epochSeconds, nanos); String valueStr = line[2]; String[] vectorValueStr = valueStr.split("\\|"); status = Integer.parseInt(line[3]); severity = Integer.parseInt(line[4]); switch(type) { case DBR_SCALAR_STRING: sampleValue = new ScalarStringSampleValue(valueStr); break; case DBR_SCALAR_SHORT: sampleValue = new ScalarValue<Short>(new Short(valueStr)); break; case DBR_SCALAR_FLOAT: sampleValue = new ScalarValue<Float>(new Float(valueStr)); break; case DBR_SCALAR_ENUM: sampleValue = new ScalarValue<Short>(new Short(valueStr)); break; case DBR_SCALAR_BYTE: sampleValue = new ScalarValue<Byte>(new Byte(valueStr)); break; case DBR_SCALAR_INT: sampleValue = new ScalarValue<Integer>(new Integer(valueStr)); break; case DBR_SCALAR_DOUBLE: sampleValue = new ScalarValue<Double>(new Double(valueStr)); break; case DBR_WAVEFORM_STRING: if(valueStr.equals("")) { sampleValue = new VectorStringSampleValue(Arrays.asList(new String[0])); } else { sampleValue = new VectorStringSampleValue(Arrays.asList(vectorValueStr)); } break; case DBR_WAVEFORM_SHORT: { if(valueStr.equals("")) { sampleValue = new VectorValue<Short>(Arrays.asList(new Short[0])); } else { ArrayList<Short> vals = new ArrayList<Short>(vectorValueStr.length); for(String val : vectorValueStr) { vals.add(new Short(val)); } sampleValue = new VectorValue<Short>(vals); } } break; case DBR_WAVEFORM_FLOAT: { if(valueStr.equals("")) { sampleValue = new VectorValue<Float>(Arrays.asList(new Float[0])); } else { ArrayList<Float> vals = new ArrayList<Float>(vectorValueStr.length); for(String val : vectorValueStr) { vals.add(new Float(val)); } sampleValue = new VectorValue<Float>(vals); } } break; case DBR_WAVEFORM_ENUM: { if(valueStr.equals("")) { sampleValue = new VectorValue<Short>(Arrays.asList(new Short[0])); } else { ArrayList<Short> vals = new ArrayList<Short>(vectorValueStr.length); for(String val : vectorValueStr) { vals.add(new Short(val)); } sampleValue = new VectorValue<Short>(vals); } } break; case DBR_WAVEFORM_BYTE: { if(valueStr.equals("")) { sampleValue = new VectorValue<Byte>(Arrays.asList(new Byte[0])); } else { ArrayList<Byte> vals = new ArrayList<Byte>(vectorValueStr.length); for(String val : vectorValueStr) { vals.add(new Byte(val)); } sampleValue = new VectorValue<Byte>(vals); } } break; case DBR_WAVEFORM_INT: { if(valueStr.equals("")) { sampleValue = new VectorValue<Integer>(Arrays.asList(new Integer[0])); } else { ArrayList<Integer> vals = new ArrayList<Integer>(vectorValueStr.length); for(String val : vectorValueStr) { vals.add(new Integer(val)); } sampleValue = new VectorValue<Integer>(vals); } } break; case DBR_WAVEFORM_DOUBLE: { if(valueStr.equals("")) { sampleValue = new VectorValue<Double>(Arrays.asList(new Double[0])); } else { ArrayList<Double> vals = new ArrayList<Double>(vectorValueStr.length); for(String val : vectorValueStr) { vals.add(new Double(val)); } sampleValue = new VectorValue<Double>(vals); } } break; case DBR_V4_GENERIC_BYTES: sampleValue = new ScalarStringSampleValue(valueStr); break; default: throw new Exception("Unsupported DBR type in swicth statement " + type.toString()); } assert(sampleValue != null); } public CSVEvent(CSVEvent src) { super(); this.timestamp = src.timestamp; this.status = src.status; this.severity = src.severity; this.sampleValue = src.sampleValue; } @Override public Event makeClone() { return new CSVEvent(this); } @Override public int getStatus() { return status; } @Override public int getSeverity() { return severity; } @Override public int getRepeatCount() { return 0; } @Override public void setRepeatCount(int repeatCount) { return; } @Override public Timestamp getEventTimeStamp() { return timestamp; } @Override public long getEpochSeconds() { return TimeUtils.convertToEpochSeconds(timestamp); } @Override public ByteArray getRawForm() { throw new UnsupportedOperationException("Not supported. Convert to a PB form if you want to use this."); } @Override public SampleValue getSampleValue() { return sampleValue; } @Override public boolean hasFieldValues() { return false; } @Override public boolean isActualChange() { return false; } @Override public HashMap<String, String> getFields() { throw new UnsupportedOperationException("Not supported. Convert to a PB form if you want to use this."); } @Override public String getFieldValue(String fieldName) { throw new UnsupportedOperationException("Not supported. Convert to a PB form if you want to use this."); } @Override public void addFieldValue(String fieldName, String fieldValue) { throw new UnsupportedOperationException("Not supported. Convert to a PB form if you want to use this."); } @Override public void markAsActualChange() { throw new UnsupportedOperationException("Not supported. Convert to a PB form if you want to use this."); } @Override public void setFieldValues(HashMap<String, String> fieldValues, boolean markAsActualChange) { throw new UnsupportedOperationException("Not supported. Convert to a PB form if you want to use this."); } public static String toString(SampleValue val, ArchDBRTypes type) throws IOException { if(val == null) return ""; switch(type) { case DBR_SCALAR_STRING: case DBR_SCALAR_SHORT: case DBR_SCALAR_FLOAT: case DBR_SCALAR_ENUM: case DBR_SCALAR_BYTE: case DBR_SCALAR_INT: case DBR_SCALAR_DOUBLE: case DBR_V4_GENERIC_BYTES: return val.toString(); case DBR_WAVEFORM_STRING: case DBR_WAVEFORM_ENUM:{ int elementCount = val.getElementCount(); boolean first = true; StringWriter buf = new StringWriter(); for(int i = 0; i < elementCount; i++) { String elemVal = val.getStringValue(i); if(first) { first = false; } else {buf.append("|"); } buf.append(elemVal); } return buf.toString(); } case DBR_WAVEFORM_SHORT: case DBR_WAVEFORM_FLOAT: case DBR_WAVEFORM_BYTE: case DBR_WAVEFORM_INT: case DBR_WAVEFORM_DOUBLE: { int elementCount = val.getElementCount(); boolean first = true; StringWriter buf = new StringWriter(); for(int i = 0; i < elementCount; i++) { String elemVal = val.getValue(i).toString(); if(first) { first = false; } else {buf.append("|"); } buf.append(elemVal); } return buf.toString(); } default: throw new IOException("Unsupported DBR type in switch statement " + type.toString()); } } @Override public ArchDBRTypes getDBRType() { return this.type; } @Override public void setStatus(int status) { this.status = status; } @Override public void setSeverity(int severity) { this.severity = severity; } }