/*******************************************************************************
* Copyright (c) 2010, Oliver Egger, visionary ag
*
* 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
*
*******************************************************************************/
package ch.docbox.model;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.program.Program;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.docbox.cdach.CdaChXPath;
import ch.docbox.elexis.UserDocboxPreferences;
import ch.elexis.core.data.activator.CoreHub;
import ch.elexis.core.ui.UiDesk;
import ch.elexis.data.Anwender;
import ch.elexis.data.Patient;
import ch.elexis.data.PersistentObject;
import ch.elexis.data.Query;
import ch.rgw.tools.ExHandler;
import ch.rgw.tools.TimeTool;
import ch.rgw.tools.VersionInfo;
public class CdaMessage extends PersistentObject {
private static Logger logger = LoggerFactory.getLogger(CdaMessage.class);
public static final String TABLENAME = "CH_DOCBOX_ELEXIS_CDAMESSAGE";
public static final String DBVERSION = "1.1.0";
public static final String createDB =
"CREATE TABLE " + TABLENAME + " (" + "ID VARCHAR(25) primary key,"
+ "CreationDate VARCHAR(15)," + "Deleted CHAR(1) default '0',"
+ "DeletedDocs CHAR(1) default '0'," + "lastupdate BIGINT,"
+ "PatID VARCHAR(25)," + "DocumentID VARCHAR(25)," + "AnwenderID VARCHAR(25),"
+ "KonsultationID VARCHAR(25)," + "Downloaded CHAR(1) default '0',"
+ "Date CHAR(24)," + "Unread CHAR(1) default '1',"
+ "Title VARCHAR(255)," + "Sender VARCHAR(255),"
+ "Patient VARCHAR(255)," + "FilesListing VARCHAR(2048)," + "Cda BLOB);"
+ "CREATE INDEX CH_DOCBOX_ELEXIS_CDAMESSAGEI1 ON " + TABLENAME + " (PatID);"
+ "CREATE INDEX CH_DOCBOX_ELEXIS_CDAMESSAGEI2 ON " + TABLENAME + " (DocumentID);"
+ "CREATE INDEX CH_DOCBOX_ELEXIS_CDAMESSAGEI3 ON " + TABLENAME + " (AnwenderID);"
+ "CREATE INDEX CH_DOCBOX_ELEXIS_CDAMESSAGEI4 ON " + TABLENAME + " (ID);" + "INSERT INTO "
+ TABLENAME + " (ID, TITLE) VALUES ('1','" + DBVERSION + "');";
public static final String upd110 = "ALTER TABLE " + TABLENAME //$NON-NLS-1$
+ " MODIFY Title VARCHAR(255);" + "ALTER TABLE " + TABLENAME //$NON-NLS-1$ //$NON-NLS-2$
+ " MODIFY Sender VARCHAR(255);" + "ALTER TABLE " + TABLENAME //$NON-NLS-1$ //$NON-NLS-2$
+ " MODIFY Patient VARCHAR(255);"; //$NON-NLS-1$
static {
addMapping(TABLENAME, "CreationDate", "DeletedDocs", "PatID", "DocumentID", "AnwenderID",
"KonsultationID", "Downloaded", "Unread", "Date", "Title", "Sender", "Patient",
"FilesListing", "Cda");
CdaMessage start = load("1");
if (start == null) {
init();
} else {
VersionInfo vi = new VersionInfo(start.get("Title"));
if (vi.isOlder(DBVERSION)) {
if (vi.isOlder("1.1.0")) { //$NON-NLS-1$
createOrModifyTable(upd110);
start.set("Title", DBVERSION);
} else {
MessageDialog.openError(UiDesk.getTopShell(), "Versionskonsflikt",
"Die Datentabelle für " + TABLENAME
+ " hat eine zu alte Versionsnummer. Dies kann zu Fehlern führen");
}
}
}
}
public static CdaMessage load(String id){
CdaMessage ret = new CdaMessage(id);
if (ret.exists()) {
return ret;
}
return null;
}
public static CdaMessage getCdaMessageEvenIfDocsDeleted(String documentId){
return getCdaMessage(CoreHub.actMandant, documentId, true);
}
public static CdaMessage getCdaMessage(String documentId){
return getCdaMessage(CoreHub.actMandant, documentId, false);
}
public static CdaMessage getCdaMessage(Anwender anwender, String documentId,
boolean alsoDeletedDoc){
Query<CdaMessage> cdaMessageQuery = new Query<CdaMessage>(CdaMessage.class);
cdaMessageQuery.add("AnwenderID", "=", anwender.getId());
cdaMessageQuery.add("DocumentID", "=", documentId);
if (!alsoDeletedDoc) {
cdaMessageQuery.add("DeletedDocs", "=", "0");
}
Object[] cdaMessages = cdaMessageQuery.execute().toArray();
if (cdaMessages == null || cdaMessages.length == 0) {
return null;
}
if (cdaMessages.length > 1) {
logger
.error("CdaMessage Query should give only one object back but got multiple with AnwenderID= "
+ anwender.getId() + ", documentID " + documentId);
}
return (CdaMessage) cdaMessages[0];
}
public static Object[] getCdaMessages(){
return getCdaMessages(CoreHub.actMandant, false);
}
public static Object[] getCdaMessages(Anwender anwender, boolean alsoDeletedDoc){
if (anwender != null) {
logger.debug("getCdaMessages for " + anwender.getId());
Query<CdaMessage> cdaMessageQuery = new Query<CdaMessage>(CdaMessage.class);
cdaMessageQuery.add("AnwenderID", "=", anwender.getId());
if (!alsoDeletedDoc) {
cdaMessageQuery.add("DeletedDocs", "=", "0");
}
cdaMessageQuery.orderBy(true, "CreationDate");
Object[] objects = cdaMessageQuery.execute().toArray();
logger.debug("returned cdaMessages" + objects.length);
return objects;
}
return new CdaMessage[0];
}
public CdaMessage(String documentId, String title, GregorianCalendar date){
create(null);
TimeTool timeTool = new TimeTool();
timeTool.set(date);
set(new String[] {
"AnwenderID", "DocumentID", "Title", "Date", "CreationDate", "Unread"
}, CoreHub.actMandant.getId(), documentId, title, timeTool.toString(TimeTool.DATE_GER),
timeTool.toString(TimeTool.TIMESTAMP), "1");
}
public boolean setDownloaded(String sender, String patient){
return set(new String[] {
"Sender", "Patient", "Downloaded"
}, sender, patient, "1");
}
public boolean setCda(String cda){
if (cda != null) {
try {
setBinary("Cda", cda.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
return false;
}
}
return true;
}
public String getCda(){
try {
return new String(getBinary("Cda"), "UTF-8");
} catch (UnsupportedEncodingException e) {} catch (NullPointerException e) {}
return null;
}
public static void init(){
createOrModifyTable(createDB);
}
@Override
public String getLabel(){
StringBuilder sb = new StringBuilder();
sb.append(get("Date")).append(" ").append(get("Title"));
return sb.toString();
}
static public boolean deleteDirectory(File path){
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
public boolean deleteDocs(){
if (this.getFiles() != null && this.getFiles().length > 0) {
try {
deleteDirectory(new File(this.getPath()));
} catch (Exception e) {}
}
setDeletedDocs();
return true;
}
/**
* currently all files are opened, if multiple we have not yet a selection possiblity
*
* @return
*/
public boolean execute(){
String files[] = this.getFiles();
if (files != null && files.length > 0) {
for (String file : files) {
int pos = file.lastIndexOf(".");
String ext = "";
if (pos > 0) {
ext = file.substring(pos);
}
if (ext != null) {
ext = ext.trim();
}
String path = getPath(file);
if (path != null) {
path = path.trim();
}
try {
Program program = Program.findProgram(ext);
if (program != null) {
program.execute(path);
} else {
if (Program.launch(path) == false) {
Runtime.getRuntime().exec(path);
}
}
} catch (Exception ex) {
ExHandler.handle(ex);
}
}
return true;
}
return false;
}
@Override
protected String getTableName(){
return TABLENAME;
}
protected CdaMessage(String id){
super(id);
}
protected CdaMessage(){}
public boolean isDownloaded(){
return getInt("Downloaded") != 0;
}
public boolean isDeletedDocs(){
return getInt("DeletedDocs") != 0;
}
public void setDeletedDocs(){
set(new String[] {
"DeletedDocs"
}, "1");
}
public void setRead(){
set(new String[] {
"Unread"
}, "0");
}
public boolean isUnread(){
return getInt("Unread") != 0;
}
public String getDate(){
return get("Date");
}
public String getCreationDate(){
return get("CreationDate");
}
public String getTitle(){
return get("Title");
}
public String getSender(){
return get("Sender");
}
public String getPatient(){
return get("Patient");
}
public String getFilesListing(){
return get("FilesListing");
}
public String[] getFiles(){
return getFilesListing().split("\n");
}
public boolean hasAssignedToOmnivore(){
return "ok".equals(getKonsultationId());
}
private String getKonsultationId(){
return get("KonsultationID");
}
public void setAssignedToOmnivore(){
set(new String[] {
"KonsultationID"
}, "ok");
}
/**
* returns the path where we will store the attachmetns
*/
public String getPath(String fileName){
String path = UserDocboxPreferences.getPathFiles();
String pathSeparator = System.getProperty("file.separator");
if (!path.endsWith(pathSeparator)) {
path = path + pathSeparator;
}
path = path + getId();
if (fileName != null) {
path += pathSeparator + fileName;
}
return path;
}
private String getPath(){
return getPath(null);
}
/**
* unzips the attachments to the specified directory in a subdirectory and sets the files
* extracted in the field fileslistings
*
* @param attachment
* byte array of a zip file
* @return true if successful false otherwise
*/
public boolean unzipAttachment(byte[] attachment){
ArrayList<String> fileList = new ArrayList<String>();
ByteArrayInputStream inputStream = new ByteArrayInputStream(attachment);
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry zipEntry = null;
String path = this.getPath();
try {
File directory = new File(path);
if (!directory.exists()) {
directory.mkdir();
}
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (!zipEntry.isDirectory()) {
String fileName = zipEntry.getName();
fileList.add(fileName);
if (fileName.contains("/")) {
fileName = fileName.replaceAll("/", "");
}
if (fileName.contains("\\")) {
fileName = fileName.replaceAll("\\\\", "");
}
logger.debug("exporting file out of attachment to " + path + "," + fileName);
File file = new File(directory, fileName);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] bytesEntry = new byte[1024];
int read = 0;
while ((read = zipInputStream.read(bytesEntry)) != -1) {
fileOutputStream.write(bytesEntry, 0, read);
}
fileOutputStream.close();
}
zipInputStream.closeEntry();
}
zipInputStream.close();
String fileListConcatenated = "";
for (int i = 0; i < fileList.size(); ++i) {
fileListConcatenated += fileList.get(i);
if (i < fileList.size() - 1) {
fileListConcatenated += " \n";
}
}
return set("FilesListing", fileListConcatenated);
} catch (Exception e) {
logger.error("Exception " + e.toString());
}
return false;
}
@Override
public boolean isDragOK(){
return true;
}
public boolean isEqualsPatient(Patient patient){
CdaChXPath cdaChXPath = new CdaChXPath();
String cda = getCda();
if (patient == null) {
return false;
}
if (cda != null) {
cdaChXPath.setPatientDocument(cda);
String lastName = cdaChXPath.getPatientLastName();
String firstName = cdaChXPath.getPatientFirstName();
String patientId = cdaChXPath.getPatientNumber();
if (patientId != null && patientId.equals(patient.getId())) {
return true;
}
if ((lastName == null || lastName.equals(patient.getName()))
&& (firstName == null || firstName.equals(patient.getVorname()))) {
return true;
}
}
return false;
}
static public boolean deleteCdaMessages(Anwender anwender){
Object[] cdaMessages = getCdaMessages(anwender, true);
if (cdaMessages != null) {
logger.debug("trying to remove cdamessage " + cdaMessages.length);
try {
for (Object cdaMessageObject : cdaMessages) {
CdaMessage cdaMessage = (CdaMessage) cdaMessageObject;
logger.debug("deleting docs with id" + cdaMessage.getId());
cdaMessage.deleteDocs();
logger.debug("deleting cdaMessage with id" + cdaMessage.getId());
cdaMessage.delete();
}
} catch (Exception e) {
logger.debug("deleting message failed");
}
}
return true;
}
}