001    /**
002    The contents of this file are subject to the Mozilla Public License Version 1.1 
003    (the "License"); you may not use this file except in compliance with the License. 
004    You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005    Software distributed under the License is distributed on an "AS IS" basis, 
006    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007    specific language governing rights and limitations under the License. 
008    
009    The Original Code is "HL7Exception.java".  Description: 
010    "Represents an exception encountered while processing 
011      an HL7 message" 
012    
013    The Initial Developer of the Original Code is University Health Network. Copyright (C) 
014    2001.  All Rights Reserved. 
015    
016    Contributor(s): ______________________________________. 
017    
018    Alternatively, the contents of this file may be used under the terms of the 
019    GNU General Public License (the  ???GPL???), in which case the provisions of the GPL are 
020    applicable instead of those above.  If you wish to allow use of your version of this 
021    file only under the terms of the GPL and not to allow others to use your version 
022    of this file under the MPL, indicate your decision by deleting  the provisions above 
023    and replace  them with the notice and other provisions required by the GPL License.  
024    If you do not delete the provisions above, a recipient may use your version of 
025    this file under either the MPL or the GPL. 
026    
027    */
028    
029    package ca.uhn.hl7v2;
030    
031    import java.sql.SQLException;
032    
033    import ca.uhn.log.*;
034    import ca.uhn.hl7v2.util.Terser;
035    import ca.uhn.hl7v2.model.Segment;
036    
037    /** 
038     * Represents an exception encountered while processing 
039     * an HL7 message.  
040     * @author Bryan Tripp (bryan_tripp@sourceforge.net)
041     */
042    public class HL7Exception extends Exception {
043    
044        private static final HapiLog ourLog = HapiLogFactory.getHapiLog(HL7Exception.class);
045    
046    
047        /** Original mode: Application Accept - Enhanced mode: Application acknowledgment: Accept */
048        public static final int ACK_AA = 1;
049    
050        /** Original mode: Application Error - Enhanced mode: Application acknowledgment: Error */
051        public static final int ACK_AE = 2;
052    
053        /** Original mode: Application Reject - Enhanced mode: Application acknowledgment: Reject */
054        public static final int ACK_AR = 3;
055    
056        /** Enhanced mode: Accept acknowledgment: Commit Accept */
057        public static final int ACK_CA = 4;
058    
059        /** Enhanced mode: Accept acknowledgment: Commit Error */
060        public static final int ACK_CE = 5;
061    
062        /** Enhanced mode: Accept acknowledgment: Commit Reject */
063        public static final int ACK_CR = 6;
064    
065    
066        public static final int MESSAGE_ACCEPTED = 0;
067        public static final int SEGMENT_SEQUENCE_ERROR = 100;
068        public static final int REQUIRED_FIELD_MISSING = 101;
069        public static final int DATA_TYPE_ERROR = 102;
070        public static final int TABLE_VALUE_NOT_FOUND = 103;
071        public static final int UNSUPPORTED_MESSAGE_TYPE = 200;
072        public static final int UNSUPPORTED_EVENT_CODE = 201;
073        public static final int UNSUPPORTED_PROCESSING_ID = 202;
074        public static final int UNSUPPORTED_VERSION_ID = 203;
075        public static final int UNKNOWN_KEY_IDENTIFIER = 204;
076        public static final int DUPLICATE_KEY_IDENTIFIER = 205;
077        public static final int APPLICATION_RECORD_LOCKED = 206;
078        public static final int APPLICATION_INTERNAL_ERROR = 207;
079    
080        private String segment = null;
081        private int segmentRep = -1;
082        private int fieldPosition = -1;
083        private int errCode = -1;
084    
085        /** 
086         * Creates an HL7Exception.
087         *  
088         * @param errorCondition a code describing the the error condition, from HL7
089         *        table 0357 (see section 2.16.8 of standard v 2.4) - HL7Exception defines 
090         *        these codes as integer constants that can be used here (e.g. 
091         *        HL7Exception.UNSUPPORTED_MESSAGE_TYPE)
092         * 
093         * @param cause The excption that caused this exception tobe thrown.
094         */
095        public HL7Exception(String message, int errorCondition, Throwable cause) {
096            super(message, cause);
097            this.errCode = errorCondition;
098        }
099    
100        /** 
101         * Creates an HL7Exception.
102         *  
103         * @param errorCondition a code describing the the error condition, from HL7
104         *        table 0357 (see section 2.16.8 of standard v 2.4) - HL7Exception defines 
105         *        these codes as integer constants that can be used here (e.g. 
106         *        HL7Exception.UNSUPPORTED_MESSAGE_TYPE)
107         */
108        public HL7Exception(String message, int errorCondition) {
109            super(message);
110            this.errCode = errorCondition;
111        }
112    
113        /**
114         * Creates an HL7Exception with the code APPLICATION_INTERNAL_ERROR
115         * 
116         * @param cause The excption that caused this exception tobe thrown.
117         */
118        public HL7Exception(String message, Throwable cause) {
119            super(message, cause);
120            this.errCode = HL7Exception.APPLICATION_INTERNAL_ERROR;
121        }
122        
123        /**
124         * Creates an HL7Exception with the code APPLICATION_INTERNAL_ERROR
125         * 
126         * @param cause The excption that caused this exception tobe thrown.
127         */
128        public HL7Exception(Throwable cause) {
129            super(cause);
130            this.errCode = HL7Exception.APPLICATION_INTERNAL_ERROR;
131        }
132    
133        /**
134         * Creates an HL7Exception with the code APPLICATION_INTERNAL_ERROR
135         */
136        public HL7Exception(String message) {
137            super(message);
138            this.errCode = HL7Exception.APPLICATION_INTERNAL_ERROR;
139        }
140    
141        /**
142         * Sets the name of the segment where the error occured. 
143         */
144        public void setSegmentName(String segmentName) {
145            this.segment = segmentName;
146        }
147    
148        /** 
149         * Returns the name of the segment where the error occured, if this has been set
150         * (null otherwise).
151         */
152        public String getSegmentName() {
153            return this.segment;
154        }
155    
156        /** 
157         * Sets the sequence number of the segment where the error occured if there 
158         * are multiplt segments with the same name (ie the sequenceNum'th segment 
159         * with the name specified in <code>setSegmentName</code>).  Numbering 
160         * starts at 1.
161         */
162        public void setSegmentRepetition(int sequenceNum) {
163            this.segmentRep = sequenceNum;
164        }
165    
166        /**
167         * Returns the sequence number of the segment where the error occured (if there 
168         * are multiple segments with the same name) if this has been set, -1 otherwise - 
169         * numbering starts at 1.
170         */
171        public int getSegmentRepetition() {
172            return this.segmentRep;
173        }
174    
175        /** 
176         * Sets the field number (within a segment) where the error occured; numbering 
177         * starts at 1. 
178         */
179        public void setFieldPosition(int fieldNum) {
180            this.fieldPosition = fieldNum;
181        }
182    
183        /** 
184         * Returns the field number within the segment where the error occured if it has been 
185         * set, -1 otherwise; numbering starts at 1.
186         */
187        public int getFieldPosition() {
188            return this.fieldPosition;
189        }
190        
191        /**
192         * @return Returns the error code associated with this exception, or <code>-1</code> if none
193         */
194        public int getErrorCode() {
195            return this.errCode;
196        }
197    
198        /**
199         * Overrides Throwable.getMessage() to add the field location of the problem if 
200         * available.
201         */
202        public String getMessage() {
203            StringBuffer msg = new StringBuffer();
204            msg.append(super.getMessage());
205            if (getSegmentName() != null) {
206                msg.append(": Segment: ");
207                msg.append(getSegmentName());
208            }
209            if (getSegmentRepetition() != -1) {
210                msg.append(" (rep ");
211                msg.append(getSegmentRepetition());
212                msg.append(")");
213            }
214            if (getFieldPosition() != -1) {
215                msg.append(" Field #");
216                msg.append(getFieldPosition());
217            }
218            return msg.toString();
219        }
220    
221        /**
222         * Populates the given error segment with information from this Exception.
223         */
224        public void populate(Segment errorSegment, String theJdbcUrl) throws HL7Exception {
225            //make sure it's an ERR
226            if (!errorSegment.getName().equals("ERR"))
227                throw new HL7Exception(
228                    "Can only populate an ERR segment with an exception -- got: " + errorSegment.getClass().getName());
229    
230            int rep = errorSegment.getField(1).length; //append after existing reps
231    
232            if (this.getSegmentName() != null)
233                Terser.set(errorSegment, 1, rep, 1, 1, this.getSegmentName());
234    
235            if (this.getSegmentRepetition() >= 0)
236                Terser.set(errorSegment, 1, rep, 2, 1, String.valueOf(this.getSegmentRepetition()));
237    
238            if (this.getFieldPosition() >= 0)
239                Terser.set(errorSegment, 1, rep, 3, 1, String.valueOf(this.getFieldPosition()));
240    
241            Terser.set(errorSegment, 1, rep, 4, 1, String.valueOf(this.errCode));
242            Terser.set(errorSegment, 1, rep, 4, 3, "hl70357");
243            Terser.set(errorSegment, 1, rep, 4, 5, this.getMessage());
244    
245            //try to get error condition text
246    //        try {
247                // FIXME: make this work
248                String desc = "ERROR"; // TableRepository.getInstance(theJdbcUrl).getDescription(357, String.valueOf(this.errCode));
249                Terser.set(errorSegment, 1, rep, 4, 2, desc);
250    //        }
251    //        catch (LookupException e) {
252    //            ourLog.debug(
253    //                "Warning: LookupException getting error condition text (are we connected to a TableRepository?)", e);
254    //        } catch (SQLException e) {
255    //            throw new HL7Exception(e);
256    //        }
257        }
258    }