boolean closeAndRemoveResourcesInSet(Set s, Method closeMethod) { boolean okay = true; Set temp; synchronized (s) { temp = new HashSet(s); } for (Iterator ii = temp.iterator(); ii.hasNext(); ) { Object rsrc = ii.next(); try { closeMethod.invoke(rsrc, CLOSE_ARGS); } catch (Exception e) { Throwable t = e; if (t instanceof InvocationTargetException) t = ((InvocationTargetException) e).getTargetException(); logger.log(MLevel.WARNING, "An exception occurred while cleaning up a resource.", t); // t.printStackTrace(); okay = false; } finally { s.remove(rsrc); } } // We had to abandon the idea of simply iterating over s directly, because // our resource close methods sometimes try to remove the resource from // its parent Set. This is important (when the user closes the resources // directly), but leads to ConcurrenModificationExceptions while we are // iterating over the Set to close. So, now we iterate over a copy, but remove // from the original Set. Since removal is idempotent, it don't matter if // the close method already provoked a remove. Sucks that we have to copy // the set though. // // Original (direct iteration) version: // // synchronized (s) // { // for (Iterator ii = s.iterator(); ii.hasNext(); ) // { // Object rsrc = ii.next(); // try // { closeMethod.invoke(rsrc, CLOSE_ARGS); } // catch (Exception e) // { // Throwable t = e; // if (t instanceof InvocationTargetException) // t = ((InvocationTargetException) e).getTargetException(); // t.printStackTrace(); // okay = false; // } // finally // { ii.remove(); } // } // } return okay; }
public Object doRawStatementOperation(Method m, Object target, Object[] args) throws IllegalAccessException, InvocationTargetException, SQLException { if (target == C3P0ProxyStatement.RAW_STATEMENT) target = nakedInner; for (int i = 0, len = args.length; i < len; ++i) if (args[i] == C3P0ProxyStatement.RAW_STATEMENT) args[i] = nakedInner; Object out = m.invoke(target, args); if (out instanceof ResultSet) out = wrap((ResultSet) out); return out; }
private Object doRawConnectionOperation(Method m, Object target, Object[] args) throws IllegalAccessException, InvocationTargetException, SQLException, Exception { if (activeConnection == null) throw new SQLException( "Connection previously closed. You cannot operate on a closed Connection."); if (target == C3P0ProxyConnection.RAW_CONNECTION) target = activeConnection; for (int i = 0, len = args.length; i < len; ++i) if (args[i] == C3P0ProxyConnection.RAW_CONNECTION) args[i] = activeConnection; Object out = m.invoke(target, args); // we never cache Statements generated by an operation on the raw Connection if (out instanceof Statement) out = createProxyStatement(false, (Statement) out); else if (out instanceof ResultSet) { if (doRawResultSets == null) doRawResultSets = new HashSet(); out = new NullStatementSetManagedResultSet((ResultSet) out, doRawResultSets); } return out; }
public synchronized Object invoke(Object proxy, Method m, Object[] args) throws Throwable { if (OBJECT_METHODS.contains(m)) return m.invoke(this, args); try { String mname = m.getName(); if (activeConnection != null) { if (mname.equals("rawConnectionOperation")) { ensureOkay(); txn_known_resolved = false; return doRawConnectionOperation((Method) args[0], args[1], (Object[]) args[2]); } else if (mname.equals("setTransactionIsolation")) { ensureOkay(); // don't modify txn_known_resolved m.invoke(activeConnection, args); int lvl = ((Integer) args[0]).intValue(); isolation_lvl_nondefault = (lvl != dflt_txn_isolation); // System.err.println("updated txn isolation to " + lvl + ", nondefault level? " + // isolation_lvl_nondefault); return null; } else if (mname.equals("setCatalog")) { ensureOkay(); // don't modify txn_known_resolved m.invoke(activeConnection, args); String catalog = (String) args[0]; catalog_nondefault = ObjectUtils.eqOrBothNull(catalog, dflt_catalog); return null; } else if (mname.equals("setHoldability")) { ensureOkay(); // don't modify txn_known_resolved m.invoke( activeConnection, args); // will throw an exception if setHoldability() not supported... int holdability = ((Integer) args[0]).intValue(); holdability_nondefault = (holdability != dflt_holdability); return null; } else if (mname.equals("createStatement")) { ensureOkay(); txn_known_resolved = false; Object stmt = m.invoke(activeConnection, args); return createProxyStatement((Statement) stmt); } else if (mname.equals("prepareStatement")) { ensureOkay(); txn_known_resolved = false; Object pstmt; if (scache == null) { pstmt = m.invoke(activeConnection, args); return createProxyStatement((Statement) pstmt); } else { pstmt = scache.checkoutStatement(physicalConnection, m, args); return createProxyStatement(true, (Statement) pstmt); } } else if (mname.equals("prepareCall")) { ensureOkay(); txn_known_resolved = false; Object cstmt; if (scache == null) { cstmt = m.invoke(activeConnection, args); return createProxyStatement((Statement) cstmt); } else { cstmt = scache.checkoutStatement(physicalConnection, m, args); return createProxyStatement(true, (Statement) cstmt); } } else if (mname.equals("getMetaData")) { ensureOkay(); txn_known_resolved = false; // views of tables etc. might be txn dependent DatabaseMetaData innerMd = activeConnection.getMetaData(); if (metaData == null) { // exposedProxy is protected by C3P0PooledConnection.this' lock synchronized (C3P0PooledConnection.this) { metaData = new SetManagedDatabaseMetaData(innerMd, activeMetaDataResultSets, exposedProxy); } } return metaData; } else if (mname.equals("silentClose")) { // the PooledConnection doesn't have to be okay doSilentClose(proxy, ((Boolean) args[0]).booleanValue(), this.txn_known_resolved); return null; } else if (mname.equals("close")) { // the PooledConnection doesn't have to be okay Exception e = doSilentClose(proxy, false, this.txn_known_resolved); if (!connection_error_signaled) ces.fireConnectionClosed(); // System.err.println("close() called on a ProxyConnection."); if (e != null) { // System.err.print("user close exception -- "); // e.printStackTrace(); throw e; } else return null; } // else if ( mname.equals("finalize") ) //REMOVE THIS CASE -- TMP DEBUG // { // System.err.println("Connection apparently finalized!"); // return m.invoke( activeConnection, args ); // } else { ensureOkay(); // we've disabled setting txn_known_resolved to true, ever, because // we failed to deal with the case that clients would work with previously // acquired Statements and ResultSets after a commit(), rollback(), or setAutoCommit(). // the new non-reflective proxies have been modified to deal with this case. // here, with soon-to-be-deprecated in "traditional reflective proxies mode" // we are reverting to the conservative, always-presume-you-have-to-rollback // policy. // txn_known_resolved = ( mname.equals("commit") || mname.equals( "rollback" ) || // mname.equals( "setAutoCommit" ) ); txn_known_resolved = false; return m.invoke(activeConnection, args); } } else { if (mname.equals("close") || mname.equals("silentClose")) return null; else if (mname.equals("isClosed")) return Boolean.TRUE; else { throw new SQLException("You can't operate on " + "a closed connection!!!"); } } } catch (InvocationTargetException e) { Throwable convertMe = e.getTargetException(); SQLException sqle = handleMaybeFatalToPooledConnection(convertMe, proxy, false); sqle.fillInStackTrace(); throw sqle; } }