/*******************************************************************************
* Copyright (c) 2006-2009, G. Weirich and Elexis
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* G. Weirich - initial implementation
*
*******************************************************************************/
package ch.elexis.core.text.model;
import java.io.CharArrayReader;
import java.util.ArrayList;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import ch.rgw.tools.TimeTool;
/**
* Ganz bescheiden: (S)tandard für den (A)ustausch (m)edizinischer (Da)ten in der (Schweiz) ->
* SAmDaS. In Ermangelung eines besseren Standards sei dieser Name gestattet ;-) Samdas ist ein
* XML-Schema, das die Übertragung medizinischer Krankengeschichten (Elecronic medical record, EMR)
* zwischen verschiedenen Endanwendungen ermöglicht. Diese Klasse ist ein API dafür
*/
public class Samdas {
public static final String ELEM_ROOT = "EMR"; //$NON-NLS-1$
public static final String ELEM_TEXT = "text"; //$NON-NLS-1$
public static final String ELEM_RECORD = "record"; //$NON-NLS-1$
public static final Namespace ns = Namespace.getNamespace("samdas", "http://www.elexis.ch/XSD"); //$NON-NLS-1$ //$NON-NLS-2$
public static final Namespace nsxsi = Namespace.getNamespace(
"xsi", "http://www.w3.org/2001/XML Schema-instance"); //$NON-NLS-1$ //$NON-NLS-2$
public static final Namespace nsschema = Namespace.getNamespace(
"schemaLocation", "http://www.elexis.ch/XSD EMR.xsd"); //$NON-NLS-1$ //$NON-NLS-2$
private Document doc;
private Element eRoot;
/**
* Der String-Konstruktor erstellt ein Samdas aus der XML-Repräsentation. Wenn diese ungültig
* ist, wird ein Default-Dokument erstellt.
*
* @param input
* eine XML-Datei (oder irgendein Text, der dann komplett ins Text-Element des
* Standard-Dokuments eingebunden wird)
*/
public Samdas(String input){
SAXBuilder builder = new SAXBuilder();
try {
CharArrayReader car = new CharArrayReader(input.toCharArray());
doc = builder.build(car);
eRoot = doc.getRootElement();
} catch (Exception e) {
// SWTHelper.alert("Fehler beim Datenimport","Der XML-String enthält
// formale Fehler oder kann nicht gelesen werden");
// ExHandler.handle(e);
doc = new Document();
eRoot = new Element(ELEM_ROOT, ns);
doc.setRootElement(eRoot);
Element record = new Element(ELEM_RECORD, ns);
Element text = new Element(ELEM_TEXT, ns);
doc.getRootElement().addContent(record);
record.addContent(text);
text.setText(input);
}
}
/**
* Der Default-Konstruktor erstellt ein leeres Standard-Dokument
*
*/
public Samdas(){
doc = new Document();
eRoot = new Element(ELEM_ROOT, ns);
// eRoot.addNamespaceDeclaration(nsxsi);
// eRoot.addNamespaceDeclaration(nsschema);
doc.setRootElement(eRoot);
}
public void setRoot(Element el){
doc.removeContent();
// doc.getRootElement().detach();
eRoot = el;
doc.setRootElement(el);
}
public Document getDocument(){
return doc;
}
/**
* Get the contents of this Samdas in form of an XML-String
*/
@Override
public String toString(){
XMLOutputter xo = new XMLOutputter(Format.getRawFormat());
return xo.outputString(doc);
}
/** Shortcut für Dokumente, die sowieso nur einen Record haben */
public String getRecordText(){
Element rec = getRecordElement();
String ret = rec.getChildText(ELEM_TEXT, ns);
return ret == null ? "" : ret; //$NON-NLS-1$
}
public Element getRecordElement(){
Element ret = eRoot.getChild(ELEM_RECORD, ns);
if (ret == null) {
ret = new Element(ELEM_RECORD, ns);
eRoot.addContent(ret);
}
return ret;
}
public Record getRecord(){
return new Record(getRecordElement());
}
public void add(Record r){
eRoot.addContent(r.eRecord);
}
/**
* A record is an Text entry. It can optionally contain style informations
*
* @author Gerry
*
*/
public static class Record {
private static final String ELEM_SECTION = "section"; //$NON-NLS-1$
public static final String ELEM_MARKUP = "markup"; //$NON-NLS-1$
public static final String ELEM_XREF = "xref"; //$NON-NLS-1$
public static final String ATTR_DATE = "date"; //$NON-NLS-1$
public static final String ATTR_RESPONSIBLE_EAN = "responsibleEAN"; //$NON-NLS-1$
public static final String ATTR_AUTHOR = "author"; //$NON-NLS-1$
private Element eRecord;
public Record(Element e){
eRecord = e;
}
public String getAuthor(){
return eRecord.getAttributeValue(ATTR_AUTHOR);
}
public String getResponsibleEAN(){
return eRecord.getAttributeValue(ATTR_RESPONSIBLE_EAN);
}
public TimeTool getDate(){
return new TimeTool(eRecord.getAttributeValue(ATTR_DATE));
}
public Element getTextElement(){
Element ret = eRecord.getChild(ELEM_TEXT, ns);
if (ret == null) {
ret = new Element(ELEM_TEXT, ns);
eRecord.addContent(ret);
}
return ret;
}
public void setText(String t){
Element eText = getTextElement();
eText.setText(t);
}
public String getText(){
Element eText = getTextElement();
return eText.getText();
}
@SuppressWarnings("unchecked")
public List<XRef> getXrefs(){
List<Element> lElm = eRecord.getChildren(ELEM_XREF, ns);
List<XRef> ret = new ArrayList<XRef>(lElm.size());
for (Element el : lElm) {
ret.add(new XRef(el));
}
return ret;
}
@SuppressWarnings("unchecked")
public List<Markup> getMarkups(){
List<Element> lElm = eRecord.getChildren(ELEM_MARKUP, ns);
List<Markup> ret = new ArrayList<Markup>(lElm.size());
for (Element el : lElm) {
ret.add(new Markup(el));
}
return ret;
}
@SuppressWarnings("unchecked")
public List<Section> getSections(){
List<Element> lElm = eRecord.getChildren(ELEM_SECTION, ns);
List<Section> ret = new ArrayList<Section>(lElm.size());
for (Element el : lElm) {
ret.add(new Section(el));
}
return ret;
}
public void add(Range x){
eRecord.addContent(x.el);
}
public void remove(Range x){
eRecord.removeContent(x.el);
}
}
/**
* A style is a display hint for a given Record or Range a Record can have several styles for
* several output media.
*
*/
public static class Style {
/** Opacity from 0 (transparent) to 1 (opaque) */
private double opacity;
/** Background color as rgb */
private long rgbBackground;
}
/**
* A Range is a part of the text. It is defined by a position, a length and a type.
*
*/
public static class Range {
public static final String ATTR_LENGTH = "length"; //$NON-NLS-1$
public static final String ATTR_FROM = "from"; //$NON-NLS-1$
protected Element el;
Range(Element e){
el = e;
}
Range(String typ, int pos, int length){
el = new Element(typ, ns);
el.setAttribute(ATTR_FROM, Integer.toString(pos));
el.setAttribute(ATTR_LENGTH, Integer.toString(length));
}
public int getPos(){
return Integer.parseInt(el.getAttributeValue(ATTR_FROM));
}
public void setPos(int p){
el.setAttribute(ATTR_FROM, Integer.toString(p));
}
public int getLength(){
return Integer.parseInt(el.getAttributeValue(ATTR_LENGTH));
}
}
/**
* An XRef is a range that defines a crossreference to some other piece of information it can
* define a class that can handle its contents
*
* @author Gerry
*
*/
public static class XRef extends Range {
public static final String ATTR_ID = "id"; //$NON-NLS-1$
public static final String ATTR_PROVIDER = "provider"; //$NON-NLS-1$
XRef(Element e){
super(e);
}
public XRef(String provider, String id, int pos, int length){
super("xref", pos, length); //$NON-NLS-1$
el.setAttribute(ATTR_PROVIDER, provider);
el.setAttribute(ATTR_ID, id);
}
public String getProvider(){
return el.getAttributeValue(ATTR_PROVIDER);
}
public String getID(){
return el.getAttributeValue(ATTR_ID);
}
}
/**
* A Markup is a Range that defines some text attributes
*
* @author Gerry
*
*/
public static class Markup extends Range {
public static final String ATTR_TYPE = "type"; //$NON-NLS-1$
Markup(Element e){
super(e);
}
public Markup(int pos, int length, String typ){
super("markup", pos, length); //$NON-NLS-1$
el.setAttribute(ATTR_TYPE, typ);
}
public String getType(){
return el.getAttributeValue(ATTR_TYPE);
}
}
/**
* A Section is a Markup that summarizes a piece of text unter a section header.
*
* @author Gerry
*
*/
public static class Section extends Range {
private static final String ATTR_NAME = "name"; //$NON-NLS-1$
Section(Element e){
super(e);
}
public Section(int pos, int length, String name){
super("section", pos, length); //$NON-NLS-1$
el.setAttribute(ATTR_NAME, name);
}
}
public static class Box {
}
@Deprecated
public static class Finding {
protected Element el;
Finding(Element e){
el = e;
}
Finding(String typ, String date, String labEAN, boolean abnormal){
el = new Element(typ);
el.setAttribute("date", date); //$NON-NLS-1$
el.setAttribute("labEAN", labEAN); //$NON-NLS-1$
el.setAttribute("abnormal", Boolean.toString(abnormal).toLowerCase()); //$NON-NLS-1$
}
public TimeTool getDate(){
return new TimeTool(el.getAttributeValue("date")); //$NON-NLS-1$
}
public boolean isAbnormal(){
return (el.getAttributeValue("abormal").equals("true")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@Deprecated
public static class Analyse extends Finding {
public Analyse(){
super(new Element("analysis")); //$NON-NLS-1$
}
}
@Deprecated
public static class Image extends Finding {
public Image(){
super(new Element("image")); //$NON-NLS-1$
}
}
@Deprecated
public static class ECG extends Finding {
public ECG(){
super(new Element("ecg")); //$NON-NLS-1$
}
}
}