All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.firebirdsql.gds.GDSExceptionHelper Maven / Gradle / Ivy

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