/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.message;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Locale;
import java.util.Properties;
import java.util.Map.Entry;
import org.h2.constant.ErrorCode;
import org.h2.jdbc.JdbcSQLException;
import org.h2.util.Resources;
import org.h2.util.StringUtils;
/**
* Messages used in the database engine.
* Use the PropertiesToUTF8 tool to translate properties files to UTF-8 and back.
* If the word 'SQL' appears then the whole SQL statement must be a parameter,
* otherwise this may be added: '; SQL statement: ' + sql
*/
public class Message {
private static final Properties MESSAGES = new Properties();
static {
try {
byte[] messages = Resources.get("/org/h2/res/_messages_en.properties");
if (messages != null) {
MESSAGES.load(new ByteArrayInputStream(messages));
}
String language = Locale.getDefault().getLanguage();
if (!"en".equals(language)) {
byte[] translations = Resources.get("/org/h2/res/_messages_"+language+".properties");
// message: translated message + english
// (otherwise certain applications don't work)
if (translations != null) {
Properties p = new Properties();
p.load(new ByteArrayInputStream(translations));
for (Iterator it = p.entrySet().iterator(); it.hasNext();) {
Entry e = (Entry) it.next();
String key = (String) e.getKey();
String translation = (String) e.getValue();
if (translation != null && !translation.startsWith("#")) {
String original = MESSAGES.getProperty(key);
String message = translation + "\n" + original;
MESSAGES.put(key, message);
}
}
}
}
} catch (IOException e) {
TraceSystem.traceThrowable(e);
}
}
/**
* Gets the SQL Exception object for a specific SQLState. Supported
* SQL states are:
*
* @param sqlState the SQL state
* @param p1 the first parameter of the message
* @return the SQLException object
*/
public static JdbcSQLException getSQLException(int sqlState, String p1) {
return getSQLException(sqlState, new String[] { p1 });
}
public static String translate(String key, String[] param) {
String message = MESSAGES.getProperty(key);
if (message == null) {
message = "(Message " +key+ " not found)";
}
if (param != null) {
Object[] o = param;
message = MessageFormat.format(message, o);
}
return message;
}
public static JdbcSQLException getSQLException(int errorCode, String[] param, Throwable cause) {
String sqlstate = ErrorCode.getState(errorCode);
String message = translate(sqlstate, param);
return new JdbcSQLException(message, null, sqlstate, errorCode, cause, null);
}
public static JdbcSQLException getSQLException(int errorCode, String[] param) {
return getSQLException(errorCode, param, null);
}
public static SQLException getSyntaxError(String sql, int index) {
sql = StringUtils.addAsterisk(sql, index);
return getSQLException(ErrorCode.SYNTAX_ERROR_1, sql);
}
public static SQLException getSyntaxError(String sql, int index, String expected) {
sql = StringUtils.addAsterisk(sql, index);
return getSQLException(ErrorCode.SYNTAX_ERROR_2, new String[]{sql, expected});
}
/**
* Gets the SQL Exception object for a specific SQLState.
*
* @param sqlstate -
* the SQL State
* @return the SQLException object
*/
public static JdbcSQLException getSQLException(int sqlstate) {
return getSQLException(sqlstate, (String) null);
}
public static JdbcSQLException getUnsupportedException() {
return getSQLException(ErrorCode.FEATURE_NOT_SUPPORTED);
}
public static JdbcSQLException getInvalidValueException(String value, String param) {
return getSQLException(ErrorCode.INVALID_VALUE_2, new String[]{value, param});
}
public static Error getInternalError(String s) {
Error e = new Error(s);
TraceSystem.traceThrowable(e);
return e;
}
public static Error getInternalError(String s, Exception e) {
//#ifdef JDK14
Error e2 = new Error(s, e);
//#endif
//#ifdef JDK13
/*
Error e2 = new Error(s);
*/
//#endif
TraceSystem.traceThrowable(e2);
return e2;
}
public static SQLException addSQL(SQLException e, String sql) {
if (e instanceof JdbcSQLException) {
JdbcSQLException j = (JdbcSQLException) e;
if (j.getSQL() == null) {
j.setSQL(sql);
}
return j;
} else {
return new JdbcSQLException(e.getMessage(), sql,
e.getSQLState(),
e.getErrorCode(), e, null);
}
}
public static SQLException convert(Throwable e) {
if (e instanceof InternalException) {
e = ((InternalException) e).getOriginalCause();
}
if (e instanceof SQLException) {
return (SQLException) e;
} else if (e instanceof InvocationTargetException) {
InvocationTargetException te = (InvocationTargetException) e;
Throwable t = te.getTargetException();
if (t instanceof SQLException) {
return (SQLException) t;
}
return getSQLException(ErrorCode.EXCEPTION_IN_FUNCTION, null, e);
} else if (e instanceof IOException) {
return getSQLException(ErrorCode.IO_EXCEPTION_1, new String[] { e.toString() }, e);
}
return getSQLException(ErrorCode.GENERAL_ERROR_1, new String[]{e.toString()}, e);
}
public static SQLException convertIOException(IOException e, String message) {
if (message == null) {
return getSQLException(ErrorCode.IO_EXCEPTION_1, new String[]{e.toString()}, e);
} else {
return getSQLException(ErrorCode.IO_EXCEPTION_2, new String[]{e.toString(), message}, e);
}
}
public static Error getInternalError() {
return getInternalError("unexpected code path");
}
public static InternalException convertToInternal(Exception e) {
return new InternalException(e);
}
public static IOException convertToIOException(Throwable e) {
if (e instanceof JdbcSQLException) {
JdbcSQLException e2 = (JdbcSQLException) e;
if (e2.getOriginalCause() != null) {
e = e2.getOriginalCause();
}
}
IOException io = new IOException(e.toString());
//#ifdef JDK14
io.initCause(e);
//#endif
return io;
}
}