View Javadoc

1   
2   /*
3    The contents of this file are subject to the Mozilla Public License Version 1.1
4    (the "License"); you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at http://www.mozilla.org/MPL/
6    Software distributed under the License is distributed on an "AS IS" basis,
7    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
8    specific language governing rights and limitations under the License.
9   
10   The Original Code is "AbstractHL7Exception.java".  Description:
11   "Exception containing a Location and Error Code"
12  
13   The Initial Developer of the Original Code is University Health Network. Copyright (C)
14   2012.  All Rights Reserved.
15  
16   Contributor(s): ______________________________________.
17  
18   Alternatively, the contents of this file may be used under the terms of the
19   GNU General Public License (the "GPL"), in which case the provisions of the GPL are
20   applicable instead of those above.  If you wish to allow use of your version of this
21   file only under the terms of the GPL and not to allow others to use your version
22   of this file under the MPL, indicate your decision by deleting  the provisions above
23   and replace  them with the notice and other provisions required by the GPL License.
24   If you do not delete the provisions above, a recipient may use your version of
25   this file under either the MPL or the GPL.
26   */
27  
28  package ca.uhn.hl7v2;
29  
30  import static ca.uhn.hl7v2.Version.V25;
31  import static ca.uhn.hl7v2.Version.versionOf;
32  
33  import ca.uhn.hl7v2.model.Message;
34  import ca.uhn.hl7v2.model.Segment;
35  import ca.uhn.hl7v2.util.Terser;
36  
37  /**
38   * 
39   * Abstract base class for Exceptions that are able to create acknowledgement
40   * messages from their error code and location information
41   * 
42   * @author Christian Ohr
43   *
44   */
45  @SuppressWarnings("serial")
46  public abstract class AbstractHL7Exception extends Exception {
47  
48  	private Location location;
49  	private ErrorCode errorCode = ErrorCode.APPLICATION_INTERNAL_ERROR;
50      private Severity severity = Severity.ERROR;
51  
52  	public AbstractHL7Exception() {
53  		super();
54  	}
55  
56  	public AbstractHL7Exception(String message, Throwable cause) {
57  		super(message, cause);
58  	}
59  
60  	public AbstractHL7Exception(String message) {
61  		super(message);
62  	}
63  
64  	public AbstractHL7Exception(Throwable cause) {
65  		super(cause);
66  	}
67  
68  	public Location getLocation() {
69  		return location;
70  	}
71  
72  	public void setLocation(Location location) {
73  		this.location = location;
74  	}
75  
76  	public void setFieldPosition(int pos) {
77  		if (location == null)
78  			location = new Location();
79  		location.setField(pos);
80  	}
81  
82  	public void setSegmentName(String segmentName) {
83  		if (location == null)
84  			location = new Location();
85  		location.setSegmentName(segmentName);
86  	}
87  
88  	public void setSegmentRepetition(int segmentRepetition) {
89  		if (location == null)
90  			location = new Location();
91  		location.setSegmentRepetition(segmentRepetition);
92  	}
93  
94  	public int getErrorCode() {
95  		return errorCode.getCode();
96  	}
97  
98  	public void setErrorCode(int errorCode) {
99  		this.errorCode = ErrorCode.errorCodeFor(errorCode);
100 	}
101 
102 	public ErrorCode getError() {
103 		return errorCode;
104 	}
105 
106 	public void setError(ErrorCode errorCode) {
107 		this.errorCode = errorCode;
108 	}
109 
110     public Severity getSeverity() {
111         return severity;
112     }
113 
114     public void setSeverity(Severity severity) {
115         this.severity = severity;
116     }
117 
118     /**
119 	 * Populates the generated response based on this exception.
120 	 * 
121 	 * @param response response message
122      * @param acknowledgmentCode the acknowledgement code
123      * @return response message
124 	 * @throws HL7Exception if populating the response fails
125 	 */
126 	public Message populateResponse(Message response, AcknowledgmentCode acknowledgmentCode, int repetition)
127 			throws HL7Exception {
128 		if (acknowledgmentCode == null) acknowledgmentCode = AcknowledgmentCode.AA;
129 		if (V25.isGreaterThan(versionOf(response.getVersion()))) {
130 			return populateResponseBefore25(response, acknowledgmentCode, repetition);
131 		}
132 		return populateResponseAsOf25(response, acknowledgmentCode, repetition);
133 	}
134 
135 	/**
136 	 * Fill segments for HL7 versions 2.5 or newer.
137 	 * <p>
138 	 * HL7 versions before 2.5 require to set MSA-1. The ERR segment has various fields (ERR-2,
139 	 * ERR-3) containing details about the exception. ERR-1 is marked as obsolete.
140 	 * 
141 	 * @param response the raw response message
142      * @param acknowledgmentCode acknowledgmentCode
143 	 * @param repetition repetition of the ERR segment that shall be populated
144 	 * @throws HL7Exception
145 	 */
146 	private Message populateResponseAsOf25(Message response, AcknowledgmentCode acknowledgmentCode,
147 			int repetition) throws HL7Exception {
148 		// TODO define what should happen if there is no MSA or ERR
149 		Segment msa = (Segment) response.get("MSA");
150 		Terser.set(msa, 1, 0, 1, 1, acknowledgmentCode.name());
151 		Segment err = (Segment) response.get("ERR", repetition);
152 		if (location != null) {
153 			if (location.getSegmentName() != null)
154 				Terser.set(err, 2, 0, 1, 1, location.getSegmentName());
155 			if (location.getField() > 0)
156 				Terser.set(err, 2, 0, 3, 1, Integer.toString(location.getField()));
157 			if (location.getFieldRepetition() > 0)
158 				Terser.set(err, 2, 0, 4, 1, Integer.toString(location.getFieldRepetition()));
159 			if (location.getComponent() > 0)
160 				Terser.set(err, 2, 0, 5, 1, Integer.toString(location.getComponent()));
161 			if (location.getSubcomponent() > 0)
162 				Terser.set(err, 2, 0, 6, 1, Integer.toString(location.getSubcomponent()));
163 		}
164 		Terser.set(err, 3, 0, 1, 1, Integer.toString(errorCode.getCode()));
165 		Terser.set(err, 3, 0, 2, 1, errorCode.getMessage());
166 		Terser.set(err, 3, 0, 3, 1, ErrorCode.codeTable());
167 		Terser.set(err, 3, 0, 9, 1, getMessage());
168 		Terser.set(err, 4, 0, 1, 1, "E");
169 		return response;
170 	}
171 
172 	/**
173 	 * Fill segments for HL7 versions before 2.5.
174 	 * <p>
175 	 * HL7 versions before 2.5 require to set MSA-1 and MSA-3. The ERR segment only has one
176 	 * repeatable field (ERR-1) with components containing details about the exception.
177 	 * 
178 	 * @param response the raw response message
179 	 * @param acknowledgmentCode acknowledgment code
180      * @param repetition repetition of the ERR segment that shall be popualted
181 	 * @throws HL7Exception
182 	 */
183 	private Message populateResponseBefore25(Message response, AcknowledgmentCode acknowledgmentCode,
184 			int repetition) throws HL7Exception {
185 		// TODO define what should happen if there is no MSA or ERR
186 		Segment msa = (Segment) response.get("MSA");
187 		Terser.set(msa, 1, 0, 1, 1, acknowledgmentCode.name());
188 		Terser.set(msa, 3, 0, 1, 1, errorCode.getMessage());
189 		Segment err = (Segment) response.get("ERR");
190 		if (location != null) {
191 			if (location.getSegmentName() != null)
192 				Terser.set(err, 1, repetition, 1, 1, location.getSegmentName());
193 			if (location.getField() > 0)
194 				Terser.set(err, 1, repetition, 3, 1, Integer.toString(location.getField()));
195 		}
196 		Terser.set(err, 1, repetition, 4, 1, Integer.toString(errorCode.getCode()));
197 		Terser.set(err, 1, repetition, 4, 2, errorCode.getMessage());
198 		Terser.set(err, 1, repetition, 4, 3, ErrorCode.codeTable());
199 		Terser.set(err, 1, repetition, 4, 5, getMessage());
200 		return response;
201 	}
202 
203 	public String getMessage() {
204 		String message = getMessageWithoutLocation();
205 		StringBuilder msg = new StringBuilder(message);
206 		if (getLocation() != null && !getLocation().isUnknown()) {
207 			msg.append(" at ").append(getLocation().toString());
208 		}
209 		return msg.toString();
210 	}
211 
212     public String getMessageWithoutLocation() {
213         String message = super.getMessage();
214         if (message == null) message = "Exception";
215         return message;
216     }
217 
218 }