001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.lib.jdbc;
020:
021: import java.sql.Connection;
022: import java.sql.PreparedStatement;
023: import java.sql.ResultSet;
024: import java.sql.SQLException;
025: import java.sql.Statement;
026:
027: import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
028:
029: /**
030: * Manages the firing of {@link JDBCEvent}s.
031: *
032: * @author Abe White
033: * @nojavadoc
034: */
035: public class JDBCEventConnectionDecorator extends
036: AbstractConcurrentEventManager implements ConnectionDecorator {
037:
038: public Connection decorate(Connection conn) {
039: if (!hasListeners())
040: return conn;
041: return new EventConnection(conn);
042: }
043:
044: /**
045: * Fire the given event to all listeners. Prevents creation of an
046: * event object when there are no listeners.
047: */
048: private JDBCEvent fireEvent(Connection source, short type,
049: JDBCEvent associatedEvent, Statement stmnt, String sql) {
050: if (!hasListeners())
051: return null;
052:
053: JDBCEvent event = new JDBCEvent(source, type, associatedEvent,
054: stmnt, sql);
055: fireEvent(event);
056: return event;
057: }
058:
059: /**
060: * Fire the given event to all listeners.
061: */
062: protected void fireEvent(Object event, Object listener) {
063: JDBCListener listen = (JDBCListener) listener;
064: JDBCEvent ev = (JDBCEvent) event;
065: switch (ev.getType()) {
066: case JDBCEvent.BEFORE_PREPARE_STATEMENT:
067: listen.beforePrepareStatement(ev);
068: break;
069: case JDBCEvent.AFTER_PREPARE_STATEMENT:
070: listen.afterPrepareStatement(ev);
071: break;
072: case JDBCEvent.BEFORE_CREATE_STATEMENT:
073: listen.beforeCreateStatement(ev);
074: break;
075: case JDBCEvent.AFTER_CREATE_STATEMENT:
076: listen.afterCreateStatement(ev);
077: break;
078: case JDBCEvent.BEFORE_EXECUTE_STATEMENT:
079: listen.beforeExecuteStatement(ev);
080: break;
081: case JDBCEvent.AFTER_EXECUTE_STATEMENT:
082: listen.afterExecuteStatement(ev);
083: break;
084: case JDBCEvent.BEFORE_COMMIT:
085: listen.beforeCommit(ev);
086: break;
087: case JDBCEvent.AFTER_COMMIT:
088: listen.afterCommit(ev);
089: break;
090: case JDBCEvent.BEFORE_ROLLBACK:
091: listen.beforeRollback(ev);
092: break;
093: case JDBCEvent.AFTER_ROLLBACK:
094: listen.afterRollback(ev);
095: break;
096: case JDBCEvent.AFTER_CONNECT:
097: listen.afterConnect(ev);
098: break;
099: case JDBCEvent.BEFORE_CLOSE:
100: listen.beforeClose(ev);
101: break;
102: }
103: }
104:
105: /**
106: * Fires events as appropriate.
107: */
108: private class EventConnection extends DelegatingConnection {
109:
110: public EventConnection(Connection conn) {
111: super (conn);
112: fireEvent(getDelegate(), JDBCEvent.AFTER_CONNECT, null,
113: null, null);
114: }
115:
116: public void commit() throws SQLException {
117: JDBCEvent before = fireEvent(getDelegate(),
118: JDBCEvent.BEFORE_COMMIT, null, null, null);
119: try {
120: super .commit();
121: } finally {
122: fireEvent(getDelegate(), JDBCEvent.AFTER_COMMIT,
123: before, null, null);
124: }
125: }
126:
127: public void rollback() throws SQLException {
128: JDBCEvent before = fireEvent(getDelegate(),
129: JDBCEvent.BEFORE_ROLLBACK, null, null, null);
130: try {
131: super .rollback();
132: } finally {
133: fireEvent(getDelegate(), JDBCEvent.AFTER_ROLLBACK,
134: before, null, null);
135: }
136: }
137:
138: protected Statement createStatement(boolean wrap)
139: throws SQLException {
140: JDBCEvent before = fireEvent(getDelegate(),
141: JDBCEvent.BEFORE_CREATE_STATEMENT, null, null, null);
142: Statement stmnt = null;
143: try {
144: stmnt = new EventStatement(
145: super .createStatement(false),
146: EventConnection.this );
147: } finally {
148: fireEvent(getDelegate(),
149: JDBCEvent.AFTER_CREATE_STATEMENT, before,
150: stmnt, null);
151: }
152: return stmnt;
153: }
154:
155: protected Statement createStatement(int rsType, int rsConcur,
156: boolean wrap) throws SQLException {
157: JDBCEvent before = fireEvent(getDelegate(),
158: JDBCEvent.BEFORE_CREATE_STATEMENT, null, null, null);
159: Statement stmnt = null;
160: try {
161: stmnt = new EventStatement(super .createStatement(
162: rsType, rsConcur, false), EventConnection.this );
163: } finally {
164: fireEvent(getDelegate(),
165: JDBCEvent.AFTER_CREATE_STATEMENT, before,
166: stmnt, null);
167: }
168: return stmnt;
169: }
170:
171: protected PreparedStatement prepareStatement(String sql,
172: boolean wrap) throws SQLException {
173: JDBCEvent before = fireEvent(getDelegate(),
174: JDBCEvent.BEFORE_PREPARE_STATEMENT, null, null, sql);
175: PreparedStatement stmnt = null;
176: try {
177: stmnt = new EventPreparedStatement(super
178: .prepareStatement(sql, false),
179: EventConnection.this , sql);
180: } finally {
181: fireEvent(getDelegate(),
182: JDBCEvent.AFTER_PREPARE_STATEMENT, before,
183: stmnt, sql);
184: }
185: return stmnt;
186: }
187:
188: protected PreparedStatement prepareStatement(String sql,
189: int rsType, int rsConcur, boolean wrap)
190: throws SQLException {
191: JDBCEvent before = fireEvent(getDelegate(),
192: JDBCEvent.BEFORE_PREPARE_STATEMENT, null, null, sql);
193: PreparedStatement stmnt = null;
194: try {
195: stmnt = new EventPreparedStatement(
196: super .prepareStatement(sql, rsType, rsConcur,
197: false), EventConnection.this , sql);
198: } finally {
199: fireEvent(getDelegate(),
200: JDBCEvent.AFTER_PREPARE_STATEMENT, before,
201: stmnt, sql);
202: }
203: return stmnt;
204: }
205:
206: public void close() throws SQLException {
207: try {
208: fireEvent(getDelegate(), JDBCEvent.BEFORE_CLOSE, null,
209: null, null);
210: } finally {
211: super .close();
212: }
213: }
214: }
215:
216: /**
217: * Fires events as appropriate.
218: */
219: private class EventPreparedStatement extends
220: DelegatingPreparedStatement {
221:
222: private final EventConnection _conn;
223: private final String _sql;
224:
225: public EventPreparedStatement(PreparedStatement ps,
226: EventConnection conn, String sql) {
227: super (ps, conn);
228: _conn = conn;
229: _sql = sql;
230: }
231:
232: public int executeUpdate() throws SQLException {
233: JDBCEvent before = fireEvent(_conn.getDelegate(),
234: JDBCEvent.BEFORE_EXECUTE_STATEMENT, null,
235: getDelegate(), _sql);
236: try {
237: return super .executeUpdate();
238: } finally {
239: fireEvent(_conn.getDelegate(),
240: JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
241: getDelegate(), _sql);
242: }
243: }
244:
245: protected ResultSet executeQuery(boolean wrap)
246: throws SQLException {
247: JDBCEvent before = fireEvent(_conn.getDelegate(),
248: JDBCEvent.BEFORE_EXECUTE_STATEMENT, null,
249: getDelegate(), _sql);
250: try {
251: return super .executeQuery(wrap);
252: } finally {
253: fireEvent(_conn.getDelegate(),
254: JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
255: getDelegate(), _sql);
256: }
257: }
258:
259: public int[] executeBatch() throws SQLException {
260: JDBCEvent before = fireEvent(_conn.getDelegate(),
261: JDBCEvent.BEFORE_EXECUTE_STATEMENT, null,
262: getDelegate(), _sql);
263: try {
264: return super .executeBatch();
265: } finally {
266: fireEvent(_conn.getDelegate(),
267: JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
268: getDelegate(), _sql);
269: }
270: }
271: }
272:
273: /**
274: * Fires events as appropriate.
275: */
276: private class EventStatement extends DelegatingStatement {
277:
278: private final EventConnection _conn;
279:
280: public EventStatement(Statement stmnt, EventConnection conn) {
281: super (stmnt, conn);
282: _conn = conn;
283: }
284:
285: public int executeUpdate(String sql) throws SQLException {
286: JDBCEvent before = fireEvent(_conn.getDelegate(),
287: JDBCEvent.BEFORE_EXECUTE_STATEMENT, null,
288: getDelegate(), sql);
289: try {
290: return super .executeUpdate(sql);
291: } finally {
292: fireEvent(_conn.getDelegate(),
293: JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
294: getDelegate(), sql);
295: }
296: }
297:
298: protected ResultSet executeQuery(String sql, boolean wrap)
299: throws SQLException {
300: JDBCEvent before = fireEvent(_conn.getDelegate(),
301: JDBCEvent.BEFORE_EXECUTE_STATEMENT, null,
302: getDelegate(), sql);
303: try {
304: return super.executeQuery(sql, wrap);
305: } finally {
306: fireEvent(_conn.getDelegate(),
307: JDBCEvent.AFTER_EXECUTE_STATEMENT, before,
308: getDelegate(), sql);
309: }
310: }
311: }
312: }
|