001/*-------------------------------------------------------------------------+ 002| | 003| Copyright 2005-2011 the ConQAT Project | 004| | 005| Licensed under the Apache License, Version 2.0 (the "License"); | 006| you may not use this file except in compliance with the License. | 007| You may obtain a copy of the License at | 008| | 009| http://www.apache.org/licenses/LICENSE-2.0 | 010| | 011| Unless required by applicable law or agreed to in writing, software | 012| distributed under the License is distributed on an "AS IS" BASIS, | 013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 014| See the License for the specific language governing permissions and | 015| limitations under the License. | 016+-------------------------------------------------------------------------*/ 017package eu.cqse.check.framework.shallowparser.util; 018 019import org.conqat.lib.commons.string.StringUtils; 020 021import eu.cqse.check.framework.shallowparser.ShallowParserException; 022 023/** 024 * Exception for parsing errors in the {@link EntitySelectionExpressionParser}. 025 */ 026public class EntitySelectionExpressionParsingException extends ShallowParserException { 027 028 /** Version for serialization. */ 029 private static final long serialVersionUID = 1; 030 031 /** The message identifier. */ 032 private final EParsingExceptionMessage messageIdentifier; 033 034 /** 035 * Constructor. 036 * 037 * @param expression 038 * the expression being parsed. 039 * @param position 040 * the current parsing position in the message. 041 * 042 */ 043 public EntitySelectionExpressionParsingException(EParsingExceptionMessage messageIdentifier, String expression, 044 int position) { 045 super(createMessage(messageIdentifier, expression, position, null)); 046 this.messageIdentifier = messageIdentifier; 047 } 048 049 /** 050 * Constructor. 051 * 052 * @param expression 053 * the expression being parsed. 054 * @param position 055 * the current parsing position in the message. 056 * @param cause 057 * may not be null. 058 * 059 */ 060 public EntitySelectionExpressionParsingException(EParsingExceptionMessage messageIdentifier, String expression, 061 int position, Throwable cause) { 062 super(createMessage(messageIdentifier, expression, position, cause), cause); 063 this.messageIdentifier = messageIdentifier; 064 } 065 066 /** Creates the message for this exception. */ 067 private static String createMessage(EParsingExceptionMessage messageIdentifier, String expression, int position, 068 Throwable cause) { 069 070 String message = messageIdentifier.getMessage(); 071 if (cause != null) { 072 message += ": " + cause.getMessage(); 073 } 074 075 if (!StringUtils.endsWithOneOf(message, ".", "!")) { 076 message += "."; 077 } 078 079 String details = "The error occurred at or before the position marked with a caret: " 080 + expression.substring(0, position) + "^" + expression.substring(position); 081 return message + " " + details; 082 } 083 084 /** Returns the message identifier. */ 085 public EParsingExceptionMessage getMessageIdentifier() { 086 return messageIdentifier; 087 } 088 089 /** 090 * Enumeration of valid messages for this exception. This is both to reduce 091 * redundancy and to simplify testing. 092 */ 093 public static enum EParsingExceptionMessage { 094 095 /** Message. */ 096 EXPECTED_EXPRESSION("Expected an expression before or at this position."), 097 098 /** Message. */ 099 EXPECTED_BINARY_OPERATOR("Expected a binary operator such as & or |."), 100 101 /** Message. */ 102 PREDICATE_CONSTRUCTION_FAILED("Failed to construct predicate"), 103 104 /** Message. */ 105 PARAMETER_MISSING("Must provide parameter for this predicate!"), 106 107 /** Message. */ 108 UNSUPPORTED_PARAMETER("May not provide parameter for this predicate!"), 109 110 /** Message. */ 111 PREDICATE_NOT_FOUND("No matching predicate found!"), 112 113 /** Message. */ 114 MISSING_CLOSING_PARENTHESIS("Missing closing parenthesis!"), 115 116 /** Message. */ 117 MISPLACED_CLOSING_PARENTHESIS("Misplaced closing parenthesis."), 118 119 /** Message. */ 120 UNEXPECTED_CHARACTER("Unexpected character."); 121 122 /** The message for the exception. */ 123 private final String message; 124 125 /** Constructor. */ 126 private EParsingExceptionMessage(String message) { 127 this.message = message; 128 } 129 130 /** Returns the message for the exception. */ 131 public String getMessage() { 132 return message; 133 } 134 } 135}