001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.message;
007:
008: import java.io.ByteArrayInputStream;
009: import java.io.IOException;
010: import java.lang.reflect.InvocationTargetException;
011: import java.sql.SQLException;
012: import java.text.MessageFormat;
013: import java.util.Iterator;
014: import java.util.Locale;
015: import java.util.Properties;
016: import java.util.Map.Entry;
017:
018: import org.h2.constant.ErrorCode;
019: import org.h2.jdbc.JdbcSQLException;
020: import org.h2.util.Resources;
021: import org.h2.util.StringUtils;
022:
023: /**
024: * Messages used in the database engine.
025: * Use the PropertiesToUTF8 tool to translate properties files to UTF-8 and back.
026: * If the word 'SQL' appears then the whole SQL statement must be a parameter,
027: * otherwise this may be added: '; SQL statement: ' + sql
028: */
029: public class Message {
030:
031: private static final Properties MESSAGES = new Properties();
032:
033: static {
034: try {
035: byte[] messages = Resources
036: .get("/org/h2/res/_messages_en.properties");
037: if (messages != null) {
038: MESSAGES.load(new ByteArrayInputStream(messages));
039: }
040: String language = Locale.getDefault().getLanguage();
041: if (!"en".equals(language)) {
042: byte[] translations = Resources
043: .get("/org/h2/res/_messages_" + language
044: + ".properties");
045: // message: translated message + english
046: // (otherwise certain applications don't work)
047: if (translations != null) {
048: Properties p = new Properties();
049: p.load(new ByteArrayInputStream(translations));
050: for (Iterator it = p.entrySet().iterator(); it
051: .hasNext();) {
052: Entry e = (Entry) it.next();
053: String key = (String) e.getKey();
054: String translation = (String) e.getValue();
055: if (translation != null
056: && !translation.startsWith("#")) {
057: String original = MESSAGES.getProperty(key);
058: String message = translation + "\n"
059: + original;
060: MESSAGES.put(key, message);
061: }
062: }
063: }
064: }
065: } catch (IOException e) {
066: TraceSystem.traceThrowable(e);
067: }
068: }
069:
070: /**
071: * Gets the SQL Exception object for a specific SQLState. Supported
072: * SQL states are:
073: *
074: * @param sqlState the SQL state
075: * @param p1 the first parameter of the message
076: * @return the SQLException object
077: */
078: public static JdbcSQLException getSQLException(int sqlState,
079: String p1) {
080: return getSQLException(sqlState, new String[] { p1 });
081: }
082:
083: public static String translate(String key, String[] param) {
084: String message = MESSAGES.getProperty(key);
085: if (message == null) {
086: message = "(Message " + key + " not found)";
087: }
088: if (param != null) {
089: Object[] o = param;
090: message = MessageFormat.format(message, o);
091: }
092: return message;
093: }
094:
095: public static JdbcSQLException getSQLException(int errorCode,
096: String[] param, Throwable cause) {
097: String sqlstate = ErrorCode.getState(errorCode);
098: String message = translate(sqlstate, param);
099: return new JdbcSQLException(message, null, sqlstate, errorCode,
100: cause, null);
101: }
102:
103: public static JdbcSQLException getSQLException(int errorCode,
104: String[] param) {
105: return getSQLException(errorCode, param, null);
106: }
107:
108: public static SQLException getSyntaxError(String sql, int index) {
109: sql = StringUtils.addAsterisk(sql, index);
110: return getSQLException(ErrorCode.SYNTAX_ERROR_1, sql);
111: }
112:
113: public static SQLException getSyntaxError(String sql, int index,
114: String expected) {
115: sql = StringUtils.addAsterisk(sql, index);
116: return getSQLException(ErrorCode.SYNTAX_ERROR_2, new String[] {
117: sql, expected });
118: }
119:
120: /**
121: * Gets the SQL Exception object for a specific SQLState.
122: *
123: * @param sqlstate -
124: * the SQL State
125: * @return the SQLException object
126: */
127: public static JdbcSQLException getSQLException(int sqlstate) {
128: return getSQLException(sqlstate, (String) null);
129: }
130:
131: public static JdbcSQLException getUnsupportedException() {
132: return getSQLException(ErrorCode.FEATURE_NOT_SUPPORTED);
133: }
134:
135: public static JdbcSQLException getInvalidValueException(
136: String value, String param) {
137: return getSQLException(ErrorCode.INVALID_VALUE_2, new String[] {
138: value, param });
139: }
140:
141: public static Error getInternalError(String s) {
142: Error e = new Error(s);
143: TraceSystem.traceThrowable(e);
144: return e;
145: }
146:
147: public static Error getInternalError(String s, Exception e) {
148: //#ifdef JDK14
149: Error e2 = new Error(s, e);
150: //#endif
151: //#ifdef JDK13
152: /*
153: Error e2 = new Error(s);
154: */
155: //#endif
156: TraceSystem.traceThrowable(e2);
157: return e2;
158: }
159:
160: public static SQLException addSQL(SQLException e, String sql) {
161: if (e instanceof JdbcSQLException) {
162: JdbcSQLException j = (JdbcSQLException) e;
163: if (j.getSQL() == null) {
164: j.setSQL(sql);
165: }
166: return j;
167: } else {
168: return new JdbcSQLException(e.getMessage(), sql, e
169: .getSQLState(), e.getErrorCode(), e, null);
170: }
171: }
172:
173: public static SQLException convert(Throwable e) {
174: if (e instanceof InternalException) {
175: e = ((InternalException) e).getOriginalCause();
176: }
177: if (e instanceof SQLException) {
178: return (SQLException) e;
179: } else if (e instanceof InvocationTargetException) {
180: InvocationTargetException te = (InvocationTargetException) e;
181: Throwable t = te.getTargetException();
182: if (t instanceof SQLException) {
183: return (SQLException) t;
184: }
185: return getSQLException(ErrorCode.EXCEPTION_IN_FUNCTION,
186: null, e);
187: } else if (e instanceof IOException) {
188: return getSQLException(ErrorCode.IO_EXCEPTION_1,
189: new String[] { e.toString() }, e);
190: }
191: return getSQLException(ErrorCode.GENERAL_ERROR_1,
192: new String[] { e.toString() }, e);
193: }
194:
195: public static SQLException convertIOException(IOException e,
196: String message) {
197: if (message == null) {
198: return getSQLException(ErrorCode.IO_EXCEPTION_1,
199: new String[] { e.toString() }, e);
200: } else {
201: return getSQLException(ErrorCode.IO_EXCEPTION_2,
202: new String[] { e.toString(), message }, e);
203: }
204: }
205:
206: public static Error getInternalError() {
207: return getInternalError("unexpected code path");
208: }
209:
210: public static InternalException convertToInternal(Exception e) {
211: return new InternalException(e);
212: }
213:
214: public static IOException convertToIOException(Throwable e) {
215: if (e instanceof JdbcSQLException) {
216: JdbcSQLException e2 = (JdbcSQLException) e;
217: if (e2.getOriginalCause() != null) {
218: e = e2.getOriginalCause();
219: }
220: }
221: IOException io = new IOException(e.toString());
222: //#ifdef JDK14
223: io.initCause(e);
224: //#endif
225: return io;
226: }
227:
228: }
|