package org.signalml.app.worker.monitor.messages.parsing;
import static org.signalml.app.util.i18n.SvarogI18n._;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.signalml.app.model.document.opensignal.ExperimentDescriptor;
import org.signalml.app.model.document.opensignal.elements.Amplifier;
import org.signalml.app.model.document.opensignal.elements.AmplifierChannel;
public abstract class AbstractResponseJSonReader {
private static final Logger logger = Logger.getLogger(AbstractResponseJSonReader.class);
private StringBuilder log = new StringBuilder();
public List<ExperimentDescriptor> parseExperiments(String s) {
ObjectMapper mapper = new ObjectMapper();
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
try {
map = mapper.readValue(s.getBytes(), new TypeReference<LinkedHashMap<String, Object>>() {});
} catch (JsonParseException e1) {
log.append(_("ERROR - JsonParseException while parsing the received message!\n"));
logger.error("", e1);
} catch (JsonMappingException e1) {
log.append(_("ERROR - JsonMappingException while parsing the received message!\n"));
logger.error("", e1);
} catch (IOException e1) {
log.append(_("ERROR - IOException while parsing the received message!\n"));
logger.error("", e1);
}
if (map == null)
return null;
List<LinkedHashMap<String, Object>> list = (List<LinkedHashMap<String, Object>>) map.get(getExperimentsListFieldName());
boolean errorAlreadyOcurred = false;
List<ExperimentDescriptor> experiments = new ArrayList<ExperimentDescriptor>();
for (LinkedHashMap<String, Object> exp: list) {
try {
ExperimentDescriptor descriptor = parseSingleExperiment(exp);
descriptor.setCorrectlyRead(true);
experiments.add(descriptor);
} catch (Exception e) {
if (!errorAlreadyOcurred) {
//we want this message to be appended only once!
log.append(_("ERROR - there was an error while parsing experiment data! (Bad message format?)\n"));
errorAlreadyOcurred = true;
}
logger.error("There was an error parsing an experiment: " + e.getMessage());
logger.error("", e);
}
}
return experiments;
}
protected abstract String getExperimentsListFieldName();
public abstract ExperimentDescriptor parseSingleExperiment(LinkedHashMap<String, Object> map);
protected void readChannelsList(List<Object> listOfChannels, ExperimentDescriptor experiment) {
Amplifier amplifier = experiment.getAmplifier();
amplifier.setChannels(new ArrayList<AmplifierChannel>());
int i = 0;
for (Object item: listOfChannels) {
LinkedHashMap<String, Object> channelInfo = (LinkedHashMap<String, Object>) item;
String channelName = (String) channelInfo.get("name");
AmplifierChannel channel = new AmplifierChannel(i+1, channelName);
channel.setOriginalName(channelName);
double gain = (Double) channelInfo.get("gain");
double offset = (Double) channelInfo.get("offset");
channel.setCalibrationGain((float)gain);
channel.setCalibrationOffset((float)offset);
/*
* Sometimes the idle field is interpreted as Long, sometimes - Integer.
* We actually need it to be double, so it's safer to trasform it to String
* and then parse.
*/
String idleString = channelInfo.get("idle").toString();
channel.setIdle(Double.parseDouble(idleString));
channel.setSelected(false);
amplifier.getChannels().add(channel);
i++;
}
experiment.getSignalParameters().setChannelCount(i);
}
protected void readSamplingFrequencies(LinkedHashMap<String, Object> parameters, ExperimentDescriptor experiment) {
Amplifier amplifier = experiment.getAmplifier();
List<Integer> samplingFrequencies = (List<Integer>) parameters.get("sampling_rates");
amplifier.setSamplingFrequencies(new ArrayList<Float>());
for (Integer sf: samplingFrequencies) {
amplifier.getSamplingFrequencies().add(new Float(sf));
}
}
public String getLog() {
return log.toString();
}
}