Commit 7d664d83 authored by R.W.Majeed's avatar R.W.Majeed

fact class annotator integrated, test case adde

parent 2a33652c
......@@ -7,6 +7,7 @@ import java.util.Map;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Annotates DOM fact objects with a {@code @class} attribute.
......@@ -67,6 +68,20 @@ class FactClassAnnotator {
}
}
/**
* Annotates all elements with local name 'fact' contained
* in the provided node list. Other nodes are ignored.
* @param facts node list containing 'fact' elements (among other nodes)
*/
public void annotateFacts(NodeList facts){
for( int i=0; i<facts.getLength(); i++ ){
Node next = facts.item(i);
if( next.getNodeType() == Node.ELEMENT_NODE && next.getLocalName().equals("fact") ){
annotateFact(next);
}
}
}
public void annotateFactSiblings(Node first){
annotateFact(first);
Node next = first.getNextSibling();
......
......@@ -7,8 +7,11 @@ import javax.xml.stream.XMLStreamException;
import javax.xml.xpath.XPath;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import de.sekmi.histream.ObservationException;
import de.sekmi.histream.export.config.Concept;
import de.sekmi.histream.export.config.ConceptGroup;
import de.sekmi.histream.export.config.ExportDescriptor;
import de.sekmi.histream.export.config.ExportException;
......@@ -27,6 +30,7 @@ class FragmentExporter extends VisitFragmentParser {
TableParser patientParser;
TableParser visitParser;
private Element currentPatient;
private FactClassAnnotator factAnnotator;
protected FragmentExporter(XPath xpath, ExportDescriptor desc, ExportWriter writer) throws ExportException, XMLStreamException, ParserConfigurationException {
super();
......@@ -37,6 +41,28 @@ class FragmentExporter extends VisitFragmentParser {
} catch (IOException e) {
throw new ExportException("Unable to open table for writing", e);
}
// initialise annotator
factAnnotator = new FactClassAnnotator();
for( ConceptGroup group : desc.getConcepts().getGroups() ){
String clazz = group.getClazz();
for( Concept concept : group.getConcepts() ){
String s = concept.getNotation();
if( s != null ){
factAnnotator.addMapRule(s, clazz);
continue;
}
s = concept.getWildcardNotation();
if( s != null ){
if( s.indexOf('*') < s.length()-1 ){
throw new ExportException("Wildcard notation '"+s+"' must contain exactly one * at the end");
}
factAnnotator.addWildcardRule(s.substring(0, s.length()-1), clazz);
continue;
}
throw new ExportException("Group concepts must have one of 'notation' or 'wildcard-notation' defined. Concept IRI not supported yet");
}
}
}
@Override
......@@ -51,6 +77,8 @@ class FragmentExporter extends VisitFragmentParser {
@Override
protected void visitFragment(Element visit) throws ObservationException {
// annotate facts with class attribute
factAnnotator.annotateFacts(visit.getChildNodes());
// move visit to patient
// this allows XPath expressions to access the patient via
// the parent element. E.g. '../@id' to get the patient id
......
......@@ -7,6 +7,15 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlID;
/**
* Group containing concepts. Useful for grouping
* concepts under a common 'class' name, which can
* be used to identify facts later without
* the need to refer to their (different) concept
* codes.
* @author R.W.Majeed
*
*/
public class ConceptGroup {
public ConceptGroup(String clazz){
this.clazz = clazz;
......@@ -17,8 +26,23 @@ public class ConceptGroup {
}
@XmlID
@XmlAttribute(name="class")
@XmlAttribute(name="class", required=true)
String clazz;
@XmlElement(name="concept")
List<Concept> concepts;
/**
* Get the class (id) attribute for this group.
* @return group class
*/
public String getClazz(){
return clazz;
}
/**
* Get the concepts in this group
* @return concepts
*/
public Iterable<Concept> getConcepts(){
return concepts;
}
}
\ No newline at end of file
......@@ -17,4 +17,11 @@ public class Concepts {
Iterable<Concept> allConcepts(){
return new IterableIterable<Concept,ConceptGroup>(groups, group -> group.concepts.iterator(), concepts);
}
public List<ConceptGroup> getGroups(){
return groups;
}
public List<Concept> ungroupedConcepts(){
return concepts;
}
}
......@@ -70,12 +70,24 @@ public class ExportDescriptor {
/**
* Get all concepts used for the export. This
* may contain duplicate concepts.
* <p>
* The returned iterator will iterate through all concepts
* contained in groups followed by all ungrouped concepts.
* </p>
*
* @return all concepts
*/
public Iterable<Concept> allConcepts(){
return concepts.allConcepts();
}
/**
* Get the {@link Concepts} object which contains concept groups and
* ungrouped concepts.
* @return concepts
*/
public Concepts getConcepts(){
return concepts;
}
public TableExport newExport(){
return new TableExport(this);
......
......@@ -11,4 +11,7 @@ public class ExportException extends Exception{
public ExportException(String message, Throwable cause){
super(message, cause);
}
public ExportException(String message){
super(message);
}
}
Markdown is supported
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