org.firebirdsql.gds.GDSExceptionHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaybird Show documentation
Show all versions of jaybird Show documentation
JDBC Driver for the Firebird RDBMS
The newest version!
/*
* Public Firebird Java API.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.firebirdsql.gds;
import org.firebirdsql.jdbc.SQLStateConstants;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class returns messages for the specified error code.
*
* This loads all messages during class initialization.
*
*
* @author David Jencks
* @author Roman Rokytskyy
* @author Blas Rodriguez Somoza
* @author Mark Rotteveel
* @version 1.0
*/
public final class GDSExceptionHelper {
private static final Pattern MESSAGE_PARAM_PATTERN = Pattern.compile("\\{(\\d+)}");
private static final MessageLookup MESSAGE_LOOKUP;
/*
* Initializes the messages map.
*/
static {
try {
MESSAGE_LOOKUP = MessageLoader.loadErrorMessages();
} catch (Exception ex) {
System.getLogger(GDSExceptionHelper.class.getName()).log(System.Logger.Level.ERROR,
"Exception in init of GDSExceptionHelper, unable to load error information", ex);
throw new ExceptionInInitializerError(ex);
}
}
private GDSExceptionHelper() {
// no instances
}
/**
* This method returns a message for the specified error code.
*
* @param code
* Firebird error code
* @return instance of {@code GDSExceptionHelper.GDSMessage} class where you can set desired parameters.
*/
public static GDSMessage getMessage(int code) {
return new GDSMessage(getMessageText(code), code != ISCConstants.isc_formatted_exception);
}
private static String getMessageText(int code) {
String message = MESSAGE_LOOKUP.getErrorMessage(code);
return message != null ? message : "No message for code " + code + " found.";
}
/**
* Get the SQL state for the specified error code.
*
* @param code
* Firebird error code
* @return SQL state for the Firebird error code, "HY000" if nothing found.
*/
public static String getSQLState(int code) {
return getSQLState(code, SQLStateConstants.SQL_STATE_GENERAL_ERROR);
}
/**
* Get the SQL state for the specified error code.
*
* @param code
* Firebird error code
* @param defaultSQLState
* The default SQLState to return
* @return SQL state for the Firebird error code, or {@code defaultSQLState} if nothing found.
*/
public static String getSQLState(int code, String defaultSQLState) {
final String sqlState = MESSAGE_LOOKUP.getSqlState(code);
return sqlState != null ? sqlState : defaultSQLState;
}
/**
* This class wraps message template obtained from isc_error_msg.properties
* file and allows to set parameters to the message.
*/
public static final class GDSMessage {
private static final int PARAM_SIZE_FACTOR = 20;
private final String template;
private final String[] params;
private final List extraParameters = new ArrayList<>();
private final boolean includeExtraParameters;
/**
* Constructs an instance of GDSMessage for the specified template.
*/
public GDSMessage(String template) {
this(template, true);
}
/**
* Constructs an instance of GDSMessage for the specified template.
*
* @param includeExtraParameters
* {@code true} append extra parameters to the end of the message, {@code false} ignore extra parameters
*/
private GDSMessage(String template, boolean includeExtraParameters) {
this.template = template;
params = new String[getParamCountInternal(template)];
this.includeExtraParameters = includeExtraParameters;
}
/**
* Returns the number of parameters for the message template.
*
* @return number of parameters.
*/
public int getParamCount() {
return params.length;
}
private static int getParamCountInternal(final String template) {
int count = 0;
final Matcher matcher = MESSAGE_PARAM_PATTERN.matcher(template);
while (matcher.find()) {
count++;
}
return count;
}
/**
* Sets the parameter value
*
* @param position
* the parameter number, 0 - first parameter.
* @param text
* value of parameter
*/
public void setParameter(int position, String text) {
if (position < params.length) {
params[position] = text;
}
}
/**
* Sets the parameter values.
*
* Parameter values with an index value higher than the number of message arguments are added as extra
* parameters.
*
*
* @param messageParameters
* Message parameters
*/
public void setParameters(List messageParameters) {
int position;
for (position = 0; position < Math.min(params.length, messageParameters.size()); position++) {
params[position] = messageParameters.get(position);
}
// If we have more messageParameters we need to store them separately
if (params.length < messageParameters.size()) {
for (; position < messageParameters.size(); position++) {
extraParameters.add(messageParameters.get(position));
}
}
}
/**
* Puts parameters into the template and return the obtained string.
*
* @return string representation of the message.
*/
public String toString() {
final var messageBuffer = new StringBuilder(estimateBufferCapacity());
final Matcher matcher = MESSAGE_PARAM_PATTERN.matcher(template);
while (matcher.find()) {
final int paramIndex = Integer.parseInt(matcher.group(1));
String parameterValue = isValidParameterIndex(paramIndex) ? params[paramIndex] : null;
matcher.appendReplacement(messageBuffer, "");
// Append separately to avoid having to quote the replacement string
messageBuffer.append(parameterValue != null ? parameterValue : "(null)");
}
matcher.appendTail(messageBuffer);
if (includeExtraParameters) {
// Include extra parameters at the end of the message
for (String extraParameter : extraParameters) {
messageBuffer.append("; ").append(extraParameter);
}
}
return messageBuffer.toString();
}
private int estimateBufferCapacity() {
return template.length()
+ (params.length + extraParameters.size()) * PARAM_SIZE_FACTOR;
}
private boolean isValidParameterIndex(int index) {
return index >= 0 && index < params.length;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy