1 // $Id: ErrorHandler.java,v 1.8 2008/10/17 06:47:06 haschart Exp $
\r
3 * Copyright (C) 2004 Bas Peters
\r
5 * This file is part of MARC4J
\r
7 * MARC4J is free software; you can redistribute it and/or
\r
8 * modify it under the terms of the GNU Lesser General Public
\r
9 * License as published by the Free Software Foundation; either
\r
10 * version 2.1 of the License, or (at your option) any later version.
\r
12 * MARC4J is distributed in the hope that it will be useful,
\r
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
15 * Lesser General Public License for more details.
\r
17 * You should have received a copy of the GNU Lesser General Public
\r
18 * License along with MARC4J; if not, write to the Free Software
\r
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
24 import java.util.Iterator;
\r
25 import java.util.LinkedList;
\r
26 import java.util.List;
\r
29 * Defines and describes errors encountered in the processing a given MARC record.
\r
30 * Used in conjunction with the MarcPermissiveReader class.
\r
32 * @author Robert Haschart
\r
33 * @version $Revision: 1.8 $
\r
35 public class ErrorHandler {
\r
38 * FATAL is the most severe error, it is usually set in conjunction with throwing an
\r
39 * exception, generally no record is returned when a FATAL error occurs. Although in
\r
40 * some instances (a record with a field > 9999 bytes long) a record will be returned
\r
41 * that can be used, but it cannot be written back out without causing an error.
\r
43 public final static int FATAL = 4;
\r
46 * MAJOR_ERROR indicates that a serious problem existed with the record, such as a
\r
47 * malformed directory or an invalid subfield tag, or an encoding error where missing
\r
48 * data had to be inferred through some heuristic process. This indicates that
\r
49 * although a record is returned, you cannot be sure that the record is not corrupted.
\r
51 public final static int MAJOR_ERROR = 3;
\r
54 * MINOR_ERROR indicates that a less serious problem existed with the record, such as
\r
55 * a mismatch between the directory stated field sizes and the actual field sizes,
\r
56 * or an encoding error where extraneous data had to be discarded to correctly
\r
57 * interpret the data.
\r
59 public final static int MINOR_ERROR = 2;
\r
62 * ERROR_TYPO indicates that an even less severe problem was found with the record,
\r
63 * such as the record leader ends with characters other than "4500" or a field tag
\r
64 * contains non-numeric characters the record contains a html-style entity reference
\r
65 * such as & or "e; which was replaced with the unescaped version.
\r
67 public final static int ERROR_TYPO = 1;
\r
70 * INFO is used to pass information about the record translation process. It does
\r
71 * not indicate an error. It usually will occur when a defaultEncoding value of "BESTGUESS"
\r
72 * is passed in. INFO statements are generated to indicate which character encoding was
\r
73 * determined to be the best fit for the data, and why.
\r
75 public final static int INFO = 0;
\r
77 private List errors;
\r
78 private String curRecordID;
\r
79 private String curField;
\r
80 private String curSubfield;
\r
81 private boolean hasMissingID;
\r
82 private int maxSeverity;
\r
84 public class Error {
\r
85 protected String curRecordID;
\r
86 protected String curField;
\r
87 protected String curSubfield;
\r
88 protected int severity;
\r
89 protected String message;
\r
91 protected Error(String recordID, String field, String subfield, int severity, String message)
\r
93 curRecordID = recordID;
\r
95 curSubfield = subfield;
\r
96 this.severity = severity;
\r
97 this.message = message;
\r
101 * Formats the error message for display
\r
103 * @return String - a formatted representation of the error.
\r
105 public String toString()
\r
107 String severityMsg = getSeverityMsg(severity);
\r
108 String ret = severityMsg +" : " + message + " --- [ " + curField + " : " + curSubfield + " ]" ;
\r
112 private void setCurRecordID(String curRecordID)
\r
114 this.curRecordID = curRecordID;
\r
117 private String getCurRecordID()
\r
119 return(curRecordID);
\r
123 public ErrorHandler()
\r
126 hasMissingID = false;
\r
127 maxSeverity = INFO;
\r
131 * Provides a descriptive string representation of the severity level.
\r
133 * @return String - a descriptive string representation of the severity level
\r
135 private String getSeverityMsg(int severity)
\r
137 switch (severity) {
\r
138 case FATAL: return("FATAL ");
\r
139 case MAJOR_ERROR: return("Major Error ");
\r
140 case MINOR_ERROR: return("Minor Error ");
\r
141 case ERROR_TYPO: return("Typo ");
\r
142 case INFO: return("Info ");
\r
148 * Returns true if any errors (or warnings) were encountered in processing the
\r
149 * current record. Note that if only INFO level messages are encountered for a
\r
150 * given record, this method will return false.
\r
152 * @return boolean - The highest error severity level encountered for the current record.
\r
154 public boolean hasErrors()
\r
156 return (errors != null && errors.size() > 0 && maxSeverity > INFO);
\r
160 * Returns the highest error severity level encountered in processing the current record.
\r
162 * @return int - The highest error severity level encountered for the current record.
\r
164 public int getMaxSeverity()
\r
166 return (maxSeverity);
\r
170 * Returns a list of all of the errors encountered in processing the current record.
\r
172 * @return List - A list of all of the errors encountered for the current record.
\r
174 public List getErrors()
\r
176 if (errors == null || errors.size() == 0) return null;
\r
181 * Resets the list of errors to empty. This should be called at the beginning of
\r
182 * processing of each record.
\r
184 public void reset()
\r
187 maxSeverity = INFO;
\r
191 * Logs an error message using the stated severity level. Uses the values passed
\r
192 * in id, field, and subfield to note the location of the error.
\r
194 * @param id - the record ID of the record currently being processed
\r
195 * @param field - the tag of the field currently being processed
\r
196 * @param subfield - the subfield tag of the subfield currently being processed
\r
197 * @param severity - An indication of the relative severity of the error that was
\r
199 * @param message - A descriptive message about the error that was encountered.
\r
201 public void addError(String id, String field, String subfield, int severity, String message)
\r
203 if (errors == null)
\r
205 errors = new LinkedList();
\r
206 hasMissingID = false;
\r
208 if (id != null && id.equals("unknown")) hasMissingID = true;
\r
209 else if (hasMissingID)
\r
211 setRecordIDForAll(id);
\r
213 errors.add(new Error(id, field, subfield, severity, message));
\r
214 if (severity > maxSeverity) maxSeverity = severity;
\r
218 * Logs an error message using the stated severity level. Uses the values stored
\r
219 * in curRecordID, curField, and curSubfield to note the location of the error.
\r
221 * @param severity - An indication of the relative severity of the error that was
\r
223 * @param message - A descriptive message about the error that was encountered.
\r
225 public void addError(int severity, String message)
\r
227 addError(curRecordID, curField, curSubfield, severity, message);
\r
230 private void setRecordIDForAll(String id)
\r
234 Iterator iter = errors.iterator();
\r
235 while (iter.hasNext())
\r
237 Error err = (Error)(iter.next());
\r
238 if (err.getCurRecordID() == null || err.getCurRecordID().equals("unknown"))
\r
240 err.setCurRecordID(id);
\r
243 hasMissingID = false;
\r
248 * Sets the record ID to be stored for subsequent error messages that are logged
\r
249 * If any previous messages are stored for the current record that don't have a
\r
250 * stored record ID, set the value for those entries to this value also.
\r
252 * @param recordID - the record ID of the record currently being processed
\r
254 public void setRecordID(String recordID)
\r
256 curRecordID = recordID;
\r
257 if (hasMissingID && errors != null) setRecordIDForAll(recordID);
\r
261 * Sets the field tag to be stored for subsequent error messages that are logged
\r
263 * @param curField - the tag of the field currently being processed
\r
265 public void setCurrentField(String curField)
\r
267 this.curField = curField;
\r
271 * Sets the subfield tag to be stored for subsequent error messages that are logged
\r
273 * @param curSubfield - the subfield tag of the subfield currently being processed
\r
275 public void setCurrentSubfield(String curSubfield)
\r
277 this.curSubfield = curSubfield;
\r