package org.epics.archiverappliance.etl.conversion;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Iterator;
import org.epics.archiverappliance.Event;
import org.epics.archiverappliance.EventStream;
import org.epics.archiverappliance.EventStreamDesc;
import org.epics.archiverappliance.config.ArchDBRTypes;
import org.epics.archiverappliance.data.DBRTimeEvent;
import org.epics.archiverappliance.data.SampleValue;
import org.epics.archiverappliance.etl.ConversionException;
import org.epics.archiverappliance.etl.ConversionFunction;
import org.epics.archiverappliance.retrieval.RemotableEventStreamDesc;
import org.epics.archiverappliance.retrieval.channelarchiver.HashMapEvent;
import edu.stanford.slac.archiverappliance.PB.data.DBR2PBTypeMapping;
/**
* Generic class for some standard type conversions.
* Not all type conversions are supported; some type conversions may be completely (or even worse, incompletely) inaccurate for your use case.
* Only a few of these have been tested and even those only incompletely.
* In most cases, you should roll your own conversion function and then apply using the ETLDest interface.
*
* @author mshankar
*
*/
public class ThruNumberAndStringConversion implements ConversionFunction {
private ArchDBRTypes destDBRType;
private Constructor<? extends DBRTimeEvent> serializingConstructor;
public ThruNumberAndStringConversion(ArchDBRTypes destDBRType) {
this.destDBRType = destDBRType;
this.serializingConstructor = DBR2PBTypeMapping.getPBClassFor(destDBRType).getSerializingConstructor();
}
@Override
public EventStream convertStream(final EventStream srcEventStream) throws IOException {
return new EventStream() {
Iterator<Event> theIterator = srcEventStream.iterator();
@Override
public void close() throws IOException {
theIterator = null;
srcEventStream.close();
}
@Override
public Iterator<Event> iterator() {
return new Iterator<Event>() {
@Override
public boolean hasNext() {
return theIterator.hasNext();
}
@Override
public Event next() {
try {
DBRTimeEvent event = (DBRTimeEvent) theIterator.next();
HashMapEvent hashEvent = new HashMapEvent(destDBRType, event);
hashEvent.setValue(HashMapEvent.VALUE_FIELD_NAME, convert2DestType(event.getSampleValue()));
DBRTimeEvent retEvent = (DBRTimeEvent) serializingConstructor.newInstance(hashEvent);
return retEvent;
} catch(Exception ex) {
throw new ConversionException("Exception during conversion of pv " + srcEventStream.getDescription().getPvName(), ex);
}
}
private String convert2DestType(SampleValue sampleValue) {
switch(destDBRType) {
case DBR_SCALAR_BYTE:
return Byte.toString(sampleValue.getValue().byteValue());
case DBR_SCALAR_DOUBLE:
return Double.toString(sampleValue.getValue().doubleValue());
case DBR_SCALAR_ENUM:
return Short.toString(sampleValue.getValue().shortValue());
case DBR_SCALAR_FLOAT:
return Float.toString(sampleValue.getValue().floatValue());
case DBR_SCALAR_INT:
return Integer.toString(sampleValue.getValue().intValue());
case DBR_SCALAR_SHORT:
return Short.toString(sampleValue.getValue().shortValue());
case DBR_SCALAR_STRING:
return sampleValue.getStringValue(0);
case DBR_V4_GENERIC_BYTES:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_BYTE:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_DOUBLE:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_ENUM:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_FLOAT:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_INT:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_SHORT:
throw new UnsupportedOperationException();
case DBR_WAVEFORM_STRING:
throw new UnsupportedOperationException();
default:
throw new UnsupportedOperationException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public EventStreamDesc getDescription() {
return new RemotableEventStreamDesc(destDBRType,
srcEventStream.getDescription().getPvName(),
((RemotableEventStreamDesc)srcEventStream.getDescription()).getYear());
}
};
}
}