Commit 469a02e9 authored by R.W.Majeed's avatar R.W.Majeed
Browse files

simplified exceptions, visit table parsing successful

parent 17dc54c4
......@@ -2,6 +2,7 @@ package de.sekmi.histream.etl;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import de.sekmi.histream.etl.config.Column;
......@@ -24,19 +25,26 @@ public class ColumnMap{
this.map = new HashMap<>();
}
public boolean registerColumn(Column column){
/**
* Register a column and lookup it's index in the header list.
* @param column
* @throws ParseException if the column cannot be found in the headers
* @throws NullPointerException if column is null
*/
public void registerColumn(Column column)throws ParseException{
Objects.requireNonNull(column);
if( map.containsKey(column.getName()) ){
// column name already registered
return true;
return;
}
// find name and map to index
for( int i=0; i<headers.length; i++ ){
if( headers[i].equals(column.getName()) ){
map.put(column.getName(), Integer.valueOf(i) );
return true;
return;
}
}
return false;
throw new ParseException("Column name '"+column.getName()+"' not found in header");
}
public Integer indexOf(Column column){
return map.get(column.getName());
......
......@@ -27,7 +27,7 @@ public class FileRowSupplier extends RowSupplier {
}
@Override
public String[] getHeaders() throws IOException {
public String[] getHeaders() {
return headers;
}
......
......@@ -9,4 +9,8 @@ public class ParseException extends Exception {
public ParseException(String message){
super(message);
}
public ParseException(String message, Throwable cause){
super(message, cause);
}
}
......@@ -10,7 +10,7 @@ public class RecordSupplier<R> implements Supplier<R>, AutoCloseable{
Table<R> table;
ColumnMap map;
public RecordSupplier(RowSupplier rows, Table<R> table) throws IOException{
public RecordSupplier(RowSupplier rows, Table<R> table)throws ParseException{
this.rows = rows;
this.table = table;
this.map = table.getColumnMap(rows.getHeaders());
......
......@@ -8,7 +8,7 @@ public abstract class RowSupplier implements Supplier<Object[]>, AutoCloseable{
public RowSupplier(){
}
public abstract String[] getHeaders()throws IOException;
public abstract String[] getHeaders();
@Override
public abstract Object[] get();
......
package de.sekmi.histream.etl;
public class VisitRow {
import de.sekmi.histream.impl.VisitImpl;
public class VisitRow extends VisitImpl{
}
......@@ -36,26 +36,16 @@ public class PatientTable extends Table<PatientRow> implements WideInterface{
}
@Override
public ColumnMap getColumnMap(String[] headers) {
public ColumnMap getColumnMap(String[] headers) throws ParseException {
ColumnMap map = new ColumnMap(headers);
if( !map.registerColumn(idat.patientId) ){
throw new IllegalArgumentException("patientId column name '"+idat.patientId.name+"' not found in patient table headers");
}
if( idat.firstname != null && !map.registerColumn(idat.firstname) ){
throw new IllegalArgumentException("firstname column not found in patient header");
}
if( idat.surname != null && !map.registerColumn(idat.surname) ){
throw new IllegalArgumentException("surname column not found in patient header");
}
if( idat.birthdate != null && !map.registerColumn(idat.birthdate) ){
throw new IllegalArgumentException("birthdate column not found in patient header");
}
if( idat.deathdate != null && !map.registerColumn(idat.deathdate) ){
throw new IllegalArgumentException("deathdate column not found in patient header");
}
if( idat.gender != null && !map.registerColumn(idat.gender) ){
throw new IllegalArgumentException("gender column not found in patient header");
}
map.registerColumn(idat.patientId);
map.registerColumn(idat.firstname);
map.registerColumn(idat.surname);
map.registerColumn(idat.birthdate);
map.registerColumn(idat.deathdate);
map.registerColumn(idat.gender);
return map;
}
......
......@@ -19,28 +19,40 @@ public abstract class Table<T> {
* Retrieve a column map for this table
* @param headers row headers
* @return column map
* @throws ParseException if the map cannot be constructed
*/
public abstract ColumnMap getColumnMap(String[] headers);
public abstract ColumnMap getColumnMap(String[] headers) throws ParseException;
/**
* Register all columns for the given concept to the column map
* @param map column map
* @param c concept to register
* @throws ParseException if headers could not be found/mapped
*/
protected void mapRegisterConcept(ColumnMap map, Concept c){
protected void mapRegisterConcept(ColumnMap map, Concept c) throws ParseException{
map.registerColumn(c.start);
map.registerColumn(c.end);
map.registerColumn(c.value);
map.registerColumn(c.unit);
for( Concept.Modifier m : c.modifiers ){
map.registerColumn(m.value);
map.registerColumn(m.unit);
if( c.end != null ){
map.registerColumn(c.end);
}
if( c.value != null ){
map.registerColumn(c.value);
}
if( c.unit != null ){
map.registerColumn(c.unit);
}
if( c.modifiers != null ){
for( Concept.Modifier m : c.modifiers ){
map.registerColumn(m.value);
if( m.unit != null ){
map.registerColumn(m.unit);
}
}
}
}
public abstract T fillRecord(ColumnMap map, Object[] row) throws ParseException;
public RecordSupplier<T> open() throws IOException{
public RecordSupplier<T> open() throws IOException, ParseException{
return new RecordSupplier<>(source.rows(), this);
}
......
......@@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
import de.sekmi.histream.DateTimeAccuracy;
import de.sekmi.histream.etl.ColumnMap;
import de.sekmi.histream.etl.ParseException;
import de.sekmi.histream.etl.VisitRow;
......@@ -29,8 +30,9 @@ public class VisitTable extends Table<VisitRow> implements WideInterface{
Column[] ignore;
}
@Override
public ColumnMap getColumnMap(String[] headers) {
public ColumnMap getColumnMap(String[] headers) throws ParseException {
ColumnMap map = new ColumnMap(headers);
map.registerColumn(idat.patientId);
map.registerColumn(idat.visitId);
map.registerColumn(idat.start);
......@@ -38,11 +40,18 @@ public class VisitTable extends Table<VisitRow> implements WideInterface{
for( Concept c : concepts ){
mapRegisterConcept(map, c);
}
return map;
}
@Override
public VisitRow fillRecord(ColumnMap map, Object[] row) throws ParseException {
// TODO Auto-generated method stub
return null;
}
}
VisitRow visit = new VisitRow();
visit.setId(idat.visitId.valueOf(map, row).toString());
visit.setPatientId(idat.patientId.valueOf(map, row).toString());
visit.setStartTime((DateTimeAccuracy)idat.start.valueOf(map, row));
visit.setEndTime((DateTimeAccuracy)idat.end.valueOf(map, row));
// TODO other
// TODO concepts
return visit;
}}
......@@ -17,7 +17,7 @@ public class WideTable extends Table<WideRow> {
Concept[] concepts;
@Override
public ColumnMap getColumnMap(String[] headers) {
public ColumnMap getColumnMap(String[] headers) throws ParseException {
ColumnMap map = new ColumnMap(headers);
map.registerColumn(idat.patientId);
map.registerColumn(idat.visitId);
......
......@@ -2,19 +2,23 @@ package de.sekmi.histream.etl.config;
import java.io.IOException;
import java.io.InputStream;
import java.time.temporal.ChronoField;
import javax.xml.bind.JAXB;
import org.junit.Test;
import de.sekmi.histream.etl.ParseException;
import de.sekmi.histream.etl.PatientRow;
import de.sekmi.histream.etl.RecordSupplier;
import de.sekmi.histream.etl.VisitRow;
import org.junit.Assert;
public class TestReadTables {
@Test
public void testReadPatients() throws IOException{
public void testReadPatients() throws IOException, ParseException{
DataSource ds;
try( InputStream in = getClass().getResourceAsStream("/test-1-datasource.xml") ){
ds = JAXB.unmarshal(in, DataSource.class);
......@@ -22,7 +26,20 @@ public class TestReadTables {
try( RecordSupplier<PatientRow> s = ds.patientTable.open() ){
PatientRow r = s.get();
Assert.assertEquals("1", r.getId());
System.out.println(r.getBirthDate());
Assert.assertEquals(2003, r.getBirthDate().get(ChronoField.YEAR));
}
}
@Test
public void testReadVisits() throws IOException, ParseException{
DataSource ds;
try( InputStream in = getClass().getResourceAsStream("/test-1-datasource.xml") ){
ds = JAXB.unmarshal(in, DataSource.class);
}
try( RecordSupplier<VisitRow> s = ds.visitTable.open() ){
VisitRow r = s.get();
Assert.assertEquals("1", r.getId());
Assert.assertEquals(2013, r.getStartTime().get(ChronoField.YEAR));
}
}
......
......@@ -40,15 +40,15 @@
<!-- optional -->
<visit-table>
<source xsi:type="fileSource">
<url>file:test-1-visits.txt</url>
<url>file:src/test/resources/test-1-visits.txt</url>
<type>text/csv</type>
<separator>\t</separator>
</source>
<idat>
<patient-id>patid</patient-id>
<visit-id>fallnr</visit-id>
<start format="ISO" na="@" truncate-to="year">start</start>
<end>end</end>
<start format="d.M.u[ H[:m[:s]]]" na="@" truncate-to="year">start</start>
<end format="d.M.u[ H[:m[:s]]]">end</end>
</idat>
<mdat>
<!-- in/out code -->
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment