001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in
015 * Java(TM), hosted at https://github.com/gunterze/dcm4che.
016 *
017 * The Initial Developer of the Original Code is
018 * Agfa Healthcare.
019 * Portions created by the Initial Developer are Copyright (C) 2012
020 * the Initial Developer. All Rights Reserved.
021 *
022 * Contributor(s):
023 * See @authors listed below
024 *
025 * Alternatively, the contents of this file may be used under the terms of
026 * either the GNU General Public License Version 2 or later (the "GPL"), or
027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
028 * in which case the provisions of the GPL or the LGPL are applicable instead
029 * of those above. If you wish to allow use of your version of this file only
030 * under the terms of either the GPL or the LGPL, and not to allow others to
031 * use your version of this file under the terms of the MPL, indicate your
032 * decision by deleting the provisions above and replace them with the notice
033 * and other provisions required by the GPL or the LGPL. If you do not delete
034 * the provisions above, a recipient may use your version of this file under
035 * the terms of any one of the MPL, the GPL or the LGPL.
036 *
037 * ***** END LICENSE BLOCK ***** */
038
039package org.dcm4che3.hl7;
040
041import java.io.UnsupportedEncodingException;
042import java.text.ParsePosition;
043import java.util.ArrayList;
044
045/**
046 * @author Gunter Zeilinger <gunterze@gmail.com>
047 *
048 */
049public class HL7Message extends ArrayList<HL7Segment> {
050
051    private static final long serialVersionUID = 5000743858306540891L;
052
053    public HL7Message() {
054    }
055
056    public HL7Message(int initialCapacity) {
057        super(initialCapacity);
058    }
059
060    public HL7Segment getSegment(String name) {
061        for (HL7Segment seg : this)
062            if (name.equals(seg.getField(0, null)))
063                return seg;
064        return null;
065    }
066
067    @Override
068    public String toString() {
069        return toString('\r');
070    }
071
072    public String toString(char segdelim) {
073        int len = size();
074        for (HL7Segment seg : this) {
075            int segSize = seg.size();
076            len += segSize - 1;
077            for (int i = 0; i < segSize; i++) {
078                String s = seg.getField(i, null);
079                if (s != null)
080                    len += s.length();
081            }
082        }
083        char[] cs = new char[len];
084        int off = 0;
085        for (HL7Segment seg : this) {
086            char delim = seg.getFieldSeparator();
087            int segSize = seg.size();
088            for (int i = 0; i < segSize; i++) {
089                String s = seg.getField(i, null);
090                if (s != null) {
091                    int l = s.length();
092                    s.getChars(0, l, cs, off);
093                    off += l;
094                }
095                cs[off++] = delim;
096            }
097            cs[off-1] = segdelim;
098        }
099        return new String(cs);
100    }
101
102    public byte[] getBytes(String defCharset) {
103        try {
104            return toString().getBytes(HL7Charset.toCharsetName(get(0).getField(17, defCharset)));
105        } catch (UnsupportedEncodingException e) {
106            throw new RuntimeException(e);
107        }
108    }
109
110    public static HL7Message parse(byte[] b, String defCharset) {
111        return parse(b, b.length, defCharset);
112    }
113
114    public static HL7Message parse(byte[] b, int size, String defCharset) {
115        ParsePosition pos = new ParsePosition(0);
116        HL7Message msg = new HL7Message();
117        HL7Segment seg = HL7Segment.parseMSH(b, size, pos);
118        char fieldSeparator = seg.getFieldSeparator();
119        String encodingCharacters = seg.getEncodingCharacters();
120        String charsetName = HL7Charset.toCharsetName(seg.getField(17, defCharset));
121        msg.add(seg);
122        while ((seg = HL7Segment.parse(
123                b, size, pos, fieldSeparator, encodingCharacters, charsetName)) != null)
124            msg.add(seg);
125        msg.trimToSize();
126        return msg;
127    }
128
129    public static HL7Message makeACK(HL7Segment msh, String ackCode, String text) {
130        int size = msh.size();
131        HL7Segment ackmsh = HL7Segment.makeMSH(size, msh.getFieldSeparator(),
132                msh.getEncodingCharacters());
133        ackmsh.setField(2, msh.getField(4, null));
134        ackmsh.setField(3, msh.getField(5, null));
135        ackmsh.setField(4, msh.getField(2, null));
136        ackmsh.setField(5, msh.getField(3, null));
137        ackmsh.setField(8, "ACK");
138        for (int i = 10; i < size; i++)
139            ackmsh.setField(i, msh.getField(i, null));
140        HL7Segment msa = new HL7Segment(4, msh.getFieldSeparator(),
141                msh.getEncodingCharacters());
142        msa.setField(0, "MSA");
143        msa.setField(1, ackCode);
144        msa.setField(2, msh.getField(9, null));
145        msa.setField(3, text != null && text.length() > 80 ? text.substring(0, 80) : text);
146        HL7Message ack = new HL7Message(2);
147        ack.add(ackmsh);
148        ack.add(msa);
149        return ack;
150    }
151
152    public static HL7Message makePixQuery(String pid, String... domains) {
153        HL7Segment msh = HL7Segment.makeMSH();
154        msh.setField(8, "QBP^Q23^QBP_Q21");
155        HL7Segment qpd = new HL7Segment(5);
156        qpd.setField(0, "QPD");
157        qpd.setField(1, "IHE PIX Query");
158        qpd.setField(2, "QRY" + msh.getField(9, ""));
159        qpd.setField(3, pid);
160        qpd.setField(4, HL7Segment.concat(domains, '~'));
161        HL7Segment rcp = new HL7Segment(8);
162        rcp.setField(0, "RCP");
163        rcp.setField(1, "I");
164        HL7Message qbp = new HL7Message(3);
165        qbp.add(msh);
166        qbp.add(qpd);
167        qbp.add(rcp);
168        return qbp;
169    }
170}