/******************************************************************************* * Copyright (c) 2009, A. Kaufmann 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: * A. Kaufmann - initial implementation * P. Chaubert - adapted to Messwerte V2 * medshare GmbH - adapted to Messwerte V2.1 in February 2012 * *******************************************************************************/ package com.hilotec.elexis.messwerte.v2.data; import java.io.File; import java.text.MessageFormat; import java.util.ArrayList; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Widget; import ch.elexis.core.data.activator.CoreHub; import ch.elexis.core.data.events.ElexisEventDispatcher; import ch.elexis.core.data.interfaces.scripting.Interpreter; import ch.elexis.core.data.util.PlatformHelper; import ch.elexis.core.exceptions.ElexisException; import ch.elexis.core.ui.Hub; import ch.elexis.core.ui.util.SWTHelper; import ch.elexis.data.Fall; import ch.elexis.data.Konsultation; import ch.elexis.data.Script; import ch.rgw.tools.Log; import ch.rgw.tools.TimeTool; import com.hilotec.elexis.messwerte.v2.data.typen.IMesswertTyp; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypBool; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypCalc; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypData; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypDate; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypEnum; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypNum; import com.hilotec.elexis.messwerte.v2.data.typen.MesswertTypStr; /** * Abstrakte Basisklasse fuer die einzelnen Messwerttypen * * @author Antoine Kaufmann */ public abstract class MesswertBase { public static String ICON_TRANSPARENT = "transparent.png"; //$NON-NLS-1$ protected static String ICON_RED = "pin_red.png"; //$NON-NLS-1$ protected static String ICON_YELLOW = "pin_yellow.png"; //$NON-NLS-1$ protected static String ICON_GREEN = "pin_green.png"; //$NON-NLS-1$ protected static String ICON_BLUE = "pin_blue.png"; //$NON-NLS-1$ protected static String ICON_BLACK = "pin_black.png"; //$NON-NLS-1$ protected final Log log = Log.get("Messwerte"); //$NON-NLS-1$ private final String name; private final String title; private final String unit; protected boolean editable = true; private String validpattern; private String invalidmessage; private String size; private boolean isShown = false; protected Widget widget; private Boolean alerts = false; private Double highAlert = Double.MAX_VALUE; private Double highWarning = Double.MAX_VALUE; private Double lowWarning = Double.MIN_VALUE; private Double lowAlert = Double.MIN_VALUE; public final static int SEVERITY_LEVEL_UNDEFINED = Integer.MAX_VALUE; public final static int SEVERITY_LEVEL_LOW_ALERT = -2; public final static int SEVERITY_LEVEL_LOW_WARNING = -1; public final static int SEVERITY_LEVEL_NORMAL = 0; public final static int SEVERITY_LEVEL_HIGH_WARNING = 1; public final static int SEVERITY_LEVEL_HIGH_ALERT = 2; /** * Eigentlicher Code der Formel */ protected String formula; /** * Interpreter, der benutzt werden soll, um die */ protected String interpreter; /** * Liste mit den Variablen die fuer die Formel gesetzt werden sollen */ protected final ArrayList<CalcVar> variables = new ArrayList<CalcVar>(); public MesswertBase(String n, String t, String u){ name = n; title = t; unit = u; } public String getName(){ return name; } public String getTitle(){ return title; } public String getUnit(){ return unit; } public boolean isEditable(){ return editable; } public void setEditable(boolean editable){ this.editable = editable; } public String getValidpattern(){ return validpattern; } public void setValidpattern(String validpattern){ this.validpattern = validpattern; } public String getInvalidmessage(){ return invalidmessage; } public void setInvalidmessage(String invalidmessage){ this.invalidmessage = invalidmessage; } public String getSize(){ return size; } public void setSize(String size){ this.size = size; } public void saveInput(Messwert messwert){} public boolean checkInput(Messwert messwert, String pattern){ IMesswertTyp typ = messwert.getTyp(); if (typ.isAlertEnabled()) { String path = PlatformHelper.getBasePath("com.hilotec.elexis.messwerte.v2") + File.separator //$NON-NLS-1$ + "rsc" + File.separator; //$NON-NLS-1$ Label lab = messwert.getIconLabel(); Image image = null; switch (typ.getSeverityLevel(widget)) { case MesswertBase.SEVERITY_LEVEL_UNDEFINED: image = new Image(lab.getDisplay(), path + ICON_TRANSPARENT); break; case MesswertBase.SEVERITY_LEVEL_HIGH_ALERT: image = new Image(lab.getDisplay(), path + ICON_RED); break; case MesswertBase.SEVERITY_LEVEL_HIGH_WARNING: image = new Image(lab.getDisplay(), path + ICON_YELLOW); break; case MesswertBase.SEVERITY_LEVEL_NORMAL: image = new Image(lab.getDisplay(), path + ICON_GREEN); break; case MesswertBase.SEVERITY_LEVEL_LOW_WARNING: image = new Image(lab.getDisplay(), path + ICON_BLUE); break; case MesswertBase.SEVERITY_LEVEL_LOW_ALERT: image = new Image(lab.getDisplay(), path + ICON_BLACK); break; } if (image != null) lab.setImage(image); } return true; } public String getActualValue(){ return ""; //$NON-NLS-1$ } public boolean isShown(){ return isShown; } public void setShown(boolean isShown){ this.isShown = isShown; } /** * Kontext des Interpreters vorbereiten um die Formel auswerten zu koennen. Dabei werden die * Variablen importiert. * * TODO: Ist noch Beanshell-spezifisch * * @param interpreter * Interpreter * @param messung * Messung in der die Formel ausgewertet werden soll * @throws EvalError */ protected void interpreterSetzeKontext(Interpreter interpreter, Messung messung) throws ElexisException{ for (CalcVar cv : variables) { Object wert = holeVariable(messung, cv.getName(), cv.getSource()); if (wert != null) { interpreter.setValue(cv.getName(), wert); } } interpreter.setValue("actPatient", ElexisEventDispatcher.getSelectedPatient()); //$NON-NLS-1$ interpreter.setValue("actFall", ElexisEventDispatcher.getSelected(Fall.class)); //$NON-NLS-1$ interpreter.setValue("actKons", ElexisEventDispatcher.getSelected(Konsultation.class)); //$NON-NLS-1$ interpreter.setValue("actMandant", CoreHub.actMandant); //$NON-NLS-1$ interpreter.setValue("actUser", CoreHub.actUser); //$NON-NLS-1$ interpreter.setValue("Elexis", Hub.plugin); //$NON-NLS-1$ } /** * Wert einer Variable fuer die Formel bestimmen * * @param messung * Messung in der die Formel ausgewertet werten soll * @param name * Name der Variable. Kann mit . getrennt sein, wenn sich links vom Punkt jeweils ein * Data-Feld befindet, dabei bezieht sich der Teil rechts vom Punkt auf das Feld in * dem referenzierten Objekt. * @param source * Quelle der Variable * * @return Wert der dem Interpreter uebergeben werden soll. Haengt vom typ der Variable ab. */ protected Object holeVariable(Messung messung, String name, String source){ if (messung == null) { return "messung?"; //$NON-NLS-1$ } if (source == null) { return "source?"; //$NON-NLS-1$ } String[] parts = source.split("\\."); //$NON-NLS-1$ Messwert messwert = messung.getMesswert(parts[0]); IMesswertTyp typ = messwert.getTyp(); if (parts.length == 1) { if (typ instanceof MesswertTypNum) { if (typ.isShown()) { return Double.parseDouble(typ.getActualValue()); } else { return Double.parseDouble(messwert.getWert()); } } else if (typ instanceof MesswertTypBool) { if (typ.isShown()) { return Boolean.parseBoolean(typ.getActualValue()); } else { return Boolean.parseBoolean(messwert.getWert()); } } else if (typ instanceof MesswertTypStr) { if (typ.isShown()) { return typ.getActualValue(); } else { return messwert.getWert(); } } else if (typ instanceof MesswertTypCalc) { if (typ.isShown()) { return Double.parseDouble(typ.getActualValue()); } else { return Double.parseDouble(messwert.getDarstellungswert()); } } else if (typ instanceof MesswertTypEnum) { if (typ.isShown()) { return Integer.parseInt(typ.getActualValue()); } else { return Integer.parseInt(messwert.getWert()); } } else if (typ instanceof MesswertTypDate) { TimeTool tt; if (typ.isShown()) { tt = new TimeTool(typ.getActualValue()); } else { tt = new TimeTool(messwert.getWert()); } return tt.getTimeInMillis(); // if (typ.isShown()) { // TimeTool tt = new TimeTool(typ.getActualValue()); // return tt.get(TimeTool.YEAR) * 365 + tt.get(TimeTool.DAY_OF_YEAR); // } else { // TimeTool tt = new TimeTool(messwert.getWert()); // return tt.get(TimeTool.YEAR) * 365 + tt.get(TimeTool.DAY_OF_YEAR); // } } else if (typ instanceof MesswertTypData) { log.log(MessageFormat.format(Messages.MesswertBase_Failure1, name, Messages.MesswertBase_DataField), Log.ERRORS); return null; } } if (!(typ instanceof MesswertTypData)) { log.log(MessageFormat.format(Messages.MesswertBase_Failure1, name, Messages.MesswertBase_NoData), Log.ERRORS); return null; } MesswertTypData t = (MesswertTypData) typ; Messung dm = t.getMessung(messwert); return holeVariable(dm, name + "." + parts[0], source.substring(source.indexOf(".") + 1)); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Interne Klasse die eine Variable fuer die Formel darstellt(nur deklaration). * * @author Antoine Kaufmann */ private class CalcVar { /** * Name der Variable */ private final String name; /** * Quelle der Variable(meist Feldname in der Messung) */ private final String source; CalcVar(String n, String s){ name = n; source = s; } String getName(){ return name; } String getSource(){ return source; } } /** * Neue Variable hinzufuegen * * @param name * Name der Variable * @param source * Quelle fuer den Variableninhalt */ public void addVariable(String name, String source){ variables.add(new CalcVar(name, source)); } /** * Formel, die berechnet werden soll, setzen. * * @param f * Formel * @param i * Interpreter fuer die Formel */ public void setFormula(String f, String i){ formula = f; interpreter = i; } public String evalateFormula(String formula, Messwert messwert){ return evalateFormula(formula, messwert, ""); //$NON-NLS-1$ } public String evalateFormula(String formula, Messwert messwert, String defaultValue){ try { Interpreter interpreter = Script.getInterpreterFor(formula); Messung messung = null; if (messwert != null) messung = messwert.getMessung(); interpreterSetzeKontext(interpreter, messung); Object wert = interpreter.run(formula, false); if (wert == null) wert = defaultValue; return String.valueOf(wert); } catch (ElexisException e) { e.printStackTrace(); String message = MessageFormat .format(Messages.MesswertBase_Failure2, formula.trim(), e.getMessage()); log.log(message, Log.ERRORS); if (System.getProperty("com.hilotec.unitests") == null || !System.getProperty("com.hilotec.unitests").equals("1")) SWTHelper.showError(Messages.DataAccessor_Title, message); } catch (Throwable e) { e.printStackTrace(); } return defaultValue; } public void setLowAlertValue(String value){ alerts = true; lowAlert = Double.MIN_VALUE; try { lowAlert = Double.parseDouble(value); } finally {} } public void setLowWarningValue(String value){ alerts = true; lowWarning = Double.MIN_VALUE; try { lowWarning = Double.parseDouble(value); } finally {} } public void setHighAlertValue(String value){ alerts = true; highAlert = Double.MAX_VALUE; try { highAlert = Double.parseDouble(value); } finally {} } public void setHighWarningValue(String value){ alerts = true; highWarning = Double.MAX_VALUE; try { highWarning = Double.parseDouble(value); } finally {} } public Boolean isAlertEnabled(){ return alerts; } public int getSeverityLevel(Widget widget){ int retVal = SEVERITY_LEVEL_UNDEFINED; try { String strValue = ((Text) widget).getText(); Double value = Double.parseDouble(strValue); retVal = SEVERITY_LEVEL_NORMAL; if (value > highAlert) { retVal = SEVERITY_LEVEL_HIGH_ALERT; } else if (value > highWarning) { retVal = SEVERITY_LEVEL_HIGH_WARNING; } else if (value < lowAlert) { retVal = SEVERITY_LEVEL_LOW_ALERT; } else if (value < lowWarning) { retVal = SEVERITY_LEVEL_LOW_WARNING; } } catch (Exception e) {} return retVal; } }