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; ...@@ -2,6 +2,7 @@ package de.sekmi.histream.etl;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import de.sekmi.histream.etl.config.Column; import de.sekmi.histream.etl.config.Column;
...@@ -24,19 +25,26 @@ public class ColumnMap{ ...@@ -24,19 +25,26 @@ public class ColumnMap{
this.map = new HashMap<>(); 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()) ){ if( map.containsKey(column.getName()) ){
// column name already registered // column name already registered
return true; return;
} }
// find name and map to index // find name and map to index
for( int i=0; i<headers.length; i++ ){ for( int i=0; i<headers.length; i++ ){
if( headers[i].equals(column.getName()) ){ if( headers[i].equals(column.getName()) ){
map.put(column.getName(), Integer.valueOf(i) ); 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){ public Integer indexOf(Column column){
return map.get(column.getName()); return map.get(column.getName());
......
...@@ -27,7 +27,7 @@ public class FileRowSupplier extends RowSupplier { ...@@ -27,7 +27,7 @@ public class FileRowSupplier extends RowSupplier {
} }
@Override @Override
public String[] getHeaders() throws IOException { public String[] getHeaders() {
return headers; return headers;
} }
......
...@@ -9,4 +9,8 @@ public class ParseException extends Exception { ...@@ -9,4 +9,8 @@ public class ParseException extends Exception {
public ParseException(String message){ public ParseException(String message){
super(message); super(message);
} }
public ParseException(String message, Throwable cause){
super(message, cause);
}
} }
...@@ -10,7 +10,7 @@ public class RecordSupplier<R> implements Supplier<R>, AutoCloseable{ ...@@ -10,7 +10,7 @@ public class RecordSupplier<R> implements Supplier<R>, AutoCloseable{
Table<R> table; Table<R> table;
ColumnMap map; ColumnMap map;
public RecordSupplier(RowSupplier rows, Table<R> table) throws IOException{ public RecordSupplier(RowSupplier rows, Table<R> table)throws ParseException{
this.rows = rows; this.rows = rows;
this.table = table; this.table = table;
this.map = table.getColumnMap(rows.getHeaders()); this.map = table.getColumnMap(rows.getHeaders());
......
...@@ -8,7 +8,7 @@ public abstract class RowSupplier implements Supplier<Object[]>, AutoCloseable{ ...@@ -8,7 +8,7 @@ public abstract class RowSupplier implements Supplier<Object[]>, AutoCloseable{
public RowSupplier(){ public RowSupplier(){
} }
public abstract String[] getHeaders()throws IOException; public abstract String[] getHeaders();
@Override @Override
public abstract Object[] get(); public abstract Object[] get();
......
package de.sekmi.histream.etl; 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{ ...@@ -36,26 +36,16 @@ public class PatientTable extends Table<PatientRow> implements WideInterface{
} }
@Override @Override
public ColumnMap getColumnMap(String[] headers) { public ColumnMap getColumnMap(String[] headers) throws ParseException {
ColumnMap map = new ColumnMap(headers); 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"); map.registerColumn(idat.patientId);
} map.registerColumn(idat.firstname);
if( idat.firstname != null && !map.registerColumn(idat.firstname) ){ map.registerColumn(idat.surname);
throw new IllegalArgumentException("firstname column not found in patient header"); map.registerColumn(idat.birthdate);
} map.registerColumn(idat.deathdate);
if( idat.surname != null && !map.registerColumn(idat.surname) ){ map.registerColumn(idat.gender);
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");
}
return map; return map;
} }
......
...@@ -19,28 +19,40 @@ public abstract class Table<T> { ...@@ -19,28 +19,40 @@ public abstract class Table<T> {
* Retrieve a column map for this table * Retrieve a column map for this table
* @param headers row headers * @param headers row headers
* @return column map * @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 * Register all columns for the given concept to the column map
* @param map column map * @param map column map
* @param c concept to register * @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.start);
map.registerColumn(c.end); if( c.end != null ){
map.registerColumn(c.value); map.registerColumn(c.end);
map.registerColumn(c.unit); }
for( Concept.Modifier m : c.modifiers ){ if( c.value != null ){
map.registerColumn(m.value); map.registerColumn(c.value);
map.registerColumn(m.unit); }
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 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); return new RecordSupplier<>(source.rows(), this);
} }
......
...@@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlElement; ...@@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlType;
import de.sekmi.histream.DateTimeAccuracy;
import de.sekmi.histream.etl.ColumnMap; import de.sekmi.histream.etl.ColumnMap;
import de.sekmi.histream.etl.ParseException; import de.sekmi.histream.etl.ParseException;
import de.sekmi.histream.etl.VisitRow; import de.sekmi.histream.etl.VisitRow;
...@@ -29,8 +30,9 @@ public class VisitTable extends Table<VisitRow> implements WideInterface{ ...@@ -29,8 +30,9 @@ public class VisitTable extends Table<VisitRow> implements WideInterface{
Column[] ignore; Column[] ignore;
} }
@Override @Override
public ColumnMap getColumnMap(String[] headers) { public ColumnMap getColumnMap(String[] headers) throws ParseException {
ColumnMap map = new ColumnMap(headers); ColumnMap map = new ColumnMap(headers);
map.registerColumn(idat.patientId); map.registerColumn(idat.patientId);
map.registerColumn(idat.visitId); map.registerColumn(idat.visitId);
map.registerColumn(idat.start); map.registerColumn(idat.start);
...@@ -38,11 +40,18 @@ public class VisitTable extends Table<VisitRow> implements WideInterface{ ...@@ -38,11 +40,18 @@ public class VisitTable extends Table<VisitRow> implements WideInterface{
for( Concept c : concepts ){ for( Concept c : concepts ){
mapRegisterConcept(map, c); mapRegisterConcept(map, c);
} }
return map; return map;
} }
@Override @Override
public VisitRow fillRecord(ColumnMap map, Object[] row) throws ParseException { public VisitRow fillRecord(ColumnMap map, Object[] row) throws ParseException {
// TODO Auto-generated method stub VisitRow visit = new VisitRow();
return null; 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> { ...@@ -17,7 +17,7 @@ public class WideTable extends Table<WideRow> {
Concept[] concepts; Concept[] concepts;
@Override @Override
public ColumnMap getColumnMap(String[] headers) { public ColumnMap getColumnMap(String[] headers) throws ParseException {
ColumnMap map = new ColumnMap(headers); ColumnMap map = new ColumnMap(headers);
map.registerColumn(idat.patientId); map.registerColumn(idat.patientId);
map.registerColumn(idat.visitId); map.registerColumn(idat.visitId);
......
...@@ -2,19 +2,23 @@ package de.sekmi.histream.etl.config; ...@@ -2,19 +2,23 @@ package de.sekmi.histream.etl.config;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.temporal.ChronoField;
import javax.xml.bind.JAXB; import javax.xml.bind.JAXB;
import org.junit.Test; import org.junit.Test;
import de.sekmi.histream.etl.ParseException;
import de.sekmi.histream.etl.PatientRow; import de.sekmi.histream.etl.PatientRow;
import de.sekmi.histream.etl.RecordSupplier; import de.sekmi.histream.etl.RecordSupplier;
import de.sekmi.histream.etl.VisitRow;
import org.junit.Assert; import org.junit.Assert;
public class TestReadTables { public class TestReadTables {
@Test @Test
public void testReadPatients() throws IOException{ public void testReadPatients() throws IOException, ParseException{
DataSource ds; DataSource ds;
try( InputStream in = getClass().getResourceAsStream("/test-1-datasource.xml") ){ try( InputStream in = getClass().getResourceAsStream("/test-1-datasource.xml") ){
ds = JAXB.unmarshal(in, DataSource.class); ds = JAXB.unmarshal(in, DataSource.class);
...@@ -22,7 +26,20 @@ public class TestReadTables { ...@@ -22,7 +26,20 @@ public class TestReadTables {
try( RecordSupplier<PatientRow> s = ds.patientTable.open() ){ try( RecordSupplier<PatientRow> s = ds.patientTable.open() ){
PatientRow r = s.get(); PatientRow r = s.get();
Assert.assertEquals("1", r.getId()); 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 @@ ...@@ -40,15 +40,15 @@
<!-- optional --> <!-- optional -->
<visit-table> <visit-table>
<source xsi:type="fileSource"> <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> <type>text/csv</type>
<separator>\t</separator> <separator>\t</separator>
</source> </source>
<idat> <idat>
<patient-id>patid</patient-id> <patient-id>patid</patient-id>
<visit-id>fallnr</visit-id> <visit-id>fallnr</visit-id>
<start format="ISO" na="@" truncate-to="year">start</start> <start format="d.M.u[ H[:m[:s]]]" na="@" truncate-to="year">start</start>
<end>end</end> <end format="d.M.u[ H[:m[:s]]]">end</end>
</idat> </idat>
<mdat> <mdat>
<!-- in/out code --> <!-- 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