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

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

There is a newer version: 4.0.10.java8
Show 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 org.firebirdsql.logging.Logger;
import org.firebirdsql.logging.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * This class returns messages for the specified error code.
 * 

* It loads all messages during the class initialization and keeps messages * in the static java.util.Properties variable. *

* * @author David Jencks * @author Roman Rokytskyy * @author Blas Rodriguez Somoza * @author Mark Rotteveel * @version 1.0 */ public class GDSExceptionHelper { private static final Logger log = LoggerFactory.getLogger(GDSExceptionHelper.class); private static final String MESSAGES = "isc_error_msg"; private static final String JAYBIRD_MESSAGES = "org/firebirdsql/jaybird_error_msg"; private static final String SQLSTATES = "isc_error_sqlstates"; private static final String JAYBIRD_SQLSTATES = "org/firebirdsql/jaybird_error_sqlstates"; private static final Map messages; private static final Map sqlstates; /** * Initializes the messages map. */ static { try { messages = loadResource(false, MESSAGES, JAYBIRD_MESSAGES); sqlstates = loadResource(true, SQLSTATES, JAYBIRD_SQLSTATES); } catch (Exception ex) { log.error("Exception in init of GDSExceptionHelper, unable to load error information", ex); throw new ExceptionInInitializerError(ex); } } private static Map loadResource(boolean deduplicate, String... resources) throws Exception { Properties properties = new Properties(); Exception firstException = null; // Load from property files for (String resource : resources) { String resourceFile = "/" + resource.replace('.', '/') + ".properties"; try (InputStream in = getResourceAsStream(resourceFile)) { if (in != null) { properties.load(in); } else { log.warn("Unable to load resource; resource " + resource + " is not found"); } } catch (IOException ioex) { log.error("Unable to load resource " + resource, ioex); if (firstException == null) { firstException = ioex; } } } if (firstException != null) { throw firstException; } // Use of HashMap avoids unnecessary synchronization in Properties return asErrorCodeMapping(deduplicate, properties); } private static Map asErrorCodeMapping(boolean deduplicate, Properties properties) { // Convert to hash map and deduplicate values if specified // We are not interning to avoid polluting the string constant pool final Map deduplicationMap = deduplicate ? new HashMap(128) : Collections.emptyMap(); final Map propsAsMap = new HashMap<>(properties.size(), 1); for (Object key : properties.keySet()) { if (!(key instanceof String)) continue; try { final String keyString = (String) key; final Integer errorCode = Integer.valueOf(keyString); String value = properties.getProperty(keyString); if (deduplicate) { if (deduplicationMap.containsKey(value)) { value = deduplicationMap.get(value); } else { deduplicationMap.put(value, value); } } propsAsMap.put(errorCode, value); } catch (NumberFormatException e) { log.warn("Key " + key + " is not a number; ignored", e); } } return propsAsMap; } private static InputStream getResourceAsStream(String res) { InputStream in = GDSExceptionHelper.class.getResourceAsStream(res); if (in == null) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); in = cl.getResourceAsStream(res); } return in; } /** * This method returns a message for the specified error code. * * @param code * Firebird error code * @return instance of GDSExceptionHelper.GDSMessage class where you can set desired parameters. */ public static GDSMessage getMessage(int code) { final String message = messages.get(code); return new GDSMessage(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 defaultSQLState if nothing found. */ public static String getSQLState(int code, String defaultSQLState) { final String sqlState = sqlstates.get(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 final String template; private final String[] params; private final List extraParameters = new ArrayList<>(); /** * Constructs an instance of GDSMessage for the specified template. */ public GDSMessage(String template) { this.template = template; params = new String[getParamCountInternal()]; } /** * Returns the number of parameters for the message template. * * @return number of parameters. */ public int getParamCount() { return params.length; } private int getParamCountInternal() { int count = 0; for (int i = 0; i < template.length(); i++) { if (template.charAt(i) == '{') 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() { String message = template; for (int i = 0; i < params.length; i++) { String param = "{" + i + "}"; int pos = message.indexOf(param); if (pos > -1) { message = message.substring(0, pos) + (params[i] != null ? params[i] : "(null)") + message.substring(pos + param.length()); } } // Include extra parameters at the end of the message for (String extraParameter : extraParameters) { message = message + "; " + extraParameter; } return message; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy