/*******************************************************************************
* 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.retrieval;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.EventStreamDesc;
import org.epics.archiverappliance.config.ArchDBRTypes;
import org.epics.archiverappliance.config.PVNames;
import org.epics.archiverappliance.config.PVTypeInfo;
import edu.stanford.slac.archiverappliance.PB.EPICSEvent;
import edu.stanford.slac.archiverappliance.PB.EPICSEvent.FieldValue;
import edu.stanford.slac.archiverappliance.PB.EPICSEvent.PayloadInfo;
/**
* Information about the whole stream that is often used in generating headers etc...
* @author mshankar
*
*/
public class RemotableEventStreamDesc extends EventStreamDesc {
private static Logger logger = Logger.getLogger(RemotableEventStreamDesc.class.getName());
private short year;
private int elementCount = 1;
private HashMap<String, String> headers = new HashMap<String, String>();
public RemotableEventStreamDesc(ArchDBRTypes archDBRType, String pvName, short year) {
super(archDBRType, pvName);
this.archDBRType = archDBRType;
this.year = year;
}
public RemotableEventStreamDesc(String pvName, PayloadInfo info) {
super(ArchDBRTypes.valueOf(info.getType()), pvName);
if(!pvName.equals(info.getPvname())) {
logger.warn("Returning data from PV " + info.getPvname() + " as the data for PV " + pvName);
}
this.year = (short) info.getYear();
if(info.hasElementCount()) this.setElementCount(info.getElementCount());
if(info.getHeadersCount() > 0 ) {
for(FieldValue f : info.getHeadersList()) {
this.headers.put(f.getName(), f.getVal());
}
}
}
public RemotableEventStreamDesc(RemotableEventStreamDesc other) {
super(other);
this.year = other.year;
this.elementCount = other.elementCount;
this.headers = new HashMap<String, String>(other.headers);
}
public void mergeFrom(PVTypeInfo info, HashMap<String, String> engineMetadata) throws IOException {
if(!PVNames.stripFieldNameFromPVName(this.pvName).equals(PVNames.stripFieldNameFromPVName(info.getPvName()))) throw new IOException("Mismatch in pv info's. Src is for " + this.pvName + ". Info from config db is for " + info.getPvName());
this.elementCount = info.getElementCount();
if(!this.headers.containsKey("EGU")) {
this.headers.put("EGU", info.getUnits());
}
if(!this.headers.containsKey("PREC")) {
this.headers.put("PREC", new Integer((int)info.getPrecision().intValue()).toString());
}
// There are cases when we use operators where the DBR type of the PVTypeInfo is not the same as the DBR type of the event stream
// So instead of throwing an exception; for now, I am just logging a warning.
// Will revisit if lets thru event streams of difference kinds.
// if(!this.archDBRType.equals(info.getDBRType())) throw new MismatchedDBRTypeException(info.getPvName(), info.getDBRType(), this.source, this.archDBRType);
if(!this.archDBRType.equals(info.getDBRType())) {
logger.warn("For pv " + this.pvName + " dbr types do not match for stream " + this.source);
}
if(engineMetadata != null) {
this.headers.putAll(engineMetadata);
}
}
public void mergeInto(PayloadInfo.Builder builder) {
if(!this.headers.isEmpty()) {
LinkedList<FieldValue> fieldValuesList = new LinkedList<FieldValue>();
for(String fieldName : this.headers.keySet()) {
String fieldValue = headers.get(fieldName);
if(fieldValue != null && !fieldValue.isEmpty()) {
fieldValuesList.add(EPICSEvent.FieldValue.newBuilder().setName(fieldName).setVal(fieldValue).build());
}
}
builder.addAllHeaders(fieldValuesList);
}
}
public ArchDBRTypes getArchDBRType() {
return archDBRType;
}
public void setArchDBRType(ArchDBRTypes archDBRType) {
this.archDBRType = archDBRType;
}
public String getPvName() {
return pvName;
}
public void setPvName(String pvName) {
this.pvName = pvName;
}
public short getYear() {
return year;
}
public void setYear(short year) {
this.year = year;
}
public int getElementCount() {
return elementCount;
}
public void setElementCount(int elementCount) {
this.elementCount = elementCount;
}
public HashMap<String, String> getHeaders() {
return headers;
}
public void addHeaders(Map<String, String> vals) {
this.headers.putAll(vals);
}
public void addHeader(String name, String value) {
this.headers.put(name, value);
}
}