/******************************************************************************* * 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.elexis; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Vector; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Text; import org.hl7.v3.ClinicalDocumentType; import org.hl7.v3.POCDMT000040Author; import org.hl7.v3.POCDMT000040Custodian; import org.hl7.v3.POCDMT000040InformationRecipient; import org.hl7.v3.POCDMT000040RecordTarget; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import ch.docbox.cdach.DocboxCDA; import ch.docbox.model.DocboxContact; import ch.docbox.ws.cdachservices.CDACHServices; import ch.docbox.ws.cdachservices.CDACHServices_Service; import ch.elexis.core.constants.StringConstants; import ch.elexis.core.data.activator.CoreHub; import ch.elexis.core.services.IFormattedOutput; import ch.elexis.core.services.IFormattedOutputFactory; import ch.elexis.core.services.IFormattedOutputFactory.ObjectType; import ch.elexis.core.services.IFormattedOutputFactory.OutputType; import ch.elexis.core.ui.UiDesk; import ch.elexis.core.ui.util.SWTHelper; import ch.elexis.data.Fall; import ch.elexis.data.Kontakt; import ch.elexis.data.Patient; import ch.elexis.data.Person; import ch.elexis.data.Query; import ch.rgw.tools.ExHandler; import ch.rgw.tools.TimeTool; public class DocboxArztArztDialog extends TitleAreaDialog { private Patient patient; private Kontakt kontakt; private DocboxCDA docboxCDA = new DocboxCDA(); private Text textTitle, textMessage; private ArrayList<Kontakt> kontakte; private Combo comboDoctor; private org.eclipse.swt.widgets.List listAttachments; public DocboxArztArztDialog(Patient patient, Kontakt kontakt){ super(UiDesk.getTopShell()); this.patient = patient; this.kontakt = kontakt; this.kontakte = new ArrayList<Kontakt>(); } @Override protected Control createDialogArea(final Composite parent){ Composite com = new Composite(parent, SWT.NONE); com.setLayoutData(SWTHelper.getFillGridData(1, true, 1, true)); com.setLayout(new GridLayout(2, false)); Label label; label = new Label(com, SWT.NONE); label.setText(Messages.DocboxArztArztDialog_TextPatient); label = new Label(com, SWT.NONE); label.setText(patient.getLabel()); label = new Label(com, SWT.NONE); label.setText(Messages.DocboxArztArztDialog_TextDoctor); comboDoctor = new Combo(com, SWT.VERTICAL | SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); Query<Kontakt> qbe = new Query<Kontakt>(Kontakt.class); List<Kontakt> list = qbe.execute(); for (Kontakt k : list) { Boolean isDoc2Doc = (Boolean) k.getInfoElement("doctodoc"); if (isDoc2Doc != null && isDoc2Doc.booleanValue()) { comboDoctor.add(k.getLabel()); kontakte.add(k); } } if (kontakt != null) { comboDoctor.setText(kontakt.getLabel()); } label = new Label(com, SWT.NONE); label.setText(Messages.DocboxArztArztDialog_TextTitle); textTitle = new Text(com, SWT.BORDER); textTitle.setText(""); textTitle.setLayoutData(SWTHelper.getFillGridData(1, true, 1, false)); Label l2 = new Label(com, SWT.NONE); l2.setText(Messages.DocboxArztArztDialog_TextMessage); textMessage = new Text(com, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); textMessage.setText("\n\n\n\n\n"); textMessage.setLayoutData(SWTHelper.getFillGridData(1, true, 1, false)); label = new Label(com, SWT.NONE); label.setText(Messages.DocboxArztArztDialog_TextAttachments); listAttachments = new org.eclipse.swt.widgets.List(com, SWT.SINGLE | SWT.V_SCROLL); listAttachments.setLayoutData(SWTHelper.getFillGridData(1, true, 1, false)); listAttachments.addListener(SWT.KeyUp, new Listener() { public void handleEvent(Event e){ if (e.keyCode == SWT.DEL || e.keyCode == SWT.BS) { if (listAttachments.isFocusControl()) { int index = listAttachments.getSelectionIndex(); if (index != 0) { listAttachments.remove(index); } } } } }); // dummy emtpy label for button label = new Label(com, SWT.NONE); Button addAttachments = new Button(com, SWT.PUSH); addAttachments.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0){ FileDialog fd = new FileDialog(UiDesk.getTopShell(), SWT.MULTI); fd.setText("Öffnen"); String[] filterExt = { "*.*", "*.doc", "*.docx", "*.doc", "*.gif", "*.jpeg", "*.jpg", "*.mov", "*.mp3", "*.mpeg", "*.pdf", "*.png", "*.ppt", "*.tiff", "*.txt", "*.xls", "*.xlsx", "*.zip", "*.odt", "*.html", "*.htm", "*.rtf", "*.oft", "*.pptx", "*.pps", "*.rpt", "*.vcf", "*.xml", "*.csv" }; fd.setFilterExtensions(filterExt); String selected = fd.open(); if (selected != null) { // Append all the selected files. Since getFileNames() returns only // the names, and not the path, prepend the path, normalizing // if necessary String[] files = fd.getFileNames(); for (int i = 0, n = files.length; i < n; i++) { StringBuffer buf = new StringBuffer(); buf.append(fd.getFilterPath()); if (buf.charAt(buf.length() - 1) != File.separatorChar) { buf.append(File.separatorChar); } buf.append(files[i]); listAttachments.add(buf.toString()); } } } }); addAttachments.setText(Messages.DocboxArztArztDialog_ButtonAddAttachments); return com; } @Override public void create(){ setShellStyle(getShellStyle() | SWT.RESIZE); super.create(); setMessage(Messages.DocboxArztArztDialog_Title); if (UiDesk.getImage(Activator.IMG_DOC2DOC) == null) { UiDesk.getImageRegistry().put(Activator.IMG_DOC2DOC, Activator.getImageDescriptor(Activator.IMG_DOC2DOC_PATH)); } setTitleImage(UiDesk.getImageRegistry().get(Activator.IMG_DOC2DOC)); } @Override protected void okPressed(){ final String title = textTitle.getText(); final String message = textMessage.getText(); final String filename = "ueberweisung.pdf"; final String[] attachments = listAttachments.getItems(); final javax.xml.ws.Holder<java.lang.Boolean> success = new javax.xml.ws.Holder<java.lang.Boolean>(); final javax.xml.ws.Holder<java.lang.String> errorMessage = new javax.xml.ws.Holder<java.lang.String>(); final javax.xml.ws.Holder<java.lang.String> documentId = new javax.xml.ws.Holder<java.lang.String>(); if (comboDoctor.getSelectionIndex() == -1) { MessageBox box = new MessageBox(UiDesk.getDisplay().getActiveShell(), SWT.ICON_ERROR); box.setText(Messages.DocboxArztArztAction_NoDoctorSelectedText); box.setMessage(Messages.DocboxArztArztAction_NoDoctorSelectedMessage); box.open(); return; } else { kontakt = this.kontakte.get(comboDoctor.getSelectionIndex()); } Runnable longJob = new Runnable() { boolean done = false; public void stop(String errMsg){ if (errMsg != null) { errorMessage.value = errMsg; } done = true; UiDesk.getDisplay().wake(); } public void run(){ Thread thread = new Thread(new Runnable() { public void run(){ success.value = Boolean.FALSE; try { final ClinicalDocumentType cda = getArztArztCda(null, title, message, filename, attachments); if (cda == null) { stop(Messages.DocboxArztArztAction_NoCdaGeneratedMessage); return; } byte[] xml = getClincicalDocumentSerialized(cda); if (xml == null) { stop(Messages.DocboxArztArztAction_NoXmlGeneratedMessage); return; } ByteArrayOutputStream pdfOut = getArztArztPdf(xml); if (pdfOut == null) { stop(Messages.DocboxArztArztAction_NoPdfGeneratedMessage); return; } final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ZipOutputStream out = new ZipOutputStream(byteArrayOutputStream); try { out.putNextEntry(new ZipEntry(filename)); pdfOut.writeTo(out); out.closeEntry(); if (attachments != null) { for (String attachFile : attachments) { String fileName = attachFile; if (fileName.indexOf("/") >= 0) { fileName = fileName.substring(fileName.lastIndexOf("/") + 1); } if (fileName.indexOf("\\") >= 0) { fileName = fileName.substring(fileName.lastIndexOf("\\") + 1); } out.putNextEntry(new ZipEntry(fileName)); int len = 0; InputStream in = new FileInputStream(attachFile); byte[] buf = new byte[1024]; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } out.closeEntry(); in.close(); } } out.close(); } catch (IOException e) { ExHandler.handle(e); stop(Messages.DocboxArztArztAction_NoZipGeneratedMessage); return; } CDACHServices port = UserDocboxPreferences.getPort(); port.sendClinicalDocument(cda, byteArrayOutputStream.toByteArray(), success, errorMessage, documentId); if (!success.value.booleanValue()) { stop(Messages.DocboxArztArztAction_SendDocumentFailed + "\n" + errorMessage.value); return; } } catch (Exception e) { ExHandler.handle(e); stop(Messages.DocboxArztArztAction_SendDocumentFailed + "\n" + errorMessage.value); return; } done = true; UiDesk.getDisplay().wake(); } }); thread.start(); while (!done && (UiDesk.getTopShell() == null || !UiDesk.getTopShell().isDisposed())) { if (!UiDesk.getDisplay().readAndDispatch()) UiDesk.getDisplay().sleep(); } } }; BusyIndicator.showWhile(UiDesk.getDisplay(), longJob); if (success != null && success.value != null && !success.value.booleanValue()) { MessageBox box = new MessageBox(UiDesk.getDisplay().getActiveShell(), SWT.ICON_ERROR); box.setText(Messages.UserDocboxPreferences_ConnectionTestWithDocbox); box.setMessage(errorMessage.value); box.open(); } else { super.okPressed(); Activator.docboxBackgroundJob.schedule(); } } private byte[] getClincicalDocumentSerialized(ClinicalDocumentType cda){ final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?xml-stylesheet type='text/xsl' href='./Terminvereinbarung.xsl'?>\n" + docboxCDA.marshallIntoString(cda.getClinicalDocument()); try { return xml.getBytes("UTF8"); } catch (final UnsupportedEncodingException e) { ExHandler.handle(e); } return null; } // FIXME FOP xml-api library crashes as eclipse plugin // http://www.mail-archive.com/fop-users@xmlgraphics.apache.org/msg12100.html private ByteArrayOutputStream getArztArztPdf(byte[] xmlData){ if (xmlData == null) { return null; } ByteArrayOutputStream pdfOut = new ByteArrayOutputStream(); BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext(); ServiceReference<IFormattedOutputFactory> fopFactoryRef = bundleContext.getServiceReference(IFormattedOutputFactory.class); if (fopFactoryRef != null) { try { IFormattedOutputFactory fopFactory = bundleContext.getService(fopFactoryRef); IFormattedOutput foOutputt = fopFactory .getFormattedOutputImplementation(ObjectType.XMLSTREAM, OutputType.PDF); ByteArrayInputStream stream = new ByteArrayInputStream(xmlData); URL xsl = CDACHServices_Service.class .getResource("/rsc/ch/docbox/ws/cdachservices/ArztArzt.xsl"); foOutputt.transform(stream, xsl.openStream(), pdfOut); } catch (IllegalStateException e) { ExHandler.handle(e); } catch (IOException e) { ExHandler.handle(e); } bundleContext.ungetService(fopFactoryRef); } return pdfOut; } private ClinicalDocumentType getArztArztCda(Fall fall, String title, String message, String filename, String[] attachments){ try { addVersicherung(fall, docboxCDA); } catch (Exception e) { ExHandler.handle(e); } Date birthday = null; if (!"".equals(patient.getGeburtsdatum())) { TimeTool ttBirthday = new TimeTool(patient.getGeburtsdatum()); birthday = ttBirthday.getTime(); } POCDMT000040RecordTarget recordTarget = docboxCDA.getRecordTarget(patient.getPatCode(), null, patient.getAnschrift() .getStrasse(), patient.getAnschrift().getPlz(), patient.getAnschrift().getOrt(), patient.get(Person.FLD_PHONE1), patient.get(Person.FLD_PHONE2), patient.getNatel(), patient.getMailAddress(), patient.getVorname(), patient.getName(), "w" .equals(patient.getGeschlecht()), "m".equals(patient.getGeschlecht()), false, birthday); POCDMT000040Author author = docboxCDA.getAuthor(CoreHub.actMandant.get(Person.TITLE), CoreHub.actMandant.getVorname(), CoreHub.actMandant.getName(), CoreHub.actMandant.getNatel(), null, null, CoreHub.actMandant.getMailAddress(), null, null, null); POCDMT000040Custodian custodian = docboxCDA.getCustodian("", docboxCDA.getAddress(CoreHub.actMandant.getAnschrift() .getStrasse(), null, CoreHub.actMandant.getAnschrift().getPlz(), CoreHub.actMandant .getAnschrift().getOrt(), "WP"), null, null, null, null); POCDMT000040InformationRecipient informationRecipient = null; if (kontakt != null) { String organization = kontakt.get(Kontakt.FLD_NAME3); if (kontakt.get(Kontakt.FLD_IS_USER).equals(StringConstants.ONE)) { organization = ""; } informationRecipient = docboxCDA.getInformationRecipient(kontakt.get(Person.TITLE), kontakt .get(Kontakt.FLD_NAME2), kontakt.get(Kontakt.FLD_NAME1), DocboxContact .getDocboxIdFor(kontakt), docboxCDA.getOrganization(organization, null, null, null, kontakt.getAnschrift().getStrasse(), kontakt.getAnschrift().getPlz(), kontakt.getAnschrift().getOrt())); } docboxCDA.addComponentToBody("Notiz", message, "NOTIZ"); Vector<String> attachmentsCda = new Vector<String>(); attachmentsCda.add(filename); if (attachments != null) { for (String attach : attachments) { attachmentsCda.add(attach); } } docboxCDA.addAttachmentsDescriptionToBody(attachmentsCda); ClinicalDocumentType _addReferral_document = new ClinicalDocumentType(); _addReferral_document.setClinicalDocument(docboxCDA.getClinicalDocument(title, recordTarget, author, custodian, informationRecipient, docboxCDA.getCodeReferral(), null, DocboxCDA.DOCBOXCDATYPE.Docbox_Arzt_Arzt)); return _addReferral_document; } private void addVersicherung(Fall fall, DocboxCDA docboxCDA){ if (fall != null) { if ("UVG".equals(fall.getAbrechnungsSystem())) { try { docboxCDA.addUnfallversicherung(fall.getRequiredContact("Kostenträger") .getLabel()); } catch (Exception e) { ExHandler.handle(e); } try { docboxCDA.addUnfallversicherungPolicenummer(fall .getRequiredString("Unfallnummer")); } catch (Exception e) { ExHandler.handle(e); } } if ("KVG".equals(fall.getAbrechnungsSystem())) { try { docboxCDA.addKrankenkasse(fall.getRequiredContact("Kostenträger").getLabel()); } catch (Exception e) { ExHandler.handle(e); } try { docboxCDA.addKrankenkassePolicenummer(fall .getRequiredString("Versicherungsnummer")); } catch (Exception e) { ExHandler.handle(e); } } } } }