View Javadoc
1   /*
2    * Copyright 2009 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *     
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.openehealth.ipf.platform.camel.ihe.hl7v2;
17  
18  import java.io.BufferedReader;
19  import java.io.File;
20  import java.io.InputStream;
21  import java.io.InputStreamReader;
22  
23  import ca.uhn.hl7v2.parser.Parser;
24  import org.apache.camel.Message;
25  import org.apache.camel.WrappedFile;
26  import org.apache.camel.converter.IOConverter;
27  
28  
29  /**
30   * Various helper methods for data transformation.
31   * @author Dmytro Rud
32   */
33  public class Hl7v2MarshalUtils {
34  
35      private Hl7v2MarshalUtils() {
36          throw new IllegalStateException("Cannot instantiate helper class");
37      }
38      
39      
40      /**
41       * Converts a set of some standard data types to String.
42       * @param message
43       *      Camel message containing the data to be converted. 
44       * @param charset
45       *      character set. 
46       * @param parser 
47       *      HL7 parser. 
48       * @return
49       *      String representing the original exchange or <tt>null</tt>
50       *      when the data type is unknown. 
51       * @throws Exception
52       *      on parsing and marshaling errors.
53       */
54      public static String marshalStandardTypes(Message message, String charset, Parser parser) throws Exception {
55          Object body = message.getBody();
56          if( ! typeSupported(body)) {
57              return null;
58          }
59          
60          String s = null;
61          if(body instanceof String) {
62              s = (String) body;
63          } else if(body instanceof ca.uhn.hl7v2.model.Message) {
64              s = parser.encode((ca.uhn.hl7v2.model.Message) body);
65          } else if(body instanceof File) {
66              s = readFile(body, charset);
67          } else if(body instanceof WrappedFile<?>) {
68              Object file = ((WrappedFile<?>) body).getFile();
69              if(file instanceof File) {
70                  s = readFile(file, charset);
71              }
72          } else {
73              // In standard Camel distribution this will concern  
74              // byte[], InputStream and ByteBuffer.
75              // See also: http://camel.apache.org/list-of-type-conversions.html
76              byte[] bytes = message.getBody(byte[].class);
77              if(bytes != null) {
78                  s = new String(bytes, charset);
79              }
80          }
81          return s;
82      }
83      
84  
85      private static String readFile(Object file, String charset) throws Exception {
86          byte[] bytes = IOConverter.toByteArray((File) file);
87          return new String(bytes, charset).replace('\n', '\r');
88      }
89      
90      
91      /**
92       * Determines whether the given object belongs to the predefined
93       * set of supported data types. 
94       * @param body
95       *      The object to check. 
96       * @return
97       *      <code>true</code> when the type of the object is supported 
98       *      by the HL7v2 adapter out-of-the-box, <code>false</code> otherwise.
99       */
100     public static boolean typeSupported(Object body) {
101         final Class<?>[] knownTypes = new Class<?>[] {
102             String.class,
103             ca.uhn.hl7v2.model.Message.class,
104             File.class,
105             InputStream.class,
106             java.nio.ByteBuffer.class,
107             byte[].class,
108             WrappedFile.class
109         };
110         
111         for(Class<?> type : knownTypes) {
112             try {
113                 type.cast(body);
114                 return true;
115             } catch (ClassCastException cce) {
116                 // nop
117             }
118         }
119         
120         return false;
121     }
122 
123     
124     /**
125      * Converts message contents to a {@link String} using the given character set
126      * and replaces all <tt>'\n'</tt>'s with <tt>'\r'</tt>'s.  
127      * If requested, segments will be defragmented as well.
128      */
129     public static String convertBodyToString(
130             Message message, 
131             String charset, 
132             boolean defragmentSegments) throws Exception 
133     {
134         InputStream stream = message.getBody(InputStream.class);
135         BufferedReader br = new BufferedReader(new InputStreamReader(stream, charset));
136         String s = IOConverter.toString(br);
137         s = s.replace('\n', '\r');
138         if (defragmentSegments) {
139             s = s.replace("\rADD" + s.charAt(3), "");
140         }
141         return s;
142     }
143     
144     
145     /**
146      * Converts the contents of the given Camel message to a {@link Message}.
147      * @param message
148      *      Camel message to be converted.
149      * @param charset
150      *      character set.
151      * @return
152      *      a {@link Message} or <code>null</code> when it was impossible
153      *      to get or create one.
154      * @param parser 
155      *      HL7 parser. 
156      * @throws Exception
157      */
158     public static ca.uhn.hl7v2.model.Message extractHapiMessage(
159             Message message,
160             String charset,
161             Parser parser) throws Exception 
162     {
163         Object body = message.getBody();
164         ca.uhn.hl7v2.model.Message msg = null;
165         if (body instanceof ca.uhn.hl7v2.model.Message) {
166             msg = (ca.uhn.hl7v2.model.Message) body;
167         } else {
168             // process all other types (String, File, InputStream, ByteBuffer, byte[])
169             // by means of the standard routine.  An exception here will be o.k.
170             String s = marshalStandardTypes(message, charset, parser);
171             if(s != null) {
172                 s = s.replace('\n', '\r');
173                 msg = parser.parse(s);
174             }
175         } 
176         return msg;
177     }
178 
179 }