1 ${database.allClassCopyright}package ${glPackageBaseCommonS2DaoInternalSqlHandler};
\r
3 import java.sql.Connection;
\r
4 import java.sql.Statement;
\r
5 import java.sql.PreparedStatement;
\r
6 import java.sql.ResultSet;
\r
7 import java.sql.SQLException;
\r
9 import javax.sql.DataSource;
\r
11 import org.seasar.extension.jdbc.StatementFactory;
\r
12 import org.seasar.extension.jdbc.ValueType;
\r
13 import org.seasar.extension.jdbc.types.ValueTypes;
\r
14 import org.seasar.framework.exception.SQLRuntimeException;
\r
16 import ${glPackageBaseCommon}.${glQLog};
\r
17 import ${glPackageBaseCommon}.${glDBFluteConfig};
\r
18 import ${glPackageBaseCommon}.${glInternalMapContextName};
\r
19 import ${glPackageBaseCommonCBean}.${glConditionBeanContextName};
\r
20 import ${glPackageBaseCommonCBean}.${glConditionBeanInterfaceName};
\r
21 import ${glPackageBaseCommonCBeanOutsidesql}.${glOutsideSqlContextName};
\r
22 import ${glPackageBaseCommonException}.${glEntityAlreadyExistsException};
\r
23 import ${glPackageBaseCommonException}.${glSQLFailureException};
\r
24 import ${glPackageBaseCommonS2DaoInternalSqlLog}.${glInternalSqlLogRegistry};
\r
25 import ${glPackageBaseCommonS2DaoInternalUtil}.${glInternalBindVariableUtil};
\r
26 import ${glPackageBaseCommonUtil}.${glSimpleSystemUtil};
\r
29 * @author ${database.ClassAuthor}
\r
31 public class ${glInternalBasicHandler} {
\r
33 // ===================================================================================
\r
36 private DataSource dataSource;
\r
38 private StatementFactory statementFactory;
\r
39 private Object[] loggingMessageSqlArgs;
\r
41 // ===================================================================================
\r
44 public ${glInternalBasicHandler}(DataSource ds, StatementFactory statementFactory) {
\r
46 setStatementFactory(statementFactory);
\r
49 public ${glInternalBasicHandler}(DataSource ds, String sql, StatementFactory statementFactory) {
\r
52 setStatementFactory(statementFactory);
\r
55 // ===================================================================================
\r
56 // Basic Method for SubClass
\r
57 // =========================
\r
58 protected void bindArgs(PreparedStatement ps, Object[] args, Class<?>[] argTypes) {
\r
62 for (int i = 0; i < args.length; ++i) {
\r
63 ValueType valueType = getValueType(argTypes[i]);
\r
65 valueType.bindValue(ps, i + 1, args[i]);
\r
66 } catch (SQLException e) {
\r
67 handleSQLException(e, ps);
\r
72 protected Class<?>[] getArgTypes(Object[] args) {
\r
76 Class<?>[] argTypes = new Class[args.length];
\r
77 for (int i = 0; i < args.length; ++i) {
\r
78 Object arg = args[i];
\r
80 argTypes[i] = arg.getClass();
\r
86 protected String getCompleteSql(Object[] args) {
\r
87 return ${glInternalBindVariableUtil}.getCompleteSql(sql, args);
\r
90 protected String getBindVariableText(Object bindVariable) {
\r
91 return ${glInternalBindVariableUtil}.getBindVariableText(bindVariable);
\r
94 protected ValueType getValueType(Class<?> clazz) {
\r
95 return ValueTypes.getValueType(clazz);
\r
98 protected void logSql(Object[] args, Class<?>[] argTypes) {
\r
99 if (${glQLog}.isLogEnabled() || ${glInternalSqlLogRegistry}.existsSqlLogRegistry()) {
\r
100 final String completeSql = getCompleteSql(args);
\r
101 if (isContainsLineSeparatorInSql()) {
\r
102 ${glQLog}.log(getLineSeparator() + completeSql);
\r
104 ${glQLog}.log(completeSql);
\r
106 if (${glInternalSqlLogRegistry}.existsSqlLogRegistry()) {
\r
107 final Object sqlLogRegistry = ${glInternalSqlLogRegistry}.findContainerSqlLogRegistry();
\r
108 if (sqlLogRegistry != null) {
\r
109 ${glInternalSqlLogRegistry}.push(getSql(), completeSql, args, argTypes, sqlLogRegistry);
\r
115 protected boolean isContainsLineSeparatorInSql() {
\r
116 return sql != null ? sql.contains(getLineSeparator()) : false;
\r
119 // ===================================================================================
\r
120 // Exception Handler
\r
121 // =================
\r
122 protected void handleSQLException(SQLException e, Statement statement) {
\r
123 handleSQLException(e, statement, false);
\r
126 protected void handleSQLException(SQLException e, Statement statement, boolean uniqueConstraintValid) {
\r
127 String completeSql = buildLoggingMessageSql();
\r
128 new SQLExceptionHandler().handleSQLException(e, statement, uniqueConstraintValid, completeSql);
\r
131 protected String buildLoggingMessageSql() {
\r
132 String completeSql = null;
\r
133 if (sql != null && loggingMessageSqlArgs != null) {
\r
135 completeSql = getCompleteSql(loggingMessageSqlArgs);
\r
136 } catch (RuntimeException ignored) {
\r
139 return completeSql;
\r
142 public static class SQLExceptionHandler {
\r
144 public void handleSQLException(SQLException e, Statement statement) {
\r
145 handleSQLException(e, statement, false);
\r
148 public void handleSQLException(SQLException e, Statement statement, boolean uniqueConstraintValid) {
\r
149 handleSQLException(e, statement, uniqueConstraintValid, null);
\r
152 public void handleSQLException(SQLException e, Statement statement, boolean uniqueConstraintValid, String completeSql) {
\r
153 if (isSqlExceptionOldStyleHandling()) {
\r
154 throw new SQLRuntimeException(e);
\r
156 if (uniqueConstraintValid && isUniqueConstraintException(e)) {
\r
157 throwEntityAlreadyExistsException(e, statement, completeSql);
\r
159 throwSQLFailureException(e, statement, completeSql);
\r
162 protected boolean isUniqueConstraintException(SQLException e) {
\r
163 ${glDBFluteConfig}.UniqueConstraintDeterminator determinator = getUniqueConstraintDeterminator();
\r
164 if (determinator != null) {
\r
165 return determinator.isUniqueConstraintException(e);
\r
167 return ${glConditionBeanContextName}.isUniqueConstraintException(extractSQLState(e), e.getErrorCode());
\r
170 protected ${glDBFluteConfig}.UniqueConstraintDeterminator getUniqueConstraintDeterminator() {
\r
171 return ${glDBFluteConfig}.getInstance().getUniqueConstraintDeterminator();
\r
174 protected boolean isSqlExceptionOldStyleHandling() {
\r
175 return ${glDBFluteConfig}.getInstance().isSqlExceptionOldStyleHandling();
\r
178 protected void throwEntityAlreadyExistsException(SQLException e, Statement statement, String completeSql) {
\r
179 String msg = "Look! Read the message below." + getLineSeparator();
\r
180 msg = msg + "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" + getLineSeparator();
\r
181 msg = msg + "The entity already exists on the database!" + getLineSeparator();
\r
182 msg = msg + getLineSeparator();
\r
183 msg = msg + "[Advice]" + getLineSeparator();
\r
184 msg = msg + "Please confirm the primary key whether it already exists on the database." + getLineSeparator();
\r
185 msg = msg + "And confirm the unique constraint for other columns." + getLineSeparator();
\r
186 msg = msg + getLineSeparator();
\r
187 msg = msg + "[SQLState]" + getLineSeparator() + extractSQLState(e) + getLineSeparator();
\r
188 msg = msg + getLineSeparator();
\r
189 msg = msg + "[ErrorCode]" + getLineSeparator() + e.getErrorCode() + getLineSeparator();
\r
190 msg = msg + getLineSeparator();
\r
191 msg = msg + "[SQLException]" + getLineSeparator() + e.getClass().getName() + getLineSeparator();
\r
192 msg = msg + e.getMessage() + getLineSeparator();
\r
193 SQLException nextEx = e.getNextException();
\r
194 if (nextEx != null) {
\r
195 msg = msg + getLineSeparator();
\r
196 msg = msg + "[NextException]" + getLineSeparator();
\r
197 msg = msg + nextEx.getClass().getName() + getLineSeparator();
\r
198 msg = msg + nextEx.getMessage() + getLineSeparator();
\r
199 SQLException nextNextEx = nextEx.getNextException();
\r
200 if (nextNextEx != null) {
\r
201 msg = msg + getLineSeparator();
\r
202 msg = msg + "[NextNextException]" + getLineSeparator();
\r
203 msg = msg + nextNextEx.getClass().getName() + getLineSeparator();
\r
204 msg = msg + nextNextEx.getMessage() + getLineSeparator();
\r
207 Object invokeName = extractBehaviorInvokeName();
\r
208 if (invokeName != null) {
\r
209 msg = msg + getLineSeparator();
\r
210 msg = msg + "[Behavior]" + getLineSeparator();
\r
211 msg = msg + invokeName + getLineSeparator();
\r
213 if (hasConditionBean()) {
\r
214 msg = msg + getLineSeparator();
\r
215 msg = msg + "[ConditionBean]" + getLineSeparator();
\r
216 msg = msg + getConditionBean().getClass().getName() + getLineSeparator();
\r
218 if (hasOutsideSqlContext()) {
\r
219 msg = msg + getLineSeparator();
\r
220 msg = msg + "[OutsideSql]" + getLineSeparator();
\r
221 msg = msg + getOutsideSqlContext().getOutsideSqlPath() + getLineSeparator();
\r
222 msg = msg + getLineSeparator();
\r
223 msg = msg + "[ParameterBean]" + getLineSeparator();
\r
224 Object pmb = getOutsideSqlContext().getParameterBean();
\r
226 msg = msg + pmb.getClass().getName() + getLineSeparator();
\r
227 msg = msg + pmb + getLineSeparator();
\r
229 msg = msg + pmb + getLineSeparator();
\r
232 if (statement != null) {
\r
233 msg = msg + getLineSeparator();
\r
234 msg = msg + "[Statement]" + getLineSeparator();
\r
235 msg = msg + statement.getClass().getName() + getLineSeparator();
\r
237 if (completeSql != null) {
\r
238 msg = msg + getLineSeparator();
\r
239 msg = msg + "[Display SQL]" + getLineSeparator();
\r
240 msg = msg + completeSql + getLineSeparator();
\r
242 msg = msg + "* * * * * * * * * */";
\r
243 throw new ${glEntityAlreadyExistsException}(msg, e);
\r
246 protected void throwSQLFailureException(SQLException e, Statement statement, String completeSql) {
\r
247 String msg = "Look! Read the message below." + getLineSeparator();
\r
248 msg = msg + "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" + getLineSeparator();
\r
249 msg = msg + "The SQL failed to execute!" + getLineSeparator();
\r
250 msg = msg + getLineSeparator();
\r
251 msg = msg + "[Advice]" + getLineSeparator();
\r
252 msg = msg + "Please confirm the SQLException message." + getLineSeparator();
\r
253 msg = msg + getLineSeparator();
\r
254 msg = msg + "[SQLState]" + getLineSeparator() + extractSQLState(e) + getLineSeparator();
\r
255 msg = msg + getLineSeparator();
\r
256 msg = msg + "[ErrorCode]" + getLineSeparator() + e.getErrorCode() + getLineSeparator();
\r
257 msg = msg + getLineSeparator();
\r
258 msg = msg + "[SQLException]" + getLineSeparator() + e.getClass().getName() + getLineSeparator();
\r
259 msg = msg + e.getMessage() + getLineSeparator();
\r
260 SQLException nextEx = e.getNextException();
\r
261 if (nextEx != null) {
\r
262 msg = msg + getLineSeparator();
\r
263 msg = msg + "[NextException]" + getLineSeparator();
\r
264 msg = msg + nextEx.getClass().getName() + getLineSeparator();
\r
265 msg = msg + nextEx.getMessage() + getLineSeparator();
\r
266 SQLException nextNextEx = nextEx.getNextException();
\r
267 if (nextNextEx != null) {
\r
268 msg = msg + getLineSeparator();
\r
269 msg = msg + "[NextNextException]" + getLineSeparator();
\r
270 msg = msg + nextNextEx.getClass().getName() + getLineSeparator();
\r
271 msg = msg + nextNextEx.getMessage() + getLineSeparator();
\r
274 Object invokeName = extractBehaviorInvokeName();
\r
275 if (invokeName != null) {
\r
276 msg = msg + getLineSeparator();
\r
277 msg = msg + "[Behavior]" + getLineSeparator();
\r
278 msg = msg + invokeName + getLineSeparator();
\r
280 if (hasConditionBean()) {
\r
281 msg = msg + getLineSeparator();
\r
282 msg = msg + "[ConditionBean]" + getLineSeparator();
\r
283 msg = msg + getConditionBean().getClass().getName() + getLineSeparator();
\r
285 if (hasOutsideSqlContext()) {
\r
286 msg = msg + getLineSeparator();
\r
287 msg = msg + "[OutsideSql]" + getLineSeparator();
\r
288 msg = msg + getOutsideSqlContext().getOutsideSqlPath() + getLineSeparator();
\r
289 msg = msg + getLineSeparator();
\r
290 msg = msg + "[ParameterBean]" + getLineSeparator();
\r
291 Object pmb = getOutsideSqlContext().getParameterBean();
\r
293 msg = msg + pmb.getClass().getName() + getLineSeparator();
\r
294 msg = msg + pmb + getLineSeparator();
\r
296 msg = msg + pmb + getLineSeparator();
\r
299 if (statement != null) {
\r
300 msg = msg + getLineSeparator();
\r
301 msg = msg + "[Statement]" + getLineSeparator();
\r
302 msg = msg + statement.getClass().getName() + getLineSeparator();
\r
304 if (completeSql != null) {
\r
305 msg = msg + getLineSeparator();
\r
306 msg = msg + "[Display SQL]" + getLineSeparator();
\r
307 msg = msg + completeSql + getLineSeparator();
\r
309 msg = msg + "* * * * * * * * * */";
\r
310 throw new ${glSQLFailureException}(msg, e);
\r
313 protected String extractSQLState(SQLException e) {
\r
314 String sqlState = e.getSQLState();
\r
315 if (sqlState != null) {
\r
320 SQLException nextEx = e.getNextException();
\r
321 if (nextEx == null) {
\r
324 sqlState = nextEx.getSQLState();
\r
325 if (sqlState != null) {
\r
330 SQLException nextNextEx = nextEx.getNextException();
\r
331 if (nextNextEx == null) {
\r
334 sqlState = nextNextEx.getSQLState();
\r
335 if (sqlState != null) {
\r
340 SQLException nextNextNextEx = nextNextEx.getNextException();
\r
341 if (nextNextNextEx == null) {
\r
344 sqlState = nextNextNextEx.getSQLState();
\r
345 if (sqlState != null) {
\r
349 // It doesn't use recursive call by design because JDBC is unpredictable fellow.
\r
353 protected String extractBehaviorInvokeName() {
\r
354 final Object behaviorInvokeName = ${glInternalMapContextName}.getObject("df:BehaviorInvokeName");
\r
355 if (behaviorInvokeName == null) {
\r
358 final Object clientInvokeName = ${glInternalMapContextName}.getObject("df:ClientInvokeName");
\r
359 final Object byPassInvokeName = ${glInternalMapContextName}.getObject("df:ByPassInvokeName");
\r
360 final StringBuilder sb = new StringBuilder();
\r
361 boolean existsPath = false;
\r
362 if (clientInvokeName != null) {
\r
364 sb.append(clientInvokeName);
\r
366 if (byPassInvokeName != null) {
\r
368 sb.append(byPassInvokeName);
\r
370 sb.append(behaviorInvokeName);
\r
374 return sb.toString();
\r
377 protected boolean hasConditionBean() {
\r
378 return ${glConditionBeanContextName}.isExistConditionBeanOnThread();
\r
381 protected ${glConditionBeanInterfaceName} getConditionBean() {
\r
382 return ${glConditionBeanContextName}.getConditionBeanOnThread();
\r
385 protected boolean hasOutsideSqlContext() {
\r
386 return ${glOutsideSqlContextName}.isExistOutsideSqlContextOnThread();
\r
389 protected ${glOutsideSqlContextName} getOutsideSqlContext() {
\r
390 return ${glOutsideSqlContextName}.getOutsideSqlContextOnThread();
\r
393 protected String getLineSeparator() {
\r
394 return ${glSimpleSystemUtil}.getLineSeparator();
\r
398 // ===================================================================================
\r
401 protected Connection getConnection() {
\r
402 if (dataSource == null) {
\r
403 throw new IllegalStateException("The dataSource should not be null!");
\r
406 return dataSource.getConnection();
\r
407 } catch (SQLException e) {
\r
408 handleSQLException(e, null);
\r
409 return null;// Unreachable!
\r
413 protected PreparedStatement prepareStatement(Connection conn) {
\r
415 throw new IllegalStateException("The sql should not be null!");
\r
417 return statementFactory.createPreparedStatement(conn, sql);
\r
420 protected int executeUpdate(PreparedStatement ps) {
\r
422 return ps.executeUpdate();
\r
423 } catch (SQLException e) {
\r
424 handleSQLException(e, ps, true);
\r
425 return 0;// Unreachable!
\r
429 protected void setFetchSize(Statement statement, int fetchSize) {
\r
430 if (statement == null) {
\r
434 statement.setFetchSize(fetchSize);
\r
435 } catch (SQLException e) {
\r
436 handleSQLException(e, statement);
\r
440 protected void setMaxRows(Statement statement, int maxRows) {
\r
441 if (statement == null) {
\r
445 statement.setMaxRows(maxRows);
\r
446 } catch (SQLException e) {
\r
447 handleSQLException(e, statement);
\r
451 protected void close(Statement statement) {
\r
452 if (statement == null) {
\r
457 } catch (SQLException e) {
\r
458 handleSQLException(e, statement);
\r
462 protected void close(ResultSet resultSet) {
\r
463 if (resultSet == null) {
\r
468 } catch (SQLException e) {
\r
469 handleSQLException(e, null);
\r
473 protected void close(Connection conn) {
\r
474 if (conn == null) {
\r
479 } catch (SQLException e) {
\r
480 handleSQLException(e, null);
\r
484 // ===================================================================================
\r
487 // It needs this method if the target database doest not support line comment.
\r
488 protected String removeLineComment(final String sql) { // With removing CR!
\r
489 if (sql == null || sql.trim().length() == 0) {
\r
492 final StringBuilder sb = new StringBuilder();
\r
493 final String[] lines = sql.split("\n");
\r
494 for (String line : lines) {
\r
495 if (line == null) {
\r
498 line = line.replaceAll("\r", ""); // Remove CR!
\r
499 if (line.startsWith("--")) {
\r
502 sb.append(line).append("\n");
\r
504 return sb.toString();
\r
507 // ===================================================================================
\r
510 protected String getLineSeparator() {
\r
511 return ${glSimpleSystemUtil}.getLineSeparator();
\r
514 // ===================================================================================
\r
517 public DataSource getDataSource() {
\r
521 public void setDataSource(DataSource dataSource) {
\r
522 this.dataSource = dataSource;
\r
525 public String getSql() {
\r
529 public void setSql(String sql) {
\r
530 #if ($database.isRemoveLineCommentFromExecutedSql())
\r
531 sql = removeLineComment(sql);
\r
536 public StatementFactory getStatementFactory() {
\r
537 return statementFactory;
\r
540 public void setStatementFactory(StatementFactory statementFactory) {
\r
541 this.statementFactory = statementFactory;
\r
544 public void setLoggingMessageSqlArgs(Object[] loggingMessageSqlArgs) {
\r
545 this.loggingMessageSqlArgs = loggingMessageSqlArgs;
\r