package at.medevit.elexis.loinc.model.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.medevit.elexis.loinc.model.ILoincCodeService;
import at.medevit.elexis.loinc.model.LoincCode;
import ch.elexis.data.Query;
import ch.rgw.tools.VersionInfo;
public class LoincCodeService implements ILoincCodeService {
private static Logger logger = LoggerFactory.getLogger(LoincCodeService.class);
private Map<Integer, String> fieldMapping;
private Integer codeMapping = -1;
public static final VersionInfo TOP2000VERSION = new VersionInfo("1.1.0");
public LoincCode getByCode(String code){
Query<LoincCode> qbe = new Query<LoincCode>(LoincCode.class);
qbe.add("ID", "!=", LoincCode.VERSIONID);
qbe.add("ID", "!=", LoincCode.VERSIONTOPID);
qbe.add(LoincCode.FLD_CODE, "=", code);
List<LoincCode> res = qbe.execute();
if (res.isEmpty()) {
return null;
} else {
return res.get(0);
}
}
public List<LoincCode> getAllCodes(){
Query<LoincCode> qbe = new Query<LoincCode>(LoincCode.class);
qbe.add("ID", "!=", LoincCode.VERSIONID);
qbe.add("ID", "!=", LoincCode.VERSIONTOPID);
return qbe.execute();
}
public void importFromCsv(InputStream csv, Map<Integer, String> fieldMapping)
throws IOException{
logger.info("Import from CSV stream " + csv);
initMapping(fieldMapping);
BufferedReader reader = new BufferedReader(new InputStreamReader(csv));
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split(",", -1);
if (parts[codeMapping].matches("[0-9\\-]*")) {
LoincCode existing = getByCode(parts[0]);
if (existing != null) {
merge(existing, parts);
} else {
logger.info("Creating object [" + parts[codeMapping] + "]");
create(parts);
}
} else {
logger.warn("Import skipping object [" + parts[codeMapping] + "]");
}
}
}
private void create(String[] parts){
LoincCode code = new LoincCode(parts[codeMapping], null, null, null, null);
for (int i = 0; i < fieldMapping.size(); i++) {
if (i >= parts.length) {
code.set(fieldMapping.get(i), "");
}
code.set(fieldMapping.get(i), parts[i]);
}
}
private void merge(LoincCode existing, String[] parts){
for (int i = 0; i < fieldMapping.size(); i++) {
existing.set(fieldMapping.get(i), parts[i]);
}
}
private void initMapping(Map<Integer, String> fieldMapping){
this.fieldMapping = fieldMapping;
for (int i = 0; i < fieldMapping.size(); i++) {
if (fieldMapping.get(i).equals(LoincCode.FLD_CODE)) {
codeMapping = i;
break;
}
}
if (codeMapping == -1) {
throw new IllegalStateException("Fieldmapping is missing the code field.");
}
}
public void updateTop2000(){
logger.info("Update Top 2000 to version " + TOP2000VERSION.version());
logger.info("Update Top 2000 from version " + LoincCode.getTop2000Verion().version());
if(TOP2000VERSION.isNewer(LoincCode.getTop2000Verion())) {
try {
importFromCsv(loadTop2000(), getTop2000FieldMapping());
LoincCode.setTop2000Version(TOP2000VERSION.version());
} catch (IOException e) {
logger.error("Top 2000 import failed.", e);
}
}
}
private static InputStream loadTop2000(){
return LoincCodeService.class
.getResourceAsStream("/rsc/TOP_2000_COMMON_LAB_RESULTS_SI_LOINC_V1-1.CSV");
}
private static Map<Integer, String> getTop2000FieldMapping(){
HashMap<Integer, String> ret = new HashMap<Integer, String>();
ret.put(0, LoincCode.FLD_CODE);
ret.put(1, LoincCode.FLD_LONGNAME);
ret.put(2, LoincCode.FLD_SHORTNAME);
ret.put(3, LoincCode.FLD_CLASS);
return ret;
}
}