/*
* Copyright 2012 Michael Bischoff
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.jpaw.bonaparte.core;
import de.jpaw.util.ApplicationException;
/**
* The MessageParserException class.
*
* @author Michael Bischoff
* @version $Revision$
*
* Extends the generic ApplicationException class in order to provide error details which are
* specific to parsing of serialized forms (primarily bonaparte data).
*/
public class MessageParserException extends ApplicationException {
private static final long serialVersionUID = 6578705245543364726L;
private static final int OFFSET = (CL_PARSER_ERROR * CLASSIFICATION_FACTOR) + 17000;
private static final int OFFSET3 = (CL_PARAMETER_ERROR * CLASSIFICATION_FACTOR) + 17000;
private static final int OFFSET8 = (CL_INTERNAL_LOGIC_ERROR * CLASSIFICATION_FACTOR) + 17000;
private final int characterIndex; // the byte count of the message at which the error occured
private final String fieldName; // if known, the name of the field where the error occured
private final String className; // if known, the name of the class which contained the field
static public final int MISSING_FIELD_TERMINATOR = OFFSET + 1;
static public final int MISSING_RECORD_TERMINATOR = OFFSET + 2;
static public final int MISSING_TERMINATOR = OFFSET + 3;
static public final int PREMATURE_END = OFFSET + 4;
static public final int FIELD_PARSE = OFFSET + 5;
static public final int ILLEGAL_CHAR_ASCII = OFFSET + 6;
static public final int ILLEGAL_CHAR_UPPER = OFFSET + 7;
static public final int ILLEGAL_CHAR_LOWER = OFFSET + 8;
static public final int ILLEGAL_CHAR_DIGIT = OFFSET + 9;
static public final int EMPTY_BUT_REQUIRED_FIELD = OFFSET + 10;
static public final int UNEXPECTED_CHARACTER = OFFSET + 11;
static public final int ILLEGAL_EXPLICIT_NULL = OFFSET + 12;
static public final int ILLEGAL_IMPLICIT_NULL = OFFSET + 13;
static public final int NO_DIGITS_FOUND = OFFSET + 14;
static public final int SUPERFLUOUS_DECIMAL_POINT = OFFSET + 15;
static public final int SUPERFLUOUS_EXPONENT = OFFSET + 16;
static public final int SUPERFLUOUS_SIGN = OFFSET + 17;
static public final int ILLEGAL_CHAR_CTRL = OFFSET + 18;
static public final int ILLEGAL_CHAR_NOT_NUMERIC = OFFSET + 19;
static public final int NUMERIC_TOO_LONG = OFFSET + 20;
static public final int STRING_TOO_LONG = OFFSET + 21;
static public final int ILLEGAL_ESCAPE_SEQUENCE = OFFSET + 22;
static public final int ILLEGAL_BOOLEAN = OFFSET + 23;
static public final int BASE64_PARSING_ERROR = OFFSET + 24;
static public final int ILLEGAL_CHAR_BASE64 = OFFSET + 25;
static public final int ARRAY_SIZE_OUT_OF_BOUNDS = OFFSET + 26;
static public final int BAD_CLASS = OFFSET + 27;
static public final int BAD_TRANSMISSION_START = OFFSET + 28;
static public final int BAD_TIMESTAMP_FRACTIONALS = OFFSET + 29;
static public final int ILLEGAL_DAY = OFFSET + 30;
static public final int ILLEGAL_TIME = OFFSET + 31;
static public final int ILLEGAL_CALENDAR_VALUE = OFFSET + 32;
static public final int EMPTY_CHAR = OFFSET + 33;
static public final int BAD_OBJECT_NAME = OFFSET + 34;
static public final int BAD_UUID_FORMAT = OFFSET + 35;
static public final int INVALID_ENUM_TOKEN = OFFSET + 36;
static public final int CLASS_NOT_FOUND = OFFSET3 + 37;
static public final int WRONG_MAP_INDEX_TYPE = OFFSET + 38;
static public final int NULL_MAP_NOT_ALLOWED_HERE = OFFSET + 39;
static public final int NULL_COLLECTION_NOT_ALLOWED = OFFSET + 40;
static public final int TOO_MANY_DECIMALS = OFFSET + 41;
static public final int INVALID_BACKREFERENCE = OFFSET + 42;
static public final int UNSUPPORTED_DATA_TYPE = OFFSET + 43;
static public final int EXTRA_FIELDS = OFFSET + 44;
static public final int TOO_MANY_DIGITS = OFFSET + 45;
static public final int UNKNOW_RECORD_TYPE = OFFSET + 46;
static public final int NULL_CLASS_PQON = OFFSET + 47;
static public final int INVALID_BASE_CLASS_REFERENCE = OFFSET + 48;
static public final int CUSTOM_OBJECT_EXCEPTION = OFFSET + 49;
static public final int NUMERIC_TOO_MANY_DIGITS = OFFSET + 50;
static public final int CHAR_TOO_LONG = OFFSET + 51;
static public final int NUMBER_PARSING_ERROR = OFFSET + 52;
static public final int BAD_CLASS_IDS = OFFSET + 53;
static public final int INVALID_REFERENCES = OFFSET + 54;
static public final int UNSUPPORTED_TOKEN = OFFSET + 55;
static public final int UNSUPPORTED_COMPRESSED = OFFSET + 56;
static public final int JSON_EXCEPTION = OFFSET + 57;
static public final int JSON_ID = OFFSET + 58;
static public final int JSON_DUPLICATE_KEY = OFFSET + 59;
static public final int JSON_NO_PQON = OFFSET + 60;
static public final int INVALID_CHAR = OFFSET + 61;
static public final int UNSUPPORTED_CONVERSION = OFFSET + 62;
static public final int BINARY_TOO_LONG = OFFSET + 63;
static public final int JSON_BAD_OBJECTREF = OFFSET8 + 64;
static public final int WRONG_CLASS = OFFSET + 65;
static public final int JSON_EXCEPTION_MAP = OFFSET + 66;
static public final int JSON_EXCEPTION_ARRAY = OFFSET + 67;
static public final int JSON_EXCEPTION_OBJECT = OFFSET + 68;
static {
codeToDescription.put(MISSING_FIELD_TERMINATOR , "Missing field terminator");
codeToDescription.put(MISSING_RECORD_TERMINATOR , "Missing record terminator");
codeToDescription.put(MISSING_TERMINATOR , "Missing message terminator");
codeToDescription.put(PREMATURE_END , "Unexpected end of message");
codeToDescription.put(FIELD_PARSE , "Field parsing error");
codeToDescription.put(ILLEGAL_CHAR_ASCII , "Field contains non-ASCII character");
codeToDescription.put(ILLEGAL_CHAR_UPPER , "Field must consist of uppercase ASCII only");
codeToDescription.put(ILLEGAL_CHAR_LOWER , "Field must consist of lowercase ASCII only");
codeToDescription.put(ILLEGAL_CHAR_DIGIT , "Field contains non-digit");
codeToDescription.put(EMPTY_BUT_REQUIRED_FIELD , "Field was empty but required non-blank");
codeToDescription.put(UNEXPECTED_CHARACTER , "Character found was not one required next");
codeToDescription.put(ILLEGAL_EXPLICIT_NULL , "NULL not allowed here (required field)");
codeToDescription.put(ILLEGAL_IMPLICIT_NULL , "implicit NULL found due to end of object, not allowed (required field)");
codeToDescription.put(NO_DIGITS_FOUND , "no digits found while parsing a numeric field (possible before exponent)");
codeToDescription.put(SUPERFLUOUS_DECIMAL_POINT , "decimal point found for an integral type, in an exponent, or multiple decimal signs");
codeToDescription.put(SUPERFLUOUS_EXPONENT , "exponent sign encountered for a fixed point field, or multiple exponent signs");
codeToDescription.put(SUPERFLUOUS_SIGN , "minus sign encountered for an unsigned field, or multiple minus signs");
codeToDescription.put(ILLEGAL_CHAR_CTRL , "Field contains control characters");
codeToDescription.put(ILLEGAL_CHAR_NOT_NUMERIC , "Illegal character in numeric field (allowed are only [-.eE0-9]");
codeToDescription.put(NUMERIC_TOO_LONG , "numeric field too long (max 40 characters allowed)");
codeToDescription.put(STRING_TOO_LONG , "String longer than allowed");
codeToDescription.put(ILLEGAL_ESCAPE_SEQUENCE , "Invalid escape sequence (second character must be between @ and _ (0x40..0x5f)");
codeToDescription.put(ILLEGAL_BOOLEAN , "only 0 and 1 are allowed for a boolean field");
codeToDescription.put(BASE64_PARSING_ERROR , "problem parsing a base64 encoded raw field");
codeToDescription.put(ILLEGAL_CHAR_BASE64 , "illegal character found while parsing a base64 encoded raw field");
codeToDescription.put(ARRAY_SIZE_OUT_OF_BOUNDS , "negative item count or item count > 1000000000");
codeToDescription.put(BAD_CLASS , "parsed class is not a subclass of the expected one or subclassing is not allowed");
codeToDescription.put(BAD_TRANSMISSION_START , "Illegal character at the start of a transmission");
codeToDescription.put(BAD_TIMESTAMP_FRACTIONALS , "Illegal number of fractional digits for timestamp (must be 6..9 for precision 0..3)");
codeToDescription.put(ILLEGAL_DAY , "Illegal day (required: year in [1601,2399], month in [1,12], day in [1,31])");
codeToDescription.put(ILLEGAL_TIME , "Illegal time (required: hour in [0,23], minute in [0,59], second in [0,59]");
codeToDescription.put(ILLEGAL_CALENDAR_VALUE , "Exception converting the date/time");
codeToDescription.put(EMPTY_CHAR , "empty character field");
codeToDescription.put(BAD_OBJECT_NAME , "bad object name (must contain a dot, and not as first or last character)");
codeToDescription.put(BAD_UUID_FORMAT , "malformed UUID");
codeToDescription.put(INVALID_ENUM_TOKEN , "invalid token to instantiate enum");
codeToDescription.put(CLASS_NOT_FOUND , "class could not be found or instantiated");
codeToDescription.put(WRONG_MAP_INDEX_TYPE , "parsed index type of map mismatches expected one");
codeToDescription.put(NULL_MAP_NOT_ALLOWED_HERE , "parsed NULL for a required Map<>");
codeToDescription.put(NULL_COLLECTION_NOT_ALLOWED , "parsed NULL for a required List, Set or Array");
codeToDescription.put(TOO_MANY_DECIMALS , "number contains more decimal places than allowed");
codeToDescription.put(INVALID_BACKREFERENCE , "The serialized message contains an invalid backreference");
codeToDescription.put(UNSUPPORTED_DATA_TYPE , "The request field type or operation is not supported for this composer or parser");
codeToDescription.put(EXTRA_FIELDS , "Extra (non-null) fields have been encountered while expecting a class terminator. Most likely your client JAR is not up to date.");
codeToDescription.put(TOO_MANY_DIGITS , "Number too big");
codeToDescription.put(UNKNOW_RECORD_TYPE , "An unmapped record type has been encountered (CSV or fixed width parser)");
codeToDescription.put(NULL_CLASS_PQON , "A null class name has been transferred");
codeToDescription.put(INVALID_BASE_CLASS_REFERENCE , "A zero length class name has been transferred, referring to a field without defined base class");
codeToDescription.put(CUSTOM_OBJECT_EXCEPTION , "Cannot construct custom object from parsed data");
codeToDescription.put(NUMERIC_TOO_MANY_DIGITS , "Numeric field has more digits than specifically configured");
codeToDescription.put(CHAR_TOO_LONG , "Parsed a character, but got more than 1 character");
codeToDescription.put(NUMBER_PARSING_ERROR , "Cannot parse number");
codeToDescription.put(BAD_CLASS_IDS , "No class registered for factoryId/ClassId");
codeToDescription.put(INVALID_REFERENCES , "Could not resolve recursive references (record for index not found)"); // mapped PersistenceException
codeToDescription.put(UNSUPPORTED_TOKEN , "Token not yet supported (while skipping unknown data)");
codeToDescription.put(UNSUPPORTED_COMPRESSED , "Attempt to skip compressed data (not yet supported by parser version)");
codeToDescription.put(JSON_EXCEPTION , "JSON parsing exception");
codeToDescription.put(JSON_ID , "Map key is not a valid JSON identifier");
codeToDescription.put(JSON_DUPLICATE_KEY , "Map key of JSON map occurs multiple times");
codeToDescription.put(JSON_NO_PQON , "No map entry @PQON of type String found");
codeToDescription.put(INVALID_CHAR , "Invalid Character: must be String type and of length 1");
codeToDescription.put(UNSUPPORTED_CONVERSION , "Unsupported conversion between types");
codeToDescription.put(BINARY_TOO_LONG , "Binary data type too long");
codeToDescription.put(JSON_BAD_OBJECTREF , "Invalid object reference definition (no subclassing allowed and no base type)");
codeToDescription.put(WRONG_CLASS , "Got an object of a different class");
codeToDescription.put(JSON_EXCEPTION_MAP , "JSON parsing exception: Map<String,Object> expected");
codeToDescription.put(JSON_EXCEPTION_ARRAY , "JSON parsing exception: List expected");
codeToDescription.put(JSON_EXCEPTION_OBJECT , "JSON parsing exception: any object");
}
/** Creates a parser exception with an explicitly defined position and class name. */
public MessageParserException(int errorCode, String fieldName, int characterIndex, String className, String contents) {
super(errorCode, (className == null ? "?" : className)
+ "." + (fieldName == null ? "?" : fieldName)
+ (characterIndex >= 0 ? " at pos " + characterIndex : "")
+ (contents == null ? "<" + contents + ">" : ""));
this.characterIndex = characterIndex;
this.fieldName = fieldName;
this.className = className;
}
/** Creates a parser exception with an explicitly defined position and class name. */
public MessageParserException(int errorCode, String fieldName, int characterIndex, String className) {
this(errorCode, fieldName, characterIndex, className, null);
}
/** Creates a parser exception for which parse position and class name will be provided by some callback. */
public MessageParserException(int errorCode, String fieldName, String fieldContents, ParsePositionProvider parsePositionProvider) {
this(errorCode, fieldName, parsePositionProvider.getParsePosition(), parsePositionProvider.getCurrentClassName(), fieldContents);
}
public MessageParserException(int errorCode) {
this(errorCode, null, -1, null);
}
// some boilerplate code to retrieve exception properties
public int getCharacterIndex() {
return characterIndex;
}
public String getFieldName() {
return fieldName;
}
public String getClassName() {
return className;
}
}