001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.hl7;
018    
019    import java.io.InputStream;
020    import java.io.OutputStream;
021    
022    import ca.uhn.hl7v2.model.Message;
023    import ca.uhn.hl7v2.util.Terser;
024    import org.apache.camel.Exchange;
025    import org.apache.camel.spi.DataFormat;
026    import org.apache.camel.util.ExchangeHelper;
027    
028    /**
029     * HL7 DataFormat (supports v2.x of the HL7 protocol).
030     * <p/>
031     * This data format supports two operations:
032     * <ul>
033     *   <li>marshal = from Message to String (can be used when returning as response using the HL7 MLLP codec)</li>
034     *   <li>unmarshal = from String to Message (can be used when receiving streamed data from the HL7 MLLP codec).
035     *   This operation will also enrich the message by adding the MSH fields (MSH-3 to MSH-12) as headers on the message.</li>
036     * </ul>
037     * <p/>
038     * Uses the <a href="http://hl7api.sourceforge.net/index.html">HAPI (HL7 API)</a> for HL7 parsing.
039     * <p/>
040     * Uses the default PipeParser from the HAPI API. This DataFormat <b>only</b> supports the EDI based HL7
041     * messages and not the XML based (their are not commonly used).
042     * <p/>
043     * The <tt>unmarshal</tt> operation adds these MSH fields as headers on the Camel message (key, MSH-field):
044     * <ul>
045     *   <li>hl7.msh.sendingApplication = MSH-3</li>
046     *   <li>hl7.msh.sendingFacility = MSH-4</li>
047     *   <li>hl7.msh.receivingApplication = MSH-5</li>
048     *   <li>hl7.msh.receivingFacility = MSH-6</li>
049     *   <li>hl7.msh.timestamp = MSH-7</li>
050     *   <li>hl7.msh.security = MSH-8</li>
051     *   <li>hl7.msh.messageType = MSH-9-1</li>
052     *   <li>hl7.msh.triggerEvent = MSH-9-2</li>
053     *   <li>hl7.msh.messageControl = MSH-10</li>
054     *   <li>hl7.msh.processingId = MSH-11</li>
055     *   <li>hl7.msh.versionId = MSH-12</li>
056     * </ul>
057     * All headers are String types.
058     * <p/>
059     * The <a href="http://www.hl7.org/Special/IG/final.pdf">HL7 spec</a> can be downloaded as a pdf at
060     *
061     * @see org.apache.camel.component.hl7.HL7MLLPCodec
062     */
063    public class HL7DataFormat implements DataFormat {
064    
065        private boolean validate = true;
066    
067        public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws Exception {
068            Message message = ExchangeHelper.convertToMandatoryType(exchange, Message.class, body);
069            String encoded = HL7Converter.encode(message, validate);
070            outputStream.write(encoded.getBytes());
071        }
072    
073        public Object unmarshal(Exchange exchange, InputStream inputStream) throws Exception {
074            String body = ExchangeHelper.convertToMandatoryType(exchange, String.class, inputStream);
075            Message message = HL7Converter.parse(body, validate);
076    
077            // add MSH fields as message out headers
078            Terser terser = new Terser(message);
079            exchange.getOut().setHeader(HL7Constants.HL7_SENDING_APPLICATION, terser.get("MSH-3"));
080            exchange.getOut().setHeader(HL7Constants.HL7_SENDING_FACILITY, terser.get("MSH-4"));
081            exchange.getOut().setHeader(HL7Constants.HL7_RECEIVING_APPLICATION, terser.get("MSH-5"));
082            exchange.getOut().setHeader(HL7Constants.HL7_RECEIVING_FACILITY, terser.get("MSH-6"));
083            exchange.getOut().setHeader(HL7Constants.HL7_TIMESTAMP, terser.get("MSH-7"));
084            exchange.getOut().setHeader(HL7Constants.HL7_SECURITY, terser.get("MSH-8"));
085            exchange.getOut().setHeader(HL7Constants.HL7_MESSAGE_TYPE, terser.get("MSH-9-1"));
086            exchange.getOut().setHeader(HL7Constants.HL7_TRIGGER_EVENT, terser.get("MSH-9-2"));
087            exchange.getOut().setHeader(HL7Constants.HL7_MESSAGE_CONTROL, terser.get("MSH-10"));
088            exchange.getOut().setHeader(HL7Constants.HL7_PROCESSING_ID, terser.get("MSH-11"));
089            exchange.getOut().setHeader(HL7Constants.HL7_VERSION_ID, terser.get("MSH-12"));
090            return message;
091        }
092    
093        public boolean isValidate() {
094            return validate;
095        }
096    
097        public void setValidate(boolean validate) {
098            this.validate = validate;
099        }
100    }
101