001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.common.jdbc.logging;
017:
018: import com.ibatis.common.beans.ClassInfo;
019: import com.ibatis.common.logging.Log;
020: import com.ibatis.common.logging.LogFactory;
021:
022: import java.lang.reflect.InvocationHandler;
023: import java.lang.reflect.Method;
024: import java.lang.reflect.Proxy;
025: import java.sql.CallableStatement;
026: import java.sql.PreparedStatement;
027: import java.sql.ResultSet;
028:
029: /**
030: * PreparedStatement proxy to add logging
031: */
032: public class PreparedStatementLogProxy extends BaseLogProxy implements
033: InvocationHandler {
034:
035: private static final Log log = LogFactory
036: .getLog(PreparedStatement.class);
037:
038: private PreparedStatement statement;
039: private String sql;
040:
041: private PreparedStatementLogProxy(PreparedStatement stmt, String sql) {
042: this .statement = stmt;
043: this .sql = sql;
044: }
045:
046: public Object invoke(Object proxy, Method method, Object[] params)
047: throws Throwable {
048: try {
049: if (EXECUTE_METHODS.contains(method.getName())) {
050: if (log.isDebugEnabled()) {
051: log.debug("{pstm-" + id + "} Executing Statement: "
052: + removeBreakingWhitespace(sql));
053: log.debug("{pstm-" + id + "} Parameters: "
054: + getValueString());
055: log.debug("{pstm-" + id + "} Types: "
056: + getTypeString());
057: }
058: clearColumnInfo();
059: if ("executeQuery".equals(method.getName())) {
060: ResultSet rs = (ResultSet) method.invoke(statement,
061: params);
062: if (rs != null) {
063: return ResultSetLogProxy.newInstance(rs);
064: } else {
065: return null;
066: }
067: } else {
068: return method.invoke(statement, params);
069: }
070: } else if (SET_METHODS.contains(method.getName())) {
071: if ("setNull".equals(method.getName())) {
072: setColumn(params[0], null);
073: } else {
074: setColumn(params[0], params[1]);
075: }
076: return method.invoke(statement, params);
077: } else if ("getResultSet".equals(method.getName())) {
078: ResultSet rs = (ResultSet) method.invoke(statement,
079: params);
080: if (rs != null) {
081: return ResultSetLogProxy.newInstance(rs);
082: } else {
083: return null;
084: }
085: } else if ("equals".equals(method.getName())) {
086: Object ps = params[0];
087: if (ps instanceof Proxy) {
088: return new Boolean(proxy == ps);
089: }
090: return new Boolean(false);
091: } else if ("hashCode".equals(method.getName())) {
092: return new Integer(proxy.hashCode());
093: } else {
094: return method.invoke(statement, params);
095: }
096: } catch (Throwable t) {
097: throw ClassInfo.unwrapThrowable(t);
098: }
099: }
100:
101: /**
102: * Creates a logging version of a PreparedStatement
103: * @param stmt - the statement
104: * @param sql - the sql statement
105: * @return - the proxy
106: */
107: public static PreparedStatement newInstance(PreparedStatement stmt,
108: String sql) {
109: InvocationHandler handler = new PreparedStatementLogProxy(stmt,
110: sql);
111: ClassLoader cl = PreparedStatement.class.getClassLoader();
112: return (PreparedStatement) Proxy.newProxyInstance(cl,
113: new Class[] { PreparedStatement.class,
114: CallableStatement.class }, handler);
115: }
116:
117: }
|