c3p0-0.9.1.2.orig/0000755000175000017500000000000010673162231011472 5ustar godgodc3p0-0.9.1.2.orig/dbms/0000755000175000017500000000000010070773132012416 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/0000755000175000017500000000000010673162231014624 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/build/0000755000175000017500000000000010624366544015734 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/dist/0000755000175000017500000000000010624366545015601 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/0000755000175000017500000000000010624366530015417 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/0000755000175000017500000000000010624366530017054 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/0000755000175000017500000000000010624366530017632 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/mchange/0000755000175000017500000000000010624366530021234 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/mchange/v2/0000755000175000017500000000000010624366530021563 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/mchange/v2/c3p0/0000755000175000017500000000000010624366530022330 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/mchange/v2/c3p0/dbms/0000755000175000017500000000000010673162231023251 5ustar godgodc3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/mchange/v2/c3p0/dbms/Debug.java0000644000175000017500000000253210624366530025150 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ /******************************************************************** * This class generated by com.mchange.v2.debug.DebugGen * and will probably be overwritten by the same! Edit at * YOUR PERIL!!! Hahahahaha. ********************************************************************/ package com.mchange.v2.c3p0.dbms; import com.mchange.v2.debug.DebugConstants; final class Debug implements DebugConstants { final static boolean DEBUG = true; final static int TRACE = TRACE_MED; private Debug() {} } c3p0-0.9.1.2.orig/dbms/oracle-thin/src/classes/com/mchange/v2/c3p0/dbms/OracleUtils.java0000644000175000017500000001122710624366530026351 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.dbms; import java.lang.reflect.*; import java.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v2.sql.SqlUtils; import oracle.sql.BLOB; import oracle.sql.CLOB; import oracle.jdbc.driver.OracleConnection; /** * A convenience class for OracleUsers who wish to use Oracle-specific Connection API * without working directly with c3p0 raw connection operations. */ public final class OracleUtils { final static Class[] CREATE_TEMP_ARGS = new Class[]{Connection.class, boolean.class, int.class}; /** * Uses Oracle-specific API on the raw, underlying Connection to create a temporary BLOB. * Users are responsible for calling freeTemporary on the returned BLOB prior to Connection close() / check-in! * c3p0 will not automatically clean up temporary BLOBs. * * @param c3p0ProxyCon may be a c3p0 proxy for an oracle.jdbc.driver.OracleConnection, or an * oracle.jdbc.driver.OracleConnection directly. */ public static BLOB createTemporaryBLOB(Connection c3p0ProxyCon, boolean cache, int duration) throws SQLException { if (c3p0ProxyCon instanceof C3P0ProxyConnection) { try { C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0ProxyCon; Method m = BLOB.class.getMethod("createTemporary", CREATE_TEMP_ARGS); Object[] args = new Object[] {C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf( cache ), new Integer( duration )}; return (BLOB) castCon.rawConnectionOperation(m, null, args); } catch (InvocationTargetException e) { if (Debug.DEBUG) e.printStackTrace(); throw SqlUtils.toSQLException( e.getTargetException() ); } catch (Exception e) { if (Debug.DEBUG) e.printStackTrace(); throw SqlUtils.toSQLException( e ); } } else if (c3p0ProxyCon instanceof OracleConnection) return BLOB.createTemporary( c3p0ProxyCon, cache, duration ); else throw new SQLException("Cannot create an oracle BLOB from a Connection that is neither an oracle.jdbc.driver.Connection, " + "nor a C3P0ProxyConnection wrapped around an oracle.jdbc.driver.Connection."); } /** * Uses Oracle-specific API on the raw, underlying Connection to create a temporary CLOB. * Users are responsible for calling freeTemporary on the returned BLOB prior to Connection close() / check-in! * c3p0 will not automatically clean up temporary CLOBs. * * @param c3p0ProxyCon may be a c3p0 proxy for an oracle.jdbc.driver.OracleConnection, or an * oracle.jdbc.driver.OracleConnection directly. */ public static CLOB createTemporaryCLOB(Connection c3p0ProxyCon, boolean cache, int duration) throws SQLException { if (c3p0ProxyCon instanceof C3P0ProxyConnection) { try { C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0ProxyCon; Method m = CLOB.class.getMethod("createTemporary", CREATE_TEMP_ARGS); Object[] args = new Object[] {C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf( cache ), new Integer( duration )}; return (CLOB) castCon.rawConnectionOperation(m, null, args); } catch (InvocationTargetException e) { if (Debug.DEBUG) e.printStackTrace(); throw SqlUtils.toSQLException( e.getTargetException() ); } catch (Exception e) { if (Debug.DEBUG) e.printStackTrace(); throw SqlUtils.toSQLException( e ); } } else if (c3p0ProxyCon instanceof OracleConnection) return CLOB.createTemporary( c3p0ProxyCon, cache, duration ); else throw new SQLException("Cannot create an oracle CLOB from a Connection that is neither an oracle.jdbc.driver.Connection, " + "nor a C3P0ProxyConnection wrapped around an oracle.jdbc.driver.Connection."); } private OracleUtils() {} } c3p0-0.9.1.2.orig/dbms/oracle-thin/build.properties0000644000175000017500000000041510070775353020047 0ustar godgod# # You'll rarely (never) want to set these properties by hand... they # are set by the main c3p0 build script. They are listed here primarily # to document the dependencies of the dbms-specific build script. # c3p0-version= c3p0.jar.file= oracle-thin.jdbc.jar.file= c3p0-0.9.1.2.orig/dbms/oracle-thin/build.xml0000644000175000017500000000452010126443310016437 0ustar godgod c3p0-0.9.1.2.orig/relproj/0000755000175000017500000000000010673162231013147 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/0000755000175000017500000000000010673162231014727 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/build/0000755000175000017500000000000010503342706016025 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/dist/0000755000175000017500000000000010673162231015672 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/0000755000175000017500000000000010212043136015505 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/app-rsrc/0000755000175000017500000000000010212043136017234 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/app-rsrc/META-INF/0000755000175000017500000000000010673162231020405 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/app-rsrc/META-INF/manifest.src0000644000175000017500000000005310624366527022734 0ustar godgodMain-Class: com.mchange.v2.debug.DebugGen c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/0000755000175000017500000000000010212043136017142 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/0000755000175000017500000000000010212043136017720 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/0000755000175000017500000000000010212043136021322 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/0000755000175000017500000000000010212043136021650 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/io/0000755000175000017500000000000010673162231022270 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/io/WriterUtils.java0000644000175000017500000000221010624366527025435 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.io; import java.io.Writer; import java.io.IOException; public final class WriterUtils { public static void attemptClose(Writer os) { try {if (os != null) os.close();} catch (IOException e) {e.printStackTrace();} } private WriterUtils() {} } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/lang/0000755000175000017500000000000010673162231022602 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/lang/BooleanUtils.java0000644000175000017500000000233110624366527026056 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.lang; public final class BooleanUtils { public static boolean parseBoolean(String str) throws IllegalArgumentException { if (str.equals("true")) return true; else if (str.equals("false")) return false; else throw new IllegalArgumentException("\"str\" is neither \"true\" nor \"false\"."); } private BooleanUtils() {} } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/util/0000755000175000017500000000000010673162231022636 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/util/ClosableResource.java0000644000175000017500000000244710624366527026756 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; /** * An interface intended to be shared by the many sorts * of objects that offer some kind of close method to * cleanup resources they might be using. (I wish Sun * had defined, and used, such an interface in the standard * APIs. */ public interface ClosableResource { /** * forces the release of any resources that might be * associated with this object. */ public void close() throws Exception; } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/util/IteratorUtils.java0000644000175000017500000001067210624366527026333 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.*; import java.lang.reflect.Array; public final class IteratorUtils { public final static Iterator EMPTY_ITERATOR = new Iterator() { public boolean hasNext() { return false; } public Object next() { throw new NoSuchElementException(); } public void remove() { throw new IllegalStateException(); } }; public static Iterator oneElementUnmodifiableIterator(final Object elem) { return new Iterator() { boolean shot = false; public boolean hasNext() { return (!shot); } public Object next() { if (shot) throw new NoSuchElementException(); else { shot = true; return elem; } } public void remove() { throw new UnsupportedOperationException("remove() not supported."); } }; } public static boolean equivalent(Iterator ii, Iterator jj) { while (true) { boolean ii_hasnext = ii.hasNext(); boolean jj_hasnext = jj.hasNext(); if (ii_hasnext ^ jj_hasnext) return false; else if (ii_hasnext) { Object iiNext = ii.next(); Object jjNext = jj.next(); if (iiNext == jjNext) continue; else if (iiNext == null) return false; else if (!iiNext.equals(jjNext)) return false; } else return true; } } public static ArrayList toArrayList(Iterator ii, int initial_capacity) { ArrayList out = new ArrayList(initial_capacity); while (ii.hasNext()) out.add(ii.next()); return out; } /** * Fills an array with the contents of an iterator. If the array is too small, * it will contain the first portion of the iterator. If the array can contain * more elements than the iterator, extra elements are left untouched, unless * null_terminate is set to true, in which case the element immediately following * the last from the iterator is set to null. (This method is intended to make * it easy to implement Collection.toArray(Object[] oo) methods... * * @param null_terminate iff there is extra space in the array, set the element * immediately after the last from the iterator to null. */ public static void fillArray(Iterator ii, Object[] fillMe, boolean null_terminate) { int i = 0; int len = fillMe.length; while ( i < len && ii.hasNext() ) fillMe[ i++ ] = ii.next(); if (null_terminate && i < len) fillMe[i] = null; } public static void fillArray(Iterator ii, Object[] fillMe) { fillArray( ii, fillMe, false); } /** * @param null_terminate iff there is extra space in the array, set the element * immediately after the last from the iterator to null. */ public static Object[] toArray(Iterator ii, int array_size, Class componentClass, boolean null_terminate) { Object[] out = (Object[]) Array.newInstance( componentClass, array_size ); fillArray(ii, out, null_terminate); return out; } public static Object[] toArray(Iterator ii, int array_size, Class componentClass) { return toArray( ii, array_size, componentClass, false ); } /** * Designed to help implement Collection.toArray(Object[] )methods... does * the right thing if you can express an iterator and know the size of your * Collection. */ public static Object[] toArray(Iterator ii, int ii_size, Object[] maybeFillMe) { if (maybeFillMe.length >= ii_size) { fillArray( ii, maybeFillMe, true ); return maybeFillMe; } else { Class componentType = maybeFillMe.getClass().getComponentType(); return toArray( ii, ii_size, componentType ); } } private IteratorUtils() {} } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/util/SetUtils.java0000644000175000017500000000420710624366527025272 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.Iterator; import java.util.Set; import java.util.AbstractSet; import java.util.HashSet; public final class SetUtils { public static Set oneElementUnmodifiableSet(final Object elem) { return new AbstractSet() { public Iterator iterator() { return IteratorUtils.oneElementUnmodifiableIterator( elem ); } public int size() { return 1; } public boolean isEmpty() { return false; } public boolean contains(Object o) { return o == elem; } }; } public static Set setFromArray(Object[] array) { HashSet out = new HashSet(); for (int i = 0, len = array.length; i < len; ++i) out.add( array[i] ); return out; } public static boolean equivalentDisregardingSort(Set a, Set b) { return a.containsAll( b ) && b.containsAll( a ); } /** * finds a hash value which takes into account * the value of all elements, such that two sets * for which equivalentDisregardingSort(a, b) returns * true will hashContentsDisregardingSort() to the same value */ public static int hashContentsDisregardingSort(Set s) { int out = 0; for (Iterator ii = s.iterator(); ii.hasNext(); ) { Object o = ii.next(); if (o != null) out ^= o.hashCode(); } return out; } } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/util/StringTokenizerUtils.java0000644000175000017500000000274310624366527027703 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.StringTokenizer; public final class StringTokenizerUtils { public static String[] tokenizeToArray(String str, String delim, boolean returntokens) { StringTokenizer st = new StringTokenizer(str, delim, returntokens); String[] strings = new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); ++i) strings[i] = st.nextToken(); return strings; } public static String[] tokenizeToArray(String str, String delim) {return tokenizeToArray(str, delim, false);} public static String[] tokenizeToArray(String str) {return tokenizeToArray(str, " \t\r\n");} } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v1/util/UIterator.java0000644000175000017500000000262210624366527025433 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; /** * Incomplete parent of "Unreliable Iterator" * This is often bound to a scarce resource! Don't * forget to close it when you are done!!! * * This interface is not intended to be implemented * directly, but to be extended by subinterfaces * that narrow the exceptions reasonably. */ public interface UIterator extends ClosableResource { public boolean hasNext() throws Exception; public Object next() throws Exception; public void remove() throws Exception; public void close() throws Exception; } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/0000755000175000017500000000000010212043136021651 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/0000755000175000017500000000000010673162231023275 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/BadCommandLineException.java0000644000175000017500000000206110624366527030625 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; public class BadCommandLineException extends Exception { public BadCommandLineException(String msg) { super(msg); } public BadCommandLineException() { super(); } } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/CommandLineUtils.java0000644000175000017500000000724610624366527027372 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; public final class CommandLineUtils { /** * "Parses" a command line by making use several conventions: *
    *
  • Certain arguments are considered "switches", by virtue * of being prefixed with some string, usually "-", "/", or "--" *
  • Switches may have arguments associated with them. This implementation * permits only a single argument per switch *
  • Switch arguments are determined via two conventions: *
      *
    1. If a switch is of the form "--switch=value" (where "--" is * set as the switch prefix), value is the switches argument. *
    2. If a switch is not of this form (simply "--switch"), then the * following item on the command line is considered the switch's * argument if and only if *
        *
      1. the argSwitches array contains the switch, and *
      2. the next item on the command line is not itself a switch *
      *
    *
* * @param argv the entire list of arguments, usually the argument to a main function * @param switchPrefix the string which separates "switches" from regular command line args. * Must be non-null * @param validSwitches a list of all the switches permissible for this command line. * If non-null, an UnexpectedSwitchException will be thrown if a switch not * in this list is encountered. Use null to accept any switches. * @param requiredSwitches a list of all the switches required by this command line. * If non-null, an MissingSwitchException will be thrown if a switch * in this list is not present. Use null if no switches should be considered required. * @param argSwitches a list of switches that should have an argument associated with them * If non-null, an MissingSwitchArgumentException will be thrown if a switch * in this list has no argument is not present. Use null if no switches should * be considered to require arguments. However, this parameter is required if * distinct items on a command line should be considered arguments to preceding * items. (For example, "f" must be an argSwitch for "-f myfile.txt" to be parsed * as switch and argument, but argSwitches is not required to parse "--file=myfile.txt" */ public static ParsedCommandLine parse(String[] argv, String switchPrefix, String[] validSwitches, String[] requiredSwitches, String[] argSwitches) throws BadCommandLineException { return new ParsedCommandLineImpl( argv, switchPrefix, validSwitches, requiredSwitches, argSwitches ); } private CommandLineUtils() {} } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/MissingSwitchException.java0000644000175000017500000000214710624366527030630 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; public class MissingSwitchException extends BadCommandLineException { String sw; MissingSwitchException(String msg, String sw) { super(msg); this.sw = sw; } public String getMissingSwitch() { return sw; } } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/ParsedCommandLine.java0000644000175000017500000000216210624366527027500 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; public interface ParsedCommandLine { public String[] getRawArgs(); public String getSwitchPrefix(); public boolean includesSwitch(String sw); public String getSwitchArg(String sw); public String[] getUnswitchedArgs(); } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/ParsedCommandLineImpl.java0000644000175000017500000000676210624366527030334 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; import java.util.*; class ParsedCommandLineImpl implements ParsedCommandLine { String[] argv; String switchPrefix; String[] unswitchedArgs; //we are relying upon the fact that //HashMaps are null-accepting collections HashMap foundSwitches = new HashMap(); ParsedCommandLineImpl(String[] argv, String switchPrefix, String[] validSwitches, String[] requiredSwitches, String[] argSwitches) throws BadCommandLineException { this.argv = argv; this.switchPrefix = switchPrefix; List unswitchedArgsList = new LinkedList(); int sp_len = switchPrefix.length(); for (int i = 0; i < argv.length; ++i) { if (argv[i].startsWith(switchPrefix)) //okay, this is a switch { String sw = argv[i].substring( sp_len ); String arg = null; int eq = sw.indexOf('='); if ( eq >= 0 ) //equals convention { arg = sw.substring( eq + 1 ); sw = sw.substring( 0, eq ); } else if ( contains( sw, argSwitches ) ) //we expect an argument, next arg convention { if (i < argv.length - 1 && !argv[i + 1].startsWith( switchPrefix) ) arg = argv[++i]; } if (validSwitches != null && ! contains( sw, validSwitches ) ) throw new UnexpectedSwitchException("Unexpected Switch: " + sw, sw); if (argSwitches != null && arg != null && ! contains( sw, argSwitches )) throw new UnexpectedSwitchArgumentException("Switch \"" + sw + "\" should not have an " + "argument. Argument \"" + arg + "\" found.", sw, arg); foundSwitches.put( sw, arg ); } else unswitchedArgsList.add( argv[i] ); } if (requiredSwitches != null) { for (int i = 0; i < requiredSwitches.length; ++i) if (! foundSwitches.containsKey( requiredSwitches[i] )) throw new MissingSwitchException("Required switch \"" + requiredSwitches[i] + "\" not found.", requiredSwitches[i]); } unswitchedArgs = new String[ unswitchedArgsList.size() ]; unswitchedArgsList.toArray( unswitchedArgs ); } public String getSwitchPrefix() { return switchPrefix; } public String[] getRawArgs() { return (String[]) argv.clone(); } public boolean includesSwitch(String sw) { return foundSwitches.containsKey( sw ); } public String getSwitchArg(String sw) { return (String) foundSwitches.get(sw); } public String[] getUnswitchedArgs() { return (String[]) unswitchedArgs.clone(); } private static boolean contains(String string, String[] list) { for (int i = list.length; --i >= 0;) if (list[i].equals(string)) return true; return false; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/UnexpectedSwitchArgumentException.javac3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/UnexpectedSwitchArgumentExcept0000644000175000017500000000234210624366527031375 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; public class UnexpectedSwitchArgumentException extends BadCommandLineException { String sw; String arg; UnexpectedSwitchArgumentException(String msg, String sw, String arg) { super(msg); this.sw = sw; this.arg = arg; } public String getSwitch() { return sw; } public String getUnexpectedArgument() { return arg; } } ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/UnexpectedSwitchException.javac3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/cmdline/UnexpectedSwitchException.java0000644000175000017500000000216010624366527031316 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cmdline; public class UnexpectedSwitchException extends BadCommandLineException { String sw; UnexpectedSwitchException(String msg, String sw) { super(msg); this.sw = sw; } public String getUnexpectedSwitch() { return sw; } } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/debug/0000755000175000017500000000000010673162231022750 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/debug/DebugConstants.java0000644000175000017500000000204310624366527026547 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.debug; public interface DebugConstants { public final static int TRACE_NONE = 0; public final static int TRACE_MED = 5; public final static int TRACE_MAX = 10; } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/debug/DebugGen.java0000644000175000017500000002713410624366527025314 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.debug; import java.io.*; import java.util.*; import com.mchange.v2.cmdline.*; import com.mchange.v2.io.FileIterator; import com.mchange.v2.io.DirectoryDescentUtils; import com.mchange.v1.io.WriterUtils; import com.mchange.v1.lang.BooleanUtils; import com.mchange.v1.util.SetUtils; import com.mchange.v1.util.StringTokenizerUtils; public final class DebugGen implements DebugConstants { final static String[] VALID = new String[] { "codebase", "packages" , "trace", "debug", "recursive", "javac", "noclobber", "classname", "skipdirs", "outputbase" }; final static String[] REQUIRED = new String[] { "codebase", "packages" , "trace", "debug" }; final static String[] ARGS = new String[] { "codebase", "packages" , "trace", "debug", "classname", "outputbase" }; final static String EOL; static { EOL = System.getProperty("line.separator"); } static int trace_level; static boolean debug; static boolean recursive; static String classname; static boolean clobber; static Set skipDirs; public synchronized static final void main(String[] argv) { String codebase; String outputbase; File[] srcPkgDirs; try { ParsedCommandLine pcl = CommandLineUtils.parse( argv, "--", VALID, REQUIRED, ARGS); //get and normalize the codebase codebase = pcl.getSwitchArg("codebase"); codebase = platify( codebase ); if (! codebase.endsWith(File.separator)) codebase += File.separator; //get and normalize the outputbase outputbase = pcl.getSwitchArg("outputbase"); if ( outputbase != null ) { outputbase = platify( outputbase ); if (! outputbase.endsWith(File.separator)) outputbase += File.separator; } else outputbase = codebase; File outputBaseDir = new File( outputbase ); //System.err.println("outputBaseDir: " + outputBaseDir + "; exists? " + outputBaseDir.exists()); if (outputBaseDir.exists()) { if (!outputBaseDir.isDirectory()) { //System.err.println("Output Base '" + outputBaseDir.getPath() + "' is not a directory!"); System.exit(-1); } else if (!outputBaseDir.canWrite()) { System.err.println("Output Base '" + outputBaseDir.getPath() + "' is not writable!"); System.exit(-1); } } else if (! outputBaseDir.mkdirs() ) { System.err.println("Output Base directory '" + outputBaseDir.getPath() + "' does not exist, and could not be created!"); System.exit(-1); } //find existing package dirs String[] packages = StringTokenizerUtils.tokenizeToArray(pcl.getSwitchArg("packages"),", \t"); srcPkgDirs = new File[ packages.length ]; for(int i = 0, len = packages.length; i < len; ++i) srcPkgDirs[i] = new File(codebase + sepify(packages[i])); //find trace level trace_level = Integer.parseInt( pcl.getSwitchArg("trace") ); //find debug debug = BooleanUtils.parseBoolean( pcl.getSwitchArg("debug") ); //find classname, or use default classname = pcl.getSwitchArg("classname"); if (classname == null) classname = "Debug"; //find recursive recursive = pcl.includesSwitch("recursive"); //find clobber clobber = !pcl.includesSwitch("noclobber"); //find skipDirs String skipdirStr = pcl.getSwitchArg("skipdirs"); if (skipdirStr != null) { String[] skipdirArray = StringTokenizerUtils.tokenizeToArray(skipdirStr, ", \t"); skipDirs = SetUtils.setFromArray( skipdirArray ); } else { skipDirs = new HashSet(); skipDirs.add("CVS"); } if ( pcl.includesSwitch("javac") ) System.err.println("autorecompilation of packages not yet implemented."); for (int i = 0, len = srcPkgDirs.length; i < len; ++i) { if (recursive) { if (! recursivePrecheckPackages( codebase, srcPkgDirs[i], outputbase, outputBaseDir )) { System.err.println("One or more of the specifies packages" + " could not be processed. Aborting." + " No files have been modified."); System.exit(-1); } } else { if (! precheckPackage( codebase, srcPkgDirs[i], outputbase, outputBaseDir )) { System.err.println("One or more of the specifies packages" + " could not be processed. Aborting." + " No files have been modified."); System.exit(-1); } } } for (int i = 0, len = srcPkgDirs.length; i < len; ++i) { if (recursive) recursiveWriteDebugFiles( codebase, srcPkgDirs[i], outputbase, outputBaseDir ); else writeDebugFile( outputbase, srcPkgDirs[i] ); } } catch (Exception e) { e.printStackTrace(); System.err.println(); usage(); } } private static void usage() { System.err.println("java " + DebugGen.class.getName() + " \\"); System.err.println("\t--codebase= \\ (no default)"); System.err.println("\t--packages= \\ (no default)"); System.err.println("\t--debug= \\ (no default)"); System.err.println("\t--trace= \\ (no default)"); System.err.println("\t--outputdir= \\ (defaults to same dir as codebase)"); System.err.println("\t--recursive \\ (no args)"); System.err.println("\t--noclobber \\ (no args)"); System.err.println("\t--classname= \\ (defaults to Debug)"); System.err.println("\t--skipdirs= \\ (defaults to CVS)"); } private static String ify(String str, char fromChar, char toChar) { if ( fromChar == toChar ) return str; StringBuffer sb = new StringBuffer(str); for (int i = 0, len = sb.length(); i < len; ++i) if (sb.charAt(i) == fromChar) sb.setCharAt(i, toChar); return sb.toString(); } private static String platify( String str ) { String out; out = ify( str, '/', File.separatorChar ); out = ify( out, '\\', File.separatorChar ); out = ify( out, ':', File.separatorChar ); return out; } private static String dottify(String str) { return ify(str, File.separatorChar, '.');} private static String sepify(String str) { return ify(str, '.', File.separatorChar);} private static boolean recursivePrecheckPackages(String codebase, File srcPkgDir, String outputbase, File outputBaseDir) throws IOException { FileIterator fii = DirectoryDescentUtils.depthFirstEagerDescent( srcPkgDir ); while (fii.hasNext()) { File pkgDir = fii.nextFile(); if (! pkgDir.isDirectory() || skipDirs.contains(pkgDir.getName())) continue; File outputDir = outputDir( codebase, pkgDir, outputbase, outputBaseDir ); if (! outputDir.exists() && !outputDir.mkdirs() ) { System.err.println( "Required output dir: '" + outputDir + "' does not exist, and could not be created."); return false; } if (!precheckOutputPackageDir( outputDir )) return false; } return true; } private static File outputDir( String codebase, File srcPkgDir, String outputbase, File outputBaseDir ) { //System.err.println("outputDir( " + codebase +", " + srcPkgDir + ", " + outputbase + ", " + outputBaseDir + " )"); if (codebase.equals(outputbase)) return srcPkgDir; String srcPath = srcPkgDir.getPath(); if (! srcPath.startsWith( codebase )) { System.err.println(DebugGen.class.getName() + ": program bug. Source package path '" + srcPath + "' does not begin with codebase '" + codebase + "'."); System.exit(-1); } return new File( outputBaseDir, srcPath.substring( codebase.length() ) ); } private static boolean precheckPackage( String codebase, File srcPkgDir, String outputbase, File outputBaseDir ) throws IOException { return precheckOutputPackageDir( outputDir(codebase, srcPkgDir, outputbase, outputBaseDir) ); } private static boolean precheckOutputPackageDir(File dir) throws IOException { File outFile = new File( dir, classname + ".java" ); if (! dir.canWrite()) { System.err.println("File '" + outFile.getPath() + "' is not writable."); return false; } else if (!clobber && outFile.exists()) { System.err.println("File '" + outFile.getPath() + "' exists, and we are in noclobber mode."); return false; } else return true; } private static void recursiveWriteDebugFiles( String codebase, File srcPkgDir, String outputbase, File outputBaseDir ) throws IOException { FileIterator fii = DirectoryDescentUtils.depthFirstEagerDescent( outputDir( codebase, srcPkgDir, outputbase, outputBaseDir ) ); while (fii.hasNext()) { File pkgDir = fii.nextFile(); //System.err.println("pkgDir: " + pkgDir); if (! pkgDir.isDirectory() || skipDirs.contains(pkgDir.getName())) continue; writeDebugFile(outputbase, pkgDir); } } private static void writeDebugFile(String outputbase, File pkgDir) throws IOException { //System.err.println("outputbase: " + outputbase + "; pkgDir: " + pkgDir); File outFile = new File( pkgDir, classname + ".java" ); String pkg = dottify( pkgDir.getPath().substring( outputbase.length() ) ); System.err.println("Writing file: " + outFile.getPath()); Writer writer = null; try { writer = new OutputStreamWriter( new BufferedOutputStream( new FileOutputStream( outFile ) ), "UTF8" ); writer.write("/********************************************************************" + EOL); writer.write(" * This class generated by " + DebugGen.class.getName() + EOL); writer.write(" * and will probably be overwritten by the same! Edit at" + EOL); writer.write(" * YOUR PERIL!!! Hahahahaha." + EOL); writer.write(" ********************************************************************/" + EOL); writer.write(EOL); writer.write("package " + pkg + ';' + EOL); writer.write(EOL); writer.write("import com.mchange.v2.debug.DebugConstants;" + EOL); writer.write(EOL); writer.write("final class " + classname + " implements DebugConstants" + EOL); writer.write("{" + EOL); writer.write("\tfinal static boolean DEBUG = " + debug + ';' + EOL); writer.write("\tfinal static int TRACE = " + traceStr( trace_level ) + ';' + EOL); writer.write(EOL); writer.write("\tprivate " + classname + "()" + EOL); writer.write("\t{}" + EOL); writer.write("}" + EOL); writer.write(EOL); writer.flush(); } finally { WriterUtils.attemptClose( writer ); } } private static String traceStr( int trace ) { if (trace == TRACE_NONE) return "TRACE_NONE"; else if (trace == TRACE_MED) return "TRACE_MED"; else if (trace == TRACE_MAX) return "TRACE_MAX"; else return String.valueOf(trace); } } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/io/0000755000175000017500000000000010673162231022271 5ustar godgodc3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/io/DirectoryDescentUtils.java0000644000175000017500000000717210624366527027450 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.io; import java.io.*; import java.util.*; public final class DirectoryDescentUtils { /** * @return FileIterator over all files and dierctories beneath root */ public static FileIterator depthFirstEagerDescent(File root) throws IOException { return depthFirstEagerDescent( root, null, false ); } /** * @return FileIterator over all files and directories beneath root that * match filter. * * @param canonical file paths will be canonicalized if true */ public static FileIterator depthFirstEagerDescent(File root, FileFilter filter, boolean canonical) throws IOException { List list = new LinkedList(); Set seenDirex = new HashSet(); depthFirstEagerDescend(root, filter, canonical, list, seenDirex); return new IteratorFileIterator( list.iterator() ); } public static void addSubtree( File root, FileFilter filter, boolean canonical, Collection addToMe ) throws IOException { Set seenDirex = new HashSet(); depthFirstEagerDescend(root, filter, canonical, addToMe, seenDirex); } private static void depthFirstEagerDescend(File dir, FileFilter filter, boolean canonical, Collection addToMe, Set seenDirex) throws IOException { String canonicalPath = dir.getCanonicalPath(); if (! seenDirex.contains( canonicalPath ) ) { if ( filter == null || filter.accept( dir ) ) addToMe.add( canonical ? new File( canonicalPath ) : dir ); seenDirex.add( canonicalPath ); String[] babies = dir.list(); for (int i = 0, len = babies.length; i < len; ++i) { File baby = new File(dir, babies[i]); if (baby.isDirectory()) depthFirstEagerDescend(baby, filter, canonical, addToMe, seenDirex); else if ( filter == null || filter.accept( baby ) ) addToMe.add( canonical ? baby.getCanonicalFile() : baby ); } } } private static class IteratorFileIterator implements FileIterator { Iterator ii; Object last; IteratorFileIterator(Iterator ii) { this.ii = ii; } public File nextFile() throws IOException { return (File) next(); } public boolean hasNext() throws IOException { return ii.hasNext(); } public Object next() throws IOException { return (last = ii.next()); } public void remove() throws IOException { if (last != null) { ((File) last).delete(); last = null; } else throw new IllegalStateException(); } public void close() throws IOException {} } private DirectoryDescentUtils() {} public static void main(String[] argv) { try { FileIterator fii = depthFirstEagerDescent( new File(argv[0]) ); while (fii.hasNext()) System.err.println( fii.nextFile().getPath() ); } catch (Exception e) { e.printStackTrace(); } } } c3p0-0.9.1.2.orig/relproj/debuggen/src/classes/com/mchange/v2/io/FileIterator.java0000644000175000017500000000314610624366527025543 0ustar godgod/* * Distributed as part of debuggen v.0.1.0 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.io; import java.io.File; import java.io.IOException; import java.util.NoSuchElementException; import com.mchange.v1.util.UIterator; public interface FileIterator extends UIterator { public File nextFile() throws IOException; public boolean hasNext() throws IOException; public Object next() throws IOException; public void remove() throws IOException; public void close() throws IOException; public final static FileIterator EMPTY_FILE_ITERATOR = new FileIterator() { public File nextFile() {throw new NoSuchElementException();} public boolean hasNext() {return false;} public Object next() {throw new NoSuchElementException();} public void remove() {throw new IllegalStateException();} public void close() {} }; } c3p0-0.9.1.2.orig/relproj/debuggen/build.xml0000644000175000017500000000474410624366527016573 0ustar godgod c3p0-0.9.1.2.orig/relproj/debuggen/version.properties0000644000175000017500000000012410624366527020541 0ustar godgod#autogenerated -- do not edit! #Mon May 21 15:04:55 EDT 2007 debuggen.version=0.1.0 c3p0-0.9.1.2.orig/relproj/dist/0000755000175000017500000000000010673162231014112 5ustar godgodc3p0-0.9.1.2.orig/relproj/build.xml0000644000175000017500000000134010212043217014755 0ustar godgod c3p0-0.9.1.2.orig/src/0000755000175000017500000000000010624366527012273 5ustar godgodc3p0-0.9.1.2.orig/src/classes/0000755000175000017500000000000010624366527013730 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/0000755000175000017500000000000010624366527014506 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/0000755000175000017500000000000010624366530016102 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/lang/0000755000175000017500000000000010673162231017017 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/lang/ByteUtils.java0000644000175000017500000000604610624366530021620 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.lang; import java.io.StringReader; import java.io.StringWriter; import java.io.IOException; public final class ByteUtils { public final static short UNSIGNED_MAX_VALUE = (Byte.MAX_VALUE * 2) + 1; public static short toUnsigned(byte b) {return (short) (b < 0 ? (UNSIGNED_MAX_VALUE + 1) + b : b);} public static String toHexAscii(byte b) { StringWriter sw = new StringWriter(2); addHexAscii(b, sw); return sw.toString(); } public static String toHexAscii(byte[] bytes) { int len = bytes.length; StringWriter sw = new StringWriter(len * 2); for (int i = 0; i < len; ++i) addHexAscii(bytes[i], sw); return sw.toString(); } public static byte[] fromHexAscii(String s) throws NumberFormatException { try { int len = s.length(); if ((len % 2) != 0) throw new NumberFormatException("Hex ascii must be exactly two digits per byte."); int out_len = len / 2; byte[] out = new byte[out_len]; int i = 0; StringReader sr = new StringReader(s); while (i < out_len) { int val = (16 * fromHexDigit(sr.read())) + fromHexDigit(sr.read()); out[i++] = (byte) val; } return out; } catch (IOException e) {throw new InternalError("IOException reading from StringReader?!?!");} } static void addHexAscii(byte b, StringWriter sw) { short ub = toUnsigned(b); int h1 = ub / 16; int h2 = ub % 16; sw.write(toHexDigit(h1)); sw.write(toHexDigit(h2)); } private static int fromHexDigit(int c) throws NumberFormatException { if (c >= 0x30 && c < 0x3A) return c - 0x30; else if (c >= 0x41 && c < 0x47) return c - 0x37; else if (c >= 0x61 && c < 0x67) return c - 0x57; else throw new NumberFormatException('\'' + c + "' is not a valid hexadecimal digit."); } /* note: we do no arg. checking, because */ /* we only ever call this from addHexAscii() */ /* above, and we are sure the args are okay */ private static char toHexDigit(int h) { char out; if (h <= 9) out = (char) (h + 0x30); else out = (char) (h + 0x37); //System.err.println(h + ": " + out); return out; } private ByteUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/lang/PotentiallySecondary.java0000644000175000017500000000214610624366530024045 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.lang; /* * An interface to be implemented by Throwable objects * that may indicate a secondary problem, originated by the * more primary, nested, throwable */ public interface PotentiallySecondary { public Throwable getNestedThrowable(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/lang/PotentiallySecondaryError.java0000644000175000017500000000355310624366527025070 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.lang; import java.io.*; public class PotentiallySecondaryError extends Error implements PotentiallySecondary { final static String NESTED_MSG = ">>>>>>>>>> NESTED THROWABLE >>>>>>>>"; Throwable nested; public PotentiallySecondaryError(String msg, Throwable t) { super(msg); this.nested = t; } public PotentiallySecondaryError(Throwable t) {this("", t);} public PotentiallySecondaryError(String msg) {this(msg, null);} public PotentiallySecondaryError() {this("", null);} public Throwable getNestedThrowable() {return nested;} public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if (nested != null) { pw.println(NESTED_MSG); nested.printStackTrace(pw); } } public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if (nested != null) { ps.println("NESTED_MSG"); nested.printStackTrace(ps); } } public void printStackTrace() {printStackTrace(System.err);} } c3p0-0.9.1.2.orig/src/classes/com/mchange/lang/PotentiallySecondaryException.java0000644000175000017500000000457210624366527025737 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.lang; import java.io.*; import com.mchange.v2.lang.VersionUtils; /** * @deprecated jdk 1.4 mow includes this idea as part of the standard * Throwable/Exception classes. */ public class PotentiallySecondaryException extends Exception implements PotentiallySecondary { final static String NESTED_MSG = ">>>>>>>>>> NESTED EXCEPTION >>>>>>>>"; Throwable nested; public PotentiallySecondaryException(String msg, Throwable t) { super(msg); this.nested = t; } public PotentiallySecondaryException(Throwable t) {this("", t);} public PotentiallySecondaryException(String msg) {this(msg, null);} public PotentiallySecondaryException() {this("", null);} public Throwable getNestedThrowable() {return nested;} private void setNested(Throwable t) { this.nested = t; if ( VersionUtils.isAtLeastJavaVersion14() ) this.initCause( t ); } public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if ( !VersionUtils.isAtLeastJavaVersion14() && nested != null) { pw.println(NESTED_MSG); nested.printStackTrace(pw); } } public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if ( !VersionUtils.isAtLeastJavaVersion14() && nested != null) { ps.println("NESTED_MSG"); nested.printStackTrace(ps); } } public void printStackTrace() { if ( VersionUtils.isAtLeastJavaVersion14() ) super.printStackTrace(); else this.printStackTrace(System.err); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/lang/PotentiallySecondaryRuntimeException.java0000644000175000017500000000365510624366527027304 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.lang; import java.io.*; public class PotentiallySecondaryRuntimeException extends RuntimeException implements PotentiallySecondary { final static String NESTED_MSG = ">>>>>>>>>> NESTED EXCEPTION >>>>>>>>"; Throwable nested; public PotentiallySecondaryRuntimeException(String msg, Throwable t) { super(msg); this.nested = t; } public PotentiallySecondaryRuntimeException(Throwable t) {this("", t);} public PotentiallySecondaryRuntimeException(String msg) {this(msg, null);} public PotentiallySecondaryRuntimeException() {this("", null);} public Throwable getNestedThrowable() {return nested;} public void printStackTrace(PrintWriter pw) { super.printStackTrace(pw); if (nested != null) { pw.println(NESTED_MSG); nested.printStackTrace(pw); } } public void printStackTrace(PrintStream ps) { super.printStackTrace(ps); if (nested != null) { ps.println("NESTED_MSG"); nested.printStackTrace(ps); } } public void printStackTrace() {printStackTrace(System.err);} } c3p0-0.9.1.2.orig/src/classes/com/mchange/lang/ThrowableUtils.java0000644000175000017500000000264110624366530022641 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.lang; import java.io.*; public final class ThrowableUtils { public static String extractStackTrace(Throwable t) { StringWriter me = new StringWriter(); PrintWriter pw = new PrintWriter(me); t.printStackTrace(pw); pw.flush(); return me.toString(); } public static boolean isChecked(Throwable t) { return t instanceof Exception && ! (t instanceof RuntimeException); } public static boolean isUnchecked(Throwable t) { return ! isChecked( t ); } private ThrowableUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/util/0000755000175000017500000000000010673162231017053 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/util/AssertException.java0000644000175000017500000000203010624366530023035 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.util; public class AssertException extends RuntimeException { public AssertException(String message) {super(message);} public AssertException() {super();} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/0000755000175000017500000000000010624366530016430 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/db/0000755000175000017500000000000010624366527017023 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/db/sql/0000755000175000017500000000000010673162231017610 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/db/sql/ConnectionUtils.java0000644000175000017500000000373410624366527023614 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.db.sql; import java.sql.*; import com.mchange.v2.log.*; public final class ConnectionUtils { private final static MLogger logger = MLog.getLogger( ConnectionUtils.class ); /** * @return false iff and Exception occurred while * trying to close this object. */ public static boolean attemptClose(Connection con) { try { if (con != null) con.close(); //System.err.println("Connection [ " + con + " ] closed."); return true; } catch (SQLException e) { //e.printStackTrace(); //System.err.println("Connection close FAILED."); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Connection close FAILED.", e ); return false; } } public static boolean attemptRollback(Connection con) { try { if (con != null) con.rollback(); return true; } catch (SQLException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Rollback FAILED.", e ); return false; } } private ConnectionUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/db/sql/ResultSetUtils.java0000644000175000017500000000302010624366527023433 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.db.sql; import java.sql.*; import com.mchange.v2.log.*; public final class ResultSetUtils { private final static MLogger logger = MLog.getLogger( ResultSetUtils.class ); /** * @return false iff and Exception occurred while * trying to close this object. */ public static boolean attemptClose(ResultSet rs) { try { if (rs != null) rs.close(); return true; } catch (SQLException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "ResultSet close FAILED.", e ); return false; } } private ResultSetUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/db/sql/StatementUtils.java0000644000175000017500000000302610624366530023445 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.db.sql; import java.sql.*; import com.mchange.v2.log.*; public final class StatementUtils { private final static MLogger logger = MLog.getLogger( StatementUtils.class ); /** * @return false iff and Exception occurred while * trying to close this object. */ public static boolean attemptClose(Statement stmt) { try { if (stmt != null) stmt.close(); return true; } catch (SQLException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Statement close FAILED.", e ); return false; } } private StatementUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/0000755000175000017500000000000010673162231020731 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/IdHashKey.java0000644000175000017500000000225210624366527023420 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; abstract class IdHashKey { Identicator id; public IdHashKey( Identicator id ) { this.id = id; } public abstract Object getKeyObj(); public Identicator getIdenticator() { return id; } public abstract boolean equals(Object o); public abstract int hashCode(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/IdHashMap.java0000644000175000017500000000216710624366527023412 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; import java.util.*; public final class IdHashMap extends IdMap implements Map { public IdHashMap(Identicator id) { super ( new HashMap(), id ); } protected IdHashKey createIdKey(Object o) { return new StrongIdHashKey( o, id ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/IdMap.java0000644000175000017500000000652710624366530022604 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; import java.util.*; import com.mchange.v1.util.*; /* * Implementation notes: many AbstractMap methods are written in * terms of entrySet(). It is most important to get that right. */ abstract class IdMap extends AbstractMap implements Map { Map inner; Identicator id; protected IdMap(Map inner, Identicator id) { this.inner = inner; this.id = id; } public Object put(Object key, Object value) { return inner.put( createIdKey( key ), value ); } public boolean containsKey(Object key) { return inner.containsKey( createIdKey( key ) ); } public Object get(Object key) { return inner.get( createIdKey( key ) ); } public Object remove(Object key) { return inner.remove( createIdKey( key ) ); } protected Object removeIdHashKey( IdHashKey idhk ) { return inner.remove( idhk ); } public Set entrySet() { return new UserEntrySet(); } protected final Set internalEntrySet() { return inner.entrySet(); } protected abstract IdHashKey createIdKey(Object o); protected final Entry createIdEntry(Object key, Object val) { return new SimpleMapEntry( createIdKey( key ), val); } protected final Entry createIdEntry(Entry entry) { return createIdEntry( entry.getKey(), entry.getValue() ); } private final class UserEntrySet extends AbstractSet { Set innerEntries = inner.entrySet(); public Iterator iterator() { return new WrapperIterator(innerEntries.iterator(), true) { protected Object transformObject(Object o) { return new UserEntry( (Entry) o ); } }; } public int size() { return innerEntries.size(); } public boolean contains(Object o) { if (o instanceof Entry) { Entry entry = (Entry) o; return innerEntries.contains( createIdEntry( entry ) ); } else return false; } public boolean remove(Object o) { if (o instanceof Entry) { Entry entry = (Entry) o; return innerEntries.remove( createIdEntry( entry ) ); } else return false; } public void clear() { inner.clear(); } } protected static class UserEntry extends AbstractMapEntry { private Entry innerEntry; UserEntry(Entry innerEntry) { this.innerEntry = innerEntry; } public final Object getKey() { return ((IdHashKey) innerEntry.getKey()).getKeyObj(); } public final Object getValue() { return innerEntry.getValue(); } public final Object setValue(Object value) { return innerEntry.setValue( value ); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/IdWeakHashMap.java0000644000175000017500000001200010624366530024177 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; import java.lang.ref.*; import java.util.*; import com.mchange.v1.util.WrapperIterator; /** * IdWeakHashMap is NOT null-accepting! */ public final class IdWeakHashMap extends IdMap implements Map { ReferenceQueue rq; public IdWeakHashMap(Identicator id) { super ( new HashMap(), id ); this.rq = new ReferenceQueue(); } //all methods from Map interface public int size() { // doing cleanCleared() afterwards, as with other methods // would be just as "correct", as weak collections // make no guarantees about when things disappear, // but for size(), it feels a little more accurate // this way. cleanCleared(); return super.size(); } public boolean isEmpty() { try { return super.isEmpty(); } finally { cleanCleared(); } } public boolean containsKey(Object o) { try { return super.containsKey( o ); } finally { cleanCleared(); } } public boolean containsValue(Object o) { try { return super.containsValue( o ); } finally { cleanCleared(); } } public Object get(Object o) { try { return super.get( o ); } finally { cleanCleared(); } } public Object put(Object k, Object v) { try { return super.put( k , v ); } finally { cleanCleared(); } } public Object remove(Object o) { try { return super.remove( o ); } finally { cleanCleared(); } } public void putAll(Map m) { try { super.putAll( m ); } finally { cleanCleared(); } } public void clear() { try { super.clear(); } finally { cleanCleared(); } } public Set keySet() { try { return super.keySet(); } finally { cleanCleared(); } } public Collection values() { try { return super.values(); } finally { cleanCleared(); } } /* * entrySet() is the basis of the implementation of the other * Collection returning methods. Get this right and the rest * follow. */ public Set entrySet() { try { return new WeakUserEntrySet(); } finally { cleanCleared(); } } public boolean equals(Object o) { try { return super.equals( o ); } finally { cleanCleared(); } } public int hashCode() { try { return super.hashCode(); } finally { cleanCleared(); } } //internal methods protected IdHashKey createIdKey(Object o) { return new WeakIdHashKey( o, id, rq ); } private void cleanCleared() { WeakIdHashKey.Ref ref; while ((ref = (WeakIdHashKey.Ref) rq.poll()) != null) this.removeIdHashKey( ref.getKey() ); } private final class WeakUserEntrySet extends AbstractSet { Set innerEntries = internalEntrySet(); public Iterator iterator() { try { return new WrapperIterator(innerEntries.iterator(), true) { protected Object transformObject(Object o) { Entry innerEntry = (Entry) o; final Object userKey = ((IdHashKey) innerEntry.getKey()).getKeyObj(); if (userKey == null) return WrapperIterator.SKIP_TOKEN; else return new UserEntry( innerEntry ) { Object preventRefClear = userKey; }; } }; } finally { cleanCleared(); } } public int size() { // doing cleanCleared() afterwards, as with other methods // would be just as "correct", as weak collections // make no guarantees about when things disappear, // but for size(), it feels a little more accurate // this way. cleanCleared(); return innerEntries.size(); } public boolean contains(Object o) { try { if (o instanceof Entry) { Entry entry = (Entry) o; return innerEntries.contains( createIdEntry( entry ) ); } else return false; } finally { cleanCleared(); } } public boolean remove(Object o) { try { if (o instanceof Entry) { Entry entry = (Entry) o; return innerEntries.remove( createIdEntry( entry ) ); } else return false; } finally { cleanCleared(); } } public void clear() { try { inner.clear(); } finally { cleanCleared(); } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/Identicator.java0000644000175000017500000000213110624366530024042 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; /** * Identicators should be immutable (sharable). * Cloned collections share identicators */ public interface Identicator { public boolean identical(Object a, Object b); public int hash(Object o); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/StrongIdHashKey.java0000644000175000017500000000266110624366530024613 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; // revisit equals() if ever made non-final final class StrongIdHashKey extends IdHashKey { Object keyObj; public StrongIdHashKey(Object keyObj, Identicator id) { super( id ); this.keyObj = keyObj; } public Object getKeyObj() { return keyObj; } public boolean equals(Object o) { // fast type-exact match for final class if (o instanceof StrongIdHashKey) return id.identical( keyObj, ((StrongIdHashKey) o).keyObj ); else return false; } public int hashCode() { return id.hash( keyObj ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/identicator/WeakIdHashKey.java0000644000175000017500000000415710624366530024230 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.identicator; import java.lang.ref.*; // revisit equals() if ever made non-final final class WeakIdHashKey extends IdHashKey { Ref keyRef; int hash; public WeakIdHashKey(Object keyObj, Identicator id, ReferenceQueue rq) { super( id ); if (keyObj == null) throw new UnsupportedOperationException("Collection does not accept nulls!"); this.keyRef = new Ref( keyObj, rq ); this.hash = id.hash( keyObj ); } public Ref getInternalRef() { return this.keyRef; } public Object getKeyObj() { return keyRef.get(); } public boolean equals(Object o) { // fast type-exact match for final class if (o instanceof WeakIdHashKey) { WeakIdHashKey other = (WeakIdHashKey) o; if (this.keyRef == other.keyRef) return true; else { Object myKeyObj = this.keyRef.get(); Object oKeyObj = other.keyRef.get(); if (myKeyObj == null || oKeyObj == null) return false; else return id.identical( myKeyObj, oKeyObj ); } } else return false; } public int hashCode() { return hash; } class Ref extends WeakReference { public Ref( Object referant, ReferenceQueue rq ) { super( referant, rq ); } WeakIdHashKey getKey() { return WeakIdHashKey.this; } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/io/0000755000175000017500000000000010673162231017033 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/io/InputStreamUtils.java0000644000175000017500000001030310624366530023173 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.io; import java.io.*; import com.mchange.v2.log.*; public final class InputStreamUtils { private final static MLogger logger = MLog.getLogger( InputStreamUtils.class ); public static boolean compare(InputStream is1, InputStream is2, long num_bytes) throws IOException { int b; for (long num_read = 0; num_read < num_bytes; ++num_read) { if ((b = is1.read()) != is2.read()) return false; else if (b < 0) //both EOF break; } return true; } public static boolean compare(InputStream is1, InputStream is2) throws IOException { int b = 0; while (b >= 0) if ((b = is1.read()) != is2.read()) return false; return true; } public static byte[] getBytes(InputStream is, int max_len) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(max_len); for(int i = 0, b = is.read(); b >= 0 && i < max_len; b = is.read(), ++i) baos.write(b); return baos.toByteArray(); } public static byte[] getBytes(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); for(int b = is.read(); b >= 0; b = is.read()) baos.write(b); return baos.toByteArray(); } public static String getContentsAsString(InputStream is, String enc) throws IOException, UnsupportedEncodingException {return new String(getBytes(is), enc);} public static String getContentsAsString(InputStream is) throws IOException { try {return getContentsAsString(is, System.getProperty("file.encoding", "8859_1"));} catch (UnsupportedEncodingException e) { throw new InternalError("You have no default character encoding, and " + "iso-8859-1 is unsupported?!?!"); } } public static String getContentsAsString(InputStream is, int max_len, String enc) throws IOException, UnsupportedEncodingException {return new String(getBytes(is, max_len), enc);} public static String getContentsAsString(InputStream is, int max_len) throws IOException { try {return getContentsAsString(is, max_len, System.getProperty("file.encoding", "8859_1"));} catch (UnsupportedEncodingException e) { throw new InternalError("You have no default character encoding, and " + "iso-8859-1 is unsupported?!?!"); } } public static InputStream getEmptyInputStream() {return EMPTY_ISTREAM;} public static void attemptClose(InputStream is) { try {if (is != null) is.close();} catch (IOException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "InputStream close FAILED.", e ); } } public static void skipFully(InputStream is, long num_bytes) throws EOFException, IOException { long num_skipped = 0; while (num_skipped < num_bytes) { long just_skipped = is.skip(num_bytes - num_skipped); if (just_skipped > 0) num_skipped += just_skipped; else { int test_byte = is.read(); if (is.read() < 0) throw new EOFException("Skipped only " + num_skipped + " bytes to end of file."); else ++num_skipped; } } } /* Is it appropriate to treat this as a constant? Is it */ /* in any discernable sense changed by read() operations */ private static InputStream EMPTY_ISTREAM = new ByteArrayInputStream(new byte[0]); private InputStreamUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/io/OutputStreamUtils.java0000644000175000017500000000262310624366530023402 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.io; import com.mchange.v2.log.*; import java.io.OutputStream; import java.io.IOException; public final class OutputStreamUtils { private final static MLogger logger = MLog.getLogger( OutputStreamUtils.class ); public static void attemptClose(OutputStream os) { try {if (os != null) os.close();} catch (IOException e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "OutputStream close FAILED.", e ); //e.printStackTrace(); } } private OutputStreamUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/jvm/0000755000175000017500000000000010673162231017220 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/jvm/InternalNameUtils.java0000644000175000017500000001171410624366530023471 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.jvm; public final class InternalNameUtils { public static String dottifySlashesAndDollarSigns(String str) { return _dottifySlashesAndDollarSigns( str ).toString(); } public static String decodeType(String internalrep) throws TypeFormatException { return _decodeType(internalrep).toString(); } public static String decodeTypeList(String internalrep) throws TypeFormatException { StringBuffer sb = new StringBuffer(64); _decodeTypeList(internalrep, 0, sb); return sb.toString(); } public static boolean isPrimitive(char rep) { return (rep == 'Z' || rep == 'B' || rep == 'C' || rep == 'S' || rep == 'I' || rep == 'J' || rep == 'F' || rep == 'D' || rep == 'V'); } private static void _decodeTypeList(String typeList, int start_pos, StringBuffer appendTo) throws TypeFormatException { if (appendTo.length() != 0) appendTo.append(' '); char c = typeList.charAt(start_pos); if (isPrimitive(c)) { appendTo.append( _decodeType( typeList.substring(start_pos, start_pos + 1) ) ); ++start_pos; } else { int stop_index; if (c == '[') { int finger = start_pos + 1; while (typeList.charAt(finger) == '[') ++finger; if (typeList.charAt(finger) == 'L') { ++finger; while (typeList.charAt( finger ) != ';') ++finger; } stop_index = finger; } else { stop_index = typeList.indexOf(';', start_pos); if (stop_index < 0) throw new TypeFormatException(typeList.substring(start_pos) + " is neither a primitive nor semicolon terminated!"); } appendTo.append( _decodeType( typeList.substring( start_pos, (start_pos = stop_index + 1) ) ) ); } if (start_pos < typeList.length()) { appendTo.append(','); _decodeTypeList(typeList, start_pos, appendTo); } } private static StringBuffer _decodeType(String type) throws TypeFormatException { // System.err.println("_decodeType: " + type); int array_level = 0; StringBuffer out; char c = type.charAt(0); switch (c) { case 'Z': out = new StringBuffer("boolean"); break; case 'B': out = new StringBuffer("byte"); break; case 'C': out = new StringBuffer("char"); break; case 'S': out = new StringBuffer("short"); break; case 'I': out = new StringBuffer("int"); break; case 'J': out = new StringBuffer("long"); break; case 'F': out = new StringBuffer("float"); break; case 'D': out = new StringBuffer("double"); break; case 'V': out = new StringBuffer("void"); break; case '[': ++array_level; out = _decodeType(type.substring(1)); break; case 'L': out = _decodeSimpleClassType(type); break; default: throw new TypeFormatException(type + " is not a valid inernal type name."); } for (int i = 0; i < array_level; ++i) out.append("[]"); return out; } private static StringBuffer _decodeSimpleClassType(String type) throws TypeFormatException { int len = type.length(); if (type.charAt(0) != 'L' || type.charAt( len - 1 ) != ';') throw new TypeFormatException(type + " is not a valid representation of a simple class type."); return _dottifySlashesAndDollarSigns( type.substring(1, len - 1) ); } private static StringBuffer _dottifySlashesAndDollarSigns(String s) { StringBuffer sb = new StringBuffer( s ); for (int i = 0, len = sb.length(); i < len; ++i) { char c = sb.charAt(i); if ( c == '/' || c == '$') sb.setCharAt(i, '.'); } return sb; } private InternalNameUtils() {} public static void main(String[] argv) { try { //System.out.println( decodeType( (new String[0]).getClass().getName() ) ); System.out.println(decodeTypeList(argv[0])); } catch (Exception e) { e.printStackTrace(); } } // public static String dottifySlashes(String name) // { // StringBuffer sb = new StringBuffer(name); // int pos = name.indexOf('/', 0); // while (pos > 0) // { // sb.setCharAt(pos, '.'); // ps = name.indexOf('/', ++pos); // } // return sb.toString(); // } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/jvm/TypeFormatException.java0000644000175000017500000000202510624366527024045 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.jvm; public class TypeFormatException extends Exception { TypeFormatException() { super(); } TypeFormatException( String msg ) { super( msg ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/lang/0000755000175000017500000000000010673162231017345 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/lang/AmbiguousClassNameException.java0000644000175000017500000000216410624366530025620 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.lang; public class AmbiguousClassNameException extends Exception { AmbiguousClassNameException(String simpleName, Class c1, Class c2) { super( simpleName + " could refer either to " + c1.getName() + " or " + c2.getName() ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/lang/BooleanUtils.java0000644000175000017500000000232710624366527022626 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.lang; public final class BooleanUtils { public static boolean parseBoolean(String str) throws IllegalArgumentException { if (str.equals("true")) return true; else if (str.equals("false")) return false; else throw new IllegalArgumentException("\"str\" is neither \"true\" nor \"false\"."); } private BooleanUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/lang/ClassUtils.java0000644000175000017500000001423710624366530022311 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.lang; import java.util.*; import com.mchange.v1.jvm.*; public final class ClassUtils { final static String[] EMPTY_SA = new String[0]; static Map primitivesToClasses; static { HashMap tmp = new HashMap(); tmp.put( "boolean", boolean.class ); tmp.put( "int", int.class ); tmp.put( "char", char.class ); tmp.put( "short", short.class ); tmp.put( "int", int.class ); tmp.put( "long", long.class ); tmp.put( "float", float.class ); tmp.put( "double", double.class ); tmp.put( "void", void.class ); primitivesToClasses = Collections.unmodifiableMap( tmp ); } public static Set allAssignableFrom(Class type) { Set out = new HashSet(); //type itself and superclasses (if any) for (Class cl = type; cl != null; cl = cl.getSuperclass()) out.add( cl ); //super interfaces (if any) addSuperInterfacesToSet( type, out ); return out; } public static String simpleClassName(Class cl) { String scn; int array_level = 0; while (cl.isArray()) { ++array_level; cl = cl.getComponentType(); } scn = simpleClassName( cl.getName() ); if ( array_level > 0 ) { StringBuffer sb = new StringBuffer(16); sb.append( scn ); for( int i = 0; i < array_level; ++i) sb.append("[]"); return sb.toString(); } else return scn; } private static String simpleClassName(String fqcn) { int pkgdot = fqcn.lastIndexOf('.'); if (pkgdot < 0) return fqcn; String scn = fqcn.substring(pkgdot + 1); if (scn.indexOf('$') >= 0) { StringBuffer sb = new StringBuffer(scn); for (int i = 0, len = sb.length(); i < len; ++i) { if (sb.charAt(i) == '$') sb.setCharAt(i, '.'); } return sb.toString(); } else return scn; } public static boolean isPrimitive(String typeStr) { return (primitivesToClasses.get( typeStr ) != null); } public static Class classForPrimitive(String typeStr) { return (Class) primitivesToClasses.get( typeStr ); } public static Class forName(String fqcnOrPrimitive ) throws ClassNotFoundException { Class out = classForPrimitive( fqcnOrPrimitive ); if (out == null) out = Class.forName( fqcnOrPrimitive ); return out; } public static Class forName( String fqOrSimple, String[] importPkgs, String[] importClasses ) throws AmbiguousClassNameException, ClassNotFoundException { try { return Class.forName( fqOrSimple ); } catch ( ClassNotFoundException e ) { return classForSimpleName( fqOrSimple, importPkgs, importClasses ); } } public static Class classForSimpleName( String simpleName, String[] importPkgs, String[] importClasses ) throws AmbiguousClassNameException, ClassNotFoundException { Set checkSet = new HashSet(); Class out = classForPrimitive( simpleName ); if (out == null) { if (importPkgs == null) importPkgs = EMPTY_SA; if (importClasses == null) importClasses = EMPTY_SA; for (int i = 0, len = importClasses.length; i < len; ++i) { String importSimpleName = fqcnLastElement( importClasses[i] ); if (! checkSet.add( importSimpleName ) ) throw new IllegalArgumentException("Duplicate imported classes: " + importSimpleName); if ( simpleName.equals( importSimpleName ) ) //we won't duplicate assign. we'd have caught it above out = Class.forName( importClasses[i] ); } if (out == null) { try { out = Class.forName("java.lang." + simpleName); } catch (ClassNotFoundException e) { /* just means we haven't found it yet */ } for (int i = 0, len = importPkgs.length; i < len; ++i) { try { String tryClass = importPkgs[i] + '.' + simpleName; Class test = Class.forName( tryClass ); if ( out == null ) out = test; else throw new AmbiguousClassNameException( simpleName, out, test ); } catch (ClassNotFoundException e) { /* just means we haven't found it yet */ } } } } if (out == null) throw new ClassNotFoundException( "Could not find a class whose unqualified name is \042" + simpleName + "\042 with the imports supplied. Import packages are " + Arrays.asList( importPkgs ) + "; class imports are " + Arrays.asList( importClasses ) ); else return out; } public static String resolvableTypeName( Class type, String[] importPkgs, String[] importClasses ) throws ClassNotFoundException { String simpleName = simpleClassName( type ); try { classForSimpleName( simpleName, importPkgs, importClasses ); } catch ( AmbiguousClassNameException e ) { return type.getName(); } return simpleName; } public static String fqcnLastElement(String fqcn) { int pkgdot = fqcn.lastIndexOf('.'); if (pkgdot < 0) return fqcn; return fqcn.substring(pkgdot + 1); } /* does not add type itself, only its superinterfaces */ private static void addSuperInterfacesToSet(Class type, Set set) { Class[] ifaces = type.getInterfaces(); for (int i = 0, len = ifaces.length; i < len; ++i) { set.add( ifaces[i] ); addSuperInterfacesToSet( ifaces[i], set ); } } private ClassUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/lang/GentleThread.java0000644000175000017500000000547510624366530022575 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.lang; /** * an abstract Thread class that provides * utilities for easily defining Threads with * safe versions of the deprecated thread * methods stop(), resume(), and start() */ public abstract class GentleThread extends Thread { boolean should_stop = false; boolean should_suspend = false; public GentleThread() { super(); } public GentleThread(String name) { super( name ); } public abstract void run(); /** * a safe method for stopping properly implemented GentleThreads */ public synchronized void gentleStop() {should_stop = true;} /** * a safe method for suspending properly implemented GentleThreads */ public synchronized void gentleSuspend() {should_suspend = true;} /** * a safe method for resuming properly implemented GentleThreads */ public synchronized void gentleResume() { should_suspend = false; this.notifyAll(); } /** * tests whether the thread should stop. * Subclasses should call this method periodically in * their run method, and return from run() is the * method returns true. */ protected synchronized boolean shouldStop() {return should_stop;} /** * tests whether the thread should suspend. * Subclasses rarely call this method directly, * and should call allowSuspend() periodically * instead. * * @see #allowSuspend */ protected synchronized boolean shouldSuspend() {return should_suspend;} /** * tests whether the thread should suspend, * and causes to the thread to pause if appropriate. * Subclasses should call this method periodically * in their run method to, um, allow suspension. * Threads paused by allowSuspend() will be properly * awoken by gentleResume() * * @see #gentleResume */ protected synchronized void allowSuspend() throws InterruptedException {while (should_suspend) this.wait();} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/lang/NullUtils.java0000644000175000017500000000226010624366527022155 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.lang; /** * @deprecated use com.mchange.v2.ObjectUtils.eqOrBothNull() */ public final class NullUtils { public static boolean equalsOrBothNull(Object a, Object b) { if (a == b) return true; else if (a == null) return false; else return a.equals( b ); } private NullUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/0000755000175000017500000000000010673162231017401 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/AbstractMapEntry.java0000644000175000017500000000312210624366527023477 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.Map; import com.mchange.v2.lang.ObjectUtils; public abstract class AbstractMapEntry implements Map.Entry { public abstract Object getKey(); public abstract Object getValue(); public abstract Object setValue(Object value); public boolean equals(Object o) { if (o instanceof Map.Entry) { Map.Entry other = (Map.Entry) o; return ObjectUtils.eqOrBothNull( this.getKey(), other.getKey() ) && ObjectUtils.eqOrBothNull( this.getValue(), other.getValue() ); } else return false; } public int hashCode() { return (this.getKey() == null ? 0 : this.getKey().hashCode()) ^ (this.getValue() == null ? 0 : this.getValue().hashCode()); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/ArrayUtils.java0000644000175000017500000002072110624366530022351 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import com.mchange.v2.lang.ObjectUtils; public final class ArrayUtils { /** * The array may contain nulls, but o * must be non-null. */ public static int indexOf(Object[] array, Object o) { for (int i = 0, len = array.length; i < len; ++i) if (o.equals(array[i])) return i; return -1; } public static int identityIndexOf(Object[] array, Object o) { for (int i = 0, len = array.length; i < len; ++i) if (o == array[i]) return i; return -1; } public static boolean startsWith( byte[] checkMe, byte[] maybePrefix ) { int cm_len = checkMe.length; int mp_len = maybePrefix.length; if (cm_len < mp_len) return false; for (int i = 0; i < mp_len; ++i) if (checkMe[i] != maybePrefix[i]) return false; return true; } /** * returns a hash-code for an array consistent with Arrays.equals( ... ) */ public static int hashArray(Object[] oo) { int len = oo.length; int out = len; for (int i = 0; i < len; ++i) { //we rotate the bits of the element hashes //around so that the hash has some loaction //dependency int elem_hash = ObjectUtils.hashOrZero(oo[i]); int rot = i % 32; int rot_hash = elem_hash >>> rot; rot_hash |= elem_hash << (32 - rot); out ^= rot_hash; } return out; } /** * returns a hash-code for an array consistent with Arrays.equals( ... ) */ public static int hashArray(int[] ii) { int len = ii.length; int out = len; for (int i = 0; i < len; ++i) { //we rotate the bits of the element hashes //around so that the hash has some loaction //dependency int elem_hash = ii[i]; int rot = i % 32; int rot_hash = elem_hash >>> rot; rot_hash |= elem_hash << (32 - rot); out ^= rot_hash; } return out; } public static int hashOrZeroArray(Object[] oo) { return (oo == null ? 0 : hashArray(oo)); } public static int hashOrZeroArray(int[] ii) { return (ii == null ? 0 : hashArray(ii)); } /** * @deprecated use the various toString(T[] methods) */ public static String stringifyContents(Object[] array) { StringBuffer sb = new StringBuffer(); sb.append("[ "); for (int i = 0, len = array.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( array[i].toString() ); } sb.append(" ]"); return sb.toString(); } //these methods are obsoleted by Arrays.toString() in jdk1.5, but //for libs that support older VMs... private static String toString(String[] strings, int guessed_len) { StringBuffer sb = new StringBuffer( guessed_len ); boolean first = true; sb.append('['); for (int i = 0, len = strings.length; i < len; ++i) { if (first) first = false; else sb.append(','); sb.append( strings[i] ); } sb.append(']'); return sb.toString(); } public static String toString(boolean[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(byte[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(char[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(short[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(int[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(long[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(float[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(double[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } public static String toString(Object[] arr) { String[] strings = new String[arr.length]; int chars = 0; for(int i = 0, len = arr.length; i < len; ++i) { String str; Object o = arr[i]; if (o instanceof Object[]) str = toString((Object[]) o); else if (o instanceof double[]) str = toString((double[]) o); else if (o instanceof float[]) str = toString((float[]) o); else if (o instanceof long[]) str = toString((long[]) o); else if (o instanceof int[]) str = toString((int[]) o); else if (o instanceof short[]) str = toString((short[]) o); else if (o instanceof char[]) str = toString((char[]) o); else if (o instanceof byte[]) str = toString((byte[]) o); else if (o instanceof boolean[]) str = toString((boolean[]) o); else str = String.valueOf(arr[i]); chars += str.length(); strings[i] = str; } return toString(strings, chars + arr.length + 1); } private ArrayUtils() {} /* public static void main(String[] argv) { int[] is = {1,2,3,4}; String[] ss = {"Hello", "There"}; Object[] os = {"Poop", is, ss, new Thread()}; System.out.println( toString(is) ); System.out.println( toString(ss) ); System.out.println( toString(os) ); } */ } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/ClosableResource.java0000644000175000017500000000244510624366530023511 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; /** * An interface intended to be shared by the many sorts * of objects that offer some kind of close method to * cleanup resources they might be using. (I wish Sun * had defined, and used, such an interface in the standard * APIs. */ public interface ClosableResource { /** * forces the release of any resources that might be * associated with this object. */ public void close() throws Exception; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/ClosableResourceUtils.java0000644000175000017500000000307410624366527024537 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import com.mchange.v2.log.*; public final class ClosableResourceUtils { private final static MLogger logger = MLog.getLogger( ClosableResourceUtils.class ); /** * attempts to close the specified resource, * logging any exception or failure, but allowing * control flow to proceed normally regardless. */ public static Exception attemptClose(ClosableResource cr) { try { if (cr != null) cr.close(); return null; } catch (Exception e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "CloseableResource close FAILED.", e ); return e; } } private ClosableResourceUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/DebugUtils.java0000644000175000017500000000226310624366530022322 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import com.mchange.util.AssertException; public class DebugUtils { private DebugUtils() {} public static void myAssert(boolean bool) {if (!bool) throw new AssertException();} public static void myAssert(boolean bool, String message) {if (!bool) throw new AssertException(message);} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/SimpleMapEntry.java0000644000175000017500000000246610624366527023177 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.Map; public class SimpleMapEntry extends AbstractMapEntry implements Map.Entry { Object key; Object value; public SimpleMapEntry(Object key, Object value) { this.key = key; this.value = value; } public Object getKey() { return key; } public Object getValue() { return value; } public Object setValue(Object value) { Object old = value; this.value = value; return old; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/StringTokenizerUtils.java0000644000175000017500000000274110624366527024444 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.StringTokenizer; public final class StringTokenizerUtils { public static String[] tokenizeToArray(String str, String delim, boolean returntokens) { StringTokenizer st = new StringTokenizer(str, delim, returntokens); String[] strings = new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); ++i) strings[i] = st.nextToken(); return strings; } public static String[] tokenizeToArray(String str, String delim) {return tokenizeToArray(str, delim, false);} public static String[] tokenizeToArray(String str) {return tokenizeToArray(str, " \t\r\n");} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/util/WrapperIterator.java0000644000175000017500000000547610624366527023424 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.util; import java.util.*; import com.mchange.v1.util.DebugUtils; /** * This implementation does not yet support removes once hasNext() has * been called... will add if necessary. */ public abstract class WrapperIterator implements Iterator { protected final static Object SKIP_TOKEN = new Object(); final static boolean DEBUG = true; Iterator inner; boolean supports_remove; Object lastOut = null; Object nextOut = SKIP_TOKEN; public WrapperIterator(Iterator inner, boolean supports_remove) { this.inner = inner; this.supports_remove = supports_remove; } public WrapperIterator(Iterator inner) { this( inner, false ); } public boolean hasNext() { findNext(); return nextOut != SKIP_TOKEN; } private void findNext() { if (nextOut == SKIP_TOKEN) { while (inner.hasNext() && nextOut == SKIP_TOKEN) this.nextOut = transformObject( inner.next() ); } } public Object next() { findNext(); if (nextOut != SKIP_TOKEN) { lastOut = nextOut; nextOut = SKIP_TOKEN; } else throw new NoSuchElementException(); //postcondition if (DEBUG) DebugUtils.myAssert( nextOut == SKIP_TOKEN && lastOut != SKIP_TOKEN ); return lastOut; } public void remove() { if (supports_remove) { if (nextOut != SKIP_TOKEN) throw new UnsupportedOperationException(this.getClass().getName() + " cannot support remove after" + " hasNext() has been called!"); if (lastOut != SKIP_TOKEN) inner.remove(); else throw new NoSuchElementException(); } else throw new UnsupportedOperationException(); } /** * return SKIP_TOKEN to indicate an object should be * skipped, i.e., not exposed as part of the iterator. * (we don't use null, because we want to support iterators * over null-accepting Collections.) */ protected abstract Object transformObject(Object o); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v1/xml/0000755000175000017500000000000010673162231017224 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v1/xml/DomParseUtils.java0000644000175000017500000001344610624366527022644 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v1.xml; import java.util.*; import org.xml.sax.*; import org.w3c.dom.*; import com.mchange.v1.util.DebugUtils; public final class DomParseUtils { final static boolean DEBUG = true; /** * @return null if child doesn't exist. */ public static String allTextFromUniqueChild(Element elem, String childTagName) throws DOMException { return allTextFromUniqueChild( elem, childTagName, false ); } /** * @return null if child doesn't exist. */ public static String allTextFromUniqueChild(Element elem, String childTagName, boolean trim) throws DOMException { Element uniqueChild = uniqueChildByTagName( elem, childTagName ); if (uniqueChild == null) return null; else return DomParseUtils.allTextFromElement( uniqueChild, trim ); } public static Element uniqueChild(Element elem, String childTagName) throws DOMException { return uniqueChildByTagName( elem, childTagName); } /** * @deprecated use uniqueChild(Element elem, String childTagName) */ public static Element uniqueChildByTagName(Element elem, String childTagName) throws DOMException { NodeList nl = elem.getElementsByTagName(childTagName); int len = nl.getLength(); if (DEBUG) DebugUtils.myAssert( len <= 1 , "There is more than one (" + len + ") child with tag name: " + childTagName + "!!!" ); return (len == 1 ? (Element) nl.item( 0 ) : null); } public static String allText(Element elem) throws DOMException { return allTextFromElement( elem ); } public static String allText(Element elem, boolean trim) throws DOMException { return allTextFromElement( elem, trim ); } /** @deprecated use allText(Element elem) */ public static String allTextFromElement(Element elem) throws DOMException { return allTextFromElement( elem, false); } /** @deprecated use allText(Element elem, boolean trim) */ public static String allTextFromElement(Element elem, boolean trim) throws DOMException { StringBuffer textBuf = new StringBuffer(); NodeList nl = elem.getChildNodes(); for (int j = 0, len = nl.getLength(); j < len; ++j) { Node node = nl.item(j); if (node instanceof Text) //includes Text and CDATA! textBuf.append(node.getNodeValue()); } String out = textBuf.toString(); return ( trim ? out.trim() : out ); } public static String[] allTextFromImmediateChildElements( Element parent, String tagName ) throws DOMException { return allTextFromImmediateChildElements( parent, tagName, false ); } public static String[] allTextFromImmediateChildElements( Element parent, String tagName, boolean trim ) throws DOMException { NodeList nl = immediateChildElementsByTagName( parent, tagName ); int len = nl.getLength(); String[] out = new String[ len ]; for (int i = 0; i < len; ++i) out[i] = allText( (Element) nl.item(i), trim ); return out; } public static NodeList immediateChildElementsByTagName( Element parent, String tagName ) throws DOMException { return getImmediateChildElementsByTagName( parent, tagName ); } /** * @deprecated use immediateChildrenByTagName( Element parent, String tagName ) */ public static NodeList getImmediateChildElementsByTagName( Element parent, String tagName ) throws DOMException { final List nodes = new ArrayList(); for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) if (child instanceof Element && ((Element) child).getTagName().equals(tagName)) nodes.add(child); return new NodeList() { public int getLength() { return nodes.size(); } public Node item( int i ) { return (Node) nodes.get( i ); } }; } public static String allTextFromUniqueImmediateChild(Element elem, String childTagName) throws DOMException { Element uniqueChild = uniqueImmediateChildByTagName( elem, childTagName ); if (uniqueChild == null) return null; return DomParseUtils.allTextFromElement( uniqueChild ); } public static Element uniqueImmediateChild(Element elem, String childTagName) throws DOMException { return uniqueImmediateChildByTagName( elem, childTagName); } /** * @deprecated use uniqueImmediateChild(Element elem, String childTagName) */ public static Element uniqueImmediateChildByTagName(Element elem, String childTagName) throws DOMException { NodeList nl = getImmediateChildElementsByTagName(elem, childTagName); int len = nl.getLength(); if (DEBUG) DebugUtils.myAssert( len <= 1 , "There is more than one (" + len + ") child with tag name: " + childTagName + "!!!" ); return (len == 1 ? (Element) nl.item( 0 ) : null); } /** * @deprecated use Element.getAttribute(String val) */ public static String attrValFromElement(Element element, String attrName) throws DOMException { Attr attr = element.getAttributeNode( attrName ); return (attr == null ? null : attr.getValue()); } private DomParseUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/0000755000175000017500000000000010624366530016431 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/0000755000175000017500000000000010673162231017542 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/junit/0000755000175000017500000000000010673162231020673 5ustar godgod././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/junit/ThreadPerTaskAsynchronousRunnerJUnitTestCase.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/junit/ThreadPerTaskAsynchronousRunnerJUnitTestCas0000644000175000017500000001413110624366530031372 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async.junit; import junit.framework.*; import com.mchange.v2.async.*; public class ThreadPerTaskAsynchronousRunnerJUnitTestCase extends TestCase { ThreadPerTaskAsynchronousRunner runner; boolean no_go = true; int gone = 0; protected void setUp() { runner = new ThreadPerTaskAsynchronousRunner(5); } protected void tearDown() { runner.close(); go(); //get any interrupt ignorers going... } private synchronized void go() { no_go = false; this.notifyAll(); } public void testBasicBehavior() { try { DumbTask dt = new DumbTask(); for( int i = 0; i < 10; ++i ) runner.postRunnable( dt ); Thread.sleep(1000); // not strictly safe, but should be plenty of time to get our tasks to the wait loop... assertEquals( "running count should be 5", 5, runner.getRunningCount() ); assertEquals( "waiting count should be 5", 5, runner.getWaitingCount() ); go(); Thread.sleep(1000); // not strictly safe, but should be plenty of time to get our tasks to finish... assertEquals( "running should be done.", 0, runner.getRunningCount() ); assertEquals( "waiting should be done.", 0, runner.getWaitingCount() ); } catch (InterruptedException e) { e.printStackTrace(); fail("Unexpected InterruptedException: " + e); } } public void testBasicBehaviorFastNoSkipClose() { try { DumbTask dt = new DumbTask(); for( int i = 0; i < 10; ++i ) runner.postRunnable( dt ); runner.close( false ); Thread.sleep(1000); // not strictly safe, but should be plenty of time to get our tasks to the wait loop... assertEquals( "running count should be 5", 5, runner.getRunningCount() ); assertEquals( "waiting count should be 5", 5, runner.getWaitingCount() ); go(); Thread.sleep(1000); // not strictly safe, but should be plenty of time to get our tasks to finish... assertEquals( "running should be done.", 0, runner.getRunningCount() ); assertEquals( "waiting should be done.", 0, runner.getWaitingCount() ); assertTrue( runner.isDoneAndGone() ); } catch (InterruptedException e) { e.printStackTrace(); fail("Unexpected InterruptedException: " + e); } } public void testBasicBehaviorFastSkipClose() { try { DumbTask dt = new DumbTask(); for( int i = 0; i < 10; ++i ) runner.postRunnable( dt ); runner.close( true ); Thread.sleep(1000); // not strictly safe, but should be plenty of time to interrupt and be done assertTrue( runner.isDoneAndGone() ); } catch (InterruptedException e) { e.printStackTrace(); fail("Unexpected InterruptedException: " + e); } } public void testDeadlockCase() { try { runner.close(); //we need a different set up... runner = new ThreadPerTaskAsynchronousRunner(5, 1000); //interrupt tasks after 1 sec, consider deadlocked after ~3 secs.. DumbTask dt = new DumbTask( true ); for( int i = 0; i < 5; ++i ) runner.postRunnable( dt ); Thread.sleep(10000); // not strictly safe, but should be plenty of time to interrupt and be done assertEquals( "running should be done.", 0, runner.getRunningCount() ); } catch (InterruptedException e) { e.printStackTrace(); fail("Unexpected InterruptedException: " + e); } } public void testDeadlockWithPentUpTasks() { try { runner.close(); //we need a different set up... runner = new ThreadPerTaskAsynchronousRunner(5, 1000); //interrupt tasks after 1 sec, consider deadlocked after ~3 secs.. //Runnable r = new Runnable() { public synchronized void run() { while (true) { try { this.wait();} catch (Exception e) {} } } }; Runnable r = new DumbTask( true ); Runnable r2 = new Runnable() { public void run() { System.out.println("done."); } }; for( int i = 0; i < 5; ++i ) runner.postRunnable( r ); for( int i = 0; i < 5; ++i ) runner.postRunnable( r2 ); Thread.sleep(10000); // not strictly safe, but should be plenty of time to interrupt and be done assertEquals( "running should be done.", 0, runner.getRunningCount() ); } catch (InterruptedException e) { e.printStackTrace(); fail("Unexpected InterruptedException: " + e); } } class DumbTask implements Runnable { boolean ignore_interrupts; DumbTask() { this( false ); } DumbTask(boolean ignore_interrupts) { this.ignore_interrupts = ignore_interrupts; } public void run() { try { synchronized (ThreadPerTaskAsynchronousRunnerJUnitTestCase.this) { while (no_go) { try { ThreadPerTaskAsynchronousRunnerJUnitTestCase.this.wait(); } catch (InterruptedException e) { if (ignore_interrupts) System.err.println(this + ": interrupt ignored!"); else { e.fillInStackTrace(); throw e; } } } //System.err.println( ++gone ); ThreadPerTaskAsynchronousRunnerJUnitTestCase.this.notifyAll(); } } catch ( Exception e ) { e.printStackTrace(); } } } public static void main(String[] argv) { junit.textui.TestRunner.run( new TestSuite( ThreadPerTaskAsynchronousRunnerJUnitTestCase.class ) ); //junit.swingui.TestRunner.run( SqlUtilsJUnitTestCase.class ); //new SqlUtilsJUnitTestCase().testGoodDebugLoggingOfNestedExceptions(); } }././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/junit/ThreadPoolAsynchronousRunnerJUnitTestCase.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/junit/ThreadPoolAsynchronousRunnerJUnitTestCase.j0000644000175000017500000000610310624366527031335 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async.junit; import junit.framework.*; import com.mchange.v2.async.*; public class ThreadPoolAsynchronousRunnerJUnitTestCase extends TestCase { ThreadPoolAsynchronousRunner runner; boolean no_go = true; int gone = 0; protected void setUp() { runner = new ThreadPoolAsynchronousRunner( 3, true, 1000, 3 * 1000, 3 * 1000); } protected void tearDown() { runner.close(); go(); //get any interrupt ignorers going... } private synchronized void go() { no_go = false; this.notifyAll(); } public void testDeadlockCase() { try { DumbTask dt = new DumbTask( true ); for( int i = 0; i < 5; ++i ) runner.postRunnable( dt ); Thread.sleep(500); assertEquals("we should have three running tasks", 3, runner.getActiveCount() ); assertEquals("we should have two pending tasks", 2, runner.getPendingTaskCount() ); Thread.sleep(10000); // not strictly safe, but should be plenty of time to interrupt and be done } catch (InterruptedException e) { e.printStackTrace(); fail("Unexpected InterruptedException: " + e); } } class DumbTask implements Runnable { boolean ignore_interrupts; DumbTask() { this( false ); } DumbTask(boolean ignore_interrupts) { this.ignore_interrupts = ignore_interrupts; } public void run() { try { synchronized (ThreadPoolAsynchronousRunnerJUnitTestCase.this) { while (no_go) { try { ThreadPoolAsynchronousRunnerJUnitTestCase.this.wait(); } catch (InterruptedException e) { if (ignore_interrupts) System.err.println(this + ": interrupt ignored!"); else { e.fillInStackTrace(); throw e; } } } //System.err.println( ++gone ); ThreadPoolAsynchronousRunnerJUnitTestCase.this.notifyAll(); } } catch ( Exception e ) { e.printStackTrace(); } } } public static void main(String[] argv) { junit.textui.TestRunner.run( new TestSuite( ThreadPoolAsynchronousRunnerJUnitTestCase.class ) ); //junit.swingui.TestRunner.run( SqlUtilsJUnitTestCase.class ); //new SqlUtilsJUnitTestCase().testGoodDebugLoggingOfNestedExceptions(); } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/AsynchronousRunner.java0000644000175000017500000000365110624366530024303 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; import com.mchange.v1.util.ClosableResource; public interface AsynchronousRunner extends ClosableResource { public void postRunnable(Runnable r); /** * Finish with this AsynchronousRunner, and clean-up * any Threads or resources it may hold. * * @param skip_remaining_tasks Should be regarded as * a hint, not a guarantee. If true, pending, * not-yet-performed tasks will be skipped, * if possible. * Currently executing tasks may or * may not be interrupted. If false, all * previously scheduled tasks will be * completed prior to clean-up. The method * returns immediately regardless. */ public void close( boolean skip_remaining_tasks ); /** * Clean-up resources held by this asynchronous runner * as soon as possible. Remaining tasks are skipped if possible, * and any tasks executing when close() is called may * or may not be interrupted. Equivalent to close( true ). */ public void close(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/CarefulRunnableQueue.java0000644000175000017500000001514110624366527024476 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; import java.util.Collections; import java.util.List; import java.util.LinkedList; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.util.ResourceClosedException; public class CarefulRunnableQueue implements RunnableQueue, Queuable, StrandedTaskReporting { private final static MLogger logger = MLog.getLogger( CarefulRunnableQueue.class ); private List taskList = new LinkedList(); private TaskThread t = new TaskThread(); private boolean shutdown_on_interrupt; private boolean gentle_close_requested = false; private List strandedTasks = null; public CarefulRunnableQueue(boolean daemon, boolean shutdown_on_interrupt) { this.shutdown_on_interrupt = shutdown_on_interrupt; t.setDaemon( daemon ); t.start(); } public RunnableQueue asRunnableQueue() { return this; } public synchronized void postRunnable(Runnable r) { try { if (gentle_close_requested) throw new ResourceClosedException("Attempted to post a task to a closing " + "CarefulRunnableQueue."); taskList.add(r); this.notifyAll(); } catch (NullPointerException e) { //e.printStackTrace(); if (Debug.DEBUG) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "NullPointerException while posting Runnable.", e ); } if (taskList == null) throw new ResourceClosedException("Attempted to post a task to a CarefulRunnableQueue " + "which has been closed, or whose TaskThread has been " + "interrupted."); else throw e; } } public synchronized void close( boolean skip_remaining_tasks ) { if (skip_remaining_tasks) { t.safeStop(); t.interrupt(); } else gentle_close_requested = true; } public synchronized void close() { this.close( true ); } public synchronized List getStrandedTasks() { try { while (gentle_close_requested && taskList != null) this.wait(); return strandedTasks; } catch (InterruptedException e) { // very, very rare I think... // if necessary I'll try a more complex solution, but I don't think // it's worth it. //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, Thread.currentThread() + " interrupted while waiting for stranded tasks from CarefulRunnableQueue.", e ); throw new RuntimeException(Thread.currentThread() + " interrupted while waiting for stranded tasks from CarefulRunnableQueue."); } } private synchronized Runnable dequeueRunnable() { Runnable r = (Runnable) taskList.get(0); taskList.remove(0); return r; } private synchronized void awaitTask() throws InterruptedException { while (taskList.size() == 0) { if ( gentle_close_requested ) { t.safeStop(); // remember t == Thread.currentThread() t.interrupt(); } this.wait(); } } class TaskThread extends Thread { boolean should_stop = false; TaskThread() { super("CarefulRunnableQueue.TaskThread"); } public synchronized void safeStop() { should_stop = true; } private synchronized boolean shouldStop() { return should_stop; } public void run() { try { while (! shouldStop() ) { try { awaitTask(); Runnable r = dequeueRunnable(); try { r.run(); } catch (Exception e) { //System.err.println(this.getClass().getName() + " -- Unexpected exception in task!"); //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log(MLevel.WARNING, this.getClass().getName() + " -- Unexpected exception in task!", e); } } catch (InterruptedException e) { if (shutdown_on_interrupt) { CarefulRunnableQueue.this.close( false ); // if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED ) // System.err.println( this.toString() + // " interrupted. Shutting down after current tasks" + // " have completed." ); if ( logger.isLoggable( MLevel.INFO ) ) logger.info(this.toString() + " interrupted. Shutting down after current tasks" + " have completed." ); } else { // if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED ) // System.err.println( this.toString() + // " received interrupt. IGNORING." ); logger.info(this.toString() + " received interrupt. IGNORING." ); } } } } // catch (ThreadDeath td) //DEBUG ONLY -- remove soon, swaldman 08-Jun-2003 // { // System.err.print("c3p0-TRAVIS: "); // System.err.println(this.getName() + ": Some bastard used the deprecated stop() method to kill me!!!!"); // td.printStackTrace(); // throw td; // } // catch (Throwable t) //DEBUG ONLY -- remove soon, swaldman 08-Jun-2003 // { // System.err.print("c3p0-TRAVIS: "); // System.err.println(this.getName() + ": Some unexpected Throwable occurred and killed me!!!!"); // t.printStackTrace(); // if (t instanceof Error) // throw (Error) t; // else if (t instanceof RuntimeException) // throw (RuntimeException) t; // else // throw new InternalError( t.toString() ); //we don't expect any checked Exceptions can happen here. // } finally { synchronized ( CarefulRunnableQueue.this ) { strandedTasks = Collections.unmodifiableList( taskList ); taskList = null; t = null; CarefulRunnableQueue.this.notifyAll(); //if anyone is waiting for stranded tasks... //System.err.print("c3p0-TRAVIS: "); //System.err.println("TaskThread dead. strandedTasks: " + strandedTasks); } } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/Queuable.java0000644000175000017500000000173510624366530022162 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; public interface Queuable extends AsynchronousRunner { public RunnableQueue asRunnableQueue(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/RoundRobinAsynchronousRunner.java0000644000175000017500000001107010624366530026277 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; import com.mchange.v2.log.*; import com.mchange.v2.util.ResourceClosedException; /** * A class that provides for effecient asynchronous execution * of multiple tasks that may block, but that do not contend * for the same locks. The order in which tasks will be executed * is not guaranteed. */ public class RoundRobinAsynchronousRunner implements AsynchronousRunner, Queuable { private final static MLogger logger = MLog.getLogger( RoundRobinAsynchronousRunner.class ); //MT: unchanging, individual elements are thread-safe final RunnableQueue[] rqs; //MT: protected by this' lock int task_turn = 0; //MT: protected by this' lock int view_turn = 0; public RoundRobinAsynchronousRunner( int num_threads, boolean daemon ) { this.rqs = new RunnableQueue[ num_threads ]; for(int i = 0; i < num_threads; ++i) rqs[i] = new CarefulRunnableQueue( daemon, false ); } public synchronized void postRunnable(Runnable r) { try { int index = task_turn; task_turn = (task_turn + 1) % rqs.length; rqs[index].postRunnable( r ); /* we do this "long-hand" to avoid bad fragility if an exception */ /* occurs in postRunnable, causing the mod step of the original */ /* concise code to get skipped, and leading (if */ /* task_turn == rqs.length - 1 when the exception occurs) to an */ /* endless cascade of ArrayIndexOutOfBoundsExceptions. */ /* we might alternatively have just put the mod step into a */ /* finally block, but that's too fancy. */ /* thanks to Travis Reeder for reporting this problem. */ //rqs[task_turn++].postRunnable( r ); //task_turn %= rqs.length; } catch ( NullPointerException e ) { //e.printStackTrace(); if ( Debug.DEBUG ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "NullPointerException while posting Runnable -- Probably we're closed.", e ); } this.close( true ); throw new ResourceClosedException("Attempted to use a RoundRobinAsynchronousRunner in a closed or broken state."); } } public synchronized RunnableQueue asRunnableQueue() { try { int index = view_turn; view_turn = (view_turn + 1) % rqs.length; return new RunnableQueueView( index ); /* same explanation as above */ //RunnableQueue out = new RunnableQueueView( view_turn++ ); //view_turn %= rqs.length; //return out; } catch ( NullPointerException e ) { //e.printStackTrace(); if ( Debug.DEBUG ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "NullPointerException in asRunnableQueue() -- Probably we're closed.", e ); } this.close( true ); throw new ResourceClosedException("Attempted to use a RoundRobinAsynchronousRunner in a closed or broken state."); } } public synchronized void close( boolean skip_remaining_tasks ) { for (int i = 0, len = rqs.length; i < len; ++i) { attemptClose( rqs[i], skip_remaining_tasks ); rqs[i] = null; } } public void close() { close( true ); } static void attemptClose(RunnableQueue rq, boolean skip_remaining_tasks) { try { rq.close( skip_remaining_tasks ); } catch ( Exception e ) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "RunnableQueue close FAILED.", e ); } } class RunnableQueueView implements RunnableQueue { final int rq_num; RunnableQueueView( int rq_num ) { this.rq_num = rq_num; } public void postRunnable(Runnable r) { rqs[ rq_num ].postRunnable( r ); } public void close( boolean skip_remaining_tasks ) { } public void close() { /* ignore */ } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/RunnableQueue.java0000644000175000017500000000206110624366530023163 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; /** * RunnableQueues guarantee that tasks will be * executed in order, where other AsynchronousRunners * may not. */ public interface RunnableQueue extends AsynchronousRunner {} c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/StrandedTaskReporting.java0000644000175000017500000000272610624366527024707 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; import java.util.List; public interface StrandedTaskReporting { /** * makes available any tasks that were unperformed when * this AsynchronousRunner was closed, either explicitly * using close() or close( true ), or implicitly because * some failure or corruption killed the Object (most likely * a Thread interruption. * * @return null if the AsynchronousRunner is still alive, a List * of Runnables otherwise, which will be empty only if all tasks * were performed before the AsynchronousRunner shut down. */ public List getStrandedTasks(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/ThreadPerTaskAsynchronousRunner.java0000644000175000017500000001626610624366527026741 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; import java.util.*; import com.mchange.v2.log.*; import com.mchange.v2.util.ResourceClosedException; public class ThreadPerTaskAsynchronousRunner implements AsynchronousRunner { final static int PRESUME_DEADLOCKED_MULTIPLE = 3; //after three times the interrupt period, we presume deadlock final static MLogger logger = MLog.getLogger( ThreadPerTaskAsynchronousRunner.class ); //MT: unchanged post-ctor final int max_task_threads; final long interrupt_task_delay; //MT: protected by this' lock LinkedList queue = new LinkedList(); ArrayList running = new ArrayList(); //as a Collection -- duplicate-accepting-ness is important, order is not ArrayList deadlockSnapshot = null; boolean still_open = true; //MT: thread-safe and not reassigned post-ctor Thread dispatchThread = new DispatchThread(); Timer interruptAndDeadlockTimer; public ThreadPerTaskAsynchronousRunner(int max_task_threads) { this( max_task_threads, 0); } public ThreadPerTaskAsynchronousRunner(int max_task_threads, long interrupt_task_delay) { this.max_task_threads = max_task_threads; this.interrupt_task_delay = interrupt_task_delay; if ( hasIdTimer() ) { interruptAndDeadlockTimer = new Timer( true ); TimerTask deadlockChecker = new TimerTask() { public void run() { checkForDeadlock(); } }; long delay = interrupt_task_delay * PRESUME_DEADLOCKED_MULTIPLE; interruptAndDeadlockTimer.schedule(deadlockChecker, delay, delay); } dispatchThread.start(); } private boolean hasIdTimer() { return (interrupt_task_delay > 0); } public synchronized void postRunnable(Runnable r) { if ( still_open ) { queue.add( r ); this.notifyAll(); } else throw new ResourceClosedException("Attempted to use a ThreadPerTaskAsynchronousRunner in a closed or broken state."); } public void close() { close( true ); } public synchronized void close( boolean skip_remaining_tasks ) { if ( still_open ) { this.still_open = false; if (skip_remaining_tasks) { queue.clear(); for (Iterator ii = running.iterator(); ii.hasNext(); ) ((Thread) ii.next()).interrupt(); closeThreadResources(); } } } public synchronized int getRunningCount() { return running.size(); } public synchronized Collection getRunningTasks() { return (Collection) running.clone(); } public synchronized int getWaitingCount() { return queue.size(); } public synchronized Collection getWaitingTasks() { return (Collection) queue.clone(); } public synchronized boolean isClosed() { return !still_open; } public synchronized boolean isDoneAndGone() { return (!dispatchThread.isAlive() && running.isEmpty() && interruptAndDeadlockTimer == null); } private synchronized void acknowledgeComplete(TaskThread tt) { if (! tt.isCompleted()) { running.remove( tt ); tt.markCompleted(); ThreadPerTaskAsynchronousRunner.this.notifyAll(); if (! still_open && queue.isEmpty() && running.isEmpty()) closeThreadResources(); } } private synchronized void checkForDeadlock() { if (deadlockSnapshot == null) { if (running.size() == max_task_threads) deadlockSnapshot = (ArrayList) running.clone(); } else if (running.size() < max_task_threads) deadlockSnapshot = null; else if (deadlockSnapshot.equals( running )) //deadlock! { if (logger.isLoggable(MLevel.WARNING)) { StringBuffer warningMsg = new StringBuffer(1024); warningMsg.append("APPARENT DEADLOCK! ("); warningMsg.append( this ); warningMsg.append(") Deadlocked threads (unresponsive to interrupt()) are being set aside as hopeless and up to "); warningMsg.append( max_task_threads ); warningMsg.append(" may now be spawned for new tasks. If tasks continue to deadlock, you may run out of memory. Deadlocked task list: "); for (int i = 0, len = deadlockSnapshot.size(); i < len; ++i) { if (i != 0) warningMsg.append(", "); warningMsg.append( ((TaskThread) deadlockSnapshot.get(i)).getTask() ); } logger.log(MLevel.WARNING, warningMsg.toString()); } // note "complete" here means from the perspective of the async runner, as complete // as it will ever be, since the task is presumed hopelessly hung for (int i = 0, len = deadlockSnapshot.size(); i < len; ++i) acknowledgeComplete( (TaskThread) deadlockSnapshot.get(i) ); deadlockSnapshot = null; } else deadlockSnapshot = (ArrayList) running.clone(); } private void closeThreadResources() { if (interruptAndDeadlockTimer != null) { interruptAndDeadlockTimer.cancel(); interruptAndDeadlockTimer = null; } dispatchThread.interrupt(); } class DispatchThread extends Thread { DispatchThread() { super( "Dispatch-Thread-for-" + ThreadPerTaskAsynchronousRunner.this ); } public void run() { synchronized (ThreadPerTaskAsynchronousRunner.this) { try { while (true) { while (queue.isEmpty() || running.size() == max_task_threads) ThreadPerTaskAsynchronousRunner.this.wait(); Runnable next = (Runnable) queue.remove(0); TaskThread doer = new TaskThread( next ); doer.start(); running.add( doer ); } } catch (InterruptedException e) { if (still_open) //we're not closed... { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, this.getName() + " unexpectedly interrupted! Shutting down!" ); close( false ); } } } } } class TaskThread extends Thread { //MT: post-ctor constant Runnable r; //MT: protected by this' lock boolean completed = false; TaskThread( Runnable r ) { super( "Task-Thread-for-" + ThreadPerTaskAsynchronousRunner.this ); this.r = r; } Runnable getTask() { return r; } synchronized void markCompleted() { completed = true; } synchronized boolean isCompleted() { return completed; } public void run() { try { if (hasIdTimer()) { TimerTask interruptTask = new TimerTask() { public void run() { TaskThread.this.interrupt(); } }; interruptAndDeadlockTimer.schedule( interruptTask , interrupt_task_delay ); } r.run(); } finally { acknowledgeComplete( this ); } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/async/ThreadPoolAsynchronousRunner.java0000644000175000017500000006433310624366527026277 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.async; import java.util.*; import com.mchange.v2.log.*; import java.io.StringWriter; import java.io.PrintWriter; import java.io.IOException; import java.lang.reflect.Method; import com.mchange.v2.io.IndentedWriter; import com.mchange.v2.util.ResourceClosedException; public final class ThreadPoolAsynchronousRunner implements AsynchronousRunner { final static MLogger logger = MLog.getLogger( ThreadPoolAsynchronousRunner.class ); final static int POLL_FOR_STOP_INTERVAL = 5000; //milliseconds final static int DFLT_DEADLOCK_DETECTOR_INTERVAL = 10000; //milliseconds final static int DFLT_INTERRUPT_DELAY_AFTER_APPARENT_DEADLOCK = 60000; //milliseconds final static int DFLT_MAX_INDIVIDUAL_TASK_TIME = 0; //milliseconds, <= 0 means don't enforce a max task time final static int DFLT_MAX_EMERGENCY_THREADS = 10; int deadlock_detector_interval; int interrupt_delay_after_apparent_deadlock; int max_individual_task_time; int num_threads; boolean daemon; HashSet managed; HashSet available; LinkedList pendingTasks; Timer myTimer; boolean should_cancel_timer; TimerTask deadlockDetector = new DeadlockDetector(); TimerTask replacedThreadInterruptor = null; Map stoppedThreadsToStopDates = new HashMap(); private ThreadPoolAsynchronousRunner( int num_threads, boolean daemon, int max_individual_task_time, int deadlock_detector_interval, int interrupt_delay_after_apparent_deadlock, Timer myTimer, boolean should_cancel_timer ) { this.num_threads = num_threads; this.daemon = daemon; this.max_individual_task_time = max_individual_task_time; this.deadlock_detector_interval = deadlock_detector_interval; this.interrupt_delay_after_apparent_deadlock = interrupt_delay_after_apparent_deadlock; this.myTimer = myTimer; this.should_cancel_timer = should_cancel_timer; recreateThreadsAndTasks(); myTimer.schedule( deadlockDetector, deadlock_detector_interval, deadlock_detector_interval ); } public ThreadPoolAsynchronousRunner( int num_threads, boolean daemon, int max_individual_task_time, int deadlock_detector_interval, int interrupt_delay_after_apparent_deadlock, Timer myTimer ) { this( num_threads, daemon, max_individual_task_time, deadlock_detector_interval, interrupt_delay_after_apparent_deadlock, myTimer, false ); } public ThreadPoolAsynchronousRunner( int num_threads, boolean daemon, int max_individual_task_time, int deadlock_detector_interval, int interrupt_delay_after_apparent_deadlock ) { this( num_threads, daemon, max_individual_task_time, deadlock_detector_interval, interrupt_delay_after_apparent_deadlock, new Timer( true ), true ); } public ThreadPoolAsynchronousRunner( int num_threads, boolean daemon, Timer sharedTimer ) { this( num_threads, daemon, DFLT_MAX_INDIVIDUAL_TASK_TIME, DFLT_DEADLOCK_DETECTOR_INTERVAL, DFLT_INTERRUPT_DELAY_AFTER_APPARENT_DEADLOCK, sharedTimer, false ); } public ThreadPoolAsynchronousRunner( int num_threads, boolean daemon ) { this( num_threads, daemon, DFLT_MAX_INDIVIDUAL_TASK_TIME, DFLT_DEADLOCK_DETECTOR_INTERVAL, DFLT_INTERRUPT_DELAY_AFTER_APPARENT_DEADLOCK, new Timer( true ), true ); } public synchronized void postRunnable(Runnable r) { try { pendingTasks.add( r ); this.notifyAll(); } catch ( NullPointerException e ) { //e.printStackTrace(); if ( Debug.DEBUG ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "NullPointerException while posting Runnable -- Probably we're closed.", e ); } throw new ResourceClosedException("Attempted to use a ThreadPoolAsynchronousRunner in a closed or broken state."); } } public synchronized int getThreadCount() { return managed.size(); } public void close( boolean skip_remaining_tasks ) { synchronized ( this ) { if (managed == null) return; deadlockDetector.cancel(); //replacedThreadInterruptor.cancel(); if (should_cancel_timer) myTimer.cancel(); myTimer = null; for (Iterator ii = managed.iterator(); ii.hasNext(); ) { PoolThread stopMe = (PoolThread) ii.next(); stopMe.gentleStop(); if (skip_remaining_tasks) stopMe.interrupt(); } managed = null; if (!skip_remaining_tasks) { for (Iterator ii = pendingTasks.iterator(); ii.hasNext(); ) { Runnable r = (Runnable) ii.next(); new Thread(r).start(); ii.remove(); } } available = null; pendingTasks = null; } } public void close() { close( true ); } public synchronized int getActiveCount() { return managed.size() - available.size(); } public synchronized int getIdleCount() { return available.size(); } public synchronized int getPendingTaskCount() { return pendingTasks.size(); } public synchronized String getStatus() { /* StringBuffer sb = new StringBuffer( 512 ); sb.append( this.toString() ); sb.append( ' ' ); appendStatusString( sb ); return sb.toString(); */ return getMultiLineStatusString(); } // done reflectively for jdk 1.3/1.4 compatability public synchronized String getStackTraces() { return getStackTraces(0); } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private String getStackTraces(int initial_indent) { if (managed == null) return null; try { Method m = Thread.class.getMethod("getStackTrace", null); StringWriter sw = new StringWriter(2048); IndentedWriter iw = new IndentedWriter( sw ); for (int i = 0; i < initial_indent; ++i) iw.upIndent(); for (Iterator ii = managed.iterator(); ii.hasNext(); ) { Object poolThread = ii.next(); Object[] stackTraces = (Object[]) m.invoke( poolThread, null ); iw.println( poolThread ); iw.upIndent(); for (int i = 0, len = stackTraces.length; i < len; ++i) iw.println( stackTraces[i] ); iw.downIndent(); } for (int i = 0; i < initial_indent; ++i) iw.downIndent(); iw.flush(); // useless, but I feel better String out = sw.toString(); iw.close(); // useless, but I feel better; return out; } catch (NoSuchMethodException e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.fine( this + ": strack traces unavailable because this is a pre-Java 1.5 VM."); return null; } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, this + ": An Exception occurred while trying to extract PoolThread stack traces.", e); return null; } } public synchronized String getMultiLineStatusString() { return this.getMultiLineStatusString(0); } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private String getMultiLineStatusString(int initial_indent) { try { StringWriter sw = new StringWriter(2048); IndentedWriter iw = new IndentedWriter( sw ); for (int i = 0; i < initial_indent; ++i) iw.upIndent(); if (managed == null) { iw.print("["); iw.print( this ); iw.println(" closed.]"); } else { HashSet active = (HashSet) managed.clone(); active.removeAll( available ); iw.print("Managed Threads: "); iw.println( managed.size() ); iw.print("Active Threads: "); iw.println( active.size() ); iw.println("Active Tasks: "); iw.upIndent(); for (Iterator ii = active.iterator(); ii.hasNext(); ) { PoolThread pt = (PoolThread) ii.next(); iw.print( pt.getCurrentTask() ); iw.print( " ("); iw.print( pt.getName() ); iw.println(')'); } iw.downIndent(); iw.println("Pending Tasks: "); iw.upIndent(); for (int i = 0, len = pendingTasks.size(); i < len; ++i) iw.println( pendingTasks.get( i ) ); iw.downIndent(); } for (int i = 0; i < initial_indent; ++i) iw.downIndent(); iw.flush(); // useless, but I feel better String out = sw.toString(); iw.close(); // useless, but I feel better; return out; } catch (IOException e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Huh? An IOException when working with a StringWriter?!?", e); throw new RuntimeException("Huh? An IOException when working with a StringWriter?!? " + e); } } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private void appendStatusString( StringBuffer sb ) { if (managed == null) sb.append( "[closed]" ); else { HashSet active = (HashSet) managed.clone(); active.removeAll( available ); sb.append("[num_managed_threads: "); sb.append( managed.size() ); sb.append(", num_active: "); sb.append( active.size() ); sb.append("; activeTasks: "); boolean first = true; for (Iterator ii = active.iterator(); ii.hasNext(); ) { if (first) first = false; else sb.append(", "); PoolThread pt = (PoolThread) ii.next(); sb.append( pt.getCurrentTask() ); sb.append( " ("); sb.append( pt.getName() ); sb.append(')'); } sb.append("; pendingTasks: "); for (int i = 0, len = pendingTasks.size(); i < len; ++i) { if (i != 0) sb.append(", "); sb.append( pendingTasks.get( i ) ); } sb.append(']'); } } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock (or is ctor) private void recreateThreadsAndTasks() { if ( this.managed != null) { Date aboutNow = new Date(); for (Iterator ii = managed.iterator(); ii.hasNext(); ) { PoolThread pt = (PoolThread) ii.next(); pt.gentleStop(); stoppedThreadsToStopDates.put( pt, aboutNow ); ensureReplacedThreadsProcessing(); } } this.managed = new HashSet(); this.available = new HashSet(); this.pendingTasks = new LinkedList(); for (int i = 0; i < num_threads; ++i) { Thread t = new PoolThread(i, daemon); managed.add( t ); available.add( t ); t.start(); } } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private void processReplacedThreads() { long about_now = System.currentTimeMillis(); for (Iterator ii = stoppedThreadsToStopDates.keySet().iterator(); ii.hasNext(); ) { PoolThread pt = (PoolThread) ii.next(); if (! pt.isAlive()) ii.remove(); else { Date d = (Date) stoppedThreadsToStopDates.get( pt ); if ((about_now - d.getTime()) > interrupt_delay_after_apparent_deadlock) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Task " + pt.getCurrentTask() + " (in deadlocked PoolThread) failed to complete in maximum time " + interrupt_delay_after_apparent_deadlock + "ms. Trying interrupt()."); pt.interrupt(); ii.remove(); } //else keep waiting... } if (stoppedThreadsToStopDates.isEmpty()) stopReplacedThreadsProcessing(); } } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private void ensureReplacedThreadsProcessing() { if (replacedThreadInterruptor == null) { if (logger.isLoggable( MLevel.FINE )) logger.fine("Apparently some threads have been replaced. Replacement thread processing enabled."); this.replacedThreadInterruptor = new ReplacedThreadInterruptor(); int replacedThreadProcessDelay = interrupt_delay_after_apparent_deadlock / 4; myTimer.schedule( replacedThreadInterruptor, replacedThreadProcessDelay, replacedThreadProcessDelay ); } } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private void stopReplacedThreadsProcessing() { if (this.replacedThreadInterruptor != null) { this.replacedThreadInterruptor.cancel(); this.replacedThreadInterruptor = null; if (logger.isLoggable( MLevel.FINE )) logger.fine("Apparently all replaced threads have either completed their tasks or been interrupted(). " + "Replacement thread processing cancelled."); } } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock private void shuttingDown( PoolThread pt ) { if (managed != null && managed.contains( pt )) //we are not closed, and this was a thread in the current pool, not a replaced thread { managed.remove( pt ); available.remove( pt ); PoolThread replacement = new PoolThread( pt.getIndex(), daemon ); managed.add( replacement ); available.add( replacement ); replacement.start(); } } class PoolThread extends Thread { // protected by ThreadPoolAsynchronousRunner.this' lock Runnable currentTask; // protected by ThreadPoolAsynchronousRunner.this' lock boolean should_stop; // post ctor immutable int index; // not shared. only accessed by the PoolThread itself TimerTask maxIndividualTaskTimeEnforcer = null; PoolThread(int index, boolean daemon) { this.setName( this.getClass().getName() + "-#" + index); this.setDaemon( daemon ); this.index = index; } public int getIndex() { return index; } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock void gentleStop() { should_stop = true; } // protected by ThreadPoolAsynchronousRunner.this' lock // BE SURE CALLER OWNS ThreadPoolAsynchronousRunner.this' lock Runnable getCurrentTask() { return currentTask; } // no need to sync. data not shared private /* synchronized */ void setMaxIndividualTaskTimeEnforcer() { this.maxIndividualTaskTimeEnforcer = new MaxIndividualTaskTimeEnforcer( this ); myTimer.schedule( maxIndividualTaskTimeEnforcer, max_individual_task_time ); } // no need to sync. data not shared private /* synchronized */ void cancelMaxIndividualTaskTimeEnforcer() { this.maxIndividualTaskTimeEnforcer.cancel(); this.maxIndividualTaskTimeEnforcer = null; } public void run() { try { thread_loop: while (true) { Runnable myTask; synchronized ( ThreadPoolAsynchronousRunner.this ) { while ( !should_stop && pendingTasks.size() == 0 ) ThreadPoolAsynchronousRunner.this.wait( POLL_FOR_STOP_INTERVAL ); if (should_stop) break thread_loop; if (! available.remove( this ) ) throw new InternalError("An unavailable PoolThread tried to check itself out!!!"); myTask = (Runnable) pendingTasks.remove(0); currentTask = myTask; } try { if (max_individual_task_time > 0) setMaxIndividualTaskTimeEnforcer(); myTask.run(); } catch ( RuntimeException e ) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log(MLevel.WARNING, this + " -- caught unexpected Exception while executing posted task.", e); //e.printStackTrace(); } finally { if ( maxIndividualTaskTimeEnforcer != null ) cancelMaxIndividualTaskTimeEnforcer(); synchronized ( ThreadPoolAsynchronousRunner.this ) { if (should_stop) break thread_loop; if ( available != null && ! available.add( this ) ) throw new InternalError("An apparently available PoolThread tried to check itself in!!!"); currentTask = null; } } } } catch ( InterruptedException exc ) { // if ( Debug.TRACE > Debug.TRACE_NONE ) // System.err.println(this + " interrupted. Shutting down."); if ( Debug.TRACE > Debug.TRACE_NONE && logger.isLoggable( MLevel.FINE ) ) logger.fine(this + " interrupted. Shutting down."); } synchronized ( ThreadPoolAsynchronousRunner.this ) { ThreadPoolAsynchronousRunner.this.shuttingDown( this ); } } } class DeadlockDetector extends TimerTask { LinkedList last = null; LinkedList current = null; public void run() { boolean run_stray_tasks = false; synchronized ( ThreadPoolAsynchronousRunner.this ) { if (pendingTasks.size() == 0) { last = null; return; } current = (LinkedList) pendingTasks.clone(); if ( current.equals( last ) ) { //System.err.println(this + " -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!"); if ( logger.isLoggable( MLevel.WARNING ) ) { logger.warning(this + " -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!"); StringWriter sw = new StringWriter( 4096 ); PrintWriter pw = new PrintWriter( sw ); //StringBuffer sb = new StringBuffer( 512 ); //appendStatusString( sb ); //System.err.println( sb.toString() ); pw.print( this ); pw.println( " -- APPARENT DEADLOCK!!! Complete Status: "); pw.print( ThreadPoolAsynchronousRunner.this.getMultiLineStatusString( 1 ) ); pw.println("Pool thread stack traces:"); String stackTraces = getStackTraces( 1 ); if (stackTraces == null) pw.println("\t[Stack traces of deadlocked task threads not available.]"); else pw.println( stackTraces ); pw.flush(); //superfluous, but I feel better logger.warning( sw.toString() ); pw.close(); //superfluous, but I feel better } recreateThreadsAndTasks(); run_stray_tasks = true; } } if (run_stray_tasks) { AsynchronousRunner ar = new ThreadPerTaskAsynchronousRunner( DFLT_MAX_EMERGENCY_THREADS, max_individual_task_time ); for ( Iterator ii = current.iterator(); ii.hasNext(); ) ar.postRunnable( (Runnable) ii.next() ); ar.close( false ); //tell the emergency runner to close itself when its tasks are complete last = null; } else last = current; // under some circumstances, these lists seem to hold onto a lot of memory... presumably this // is when long pending task lists build up for some reason... nevertheless, let's dereference // things as soon as possible. [Thanks to Venkatesh Seetharamaiah for calling attention to this // issue, and for documenting the source of object retention.] current = null; } } class MaxIndividualTaskTimeEnforcer extends TimerTask { PoolThread pt; Thread interruptMe; String threadStr; String fixedTaskStr; MaxIndividualTaskTimeEnforcer(PoolThread pt) { this.pt = pt; this.interruptMe = pt; this.threadStr = pt.toString(); this.fixedTaskStr = null; } MaxIndividualTaskTimeEnforcer(Thread interruptMe, String threadStr, String fixedTaskStr) { this.pt = null; this.interruptMe = interruptMe; this.threadStr = threadStr; this.fixedTaskStr = fixedTaskStr; } public void run() { String taskStr; if (fixedTaskStr != null) taskStr = fixedTaskStr; else if (pt != null) { synchronized (ThreadPoolAsynchronousRunner.this) { taskStr = String.valueOf( pt.getCurrentTask() ); } } else taskStr = "Unknown task?!"; if (logger.isLoggable( MLevel.WARNING )) logger.warning("A task has exceeded the maximum allowable task time. Will interrupt() thread [" + threadStr + "], with current task: " + taskStr); interruptMe.interrupt(); if (logger.isLoggable( MLevel.WARNING )) logger.warning("Thread [" + threadStr + "] interrupted."); } } //not currently used... private void runInEmergencyThread( final Runnable r ) { final Thread t = new Thread( r ); t.start(); if (max_individual_task_time > 0) { TimerTask maxIndividualTaskTimeEnforcer = new MaxIndividualTaskTimeEnforcer(t, t + " [One-off emergency thread!!!]", r.toString()); myTimer.schedule( maxIndividualTaskTimeEnforcer, max_individual_task_time ); } } class ReplacedThreadInterruptor extends TimerTask { public void run() { synchronized (ThreadPoolAsynchronousRunner.this) { processReplacedThreads(); } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/beans/0000755000175000017500000000000010673162231017515 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/beans/BeansUtils.java0000644000175000017500000005156010624366530022444 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.beans; import java.beans.*; import java.lang.reflect.*; import java.util.*; import com.mchange.v2.log.*; import com.mchange.v2.lang.Coerce; public final class BeansUtils { final static MLogger logger = MLog.getLogger( BeansUtils.class ); final static Object[] EMPTY_ARGS = new Object[0]; public static PropertyEditor findPropertyEditor( PropertyDescriptor pd ) { PropertyEditor out = null; Class editorClass = null; try { editorClass = pd.getPropertyEditorClass(); if (editorClass != null) out = (PropertyEditor) editorClass.newInstance(); } catch (Exception e) { // e.printStackTrace(); // System.err.println("WARNING: Bad property editor class " + editorClass.getName() + // " registered for property " + pd.getName()); if (logger.isLoggable( MLevel.WARNING ) ) logger.log(MLevel.WARNING, "Bad property editor class " + editorClass.getName() + " registered for property " + pd.getName(), e); } if ( out == null ) out = PropertyEditorManager.findEditor( pd.getPropertyType() ); return out; } public static boolean equalsByAccessibleProperties( Object bean0, Object bean1 ) throws IntrospectionException { return equalsByAccessibleProperties( bean0, bean1, Collections.EMPTY_SET ); } public static boolean equalsByAccessibleProperties( Object bean0, Object bean1, Collection ignoreProps ) throws IntrospectionException { Map m0 = new HashMap(); Map m1 = new HashMap(); extractAccessiblePropertiesToMap( m0, bean0, ignoreProps ); extractAccessiblePropertiesToMap( m1, bean1, ignoreProps ); //System.err.println("Map0 -> " + m0); //System.err.println("Map1 -> " + m1); return m0.equals(m1); } public static void overwriteAccessibleProperties( Object sourceBean, Object destBean ) throws IntrospectionException { overwriteAccessibleProperties( sourceBean, destBean, Collections.EMPTY_SET ); } public static void overwriteAccessibleProperties( Object sourceBean, Object destBean, Collection ignoreProps ) throws IntrospectionException { try { BeanInfo beanInfo = Introspector.getBeanInfo( sourceBean.getClass(), Object.class ); //so we don't see message about getClass() PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for( int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; if ( ignoreProps.contains( pd.getName() ) ) continue; Method getter = pd.getReadMethod(); Method setter = pd.getWriteMethod(); if ( getter == null || setter == null ) { if ( pd instanceof IndexedPropertyDescriptor ) { // System.err.println("WARNING: BeansUtils.overwriteAccessibleProperties() does not"); // System.err.println("support indexed properties that do not provide single-valued"); // System.err.println("array getters and setters! [The indexed methods provide no means"); // System.err.println("of modifying the size of the array in the destination bean if"); // System.err.println("it does not match the source.]"); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning("BeansUtils.overwriteAccessibleProperties() does not" + " support indexed properties that do not provide single-valued" + " array getters and setters! [The indexed methods provide no means" + " of modifying the size of the array in the destination bean if" + " it does not match the source.]"); } //System.err.println("Property inaccessible for overwriting: " + pd.getName()); if (logger.isLoggable( MLevel.INFO )) logger.info("Property inaccessible for overwriting: " + pd.getName()); } else { Object value = getter.invoke( sourceBean, EMPTY_ARGS ); setter.invoke( destBean, new Object[] { value } ); } } } catch ( IntrospectionException e ) { throw e; } catch ( Exception e ) { //e.printStackTrace(); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "Converting exception to throwable IntrospectionException" ); throw new IntrospectionException( e.getMessage() ); } } public static void overwriteAccessiblePropertiesFromMap( Map sourceMap, Object destBean, boolean skip_nulls ) throws IntrospectionException { overwriteAccessiblePropertiesFromMap( sourceMap, destBean, skip_nulls, Collections.EMPTY_SET ); } public static void overwriteAccessiblePropertiesFromMap( Map sourceMap, Object destBean, boolean skip_nulls, Collection ignoreProps ) throws IntrospectionException { overwriteAccessiblePropertiesFromMap( sourceMap, destBean, skip_nulls, ignoreProps, false, MLevel.WARNING, MLevel.WARNING, true); } public static void overwriteAccessiblePropertiesFromMap( Map sourceMap, Object destBean, boolean skip_nulls, Collection ignoreProps, boolean coerce_strings, MLevel cantWriteLevel, MLevel cantCoerceLevel, boolean die_on_one_prop_failure) throws IntrospectionException { if (cantWriteLevel == null) cantWriteLevel = MLevel.WARNING; if (cantCoerceLevel == null) cantCoerceLevel = MLevel.WARNING; Set sourceMapProps = sourceMap.keySet(); String propName = null; BeanInfo beanInfo = Introspector.getBeanInfo( destBean.getClass(), Object.class ); //so we don't see message about getClass() PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); //System.err.println("ignoreProps: " + ignoreProps ); for( int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; propName = pd.getName(); if (! sourceMapProps.contains( propName )) continue; if ( ignoreProps != null && ignoreProps.contains( propName ) ) { //System.err.println("ignoring: " + propName); continue; } //else // System.err.println("not ignoring: " + propName); Object propVal = sourceMap.get( propName ); if (propVal == null) { if (skip_nulls) continue; //do we need to worry about primitives here? } Method setter = pd.getWriteMethod(); boolean rethrow = false; Class propType = pd.getPropertyType();; // try // { if ( setter == null ) { if ( pd instanceof IndexedPropertyDescriptor ) { if ( logger.isLoggable( MLevel.FINER ) ) logger.finer("BeansUtils.overwriteAccessiblePropertiesFromMap() does not" + " support indexed properties that do not provide single-valued" + " array getters and setters! [The indexed methods provide no means" + " of modifying the size of the array in the destination bean if" + " it does not match the source.]"); } if ( logger.isLoggable( cantWriteLevel )) { String msg = "Property inaccessible for overwriting: " + propName; logger.log( cantWriteLevel, msg ); if (die_on_one_prop_failure) { rethrow = true; throw new IntrospectionException( msg ); } } } else { if (coerce_strings && propVal != null && propVal.getClass() == String.class && (propType = pd.getPropertyType()) != String.class && Coerce.canCoerce( propType )) { Object coercedPropVal; try { coercedPropVal = Coerce.toObject( (String) propVal, propType ); //System.err.println(propName + "-> coercedPropVal: " + coercedPropVal); setter.invoke( destBean, new Object[] { coercedPropVal } ); } catch (IllegalArgumentException e) { // thrown by Coerce.toObject() // recall that NumberFormatException inherits from IllegalArgumentException String msg = "Failed to coerce property: " + propName + " [propVal: " + propVal + "; propType: " + propType + "]"; if ( logger.isLoggable( cantCoerceLevel ) ) logger.log( cantCoerceLevel, msg, e ); if (die_on_one_prop_failure) { rethrow = true; throw new IntrospectionException( msg ); } } catch (Exception e) { String msg = "Failed to set property: " + propName + " [propVal: " + propVal + "; propType: " + propType + "]"; if ( logger.isLoggable( cantWriteLevel ) ) logger.log( cantWriteLevel, msg, e ); if (die_on_one_prop_failure) { rethrow = true; throw new IntrospectionException( msg ); } } } else { try { //System.err.println("invoking method: " + setter); setter.invoke( destBean, new Object[] { propVal } ); } catch (Exception e) { String msg = "Failed to set property: " + propName + " [propVal: " + propVal + "; propType: " + propType + "]"; if ( logger.isLoggable( cantWriteLevel ) ) logger.log( cantWriteLevel, msg, e ); if (die_on_one_prop_failure) { rethrow = true; throw new IntrospectionException( msg ); } } } } // } // catch (Exception e) // { // if (e instanceof IntrospectionException && rethrow) // throw (IntrospectionException) e; // else // { // String msg = // "An exception occurred while trying to set property '" + propName + // "' to value '" + propVal + "'. "; // logger.log(MLevel.WARNING, msg, e); // if (die_on_one_prop_failure) // { // rethrow = true; // throw new IntrospectionException( msg + e.toString()); // } // } // } } } public static void appendPropNamesAndValues(StringBuffer appendIntoMe, Object bean, Collection ignoreProps) throws IntrospectionException { Map tmp = new TreeMap( String.CASE_INSENSITIVE_ORDER ); extractAccessiblePropertiesToMap( tmp, bean, ignoreProps ); boolean first = true; for (Iterator ii = tmp.keySet().iterator(); ii.hasNext(); ) { String key = (String) ii.next(); Object val = tmp.get( key ); if (first) first = false; else appendIntoMe.append( ", " ); appendIntoMe.append( key ); appendIntoMe.append( " -> "); appendIntoMe.append( val ); } } public static void extractAccessiblePropertiesToMap( Map fillMe, Object bean ) throws IntrospectionException { extractAccessiblePropertiesToMap( fillMe, bean, Collections.EMPTY_SET ); } public static void extractAccessiblePropertiesToMap( Map fillMe, Object bean, Collection ignoreProps ) throws IntrospectionException { String propName = null; try { BeanInfo bi = Introspector.getBeanInfo( bean.getClass(), Object.class ); PropertyDescriptor[] pds = bi.getPropertyDescriptors(); for (int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; propName = pd.getName(); if (ignoreProps.contains( propName )) continue; Method readMethod = pd.getReadMethod(); Object propVal = readMethod.invoke( bean, EMPTY_ARGS ); fillMe.put( propName, propVal ); } } catch ( IntrospectionException e ) { // if (propName != null) // System.err.println("Problem occurred while overwriting property: " + propName); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning("Problem occurred while overwriting property: " + propName); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINE )) logger.logp( MLevel.FINE, BeansUtils.class.getName(), "extractAccessiblePropertiesToMap( Map fillMe, Object bean, Collection ignoreProps )", (propName != null ? "Problem occurred while overwriting property: " + propName : "") + " throwing...", e ); throw e; } catch ( Exception e ) { //e.printStackTrace(); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINE )) logger.logp( MLevel.FINE, BeansUtils.class.getName(), "extractAccessiblePropertiesToMap( Map fillMe, Object bean, Collection ignoreProps )", "Caught unexpected Exception; Converting to IntrospectionException.", e ); throw new IntrospectionException( e.toString() + (propName == null ? "" : " [" + propName + ']') ); } } private static void overwriteProperty( String propName, Object value, Method putativeSetter, Object target ) throws Exception { if ( putativeSetter.getDeclaringClass().isAssignableFrom( target.getClass() ) ) putativeSetter.invoke( target, new Object[] { value } ); else { BeanInfo beanInfo = Introspector.getBeanInfo( target.getClass(), Object.class ); PropertyDescriptor pd = null; PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for( int i = 0, len = pds.length; i < len; ++i) if (propName.equals( pds[i].getName() )) { pd = pds[i]; break; } Method targetSetter = pd.getWriteMethod(); targetSetter.invoke( target, new Object[] { value } ); } } public static void overwriteSpecificAccessibleProperties( Object sourceBean, Object destBean, Collection props ) throws IntrospectionException { try { Set _props = new HashSet(props); BeanInfo beanInfo = Introspector.getBeanInfo( sourceBean.getClass(), Object.class ); //so we don't see message about getClass() PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); for( int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; String name = pd.getName(); if (! _props.remove( name ) ) continue; Method getter = pd.getReadMethod(); Method setter = pd.getWriteMethod(); if ( getter == null || setter == null ) { if ( pd instanceof IndexedPropertyDescriptor ) { // System.err.println("WARNING: BeansUtils.overwriteAccessibleProperties() does not"); // System.err.println("support indexed properties that do not provide single-valued"); // System.err.println("array getters and setters! [The indexed methods provide no means"); // System.err.println("of modifying the size of the array in the destination bean if"); // System.err.println("it does not match the source.]"); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning("BeansUtils.overwriteAccessibleProperties() does not" + " support indexed properties that do not provide single-valued" + " array getters and setters! [The indexed methods provide no means" + " of modifying the size of the array in the destination bean if" + " it does not match the source.]"); } if ( logger.isLoggable( MLevel.INFO ) ) logger.info("Property inaccessible for overwriting: " + pd.getName()); } else { Object value = getter.invoke( sourceBean, EMPTY_ARGS ); overwriteProperty( name, value, setter, destBean ); //setter.invoke( destBean, new Object[] { value } ); } } if ( logger.isLoggable( MLevel.WARNING ) ) { for (Iterator ii = _props.iterator(); ii.hasNext(); ) logger.warning("failed to find expected property: " + ii.next()); //System.err.println("failed to find expected property: " + ii.next()); } } catch ( IntrospectionException e ) { throw e; } catch ( Exception e ) { //e.printStackTrace(); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINE )) logger.logp( MLevel.FINE, BeansUtils.class.getName(), "overwriteSpecificAccessibleProperties( Object sourceBean, Object destBean, Collection props )", "Caught unexpected Exception; Converting to IntrospectionException.", e ); throw new IntrospectionException( e.getMessage() ); } } public static void debugShowPropertyChange( PropertyChangeEvent evt ) { System.err.println("PropertyChangeEvent: [ propertyName -> " + evt.getPropertyName() + ", oldValue -> " + evt.getOldValue() + ", newValue -> " + evt.getNewValue() + " ]"); } private BeansUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/beans/StateBean.java0000644000175000017500000000162610624366527022245 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.beans; public interface StateBean {} c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/beans/StateBeanExporter.java0000644000175000017500000000225010624366527023770 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.beans; /** * offers a bean suitable for bean getter/setter-based serialization/deserialization * a la XMLSerializer. Should have a constructor that accepts the exported Object and * constructs a new bean with the same state. */ public interface StateBeanExporter { public StateBean exportStateBean(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/beans/StateBeanImporter.java0000644000175000017500000000175010624366530023757 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.beans; public interface StateBeanImporter extends StateBeanExporter { public void importStateBean(StateBean sb); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/0000755000175000017500000000000010673162231017172 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/0000755000175000017500000000000010673162231017731 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/C3P0Config.java0000644000175000017500000002264310624366527022410 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.cfg; import java.beans.*; import java.util.*; import com.mchange.v2.c3p0.impl.*; import com.mchange.v2.beans.*; import com.mchange.v2.cfg.*; import com.mchange.v2.log.*; import java.io.IOException; import java.lang.reflect.Method; import com.mchange.v1.lang.BooleanUtils; //all internal maps should be HashMaps (the implementation presumes HashMaps) public final class C3P0Config { public final static String CFG_FINDER_CLASSNAME_KEY = "com.mchange.v2.c3p0.cfg.finder"; public final static String DEFAULT_CONFIG_NAME = "default"; public final static C3P0Config MAIN; final static MLogger logger = MLog.getLogger( C3P0Config.class ); static { // Set knownProps = new HashSet(); // knownProps.add("acquireIncrement"); // knownProps.add("acquireRetryAttempts"); // knownProps.add("acquireRetryDelay"); // knownProps.add("autoCommitOnClose"); // knownProps.add("automaticTestTable"); // knownProps.add("breakAfterAcqireFailure"); // knownProps.add("checkoutTimeout"); // knownProps.add("connectionTesterClassName"); // knownProps.add("factoryClassLocation"); // knownProps.add("forceIgnoreUnresolvedTransactions"); // knownProps.add("idleConnectionTestPeriod"); // knownProps.add("initialPoolSize"); // knownProps.add("maxIdleTime"); // knownProps.add("maxPoolSize"); C3P0Config protoMain; String cname = MultiPropertiesConfig.readVmConfig().getProperty( CFG_FINDER_CLASSNAME_KEY ); C3P0ConfigFinder cfgFinder = null; try { if (cname != null) cfgFinder = (C3P0ConfigFinder) Class.forName( cname ).newInstance(); } catch (Exception e) { if ( logger.isLoggable(MLevel.WARNING) ) logger.log( MLevel.WARNING, "Could not load specified C3P0ConfigFinder class'" + cname + "'.", e); } try { if (cfgFinder == null) { Class.forName("org.w3c.dom.Node"); Class.forName("com.mchange.v2.c3p0.cfg.C3P0ConfigXmlUtils"); //fail nicely if we don't have XML libs cfgFinder = new DefaultC3P0ConfigFinder(); } protoMain = cfgFinder.findConfig(); } catch (Exception e) { if ( logger.isLoggable(MLevel.WARNING) ) logger.log( MLevel.WARNING, "XML configuration disabled! Verify that standard XML libs are available.", e); HashMap flatDefaults = C3P0ConfigUtils.extractHardcodedC3P0Defaults(); flatDefaults.putAll( C3P0ConfigUtils.extractC3P0PropertiesResources() ); protoMain = C3P0ConfigUtils.configFromFlatDefaults( flatDefaults ); } MAIN = protoMain; warnOnUnknownProperties( MAIN ); } private static void warnOnUnknownProperties( C3P0Config cfg ) { warnOnUnknownProperties( cfg.defaultConfig ); for (Iterator ii = cfg.configNamesToNamedScopes.values().iterator(); ii.hasNext(); ) warnOnUnknownProperties( (NamedScope) ii.next() ); } private static void warnOnUnknownProperties( NamedScope scope ) { warnOnUnknownProperties( scope.props ); for (Iterator ii = scope.userNamesToOverrides.values().iterator(); ii.hasNext(); ) warnOnUnknownProperties( (Map) ii.next() ); } private static void warnOnUnknownProperties( Map propMap ) { for (Iterator ii = propMap.keySet().iterator(); ii.hasNext(); ) { String prop = (String) ii.next(); if (! C3P0Defaults.isKnownProperty( prop ) && logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Unknown c3p0-config property: " + prop); } } public static String getUnspecifiedUserProperty( String propKey, String configName ) { String out = null; if (configName == null) out = (String) MAIN.defaultConfig.props.get( propKey ); else { NamedScope named = (NamedScope) MAIN.configNamesToNamedScopes.get( configName ); if (named != null) out = (String) named.props.get(propKey); else logger.warning("named-config with name '" + configName + "' does not exist. Using default-config for property '" + propKey + "'."); if (out == null) out = (String) MAIN.defaultConfig.props.get( propKey ); } return out; } public static Map getUnspecifiedUserProperties(String configName) { Map out = new HashMap(); out.putAll( MAIN.defaultConfig.props ); if (configName != null) { NamedScope named = (NamedScope) MAIN.configNamesToNamedScopes.get( configName ); if (named != null) out.putAll( named.props ); else logger.warning("named-config with name '" + configName + "' does not exist. Using default-config."); } return out; } public static Map getUserOverrides( String configName ) { Map out = new HashMap(); NamedScope namedConfigScope = null; if (configName != null) namedConfigScope = (NamedScope) MAIN.configNamesToNamedScopes.get( configName ); out.putAll( MAIN.defaultConfig.userNamesToOverrides ); if (namedConfigScope != null) out.putAll( namedConfigScope.userNamesToOverrides ); return (out.isEmpty() ? null : out ); } public static String getUserOverridesAsString(String configName) throws IOException { Map userOverrides = getUserOverrides( configName ); if (userOverrides == null) return null; else return C3P0ImplUtils.createUserOverridesAsString( userOverrides ).intern(); } final static Class[] SUOAS_ARGS = new Class[] { String.class }; final static Collection SKIP_BIND_PROPS = Arrays.asList( new String[] {"loginTimeout", "properties"} ); public static void bindNamedConfigToBean(Object bean, String configName) throws IntrospectionException { Map defaultUserProps = C3P0Config.getUnspecifiedUserProperties( configName ); BeansUtils.overwriteAccessiblePropertiesFromMap( defaultUserProps, bean, false, SKIP_BIND_PROPS, true, MLevel.FINEST, MLevel.WARNING, false); try { Method m = bean.getClass().getMethod( "setUserOverridesAsString", SUOAS_ARGS ); m.invoke( bean, new Object[] {getUserOverridesAsString( configName )} ); } catch (NoSuchMethodException e) { e.printStackTrace(); /* ignore */ } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "An exception occurred while trying to bind user overrides " + "for named config '" + configName + "'. Only default user configs " + "will be used." , e); } } /* * Note that on initialization of a DataSource, no config name is known. * We initialize local vars using the default config. The DataSources class * and/or constructors that accept a configName then overwrite the initial * values with namedConfig overrides if supplied. */ public static String initializeUserOverridesAsString() { try { return getUserOverridesAsString( null ); } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Error initializing default user overrides. User overrides may be ignored.", e); return null; } } public static String initializeStringPropertyVar(String propKey, String dflt) { String out = getUnspecifiedUserProperty( propKey, null ); if (out == null) out = dflt; return out; } public static int initializeIntPropertyVar(String propKey, int dflt) { boolean set = false; int out = -1; String outStr = getUnspecifiedUserProperty( propKey, null ); if (outStr != null) { try { out = Integer.parseInt( outStr.trim() ); set = true; } catch (NumberFormatException e) { logger.info("'" + outStr + "' is not a legal value for property '" + propKey + "'. Using default value: " + dflt); } } if (!set) out = dflt; //System.err.println("initializing " + propKey + " to " + out); return out; } public static boolean initializeBooleanPropertyVar(String propKey, boolean dflt) { boolean set = false; boolean out = false; String outStr = getUnspecifiedUserProperty( propKey, null ); if (outStr != null) { try { out = BooleanUtils.parseBoolean( outStr.trim() ); set = true; } catch (IllegalArgumentException e) { logger.info("'" + outStr + "' is not a legal value for property '" + propKey + "'. Using default value: " + dflt); } } if (!set) out = dflt; return out; } NamedScope defaultConfig; HashMap configNamesToNamedScopes; C3P0Config( NamedScope defaultConfig, HashMap configNamesToNamedScopes) { this.defaultConfig = defaultConfig; this.configNamesToNamedScopes = configNamesToNamedScopes; } // C3P0Config() // { // this.defaultConfig = new NamedScope(); // this.configNamesToNamedScopes = new HashMap(); // } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/C3P0ConfigFinder.java0000644000175000017500000000176410624366527023541 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.cfg; import java.sql.SQLException; public interface C3P0ConfigFinder { public C3P0Config findConfig() throws Exception; }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/C3P0ConfigUtils.java0000644000175000017500000001210710624366527023423 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.cfg; import java.io.*; import java.lang.reflect.*; import java.util.*; import com.mchange.v2.cfg.*; import com.mchange.v2.log.*; import com.mchange.v2.c3p0.impl.*; public final class C3P0ConfigUtils { public final static String PROPS_FILE_RSRC_PATH = "/c3p0.properties"; public final static String PROPS_FILE_PROP_PFX = "c3p0."; public final static int PROPS_FILE_PROP_PFX_LEN = 5; private final static String[] MISSPELL_PFXS = {"/c3pO", "/c3po", "/C3P0", "/C3PO"}; final static MLogger logger = MLog.getLogger( C3P0ConfigUtils.class ); static { if ( logger.isLoggable(MLevel.WARNING) && C3P0ConfigUtils.class.getResource( PROPS_FILE_RSRC_PATH ) == null ) { // warn on a misspelling... its an ugly way to do this, but since resources are not listable... for (int i = 0; i < MISSPELL_PFXS.length; ++i) { String test = MISSPELL_PFXS[i] + ".properties"; if (C3P0ConfigUtils.class.getResource( MISSPELL_PFXS[i] + ".properties" ) != null) { logger.warning("POSSIBLY MISSPELLED c3p0.properties CONFIG RESOURCE FOUND. " + "Please ensure the file name is c3p0.properties, all lower case, " + "with the digit 0 (NOT the letter O) in c3p0. It should be placed " + " in the top level of c3p0's effective classpath."); break; } } } } public static HashMap extractHardcodedC3P0Defaults(boolean stringify) { HashMap out = new HashMap(); try { Method[] methods = C3P0Defaults.class.getMethods(); for (int i = 0, len = methods.length; i < len; ++i) { Method m = methods[i]; int mods = m.getModifiers(); if ((mods & Modifier.PUBLIC) != 0 && (mods & Modifier.STATIC) != 0 && m.getParameterTypes().length == 0) { if (stringify) { Object val = m.invoke( null, null ); if ( val != null ) out.put( m.getName(), String.valueOf( val ) ); } else out.put( m.getName(), m.invoke( null, null ) ); } } } catch (Exception e) { logger.log( MLevel.WARNING, "Failed to extract hardcoded default config!?", e ); } return out; } public static HashMap extractHardcodedC3P0Defaults() { return extractHardcodedC3P0Defaults( true ); } public static HashMap extractC3P0PropertiesResources() { HashMap out = new HashMap(); // Properties props = findResourceProperties(); // props.putAll( findAllC3P0Properties() ); Properties props = findAllC3P0Properties(); for (Iterator ii = props.keySet().iterator(); ii.hasNext(); ) { String key = (String) ii.next(); String val = (String) props.get(key); if ( key.startsWith(PROPS_FILE_PROP_PFX) ) out.put( key.substring(PROPS_FILE_PROP_PFX_LEN).trim(), val.trim() ); } return out; } public static C3P0Config configFromFlatDefaults(HashMap flatDefaults) { NamedScope defaults = new NamedScope(); defaults.props.putAll( flatDefaults ); HashMap configNamesToNamedScopes = new HashMap(); return new C3P0Config( defaults, configNamesToNamedScopes ); } public static String getPropFileConfigProperty( String prop ) { return MultiPropertiesConfig.readVmConfig().getProperty( prop ); } private static Properties findResourceProperties() { return MultiPropertiesConfig.readVmConfig().getPropertiesByResourcePath(PROPS_FILE_RSRC_PATH); } private static Properties findAllC3P0Properties() { return MultiPropertiesConfig.readVmConfig().getPropertiesByPrefix("c3p0"); } static Properties findAllC3P0SystemProperties() { Properties out = new Properties(); SecurityException sampleExc = null; try { for (Iterator ii = C3P0Defaults.getKnownProperties().iterator(); ii.hasNext(); ) { String key = (String) ii.next(); String prefixedKey = "c3p0." + key; String value = System.getProperty( prefixedKey ); if (value != null && value.trim().length() > 0) out.put( key, value ); } } catch (SecurityException e) { sampleExc = e; } return out; } private C3P0ConfigUtils() {} }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/C3P0ConfigXmlUtils.java0000644000175000017500000002131710624366527024107 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.cfg; import java.io.*; import java.util.*; import javax.xml.parsers.*; import org.w3c.dom.*; import com.mchange.v2.log.*; import com.mchange.v1.xml.DomParseUtils; public final class C3P0ConfigXmlUtils { public final static String XML_CONFIG_RSRC_PATH = "/c3p0-config.xml"; final static MLogger logger = MLog.getLogger( C3P0ConfigXmlUtils.class ); public final static String LINESEP; private final static String[] MISSPELL_PFXS = {"/c3p0", "/c3pO", "/c3po", "/C3P0", "/C3PO"}; private final static char[] MISSPELL_LINES = {'-', '_'}; private final static String[] MISSPELL_CONFIG = {"config", "CONFIG"}; private final static String[] MISSPELL_XML = {"xml", "XML"}; // its an ugly way to do this, but since resources are not listable... // // this is only executed once, and does about 40 tests (for now) // should I care about the cost in initialization time? // // should only be run if we've checked for the correct file, but // not found it private final static void warnCommonXmlConfigResourceMisspellings() { if (logger.isLoggable( MLevel.WARNING) ) { for (int a = 0, lena = MISSPELL_PFXS.length; a < lena; ++a) { StringBuffer sb = new StringBuffer(16); sb.append( MISSPELL_PFXS[a] ); for (int b = 0, lenb = MISSPELL_LINES.length; b < lenb; ++b) { sb.append(MISSPELL_LINES[b]); for (int c = 0, lenc = MISSPELL_CONFIG.length; c < lenc; ++c) { sb.append(MISSPELL_CONFIG[c]); sb.append('.'); for (int d = 0, lend = MISSPELL_XML.length; d < lend; ++d) { sb.append(MISSPELL_XML[d]); String test = sb.toString(); if (!test.equals(XML_CONFIG_RSRC_PATH)) { Object hopefullyNull = C3P0ConfigXmlUtils.class.getResource( test ); if (hopefullyNull != null) { logger.warning("POSSIBLY MISSPELLED c3p0-conf.xml RESOURCE FOUND. " + "Please ensure the file name is c3p0-config.xml, all lower case, " + "with the digit 0 (NOT the letter O) in c3p0. It should be placed " + " in the top level of c3p0's effective classpath."); return; } } } } } } } } static { String ls; try { ls = System.getProperty("line.separator", "\r\n"); } catch (Exception e) { ls = "\r\n"; } LINESEP = ls; } public static C3P0Config extractXmlConfigFromDefaultResource() throws Exception { InputStream is = null; try { is = C3P0ConfigUtils.class.getResourceAsStream(XML_CONFIG_RSRC_PATH); if ( is == null ) { warnCommonXmlConfigResourceMisspellings(); return null; } else return extractXmlConfigFromInputStream( is ); } finally { try { if (is != null) is.close(); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log(MLevel.FINE,"Exception on resource InputStream close.", e); } } } public static C3P0Config extractXmlConfigFromInputStream(InputStream is) throws Exception { DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); DocumentBuilder db = fact.newDocumentBuilder(); Document doc = db.parse( is ); return extractConfigFromXmlDoc(doc); } public static C3P0Config extractConfigFromXmlDoc(Document doc) throws Exception { Element docElem = doc.getDocumentElement(); if (docElem.getTagName().equals("c3p0-config")) { NamedScope defaults; HashMap configNamesToNamedScopes = new HashMap(); Element defaultConfigElem = DomParseUtils.uniqueChild( docElem, "default-config" ); if (defaultConfigElem != null) defaults = extractNamedScopeFromLevel( defaultConfigElem ); else defaults = new NamedScope(); NodeList nl = DomParseUtils.immediateChildElementsByTagName(docElem, "named-config"); for (int i = 0, len = nl.getLength(); i < len; ++i) { Element namedConfigElem = (Element) nl.item(i); String configName = namedConfigElem.getAttribute("name"); if (configName != null && configName.length() > 0) { NamedScope namedConfig = extractNamedScopeFromLevel( namedConfigElem ); configNamesToNamedScopes.put( configName, namedConfig); } else logger.warning("Configuration XML contained named-config element without name attribute: " + namedConfigElem); } return new C3P0Config( defaults, configNamesToNamedScopes ); } else throw new Exception("Root element of c3p0 config xml should be 'c3p0-config', not '" + docElem.getTagName() + "'."); } private static NamedScope extractNamedScopeFromLevel(Element elem) { HashMap props = extractPropertiesFromLevel( elem ); HashMap userNamesToOverrides = new HashMap(); NodeList nl = DomParseUtils.immediateChildElementsByTagName(elem, "user-overrides"); for (int i = 0, len = nl.getLength(); i < len; ++i) { Element perUserConfigElem = (Element) nl.item(i); String userName = perUserConfigElem.getAttribute("user"); if (userName != null && userName.length() > 0) { HashMap userProps = extractPropertiesFromLevel( perUserConfigElem ); userNamesToOverrides.put( userName, userProps ); } else logger.warning("Configuration XML contained user-overrides element without user attribute: " + LINESEP + perUserConfigElem); } return new NamedScope(props, userNamesToOverrides); } private static HashMap extractPropertiesFromLevel(Element elem) { // System.err.println( "extractPropertiesFromLevel()" ); HashMap out = new HashMap(); try { NodeList nl = DomParseUtils.immediateChildElementsByTagName(elem, "property"); int len = nl.getLength(); for (int i = 0; i < len; ++i) { Element propertyElem = (Element) nl.item(i); String propName = propertyElem.getAttribute("name"); if (propName != null && propName.length() > 0) { String propVal = DomParseUtils.allTextFromElement(propertyElem, true); out.put( propName, propVal ); //System.err.println( propName + " -> " + propVal ); } else logger.warning("Configuration XML contained property element without name attribute: " + LINESEP + propertyElem); } } catch (Exception e) { logger.log( MLevel.WARNING, "An exception occurred while reading config XML. " + "Some configuration information has probably been ignored.", e ); } return out; } private C3P0ConfigXmlUtils() {} }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/DefaultC3P0ConfigFinder.java0000644000175000017500000000536710624366530025043 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.cfg; import java.io.*; import java.util.HashMap; import java.util.Properties; import com.mchange.v2.cfg.MultiPropertiesConfig; public class DefaultC3P0ConfigFinder implements C3P0ConfigFinder { final static String XML_CFG_FILE_KEY = "com.mchange.v2.c3p0.cfg.xml"; public C3P0Config findConfig() throws Exception { C3P0Config out; HashMap flatDefaults = C3P0ConfigUtils.extractHardcodedC3P0Defaults(); // this includes System properties, but we have to check for System properties // again, since we want system properties to override unspecified user, default-config // properties in the XML flatDefaults.putAll( C3P0ConfigUtils.extractC3P0PropertiesResources() ); String cfgFile = MultiPropertiesConfig.readVmConfig().getProperty( XML_CFG_FILE_KEY ); if (cfgFile == null) { C3P0Config xmlConfig = C3P0ConfigXmlUtils.extractXmlConfigFromDefaultResource(); if (xmlConfig != null) { insertDefaultsUnderNascentConfig( flatDefaults, xmlConfig ); out = xmlConfig; } else out = C3P0ConfigUtils.configFromFlatDefaults( flatDefaults ); } else { InputStream is = new BufferedInputStream( new FileInputStream( cfgFile ) ); try { C3P0Config xmlConfig = C3P0ConfigXmlUtils.extractXmlConfigFromInputStream( is ); insertDefaultsUnderNascentConfig( flatDefaults, xmlConfig ); out = xmlConfig; } finally { try {is.close();} catch (Exception e) { e.printStackTrace(); } } } // overwrite default, unspecified user config with System properties // defined values Properties sysPropConfig = C3P0ConfigUtils.findAllC3P0SystemProperties(); out.defaultConfig.props.putAll( sysPropConfig ); return out; } private void insertDefaultsUnderNascentConfig(HashMap flatDefaults, C3P0Config config) { flatDefaults.putAll( config.defaultConfig.props ); config.defaultConfig.props = flatDefaults; } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/cfg/NamedScope.java0000644000175000017500000000250010624366530022613 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.cfg; import java.util.*; //all internal maps should be HashMaps (the implementation presumes HashMaps) class NamedScope { HashMap props; HashMap userNamesToOverrides; NamedScope() { this.props = new HashMap(); this.userNamesToOverrides = new HashMap(); } NamedScope( HashMap props, HashMap userNamesToOverrides) { this.props = props; this.userNamesToOverrides = userNamesToOverrides; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/codegen/0000755000175000017500000000000010673162231020576 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/codegen/BeangenDataSourceGenerator.java0000644000175000017500000001744610624366527026650 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.codegen; import java.io.*; import java.util.*; import javax.xml.parsers.*; import org.w3c.dom.*; import com.mchange.v2.codegen.*; import com.mchange.v2.codegen.bean.*; import com.mchange.v2.c3p0.impl.*; import java.lang.reflect.Modifier; import com.mchange.v1.xml.DomParseUtils; public class BeangenDataSourceGenerator { public static void main( String[] argv ) { try { if (argv.length != 2) { System.err.println("java " + BeangenDataSourceGenerator.class.getName() + " "); return; } File outFile = new File( argv[1] ); File parentDir = outFile.getParentFile(); if (! parentDir.exists()) { System.err.println("Warning: making parent directory: " + parentDir); parentDir.mkdirs(); } DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); DocumentBuilder db = fact.newDocumentBuilder(); Document doc = db.parse( new File( argv[0] ) ); ParsedPropertyBeanDocument parsed = new ParsedPropertyBeanDocument( doc ); Writer w = new BufferedWriter( new FileWriter( outFile ) ); SimplePropertyBeanGenerator gen = new SimplePropertyBeanGenerator(); gen.setGeneratorName( BeangenDataSourceGenerator.class.getName() ); // tightly coupled to the implementation of SimplePropertyBeanGenerator! IndirectingSerializableExtension idse = new IndirectingSerializableExtension("com.mchange.v2.naming.ReferenceIndirector") { protected void generateExtraSerInitializers(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { if (BeangenUtils.hasBoundProperties( props )) iw.println("this.pcs = new PropertyChangeSupport( this );"); if (BeangenUtils.hasConstrainedProperties( props )) iw.println("this.vcs = new VetoableChangeSupport( this );"); } }; gen.addExtension( idse ); PropsToStringGeneratorExtension tsge = new PropsToStringGeneratorExtension(); tsge.setExcludePropertyNames( Arrays.asList( new String[] {"userOverridesAsString","overrideDefaultUser","overrideDefaultPassword"} ) ); gen.addExtension( tsge ); PropertyReferenceableExtension prex = new PropertyReferenceableExtension(); prex.setUseExplicitReferenceProperties( true ); // we use the string version to creating dependencies between the bean generator and c3p0 classes //prex.setFactoryClassName( C3P0JavaBeanObjectFactory.class.getName() ); prex.setFactoryClassName( "com.mchange.v2.c3p0.impl.C3P0JavaBeanObjectFactory" ); gen.addExtension( prex ); BooleanInitIdentityTokenConstructortorGeneratorExtension biitcge = new BooleanInitIdentityTokenConstructortorGeneratorExtension(); gen.addExtension( biitcge ); if ( parsed.getClassInfo().getClassName().equals("WrapperConnectionPoolDataSourceBase") ) gen.addExtension( new WcpdsExtrasGeneratorExtension() ); if (unmodifiableShadow( doc ) ) gen.addExtension( new UnmodifiableShadowGeneratorExtension() ); gen.generate( parsed.getClassInfo(), parsed.getProperties(), w ); w.flush(); w.close(); System.err.println("Processed: " + argv[0] ); //+ " -> " + argv[1]); } catch ( Exception e ) { e.printStackTrace(); } } private static boolean unmodifiableShadow( Document doc ) { Element docElem = doc.getDocumentElement(); return DomParseUtils.uniqueChild(docElem, "unmodifiable-shadow") != null; } static class BooleanInitIdentityTokenConstructortorGeneratorExtension implements GeneratorExtension { public Collection extraGeneralImports() {return Collections.EMPTY_SET;} public Collection extraSpecificImports() { Set out = new HashSet(); out.add( "com.mchange.v2.c3p0.C3P0Registry" ); return out; } public Collection extraInterfaceNames() {return Collections.EMPTY_SET;} public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { BeangenUtils.writeExplicitDefaultConstructor( Modifier.PRIVATE, info, iw); iw.println(); iw.println("public " + info.getClassName() + "( boolean autoregister )"); iw.println("{"); iw.upIndent(); iw.println( "if (autoregister)"); iw.println("{"); iw.upIndent(); iw.println("this.identityToken = C3P0ImplUtils.allocateIdentityToken( this );"); iw.println("C3P0Registry.reregister( this );"); iw.downIndent(); iw.println("}"); iw.downIndent(); iw.println("}"); } } static class WcpdsExtrasGeneratorExtension implements GeneratorExtension { public Collection extraGeneralImports() {return Collections.EMPTY_SET;} public Collection extraSpecificImports() { Set out = new HashSet(); out.add( "com.mchange.v2.c3p0.ConnectionCustomizer" ); out.add( "javax.sql.PooledConnection" ); out.add( "java.sql.SQLException" ); return out; } public Collection extraInterfaceNames() {return Collections.EMPTY_SET;} public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.println("protected abstract PooledConnection getPooledConnection( ConnectionCustomizer cc, String idt)" + " throws SQLException;"); iw.println("protected abstract PooledConnection getPooledConnection(String user, String password, ConnectionCustomizer cc, String idt)" + " throws SQLException;"); } } static class UnmodifiableShadowGeneratorExtension implements GeneratorExtension { BeanExtractingGeneratorExtension bege; CompleteConstructorGeneratorExtension ccge; { bege = new BeanExtractingGeneratorExtension(); bege.setExtractMethodModifiers( Modifier.PRIVATE ); bege.setConstructorModifiers( Modifier.PUBLIC ); ccge = new CompleteConstructorGeneratorExtension(); } public Collection extraGeneralImports() { Set out = new HashSet(); out.addAll( bege.extraGeneralImports() ); out.addAll( ccge.extraGeneralImports() ); return out; } public Collection extraSpecificImports() { Set out = new HashSet(); out.addAll( bege.extraSpecificImports() ); out.addAll( ccge.extraSpecificImports() ); return out; } public Collection extraInterfaceNames() {return Collections.EMPTY_SET;} public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { ClassInfo innerInfo = new SimpleClassInfo( info.getPackageName(), Modifier.PUBLIC | Modifier.STATIC, "UnmodifiableShadow", info.getSuperclassName(), info.getInterfaceNames(), info.getGeneralImports(), info.getSpecificImports() ); SimplePropertyBeanGenerator innerGen = new SimplePropertyBeanGenerator(); innerGen.setInner( true ); innerGen.setForceUnmodifiable( true ); innerGen.addExtension( bege ); innerGen.addExtension( ccge ); innerGen.generate( innerInfo, props, iw ); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/codegen/JdbcProxyGenerator.java0000644000175000017500000012561010624366527025233 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.codegen; import java.io.*; import java.lang.reflect.*; import java.sql.*; import com.mchange.v2.codegen.*; import com.mchange.v2.codegen.intfc.*; import com.mchange.v2.c3p0.C3P0ProxyConnection; import com.mchange.v2.c3p0.C3P0ProxyStatement; public abstract class JdbcProxyGenerator extends DelegatorGenerator { final static boolean PREMATURE_DETACH_DEBUG = false; JdbcProxyGenerator() { this.setGenerateInnerSetter( false ); this.setGenerateInnerGetter( false ); this.setGenerateNoArgConstructor( false ); this.setGenerateWrappingConstructor( true ); this.setClassModifiers( Modifier.PUBLIC | Modifier.FINAL ); this.setMethodModifiers( Modifier.PUBLIC | Modifier.FINAL ); } abstract String getInnerTypeName(); static final class NewProxyMetaDataGenerator extends JdbcProxyGenerator { String getInnerTypeName() { return "DatabaseMetaData"; } protected void generateDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { String mname = method.getName(); Class retType = method.getReturnType(); if ( ResultSet.class.isAssignableFrom( retType ) ) { iw.println("ResultSet innerResultSet = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("if (innerResultSet == null) return null;"); iw.println("return new NewProxyResultSet( innerResultSet, parentPooledConnection, inner, this );"); } else if ( mname.equals( "getConnection" ) ) { iw.println("return this.proxyCon;"); } else super.generateDelegateCode( intfcl, genclass, method, iw ); } protected void generatePreDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { if ( method.getExceptionTypes().length > 0 ) super.generatePreDelegateCode( intfcl, genclass, method, iw ); } protected void generatePostDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { if ( method.getExceptionTypes().length > 0 ) super.generatePostDelegateCode( intfcl, genclass, method, iw ); } protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException { super.generateExtraDeclarations( intfcl, genclass, iw ); iw.println(); iw.println("NewProxyConnection proxyCon;"); iw.println(); iw.print( CodegenUtils.fqcnLastElement( genclass ) ); iw.println("( " + CodegenUtils.simpleClassName( intfcl ) + " inner, NewPooledConnection parentPooledConnection, NewProxyConnection proxyCon )"); iw.println("{"); iw.upIndent(); iw.println("this( inner, parentPooledConnection );"); iw.println("this.proxyCon = proxyCon;"); iw.downIndent(); iw.println("}"); } } static final class NewProxyResultSetGenerator extends JdbcProxyGenerator { String getInnerTypeName() { return "ResultSet"; } protected void generateDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { iw.println("if (proxyConn != null) proxyConn.maybeDirtyTransaction();"); iw.println(); String mname = method.getName(); Class retType = method.getReturnType(); if ( mname.equals("close") ) { iw.println("if (! this.isDetached())"); iw.println("{"); iw.upIndent(); iw.println("if (creator instanceof Statement)"); iw.upIndent(); iw.println("parentPooledConnection.markInactiveResultSetForStatement( (Statement) creator, inner );"); iw.downIndent(); iw.println("else if (creator instanceof DatabaseMetaData)"); iw.upIndent(); iw.println("parentPooledConnection.markInactiveMetaDataResultSet( inner );"); iw.downIndent(); iw.println("else if (creator instanceof Connection)"); iw.upIndent(); iw.println("parentPooledConnection.markInactiveRawConnectionResultSet( inner );"); iw.downIndent(); iw.println("else throw new InternalError(\042Must be Statement or DatabaseMetaData -- Bad Creator: \042 + creator);"); iw.println("this.detach();"); iw.println("inner.close();"); iw.println("this.inner = null;"); iw.downIndent(); iw.println("}"); } else if ( mname.equals("getStatement") ) { iw.println("if (creator instanceof Statement)"); iw.upIndent(); iw.println("return (Statement) creatorProxy;"); iw.downIndent(); iw.println("else if (creator instanceof DatabaseMetaData)"); iw.upIndent(); iw.println("return null;"); iw.downIndent(); iw.println("else throw new InternalError(\042Must be Statement or DatabaseMetaData -- Bad Creator: \042 + creator);"); } else if ( mname.equals("isClosed") ) { iw.println( "return this.isDetached();" ); } else super.generateDelegateCode( intfcl, genclass, method, iw ); } protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException { super.generateExtraDeclarations( intfcl, genclass, iw ); iw.println(); iw.println("Object creator;"); iw.println("Object creatorProxy;"); iw.println("NewProxyConnection proxyConn;"); iw.println(); iw.print( CodegenUtils.fqcnLastElement( genclass ) ); iw.println("( " + CodegenUtils.simpleClassName( intfcl ) + " inner, NewPooledConnection parentPooledConnection, Object c, Object cProxy )"); iw.println("{"); iw.upIndent(); iw.println("this( inner, parentPooledConnection );"); iw.println("this.creator = c;"); iw.println("this.creatorProxy = cProxy;"); iw.println("if (creatorProxy instanceof NewProxyConnection) this.proxyConn = (NewProxyConnection) cProxy;"); iw.downIndent(); iw.println("}"); } protected void generatePreDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { super.generatePreDelegateCode( intfcl, genclass, method, iw ); } } static final class NewProxyAnyStatementGenerator extends JdbcProxyGenerator { String getInnerTypeName() { return "Statement"; } private final static boolean CONCURRENT_ACCESS_DEBUG = false; { this.setExtraInterfaces( new Class[] { C3P0ProxyStatement.class } ); } protected void generateDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { iw.println("maybeDirtyTransaction();"); iw.println(); String mname = method.getName(); Class retType = method.getReturnType(); if ( ResultSet.class.isAssignableFrom( retType ) ) { iw.println("ResultSet innerResultSet = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("if (innerResultSet == null) return null;"); iw.println("parentPooledConnection.markActiveResultSetForStatement( inner, innerResultSet );"); iw.println("return new NewProxyResultSet( innerResultSet, parentPooledConnection, inner, this );"); } else if ( mname.equals("getConnection") ) { iw.println("if (! this.isDetached())"); iw.upIndent(); iw.println("return creatorProxy;"); iw.downIndent(); iw.println("else"); iw.upIndent(); iw.println("throw new SQLException(\"You cannot operate on a closed Statement!\");"); iw.downIndent(); } else if ( mname.equals("close") ) { iw.println("if (! this.isDetached())"); iw.println("{"); iw.upIndent(); iw.println("if ( is_cached )"); iw.upIndent(); iw.println("parentPooledConnection.checkinStatement( inner );"); iw.downIndent(); iw.println("else"); iw.println("{"); iw.upIndent(); iw.println("parentPooledConnection.markInactiveUncachedStatement( inner );"); iw.println("try{ inner.close(); }"); iw.println("catch (Exception e )"); iw.println("{"); iw.upIndent(); iw.println("if (logger.isLoggable( MLevel.WARNING ))"); iw.upIndent(); iw.println("logger.log( MLevel.WARNING, \042Exception on close of inner statement.\042, e);"); iw.downIndent(); iw.println( "SQLException sqle = SqlUtils.toSQLException( e );" ); iw.println( "throw sqle;" ); iw.downIndent(); iw.println("}"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("this.detach();"); iw.println("this.inner = null;"); iw.println("this.creatorProxy = null;"); iw.downIndent(); iw.println("}"); } else if ( mname.equals("isClosed") ) { iw.println( "return this.isDetached();" ); } else super.generateDelegateCode( intfcl, genclass, method, iw ); } protected void generatePreDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { // concurrent-access-debug only if (CONCURRENT_ACCESS_DEBUG) { iw.println("Object record;"); iw.println("synchronized (concurrentAccessRecorder)"); iw.println("{"); iw.upIndent(); iw.println("record = concurrentAccessRecorder.record();"); iw.println("int num_concurrent_clients = concurrentAccessRecorder.size();"); iw.println("if (num_concurrent_clients != 1)"); iw.upIndent(); iw.println("logger.log(MLevel.WARNING, " + "concurrentAccessRecorder.getDump(\042Apparent concurrent access! (\042 + num_concurrent_clients + \042 clients.\042) );"); iw.downIndent(); iw.downIndent(); iw.println("}"); iw.println(); } // end concurrent-access-debug only super.generatePreDelegateCode( intfcl, genclass, method, iw ); } protected void generatePostDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { super.generatePostDelegateCode( intfcl, genclass, method, iw ); // concurrent-access-debug only if (CONCURRENT_ACCESS_DEBUG) { iw.println("finally"); iw.println("{"); iw.upIndent(); iw.println("concurrentAccessRecorder.remove( record );"); iw.downIndent(); iw.println("}"); } // end concurrent-access-debug only } protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException { super.generateExtraDeclarations( intfcl, genclass, iw ); iw.println(); // concurrent-access-debug only! if (CONCURRENT_ACCESS_DEBUG) { iw.println("com.mchange.v2.debug.ThreadNameStackTraceRecorder concurrentAccessRecorder"); iw.upIndent(); iw.println("= new com.mchange.v2.debug.ThreadNameStackTraceRecorder(\042Concurrent Access Recorder\042);"); iw.downIndent(); } // end concurrent-access-debug only! iw.println("boolean is_cached;"); iw.println("NewProxyConnection creatorProxy;"); iw.println(); iw.print( CodegenUtils.fqcnLastElement( genclass ) ); iw.println("( " + CodegenUtils.simpleClassName( intfcl ) + " inner, NewPooledConnection parentPooledConnection, boolean cached, NewProxyConnection cProxy )"); iw.println("{"); iw.upIndent(); iw.println("this( inner, parentPooledConnection );"); iw.println("this.is_cached = cached;"); iw.println("this.creatorProxy = cProxy;"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("public Object rawStatementOperation(Method m, Object target, Object[] args) " + "throws IllegalAccessException, InvocationTargetException, SQLException"); iw.println("{"); iw.upIndent(); iw.println("maybeDirtyTransaction();"); iw.println(); iw.println("if (target == C3P0ProxyStatement.RAW_STATEMENT) target = inner;"); iw.println("for (int i = 0, len = args.length; i < len; ++i)"); iw.upIndent(); iw.println("if (args[i] == C3P0ProxyStatement.RAW_STATEMENT) args[i] = inner;"); iw.downIndent(); iw.println("Object out = m.invoke(target, args);"); iw.println("if (out instanceof ResultSet)"); iw.println("{"); iw.upIndent(); iw.println("ResultSet innerResultSet = (ResultSet) out;"); iw.println("parentPooledConnection.markActiveResultSetForStatement( inner, innerResultSet );"); iw.println("out = new NewProxyResultSet( innerResultSet, parentPooledConnection, inner, this );"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("return out;"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("void maybeDirtyTransaction()"); iw.println("{ creatorProxy.maybeDirtyTransaction(); }"); } protected void generateExtraImports( IndentedWriter iw ) throws IOException { super.generateExtraImports( iw ); iw.println("import java.lang.reflect.InvocationTargetException;"); } } // protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException // { // super.generateExtraDeclarations( intfcl, genclass, iw ); // iw.println(); // iw.println("Statement creatingStatement;"); // iw.println(); // iw.print( CodegenUtils.fqcnLastElement( genclass ) ); // iw.println("( " + CodegenUtils.simpleClassName( intfcl.getClass() ) + " inner, NewPooledConnection parentPooledConnection, Statement stmt )"); // iw.println("{"); // iw.upIndent(); // iw.println("this( inner, parentPooledConnection );"); // iw.println("this.creatingStatement = stmt;"); // iw.downIndent(); // iw.println("}"); // } static final class NewProxyConnectionGenerator extends JdbcProxyGenerator { String getInnerTypeName() { return "Connection"; } { this.setMethodModifiers( Modifier.PUBLIC | Modifier.SYNCHRONIZED ); this.setExtraInterfaces( new Class[] { C3P0ProxyConnection.class } ); } protected void generateDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { String mname = method.getName(); if (mname.equals("createStatement")) { iw.println("txn_known_resolved = false;"); iw.println(); iw.println("Statement innerStmt = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("return new NewProxyStatement( innerStmt, parentPooledConnection, false, this );"); } else if (mname.equals("prepareStatement")) { iw.println("txn_known_resolved = false;"); iw.println(); iw.println("PreparedStatement innerStmt;"); iw.println(); iw.println("if ( parentPooledConnection.isStatementCaching() )"); iw.println("{"); iw.upIndent(); iw.println("try"); iw.println("{"); iw.upIndent(); generateFindMethodAndArgs( method, iw ); iw.println("innerStmt = (PreparedStatement) parentPooledConnection.checkoutStatement( method, args );"); iw.println("return new NewProxyPreparedStatement( innerStmt, parentPooledConnection, true, this );"); iw.downIndent(); iw.println("}"); iw.println("catch (ResourceClosedException e)"); iw.println("{"); iw.upIndent(); iw.println("if ( logger.isLoggable( MLevel.FINE ) )"); iw.upIndent(); iw.println("logger.log( MLevel.FINE, " + "\042A Connection tried to prepare a Statement via a Statement cache that is already closed. " + "This can happen -- rarely -- if a DataSource is closed or reset() while Connections are checked-out and in use.\042, e );"); iw.downIndent(); // repeated code... any changes probably need to be duplicated below iw.println("innerStmt = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("return new NewProxyPreparedStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); iw.downIndent(); iw.println("}"); iw.println("else"); iw.println("{"); iw.upIndent(); // repeated code... any changes probably need to be duplicated above iw.println("innerStmt = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("return new NewProxyPreparedStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); } else if (mname.equals("prepareCall")) { iw.println("txn_known_resolved = false;"); iw.println(); iw.println("CallableStatement innerStmt;"); iw.println(); iw.println("if ( parentPooledConnection.isStatementCaching() )"); iw.println("{"); iw.upIndent(); iw.println("try"); iw.println("{"); iw.upIndent(); generateFindMethodAndArgs( method, iw ); iw.println("innerStmt = (CallableStatement) parentPooledConnection.checkoutStatement( method, args );"); iw.println("return new NewProxyCallableStatement( innerStmt, parentPooledConnection, true, this );"); iw.downIndent(); iw.println("}"); iw.println("catch (ResourceClosedException e)"); iw.println("{"); iw.upIndent(); iw.println("if ( logger.isLoggable( MLevel.FINE ) )"); iw.upIndent(); iw.println("logger.log( MLevel.FINE, " + "\042A Connection tried to prepare a CallableStatement via a Statement cache that is already closed. " + "This can happen -- rarely -- if a DataSource is closed or reset() while Connections are checked-out and in use.\042, e );"); iw.downIndent(); // repeated code... any changes probably need to be duplicated below iw.println("innerStmt = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("return new NewProxyCallableStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); iw.downIndent(); iw.println("}"); iw.println("else"); iw.println("{"); iw.upIndent(); // repeated code... any changes probably need to be duplicated above iw.println("innerStmt = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("return new NewProxyCallableStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); } else if (mname.equals("getMetaData")) { iw.println("txn_known_resolved = false;"); iw.println(); iw.println("if (this.metaData == null)"); iw.println("{"); iw.upIndent(); iw.println("DatabaseMetaData innerMetaData = inner." + CodegenUtils.methodCall( method ) + ";"); iw.println("this.metaData = new NewProxyDatabaseMetaData( innerMetaData, parentPooledConnection, this );"); iw.downIndent(); iw.println("}"); iw.println("return this.metaData;"); } else if ( mname.equals("setTransactionIsolation") ) { //do nothing with txn_known_resolved super.generateDelegateCode( intfcl, genclass, method, iw ); iw.println( "parentPooledConnection.markNewTxnIsolation( " + CodegenUtils.generatedArgumentName( 0 ) + " );"); } else if ( mname.equals("setCatalog") ) { //do nothing with txn_known_resolved super.generateDelegateCode( intfcl, genclass, method, iw ); iw.println( "parentPooledConnection.markNewCatalog( " + CodegenUtils.generatedArgumentName( 0 ) + " );"); } else if ( mname.equals("setHoldability") ) { //do nothing with txn_known_resolved super.generateDelegateCode( intfcl, genclass, method, iw ); iw.println( "parentPooledConnection.markNewHoldability( " + CodegenUtils.generatedArgumentName( 0 ) + " );"); } else if ( mname.equals("setReadOnly") ) { //do nothing with txn_known_resolved super.generateDelegateCode( intfcl, genclass, method, iw ); iw.println( "parentPooledConnection.markNewReadOnly( " + CodegenUtils.generatedArgumentName( 0 ) + " );"); } else if ( mname.equals("setTypeMap") ) { //do nothing with txn_known_resolved super.generateDelegateCode( intfcl, genclass, method, iw ); iw.println( "parentPooledConnection.markNewTypeMap( " + CodegenUtils.generatedArgumentName( 0 ) + " );"); } else if ( mname.equals("close") ) { iw.println("if (! this.isDetached())"); iw.println("{"); iw.upIndent(); iw.println("NewPooledConnection npc = parentPooledConnection;"); iw.println("this.detach();"); iw.println("npc.markClosedProxyConnection( this, txn_known_resolved );"); iw.println("this.inner = null;"); iw.downIndent(); iw.println("}"); iw.println("else if (Debug.DEBUG && logger.isLoggable( MLevel.FINE ))"); iw.println("{"); iw.upIndent(); iw.println("logger.log( MLevel.FINE, this + \042: close() called more than once.\042 );"); // premature-detach-debug-debug only! if (PREMATURE_DETACH_DEBUG) { iw.println("prematureDetachRecorder.record();"); iw.println("logger.warning( prematureDetachRecorder.getDump(\042Apparent multiple close of " + getInnerTypeName() + ".\042) );"); } // end-premature-detach-debug-only! iw.downIndent(); iw.println("}"); } else if ( mname.equals("isClosed") ) { iw.println("return this.isDetached();"); } else { iw.println("txn_known_resolved = " + ( mname.equals("commit") || mname.equals( "rollback" ) || mname.equals( "setAutoCommit" ) ) + ';'); iw.println(); super.generateDelegateCode( intfcl, genclass, method, iw ); } } protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException { iw.println("boolean txn_known_resolved = true;"); iw.println(); iw.println("DatabaseMetaData metaData = null;"); iw.println(); // We've nothing to do with preferredTestQuery here... the stuff below was unnecessary // iw.println("String preferredTestQuery = null;"); // iw.println(); // iw.print( CodegenUtils.fqcnLastElement( genclass ) ); // iw.println("( " + CodegenUtils.simpleClassName( intfcl ) + " inner, NewPooledConnection parentPooledConnection, String preferredTestQuery )"); // iw.println("{"); // iw.upIndent(); // iw.println("this( inner, parentPooledConnection );"); // iw.println("this.preferredTestQuery = preferredTestQuery;"); // iw.downIndent(); // iw.println("}"); // iw.println(); iw.println("public Object rawConnectionOperation(Method m, Object target, Object[] args)"); iw.upIndent(); iw.println("throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException"); iw.downIndent(); iw.println("{"); iw.upIndent(); iw.println("maybeDirtyTransaction();"); iw.println(); iw.println("if (inner == null)"); iw.upIndent(); iw.println("throw new SQLException(\"You cannot operate on a closed Connection!\");"); iw.downIndent(); iw.println("if ( target == C3P0ProxyConnection.RAW_CONNECTION)"); iw.upIndent(); iw.println("target = inner;"); iw.downIndent(); iw.println("for (int i = 0, len = args.length; i < len; ++i)"); iw.upIndent(); iw.println("if (args[i] == C3P0ProxyConnection.RAW_CONNECTION)"); iw.upIndent(); iw.println("args[i] = inner;"); iw.downIndent(); iw.downIndent(); iw.println("Object out = m.invoke( target, args );"); iw.println(); iw.println("// we never cache Statements generated by an operation on the raw Connection"); iw.println("if (out instanceof CallableStatement)"); iw.println("{"); iw.upIndent(); iw.println("CallableStatement innerStmt = (CallableStatement) out;"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("out = new NewProxyCallableStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); iw.println("else if (out instanceof PreparedStatement)"); iw.println("{"); iw.upIndent(); iw.println("PreparedStatement innerStmt = (PreparedStatement) out;"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("out = new NewProxyPreparedStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); iw.println("else if (out instanceof Statement)"); iw.println("{"); iw.upIndent(); iw.println("Statement innerStmt = (Statement) out;"); iw.println("parentPooledConnection.markActiveUncachedStatement( innerStmt );"); iw.println("out = new NewProxyStatement( innerStmt, parentPooledConnection, false, this );"); iw.downIndent(); iw.println("}"); iw.println("else if (out instanceof ResultSet)"); iw.println("{"); iw.upIndent(); iw.println("ResultSet innerRs = (ResultSet) out;"); iw.println("parentPooledConnection.markActiveRawConnectionResultSet( innerRs );"); iw.println("out = new NewProxyResultSet( innerRs, parentPooledConnection, inner, this );"); iw.downIndent(); iw.println("}"); iw.println("else if (out instanceof DatabaseMetaData)"); iw.upIndent(); iw.println("out = new NewProxyDatabaseMetaData( (DatabaseMetaData) out, parentPooledConnection );"); iw.downIndent(); iw.println("return out;"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("synchronized void maybeDirtyTransaction()"); iw.println("{ txn_known_resolved = false; }"); super.generateExtraDeclarations( intfcl, genclass, iw ); } void generateFindMethodAndArgs( Method method, IndentedWriter iw ) throws IOException { iw.println("Class[] argTypes = "); iw.println("{"); iw.upIndent(); Class[] argTypes = method.getParameterTypes(); for (int i = 0, len = argTypes.length; i < len; ++i) { if (i != 0) iw.println(","); iw.print( CodegenUtils.simpleClassName( argTypes[i] ) + ".class" ); } iw.println(); iw.downIndent(); iw.println("};"); iw.println("Method method = Connection.class.getMethod( \042" + method.getName() + "\042 , argTypes );"); iw.println(); iw.println("Object[] args = "); iw.println("{"); iw.upIndent(); for (int i = 0, len = argTypes.length; i < len; ++i) { if (i != 0) iw.println(","); String argName = CodegenUtils.generatedArgumentName( i ); Class argType = argTypes[i]; if (argType.isPrimitive()) { if (argType == boolean.class) iw.print( "Boolean.valueOf( " + argName + " )" ); else if (argType == byte.class) iw.print( "new Byte( " + argName + " )" ); else if (argType == char.class) iw.print( "new Character( " + argName + " )" ); else if (argType == short.class) iw.print( "new Short( " + argName + " )" ); else if (argType == int.class) iw.print( "new Integer( " + argName + " )" ); else if (argType == long.class) iw.print( "new Long( " + argName + " )" ); else if (argType == float.class) iw.print( "new Float( " + argName + " )" ); else if (argType == double.class) iw.print( "new Double( " + argName + " )" ); } else iw.print( argName ); } iw.downIndent(); iw.println("};"); } protected void generateExtraImports( IndentedWriter iw ) throws IOException { super.generateExtraImports( iw ); iw.println("import java.lang.reflect.InvocationTargetException;"); iw.println("import com.mchange.v2.util.ResourceClosedException;"); } } protected void generatePreDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { generateTryOpener( iw ); } protected void generatePostDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { generateTryCloserAndCatch( intfcl, genclass, method, iw ); } void generateTryOpener( IndentedWriter iw ) throws IOException { iw.println("try"); iw.println("{"); iw.upIndent(); } void generateTryCloserAndCatch( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { iw.downIndent(); iw.println("}"); iw.println("catch (NullPointerException exc)"); iw.println("{"); iw.upIndent(); iw.println("if ( this.isDetached() )"); iw.println("{"); iw.upIndent(); //iw.println( "System.err.print(\042probably 'cuz we're closed -- \042);" ); //iw.println( "exc.printStackTrace();" ); if ( "close".equals( method.getName() ) ) { iw.println("if (Debug.DEBUG && logger.isLoggable( MLevel.FINE ))"); iw.println("{"); iw.upIndent(); iw.println("logger.log( MLevel.FINE, this + \042: close() called more than once.\042 );"); // premature-detach-debug-debug only! if (PREMATURE_DETACH_DEBUG) { iw.println("prematureDetachRecorder.record();"); iw.println("logger.warning( prematureDetachRecorder.getDump(\042Apparent multiple close of " + getInnerTypeName() + ".\042) );"); } // end-premature-detach-debug-only! iw.downIndent(); iw.println("}"); } else { // premature-detach-debug-debug only! if (PREMATURE_DETACH_DEBUG) { iw.println("prematureDetachRecorder.record();"); iw.println("logger.warning( prematureDetachRecorder.getDump(\042Use of already detached " + getInnerTypeName() + ".\042) );"); } // end-premature-detach-debug-only! iw.println( "throw SqlUtils.toSQLException(\042You can't operate on a closed " + getInnerTypeName() + "!!!\042, exc);"); } iw.downIndent(); iw.println("}"); iw.println( "else throw exc;" ); iw.downIndent(); iw.println("}"); iw.println("catch (Exception exc)"); iw.println("{"); iw.upIndent(); iw.println("if (! this.isDetached())"); iw.println("{"); iw.upIndent(); //iw.println( "exc.printStackTrace();" ); iw.println( "throw parentPooledConnection.handleThrowable( exc );" ); iw.downIndent(); iw.println("}"); iw.println("else throw SqlUtils.toSQLException( exc );"); iw.downIndent(); iw.println("}"); } protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException { // premature-detach-debug-debug only! if (PREMATURE_DETACH_DEBUG) { iw.println("com.mchange.v2.debug.ThreadNameStackTraceRecorder prematureDetachRecorder"); iw.upIndent(); iw.println("= new com.mchange.v2.debug.ThreadNameStackTraceRecorder(\042Premature Detach Recorder\042);"); iw.downIndent(); } // end-premature-detach-debug-only! iw.println("private final static MLogger logger = MLog.getLogger( \042" + genclass + "\042 );"); iw.println(); iw.println("volatile NewPooledConnection parentPooledConnection;"); iw.println(); iw.println("ConnectionEventListener cel = new ConnectionEventListener()"); iw.println("{"); iw.upIndent(); iw.println("public void connectionErrorOccurred(ConnectionEvent evt)"); iw.println("{ /* DON'T detach()... IGNORE -- this could be an ordinary error. Leave it to the PooledConnection to test, but leave proxies intact */ }"); //BAD puppy -- iw.println("{ detach(); }"); iw.println(); iw.println("public void connectionClosed(ConnectionEvent evt)"); iw.println("{ detach(); }"); iw.downIndent(); iw.println("};"); iw.println(); iw.println("void attach( NewPooledConnection parentPooledConnection )"); iw.println("{"); iw.upIndent(); iw.println("this.parentPooledConnection = parentPooledConnection;"); iw.println("parentPooledConnection.addConnectionEventListener( cel );"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("private void detach()"); iw.println("{"); iw.upIndent(); // factored out so we could define debug versions... writeDetachBody(iw); iw.downIndent(); iw.println("}"); iw.println(); iw.print( CodegenUtils.fqcnLastElement( genclass ) ); iw.println("( " + CodegenUtils.simpleClassName( intfcl ) + " inner, NewPooledConnection parentPooledConnection )"); iw.println("{"); iw.upIndent(); iw.println("this( inner );"); iw.println("attach( parentPooledConnection );"); generateExtraConstructorCode( intfcl, genclass, iw ); iw.downIndent(); iw.println("}"); iw.println(); iw.println("boolean isDetached()"); iw.println("{ return (this.parentPooledConnection == null); }"); } protected void writeDetachBody(IndentedWriter iw) throws IOException { // premature-detach-debug only if (PREMATURE_DETACH_DEBUG) { iw.println("prematureDetachRecorder.record();"); iw.println("if (this.isDetached())"); iw.upIndent(); iw.println("logger.warning( prematureDetachRecorder.getDump(\042Double Detach.\042) );"); iw.downIndent(); } // end premature-detach-debug only iw.println("parentPooledConnection.removeConnectionEventListener( cel );"); iw.println("parentPooledConnection = null;"); } protected void generateExtraImports( IndentedWriter iw ) throws IOException { iw.println("import java.sql.*;"); iw.println("import javax.sql.*;"); iw.println("import com.mchange.v2.log.*;"); iw.println("import java.lang.reflect.Method;"); iw.println("import com.mchange.v2.sql.SqlUtils;"); } void generateExtraConstructorCode( Class intfcl, String genclass, IndentedWriter iw ) throws IOException {} public static void main( String[] argv ) { try { if (argv.length != 1) { System.err.println("java " + JdbcProxyGenerator.class.getName() + " "); return; } File srcroot = new File( argv[0] ); if (! srcroot.exists() || !srcroot.canWrite() ) { System.err.println(JdbcProxyGenerator.class.getName() + " -- sourceroot: " + argv[0] + " must exist and be writable"); return; } DelegatorGenerator mdgen = new NewProxyMetaDataGenerator(); DelegatorGenerator rsgen = new NewProxyResultSetGenerator(); DelegatorGenerator stgen = new NewProxyAnyStatementGenerator(); DelegatorGenerator cngen = new NewProxyConnectionGenerator(); genclass( cngen, Connection.class, "com.mchange.v2.c3p0.impl.NewProxyConnection", srcroot ); genclass( stgen, Statement.class, "com.mchange.v2.c3p0.impl.NewProxyStatement", srcroot ); genclass( stgen, PreparedStatement.class, "com.mchange.v2.c3p0.impl.NewProxyPreparedStatement", srcroot ); genclass( stgen, CallableStatement.class, "com.mchange.v2.c3p0.impl.NewProxyCallableStatement", srcroot ); genclass( rsgen, ResultSet.class, "com.mchange.v2.c3p0.impl.NewProxyResultSet", srcroot ); genclass( mdgen, DatabaseMetaData.class, "com.mchange.v2.c3p0.impl.NewProxyDatabaseMetaData", srcroot ); } catch ( Exception e ) { e.printStackTrace(); } } static void genclass( DelegatorGenerator dg, Class intfcl, String fqcn, File srcroot ) throws IOException { File genDir = new File( srcroot, dirForFqcn( fqcn ) ); if (! genDir.exists() ) { System.err.println( JdbcProxyGenerator.class.getName() + " -- creating directory: " + genDir.getAbsolutePath() ); genDir.mkdirs(); } String fileName = CodegenUtils.fqcnLastElement( fqcn ) + ".java"; Writer w = null; try { w = new BufferedWriter( new FileWriter( new File( genDir, fileName ) ) ); dg.writeDelegator( intfcl, fqcn, w ); w.flush(); System.err.println("Generated " + fileName); } finally { try { if (w != null) w.close(); } catch ( Exception e ) { e.printStackTrace(); } } } static String dirForFqcn( String fqcn ) { int last_dot = fqcn.lastIndexOf('.'); StringBuffer sb = new StringBuffer( fqcn.substring( 0, last_dot + 1) ); for (int i = 0, len = sb.length(); i < len; ++i) if (sb.charAt(i) == '.') sb.setCharAt(i, '/'); return sb.toString(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/filter/0000755000175000017500000000000010673162231020457 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/filter/FilterDataSource.java0000644000175000017500000000362310624366527024540 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.filter; import java.io.PrintWriter; import java.lang.String; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; public abstract class FilterDataSource implements DataSource { protected DataSource inner; public FilterDataSource(DataSource inner) { this.inner = inner; } public Connection getConnection() throws SQLException { return inner.getConnection(); } public Connection getConnection(String a, String b) throws SQLException { return inner.getConnection(a, b); } public PrintWriter getLogWriter() throws SQLException { return inner.getLogWriter(); } public int getLoginTimeout() throws SQLException { return inner.getLoginTimeout(); } public void setLogWriter(PrintWriter a) throws SQLException { inner.setLogWriter(a); } public void setLoginTimeout(int a) throws SQLException { inner.setLoginTimeout(a); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/0000755000175000017500000000000010673162231020133 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/AbstractC3P0PooledConnection.java0000644000175000017500000000236010624366527026325 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.sql.Connection; import javax.sql.PooledConnection; import com.mchange.v2.c3p0.stmt.GooGooStatementCache; import com.mchange.v1.util.ClosableResource; abstract class AbstractC3P0PooledConnection implements PooledConnection, ClosableResource { abstract Connection getPhysicalConnection(); abstract void initStatementCache(GooGooStatementCache scache); }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/AbstractIdentityTokenized.java0000644000175000017500000000306210624366527026143 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; /* * It would be convenient to put the getter/setter methods * for the identity token here, but unfortunately we have no * way of setting up the for Referenceability in multiple * levels of a class hierarchy. So we leave the getters/setters, * and variable initialization to code-generators. */ public abstract class AbstractIdentityTokenized implements IdentityTokenized { public boolean equals(Object o) { if (this == o) return true; if (o instanceof IdentityTokenized) return this.getIdentityToken().equals( ((IdentityTokenized) o).getIdentityToken() ); else return false; } public int hashCode() { return ~this.getIdentityToken().hashCode(); } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/AbstractPoolBackedDataSource.java0000644000175000017500000004777210624366530026465 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.io.*; import java.sql.*; import javax.sql.*; import com.mchange.lang.ThrowableUtils; import com.mchange.v2.c3p0.*; import com.mchange.v2.log.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.beans.VetoableChangeListener; import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Set; import com.mchange.v2.c3p0.cfg.C3P0Config; public abstract class AbstractPoolBackedDataSource extends PoolBackedDataSourceBase implements PooledDataSource { final static MLogger logger = MLog.getLogger( AbstractPoolBackedDataSource.class ); final static String NO_CPDS_ERR_MSG = "Attempted to use an uninitialized PoolBackedDataSource. " + "Please call setConnectionPoolDataSource( ... ) to initialize."; //MT: protected by this' lock transient C3P0PooledConnectionPoolManager poolManager; transient boolean is_closed = false; //MT: end protected by this' lock protected AbstractPoolBackedDataSource( boolean autoregister ) { super( autoregister ); setUpPropertyEvents(); } protected AbstractPoolBackedDataSource(String configName) { this( true ); initializeNamedConfig( configName ); } private void setUpPropertyEvents() { PropertyChangeListener l = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { resetPoolManager(); } }; this.addPropertyChangeListener( l ); } protected void initializeNamedConfig(String configName) { try { if (configName != null) { C3P0Config.bindNamedConfigToBean( this, configName ); if ( this.getDataSourceName().equals( this.getIdentityToken() ) ) //dataSourceName has not been specified in config this.setDataSourceName( configName ); } } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Error binding PoolBackedDataSource to named-config '" + configName + "'. Some default-config values may be used.", e); } } // Commented out method is just super.getReference() with a lot of extra printing // public javax.naming.Reference getReference() throws javax.naming.NamingException // { // System.err.println("getReference()!!!!"); // new Exception("PRINT-STACK-TRACE").printStackTrace(); // javax.naming.Reference out = super.getReference(); // System.err.println(out); // return out; // } // report our ID token as dataSourceName if we have no // name explicitly set public String getDataSourceName() { String out = super.getDataSourceName(); if (out == null) out = this.getIdentityToken(); return out; } //implementation of javax.sql.DataSource public Connection getConnection() throws SQLException { PooledConnection pc = getPoolManager().getPool().checkoutPooledConnection(); return pc.getConnection(); } public Connection getConnection(String username, String password) throws SQLException { PooledConnection pc = getPoolManager().getPool(username, password).checkoutPooledConnection(); return pc.getConnection(); } public PrintWriter getLogWriter() throws SQLException { return assertCpds().getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { assertCpds().setLogWriter( out ); } public int getLoginTimeout() throws SQLException { return assertCpds().getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { assertCpds().setLoginTimeout( seconds ); } //implementation of com.mchange.v2.c3p0.PoolingDataSource public int getNumConnections() throws SQLException { return getPoolManager().getPool().getNumConnections(); } public int getNumIdleConnections() throws SQLException { return getPoolManager().getPool().getNumIdleConnections(); } public int getNumBusyConnections() throws SQLException { return getPoolManager().getPool().getNumBusyConnections(); } public int getNumUnclosedOrphanedConnections() throws SQLException { return getPoolManager().getPool().getNumUnclosedOrphanedConnections(); } public int getNumConnectionsDefaultUser() throws SQLException { return getNumConnections();} public int getNumIdleConnectionsDefaultUser() throws SQLException { return getNumIdleConnections();} public int getNumBusyConnectionsDefaultUser() throws SQLException { return getNumBusyConnections();} public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException { return getNumUnclosedOrphanedConnections();} public int getStatementCacheNumStatementsDefaultUser() throws SQLException { return getPoolManager().getPool().getStatementCacheNumStatements(); } public int getStatementCacheNumCheckedOutDefaultUser() throws SQLException { return getPoolManager().getPool().getStatementCacheNumCheckedOut(); } public int getStatementCacheNumConnectionsWithCachedStatementsDefaultUser() throws SQLException { return getPoolManager().getPool().getStatementCacheNumConnectionsWithCachedStatements(); } public float getEffectivePropertyCycleDefaultUser() throws SQLException { return getPoolManager().getPool().getEffectivePropertyCycle(); } public long getStartTimeMillisDefaultUser() throws SQLException { return getPoolManager().getPool().getStartTime(); } public long getUpTimeMillisDefaultUser() throws SQLException { return getPoolManager().getPool().getUpTime(); } public long getNumFailedCheckinsDefaultUser() throws SQLException { return getPoolManager().getPool().getNumFailedCheckins(); } public long getNumFailedCheckoutsDefaultUser() throws SQLException { return getPoolManager().getPool().getNumFailedCheckouts(); } public long getNumFailedIdleTestsDefaultUser() throws SQLException { return getPoolManager().getPool().getNumFailedIdleTests(); } public int getNumThreadsAwaitingCheckoutDefaultUser() throws SQLException { return getPoolManager().getPool().getNumThreadsAwaitingCheckout(); } public int getThreadPoolSize() throws SQLException { return getPoolManager().getThreadPoolSize(); } public int getThreadPoolNumActiveThreads() throws SQLException { return getPoolManager().getThreadPoolNumActiveThreads(); } public int getThreadPoolNumIdleThreads() throws SQLException { return getPoolManager().getThreadPoolNumIdleThreads(); } public int getThreadPoolNumTasksPending() throws SQLException { return getPoolManager().getThreadPoolNumTasksPending(); } public String sampleThreadPoolStackTraces() throws SQLException { return getPoolManager().getThreadPoolStackTraces(); } public String sampleThreadPoolStatus() throws SQLException { return getPoolManager().getThreadPoolStatus(); } public String sampleStatementCacheStatusDefaultUser() throws SQLException { return getPoolManager().getPool().dumpStatementCacheStatus(); } public String sampleStatementCacheStatus(String username, String password) throws SQLException { return assertAuthPool(username, password).dumpStatementCacheStatus(); } public Throwable getLastAcquisitionFailureDefaultUser() throws SQLException { return getPoolManager().getPool().getLastAcquisitionFailure(); } public Throwable getLastCheckinFailureDefaultUser() throws SQLException { return getPoolManager().getPool().getLastCheckinFailure(); } public Throwable getLastCheckoutFailureDefaultUser() throws SQLException { return getPoolManager().getPool().getLastCheckoutFailure(); } public Throwable getLastIdleTestFailureDefaultUser() throws SQLException { return getPoolManager().getPool().getLastIdleTestFailure(); } public Throwable getLastConnectionTestFailureDefaultUser() throws SQLException { return getPoolManager().getPool().getLastConnectionTestFailure(); } public Throwable getLastAcquisitionFailure(String username, String password) throws SQLException { return assertAuthPool(username, password).getLastAcquisitionFailure(); } public Throwable getLastCheckinFailure(String username, String password) throws SQLException { return assertAuthPool(username, password).getLastCheckinFailure(); } public Throwable getLastCheckoutFailure(String username, String password) throws SQLException { return assertAuthPool(username, password).getLastCheckoutFailure(); } public Throwable getLastIdleTestFailure(String username, String password) throws SQLException { return assertAuthPool(username, password).getLastIdleTestFailure(); } public Throwable getLastConnectionTestFailure(String username, String password) throws SQLException { return assertAuthPool(username, password).getLastConnectionTestFailure(); } public int getNumThreadsAwaitingCheckout(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumThreadsAwaitingCheckout(); } public String sampleLastAcquisitionFailureStackTraceDefaultUser() throws SQLException { Throwable t = getLastAcquisitionFailureDefaultUser(); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastCheckinFailureStackTraceDefaultUser() throws SQLException { Throwable t = getLastCheckinFailureDefaultUser(); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastCheckoutFailureStackTraceDefaultUser() throws SQLException { Throwable t = getLastCheckoutFailureDefaultUser(); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastIdleTestFailureStackTraceDefaultUser() throws SQLException { Throwable t = getLastIdleTestFailureDefaultUser(); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastConnectionTestFailureStackTraceDefaultUser() throws SQLException { Throwable t = getLastConnectionTestFailureDefaultUser(); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastAcquisitionFailureStackTrace(String username, String password) throws SQLException { Throwable t = getLastAcquisitionFailure(username, password); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastCheckinFailureStackTrace(String username, String password) throws SQLException { Throwable t = getLastCheckinFailure(username, password); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastCheckoutFailureStackTrace(String username, String password) throws SQLException { Throwable t = getLastCheckoutFailure(username, password); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastIdleTestFailureStackTrace(String username, String password) throws SQLException { Throwable t = getLastIdleTestFailure(username, password); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public String sampleLastConnectionTestFailureStackTrace(String username, String password) throws SQLException { Throwable t = getLastConnectionTestFailure(username, password); return t == null ? null : ThrowableUtils.extractStackTrace( t ); } public void softResetDefaultUser() throws SQLException { getPoolManager().getPool().reset(); } public int getNumConnections(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumConnections(); } public int getNumIdleConnections(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumIdleConnections(); } public int getNumBusyConnections(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumBusyConnections(); } public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumUnclosedOrphanedConnections(); } public int getStatementCacheNumStatements(String username, String password) throws SQLException { return assertAuthPool(username, password).getStatementCacheNumStatements(); } public int getStatementCacheNumCheckedOut(String username, String password) throws SQLException { return assertAuthPool(username, password).getStatementCacheNumCheckedOut(); } public int getStatementCacheNumConnectionsWithCachedStatements(String username, String password) throws SQLException { return assertAuthPool(username, password).getStatementCacheNumConnectionsWithCachedStatements(); } public float getEffectivePropertyCycle(String username, String password) throws SQLException { return assertAuthPool(username, password).getEffectivePropertyCycle(); } public long getStartTimeMillis(String username, String password) throws SQLException { return assertAuthPool(username, password).getStartTime(); } public long getUpTimeMillis(String username, String password) throws SQLException { return assertAuthPool(username, password).getUpTime(); } public long getNumFailedCheckins(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumFailedCheckins(); } public long getNumFailedCheckouts(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumFailedCheckouts(); } public long getNumFailedIdleTests(String username, String password) throws SQLException { return assertAuthPool(username, password).getNumFailedIdleTests(); } public void softReset(String username, String password) throws SQLException { assertAuthPool(username, password).reset(); } public int getNumBusyConnectionsAllUsers() throws SQLException { return getPoolManager().getNumBusyConnectionsAllAuths(); } public int getNumIdleConnectionsAllUsers() throws SQLException { return getPoolManager().getNumIdleConnectionsAllAuths(); } public int getNumConnectionsAllUsers() throws SQLException { return getPoolManager().getNumConnectionsAllAuths(); } public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException { return getPoolManager().getNumUnclosedOrphanedConnectionsAllAuths(); } public int getStatementCacheNumStatementsAllUsers() throws SQLException { return getPoolManager().getStatementCacheNumStatementsAllUsers(); } public int getStatementCacheNumCheckedOutStatementsAllUsers() throws SQLException { return getPoolManager().getStatementCacheNumCheckedOutStatementsAllUsers(); } public synchronized int getStatementCacheNumConnectionsWithCachedStatementsAllUsers() throws SQLException { return getPoolManager().getStatementCacheNumConnectionsWithCachedStatementsAllUsers(); } public void softResetAllUsers() throws SQLException { getPoolManager().softResetAllAuths(); } public int getNumUserPools() throws SQLException { return getPoolManager().getNumManagedAuths(); } public Collection getAllUsers() throws SQLException { LinkedList out = new LinkedList(); Set auths = getPoolManager().getManagedAuths(); for ( Iterator ii = auths.iterator(); ii.hasNext(); ) out.add( ((DbAuth) ii.next()).getUser() ); return Collections.unmodifiableList( out ); } public synchronized void hardReset() { resetPoolManager(); } public synchronized void close() { resetPoolManager(); is_closed = true; C3P0Registry.markClosed(this); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable(MLevel.FINEST)) { logger.log(MLevel.FINEST, this.getClass().getName() + '@' + Integer.toHexString( System.identityHashCode( this ) ) + " has been closed. ", new Exception("DEBUG STACK TRACE for PoolBackedDataSource.close().")); } } /** * @deprecated the force_destroy argument is now meaningless, as pools are no longer * potentially shared between multiple DataSources. */ public void close(boolean force_destroy) { close(); } //other code public synchronized void resetPoolManager() //used by other, wrapping datasources in package, and in mbean package { resetPoolManager( true ); } public synchronized void resetPoolManager( boolean close_checked_out_connections ) //used by other, wrapping datasources in package, and in mbean package { if ( poolManager != null ) { poolManager.close( close_checked_out_connections ); poolManager = null; } } private synchronized ConnectionPoolDataSource assertCpds() throws SQLException { if ( is_closed ) throw new SQLException(this + " has been closed() -- you can no longer use it."); ConnectionPoolDataSource out = this.getConnectionPoolDataSource(); if ( out == null ) throw new SQLException(NO_CPDS_ERR_MSG); return out; } private synchronized C3P0PooledConnectionPoolManager getPoolManager() throws SQLException { if (poolManager == null) { ConnectionPoolDataSource cpds = assertCpds(); poolManager = new C3P0PooledConnectionPoolManager(cpds, null, null, this.getNumHelperThreads(), this.getIdentityToken()); if (logger.isLoggable(MLevel.INFO)) logger.info("Initializing c3p0 pool... " + this.toString() /* + "; using pool manager: " + poolManager */); } return poolManager; } private C3P0PooledConnectionPool assertAuthPool( String username, String password ) throws SQLException { C3P0PooledConnectionPool authPool = getPoolManager().getPool(username, password, false); if (authPool == null) throw new SQLException("No pool has been yet been established for Connections authenticated by user '" + username + "' with the password provided. [Use getConnection( username, password ) " + "to initialize such a pool.]"); else return authPool; } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: setUpPropertyEvents(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/AuthMaskingProperties.java0000644000175000017500000000366010624366527025305 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.util.Enumeration; import java.util.Properties; public class AuthMaskingProperties extends Properties { public AuthMaskingProperties() { super(); } public AuthMaskingProperties( Properties p ) { super( p ); } public static AuthMaskingProperties fromAnyProperties( Properties p ) { AuthMaskingProperties out = new AuthMaskingProperties(); for( Enumeration e = p.propertyNames(); e.hasMoreElements(); ) { String key = (String) e.nextElement(); out.setProperty( key, p.getProperty( key ) ); } return out; } private String normalToString() { return super.toString(); } public String toString() { boolean hasUser = (this.get("user") != null); boolean hasPassword = (this.get("password") != null); if ( hasUser || hasPassword ) { AuthMaskingProperties clone = (AuthMaskingProperties) this.clone(); if (hasUser) clone.put("user", "******"); if (hasPassword) clone.put("password", "******"); return clone.normalToString(); } else return this.normalToString(); } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/C3P0Defaults.java0000644000175000017500000001701210624366527023146 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.lang.reflect.*; import java.util.*; import com.mchange.v2.c3p0.ConnectionTester; // all public static methods should have the name of a c3p0 config property and // return its default value public final class C3P0Defaults { private final static int MAX_STATEMENTS = 0; private final static int MAX_STATEMENTS_PER_CONNECTION = 0; private final static int INITIAL_POOL_SIZE = 3; private final static int MIN_POOL_SIZE = 3; private final static int MAX_POOL_SIZE = 15; private final static int IDLE_CONNECTION_TEST_PERIOD = 0; //idle connections never tested private final static int MAX_IDLE_TIME = 0; //seconds, 0 means connections never expire private final static int PROPERTY_CYCLE = 0; //seconds private final static int ACQUIRE_INCREMENT = 3; private final static int ACQUIRE_RETRY_ATTEMPTS = 30; private final static int ACQUIRE_RETRY_DELAY = 1000; //milliseconds private final static int CHECKOUT_TIMEOUT = 0; //milliseconds private final static int MAX_ADMINISTRATIVE_TASK_TIME = 0; //seconds private final static int MAX_IDLE_TIME_EXCESS_CONNECTIONS = 0; //seconds private final static int MAX_CONNECTION_AGE = 0; //seconds private final static int UNRETURNED_CONNECTION_TIMEOUT = 0; //seconds private final static boolean BREAK_AFTER_ACQUIRE_FAILURE = false; private final static boolean TEST_CONNECTION_ON_CHECKOUT = false; private final static boolean TEST_CONNECTION_ON_CHECKIN = false; private final static boolean AUTO_COMMIT_ON_CLOSE = false; private final static boolean FORCE_IGNORE_UNRESOLVED_TXNS = false; private final static boolean USES_TRADITIONAL_REFLECTIVE_PROXIES = false; private final static boolean DEBUG_UNRETURNED_CONNECTION_STACK_TRACES = false; private final static ConnectionTester CONNECTION_TESTER = new DefaultConnectionTester(); private final static int NUM_HELPER_THREADS = 3; private final static String AUTOMATIC_TEST_TABLE = null; private final static String CONNECTION_CUSTOMIZER_CLASS_NAME = null; private final static String DRIVER_CLASS = null; private final static String JDBC_URL = null; private final static String OVERRIDE_DEFAULT_USER = null; private final static String OVERRIDE_DEFAULT_PASSWORD = null; private final static String PASSWORD = null; private final static String PREFERRED_TEST_QUERY = null; private final static String FACTORY_CLASS_LOCATION = null; private final static String USER_OVERRIDES_AS_STRING = null; private final static String USER = null; private static Set KNOWN_PROPERTIES; static { Method[] methods = C3P0Defaults.class.getMethods(); Set s = new HashSet(); for (int i = 0, len = methods.length; i < len; ++i) { Method m = methods[i]; if (Modifier.isStatic( m.getModifiers() ) && m.getParameterTypes().length == 0) s.add( m.getName() ); } KNOWN_PROPERTIES = Collections.unmodifiableSet( s ); } public static Set getKnownProperties() { return KNOWN_PROPERTIES; } public static boolean isKnownProperty( String s ) { return KNOWN_PROPERTIES.contains( s ); } public static int maxStatements() { return MAX_STATEMENTS; } public static int maxStatementsPerConnection() { return MAX_STATEMENTS_PER_CONNECTION; } public static int initialPoolSize() { return INITIAL_POOL_SIZE; } public static int minPoolSize() { return MIN_POOL_SIZE; } public static int maxPoolSize() { return MAX_POOL_SIZE; } public static int idleConnectionTestPeriod() { return IDLE_CONNECTION_TEST_PERIOD; } public static int maxIdleTime() { return MAX_IDLE_TIME; } public static int unreturnedConnectionTimeout() { return UNRETURNED_CONNECTION_TIMEOUT; } public static int propertyCycle() { return PROPERTY_CYCLE; } public static int acquireIncrement() { return ACQUIRE_INCREMENT; } public static int acquireRetryAttempts() { return ACQUIRE_RETRY_ATTEMPTS; } public static int acquireRetryDelay() { return ACQUIRE_RETRY_DELAY; } public static int checkoutTimeout() { return CHECKOUT_TIMEOUT; } public static String connectionCustomizerClassName() { return CONNECTION_CUSTOMIZER_CLASS_NAME; } public static ConnectionTester connectionTester() { return CONNECTION_TESTER; } public static String connectionTesterClassName() { return CONNECTION_TESTER.getClass().getName(); } public static String automaticTestTable() { return AUTOMATIC_TEST_TABLE; } public static String driverClass() { return DRIVER_CLASS; } public static String jdbcUrl() { return JDBC_URL; } public static int numHelperThreads() { return NUM_HELPER_THREADS; } public static boolean breakAfterAcquireFailure() { return BREAK_AFTER_ACQUIRE_FAILURE; } public static boolean testConnectionOnCheckout() { return TEST_CONNECTION_ON_CHECKOUT; } public static boolean testConnectionOnCheckin() { return TEST_CONNECTION_ON_CHECKIN; } public static boolean autoCommitOnClose() { return AUTO_COMMIT_ON_CLOSE; } public static boolean forceIgnoreUnresolvedTransactions() { return FORCE_IGNORE_UNRESOLVED_TXNS; } public static boolean debugUnreturnedConnectionStackTraces() { return DEBUG_UNRETURNED_CONNECTION_STACK_TRACES; } public static boolean usesTraditionalReflectiveProxies() { return USES_TRADITIONAL_REFLECTIVE_PROXIES; } public static String preferredTestQuery() { return PREFERRED_TEST_QUERY; } public static String userOverridesAsString() { return USER_OVERRIDES_AS_STRING; } public static String factoryClassLocation() { return FACTORY_CLASS_LOCATION; } public static String overrideDefaultUser() { return OVERRIDE_DEFAULT_USER; } public static String overrideDefaultPassword() { return OVERRIDE_DEFAULT_PASSWORD; } public static String user() { return USER; } public static String password() { return PASSWORD; } public static int maxAdministrativeTaskTime() { return MAX_ADMINISTRATIVE_TASK_TIME; } public static int maxIdleTimeExcessConnections() { return MAX_IDLE_TIME_EXCESS_CONNECTIONS; } public static int maxConnectionAge() { return MAX_CONNECTION_AGE; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/C3P0ImplUtils.java0000644000175000017500000003106110624366530023313 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.beans.*; import java.util.*; import java.lang.reflect.*; import java.net.InetAddress; import com.mchange.v2.c3p0.*; import com.mchange.v2.cfg.MultiPropertiesConfig; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.security.SecureRandom; import java.sql.Connection; import java.sql.SQLException; import com.mchange.lang.ByteUtils; import com.mchange.v2.encounter.EncounterCounter; import com.mchange.v2.encounter.EqualityEncounterCounter; import com.mchange.v2.lang.VersionUtils; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.ser.SerializableUtils; import com.mchange.v2.sql.SqlUtils; public final class C3P0ImplUtils { // turning this on would only test to generate long tokens // on 64 bit machines, but since identityHashCode() is not // GUARANTEED unique under 32-bit JVMs, even if in practice // always is, we always test to be sure we're not reusing // an identity token. private final static boolean CONDITIONAL_LONG_TOKENS = false; final static MLogger logger = MLog.getLogger( C3P0ImplUtils.class ); public final static DbAuth NULL_AUTH = new DbAuth(null,null); public final static Object[] NOARGS = new Object[0]; private final static EncounterCounter ID_TOKEN_COUNTER; static { if (CONDITIONAL_LONG_TOKENS) { boolean long_tokens; Integer jnb = VersionUtils.jvmNumberOfBits(); if (jnb == null) long_tokens = true; else if (jnb.intValue() > 32) long_tokens = true; else long_tokens = false; if (long_tokens) ID_TOKEN_COUNTER = new EqualityEncounterCounter(); else ID_TOKEN_COUNTER = null; } else ID_TOKEN_COUNTER = new EqualityEncounterCounter(); } public final static String VMID_PROPKEY = "com.mchange.v2.c3p0.VMID"; private final static String VMID_PFX; static { String vmid = MultiPropertiesConfig.readVmConfig().getProperty(VMID_PROPKEY); if (vmid == null || (vmid = vmid.trim()).equals("") || vmid.equals("AUTO")) VMID_PFX = generateVmId() + '|'; else if (vmid.equals("NONE")) VMID_PFX = ""; else VMID_PFX = vmid + "|"; } //MT: protected by class' lock static String connectionTesterClassName = null; static ConnectionTester cachedTester = null; private static String generateVmId() { DataOutputStream dos = null; DataInputStream dis = null; try { SecureRandom srand = new SecureRandom(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); dos = new DataOutputStream( baos ); try { dos.write( InetAddress.getLocalHost().getAddress() ); } catch (Exception e) { if (logger.isLoggable(MLevel.INFO)) logger.log(MLevel.INFO, "Failed to get local InetAddress for VMID. This is unlikely to matter. At all. We'll add some extra randomness", e); dos.write( srand.nextInt() ); } dos.writeLong(System.currentTimeMillis()); dos.write( srand.nextInt() ); int remainder = baos.size() % 4; //if it wasn't a 4 byte inet address if (remainder > 0) { int pad = 4 - remainder; byte[] pad_bytes = new byte[pad]; srand.nextBytes(pad_bytes); dos.write(pad_bytes); } StringBuffer sb = new StringBuffer(32); byte[] vmid_bytes = baos.toByteArray(); dis = new DataInputStream(new ByteArrayInputStream( vmid_bytes ) ); for (int i = 0, num_ints = vmid_bytes.length / 4; i < num_ints; ++i) { int signed = dis.readInt(); long unsigned = ((long) signed) & 0x00000000FFFFFFFFL; sb.append(Long.toString(unsigned, Character.MAX_RADIX)); } return sb.toString(); } catch (IOException e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Bizarro! IOException while reading/writing from ByteArray-based streams? " + "We're skipping the VMID thing. It almost certainly doesn't matter, " + "but please report the error.", e); return ""; } finally { // this is like total overkill for byte-array based streams, // but it's a good habit try { if (dos != null) dos.close(); } catch ( IOException e ) { logger.log(MLevel.WARNING, "Huh? Exception close()ing a byte-array bound OutputStream.", e); } try { if (dis != null) dis.close(); } catch ( IOException e ) { logger.log(MLevel.WARNING, "Huh? Exception close()ing a byte-array bound IntputStream.", e); } } } // identityHashCode() is not a sufficient unique token, because they are // not guaranteed unique, and in practice are occasionally not unique, // particularly on 64-bit systems. public static String allocateIdentityToken(Object o) { if (o == null) return null; else { String shortIdToken = Integer.toString( System.identityHashCode( o ), 16 ); //new Exception( "DEBUG_STACK_TRACE: " + o.getClass().getName() + " " + shortIdToken ).printStackTrace(); String out; long count; StringBuffer sb = new StringBuffer(128); sb.append(VMID_PFX); if (ID_TOKEN_COUNTER != null && ((count = ID_TOKEN_COUNTER.encounter( shortIdToken )) > 0)) { sb.append( shortIdToken ); sb.append('#'); sb.append( count ); } else sb.append(shortIdToken); out = sb.toString().intern(); return out; } } public static DbAuth findAuth(Object o) throws SQLException { if ( o == null ) return NULL_AUTH; String user = null; String password = null; String overrideDefaultUser = null; String overrideDefaultPassword = null; try { BeanInfo bi = Introspector.getBeanInfo( o.getClass() ); PropertyDescriptor[] pds = bi.getPropertyDescriptors(); for (int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; Class propCl = pd.getPropertyType(); String propName = pd.getName(); if (propCl == String.class) { // System.err.println( "---> " + propName ); // System.err.println( o.getClass() ); // System.err.println( pd.getReadMethod() ); Method readMethod = pd.getReadMethod(); if (readMethod != null) { Object propVal = readMethod.invoke( o, NOARGS ); String value = (String) propVal; if ("user".equals(propName)) user = value; else if ("password".equals(propName)) password = value; else if ("overrideDefaultUser".equals(propName)) overrideDefaultUser = value; else if ("overrideDefaultPassword".equals(propName)) overrideDefaultPassword = value; } } } if (overrideDefaultUser != null) return new DbAuth( overrideDefaultUser, overrideDefaultPassword ); else if (user != null) return new DbAuth( user, password ); else return NULL_AUTH; } catch (Exception e) { if (Debug.DEBUG && logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "An exception occurred while trying to extract the default authentification info from a bean.", e ); throw SqlUtils.toSQLException(e); } } static void resetTxnState( Connection pCon, boolean forceIgnoreUnresolvedTransactions, boolean autoCommitOnClose, boolean txnKnownResolved ) throws SQLException { if ( !forceIgnoreUnresolvedTransactions && !pCon.getAutoCommit() ) { if (! autoCommitOnClose && ! txnKnownResolved) { //System.err.println("Rolling back potentially unresolved txn..."); pCon.rollback(); } pCon.setAutoCommit( true ); //implies commit if not already rolled back. } } public synchronized static ConnectionTester defaultConnectionTester() { String dfltCxnTesterClassName = PoolConfig.defaultConnectionTesterClassName(); if ( connectionTesterClassName != null && connectionTesterClassName.equals(dfltCxnTesterClassName) ) return cachedTester; else { try { cachedTester = (ConnectionTester) Class.forName( dfltCxnTesterClassName ).newInstance(); connectionTesterClassName = cachedTester.getClass().getName(); } catch ( Exception e ) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log(MLevel.WARNING, "Could not load ConnectionTester " + dfltCxnTesterClassName + ", using built in default.", e); cachedTester = C3P0Defaults.connectionTester(); connectionTesterClassName = cachedTester.getClass().getName(); } return cachedTester; } } public static boolean supportsMethod(Object target, String mname, Class[] argTypes) { try {return (target.getClass().getMethod( mname, argTypes ) != null); } catch ( NoSuchMethodException e ) { return false; } catch (SecurityException e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log(MLevel.FINE, "We were denied access in a check of whether " + target + " supports method " + mname + ". Prob means external clients have no access, returning false.", e); return false; } } private final static String HASM_HEADER = "HexAsciiSerializedMap"; public static String createUserOverridesAsString( Map userOverrides ) throws IOException { StringBuffer sb = new StringBuffer(); sb.append(HASM_HEADER); sb.append('['); sb.append( ByteUtils.toHexAscii( SerializableUtils.toByteArray( userOverrides ) ) ); sb.append(']'); return sb.toString(); } public static Map parseUserOverridesAsString( String userOverridesAsString ) throws IOException, ClassNotFoundException { if (userOverridesAsString != null) { String hexAscii = userOverridesAsString.substring(HASM_HEADER.length() + 1, userOverridesAsString.length() - 1); byte[] serBytes = ByteUtils.fromHexAscii( hexAscii ); return Collections.unmodifiableMap( (Map) SerializableUtils.fromByteArray( serBytes ) ); } else return Collections.EMPTY_MAP; } private C3P0ImplUtils() {} } // Class methodClass = readMethod.getDeclaringClass(); // Package methodPkg = methodClass.getPackage(); // System.err.println( methodPkg.getName() + '\t' + C3P0ImplUtils.class.getPackage().getName() ); // if (! methodPkg.getName().equals( // C3P0ImplUtils.class.getPackage().getName() ) ) // { // System.err.println("public check: " + (methodClass.getModifiers() & Modifier.PUBLIC)); // if ((methodClass.getModifiers() & Modifier.PUBLIC) == 0) // { // System.err.println("SKIPPED -- Can't Access!"); // continue; // } // } // System.err.println( o ); /* private final static ThreadLocal threadLocalConnectionCustomizer = new ThreadLocal(); // used so that C3P0PooledConnectionPool can pass a ConnectionCustomizer // to WrapperConnectionPoolDataSource without altering that class' public API public static void setThreadConnectionCustomizer(ConnectionCustomizer cc) { threadLocalConnectionCustomizer.set( cc ); } public static ConnectionCustomizer getThreadConnectionCustomizer() { return threadLocalConnectionCustomizer.get(); } public static void unsetThreadConnectionCustomizer() { setThreadConnectionCustomizer( null ); } */ c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/C3P0JavaBeanObjectFactory.java0000644000175000017500000000371010624366530025517 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.lang.reflect.Constructor; import java.util.Map; import java.util.Set; import com.mchange.v2.c3p0.C3P0Registry; import com.mchange.v2.naming.JavaBeanObjectFactory; public class C3P0JavaBeanObjectFactory extends JavaBeanObjectFactory { private final static Class[] CTOR_ARG_TYPES = new Class[] { boolean.class }; private final static Object[] CTOR_ARGS = new Object[] { Boolean.FALSE }; protected Object createBlankInstance(Class beanClass) throws Exception { if ( IdentityTokenized.class.isAssignableFrom( beanClass ) ) { Constructor ctor = beanClass.getConstructor( CTOR_ARG_TYPES ); return ctor.newInstance( CTOR_ARGS ); } else return super.createBlankInstance( beanClass ); } protected Object findBean(Class beanClass, Map propertyMap, Set refProps ) throws Exception { Object out = super.findBean( beanClass, propertyMap, refProps ); if (out instanceof IdentityTokenized) out = C3P0Registry.reregister( (IdentityTokenized) out ); //System.err.println("--> findBean()"); //System.err.println(out); return out; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/C3P0PooledConnection.java0000644000175000017500000011112710624366527024643 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.lang.reflect.*; import java.sql.*; import java.util.*; import javax.sql.*; import com.mchange.v2.log.*; import com.mchange.v2.sql.*; import com.mchange.v2.sql.filter.*; import com.mchange.v2.c3p0.*; import com.mchange.v2.c3p0.stmt.*; import com.mchange.v2.c3p0.C3P0ProxyConnection; import com.mchange.v2.c3p0.util.ConnectionEventSupport; import com.mchange.v2.lang.ObjectUtils; public final class C3P0PooledConnection extends AbstractC3P0PooledConnection { final static MLogger logger = MLog.getLogger( C3P0PooledConnection.class ); final static Class[] PROXY_CTOR_ARGS = new Class[]{ InvocationHandler.class }; final static Constructor CON_PROXY_CTOR; final static Method RS_CLOSE_METHOD; final static Method STMT_CLOSE_METHOD; final static Object[] CLOSE_ARGS; final static Set OBJECT_METHODS; /** * @deprecated use or rewrite in terms of ReflectUtils.findProxyConstructor() */ private static Constructor createProxyConstructor(Class intfc) throws NoSuchMethodException { Class[] proxyInterfaces = new Class[] { intfc }; Class proxyCl = Proxy.getProxyClass(C3P0PooledConnection.class.getClassLoader(), proxyInterfaces); return proxyCl.getConstructor( PROXY_CTOR_ARGS ); } static { try { CON_PROXY_CTOR = createProxyConstructor( ProxyConnection.class ); Class[] argClasses = new Class[0]; RS_CLOSE_METHOD = ResultSet.class.getMethod("close", argClasses); STMT_CLOSE_METHOD = Statement.class.getMethod("close", argClasses); CLOSE_ARGS = new Object[0]; OBJECT_METHODS = Collections.unmodifiableSet( new HashSet( Arrays.asList( Object.class.getMethods() ) ) ); } catch (Exception e) { //e.printStackTrace(); logger.log(MLevel.SEVERE, "An Exception occurred in static initializer of" + C3P0PooledConnection.class.getName(), e); throw new InternalError("Something is very wrong, or this is a pre 1.3 JVM." + "We cannot set up dynamic proxies and/or methods!"); } } //MT: post-constructor constants final ConnectionTester connectionTester; final boolean autoCommitOnClose; final boolean forceIgnoreUnresolvedTransactions; final boolean supports_setTypeMap; final boolean supports_setHoldability; final int dflt_txn_isolation; final String dflt_catalog; final int dflt_holdability; //MT: thread-safe final ConnectionEventSupport ces = new ConnectionEventSupport(this); //MT: threadsafe, but reassigned (on close) volatile Connection physicalConnection; volatile Exception invalidatingException = null; //MT: threadsafe, but reassigned, and a read + reassignment must happen // atomically. protected by this' lock. ProxyConnection exposedProxy; //MT: protected by this' lock int connection_status = ConnectionTester.CONNECTION_IS_OKAY; /* * contains all unclosed Statements not managed by a StatementCache * associated with the physical connection * * MT: protected by its own lock, not reassigned */ final Set uncachedActiveStatements = Collections.synchronizedSet( new HashSet() ); //MT: Thread-safe, assigned volatile GooGooStatementCache scache; volatile boolean isolation_lvl_nondefault = false; volatile boolean catalog_nondefault = false; volatile boolean holdability_nondefault = false; public C3P0PooledConnection(Connection con, ConnectionTester connectionTester, boolean autoCommitOnClose, boolean forceIgnoreUnresolvedTransactions, ConnectionCustomizer cc, String pdsIdt) throws SQLException { try { if (cc != null) cc.onAcquire( con, pdsIdt ); } catch (Exception e) { throw SqlUtils.toSQLException(e); } this.physicalConnection = con; this.connectionTester = connectionTester; this.autoCommitOnClose = autoCommitOnClose; this.forceIgnoreUnresolvedTransactions = forceIgnoreUnresolvedTransactions; this.supports_setTypeMap = C3P0ImplUtils.supportsMethod(con, "setTypeMap", new Class[]{ Map.class }); this.supports_setHoldability = C3P0ImplUtils.supportsMethod(con, "setHoldability", new Class[]{ int.class }); this.dflt_txn_isolation = con.getTransactionIsolation(); this.dflt_catalog = con.getCatalog(); this.dflt_holdability = (supports_setHoldability ? con.getHoldability() : ResultSet.CLOSE_CURSORS_AT_COMMIT); } //used by C3P0PooledConnectionPool Connection getPhysicalConnection() { return physicalConnection; } boolean isClosed() throws SQLException { return (physicalConnection == null); } void initStatementCache( GooGooStatementCache scache ) { this.scache = scache; } //DEBUG //Exception origGet = null; // synchronized to protect exposedProxy public synchronized Connection getConnection() throws SQLException { if ( exposedProxy != null) { //DEBUG //System.err.println("[DOUBLE_GET_TESTER] -- double getting a Connection from " + this ); //new Exception("[DOUBLE_GET_TESTER] -- Double-Get Stack Trace").printStackTrace(); //origGet.printStackTrace(); // System.err.println("c3p0 -- Uh oh... getConnection() was called on a PooledConnection when " + // "it had already provided a client with a Connection that has not yet been " + // "closed. This probably indicates a bug in the connection pool!!!"); logger.warning("c3p0 -- Uh oh... getConnection() was called on a PooledConnection when " + "it had already provided a client with a Connection that has not yet been " + "closed. This probably indicates a bug in the connection pool!!!"); return exposedProxy; } else { return getCreateNewConnection(); } } // must be called from sync'ed method to protecte // exposedProxy private Connection getCreateNewConnection() throws SQLException { try { //DEBUG //origGet = new Exception("[DOUBLE_GET_TESTER] -- Orig Get"); ensureOkay(); /* * we reset the physical connection when we close an exposed proxy * no need to do it again when we create one */ //reset(); return (exposedProxy = createProxyConnection()); } catch (SQLException e) { throw e; } catch (Exception e) { //e.printStackTrace(); logger.log(MLevel.WARNING, "Failed to acquire connection!", e); throw new SQLException("Failed to acquire connection!"); } } public void closeAll() throws SQLException { if (scache != null) scache.closeAll( physicalConnection ); } public void close() throws SQLException { this.close( false ); } //TODO: factor out repetitive debugging code private synchronized void close(boolean known_invalid) throws SQLException { //System.err.println("Closing " + this); if ( physicalConnection != null ) { try { StringBuffer debugOnlyLog = null; if ( Debug.DEBUG && known_invalid ) { debugOnlyLog = new StringBuffer(); debugOnlyLog.append("[ exceptions: "); } Exception exc = cleanupUncachedActiveStatements(); if (Debug.DEBUG && exc != null) { if (known_invalid) debugOnlyLog.append( exc.toString() + ' ' ); else logger.log(MLevel.WARNING, "An exception occurred while cleaning up uncached active Statements.", exc); //exc.printStackTrace(); } try { // we've got to use silentClose() rather than close() here, // 'cuz if there's still an exposedProxy (say a user forgot to // close his Connection) before we close, and we use regular (loud) // close, we will try to check this dead or dying PooledConnection // back into the pool. We only want to do this when close is called // on user proxies, and the underlying PooledConnection might still // be good. The PooledConnection itself should only be closed by the // pool. if (exposedProxy != null) exposedProxy.silentClose( known_invalid ); } catch (Exception e) { if (Debug.DEBUG) { if (known_invalid) debugOnlyLog.append( e.toString() + ' ' ); else logger.log(MLevel.WARNING, "An exception occurred.", exc); //e.printStackTrace(); } exc = e; } try { this.closeAll(); } catch (Exception e) { if (Debug.DEBUG) { if (known_invalid) debugOnlyLog.append( e.toString() + ' ' ); else logger.log(MLevel.WARNING, "An exception occurred.", exc); //e.printStackTrace(); } exc = e; } try { physicalConnection.close(); } catch (Exception e) { if (Debug.DEBUG) { if (known_invalid) debugOnlyLog.append( e.toString() + ' ' ); else logger.log(MLevel.WARNING, "An exception occurred.", exc); e.printStackTrace(); } exc = e; } if (exc != null) { if (known_invalid) { debugOnlyLog.append(" ]"); if (Debug.DEBUG) { // System.err.print("[DEBUG]" + this + ": while closing a PooledConnection known to be invalid, "); // System.err.println(" some exceptions occurred. This is probably not a problem:"); // System.err.println( debugOnlyLog.toString() ); logger.fine(this + ": while closing a PooledConnection known to be invalid, " + " some exceptions occurred. This is probably not a problem: " + debugOnlyLog.toString() ); } } else throw new SQLException("At least one error occurred while attempting " + "to close() the PooledConnection: " + exc); } if (Debug.TRACE == Debug.TRACE_MAX) logger.fine("C3P0PooledConnection closed. [" + this + ']'); //System.err.println("C3P0PooledConnection closed. [" + this + ']'); } finally { physicalConnection = null; } } } public void addConnectionEventListener(ConnectionEventListener listener) { ces.addConnectionEventListener( listener ); } public void removeConnectionEventListener(ConnectionEventListener listener) { ces.removeConnectionEventListener( listener ); } private void reset() throws SQLException { reset( false ); } private void reset( boolean known_resolved_txn ) throws SQLException { ensureOkay(); C3P0ImplUtils.resetTxnState( physicalConnection, forceIgnoreUnresolvedTransactions, autoCommitOnClose, known_resolved_txn ); if (isolation_lvl_nondefault) { physicalConnection.setTransactionIsolation( dflt_txn_isolation ); isolation_lvl_nondefault = false; } if (catalog_nondefault) { physicalConnection.setCatalog( dflt_catalog ); catalog_nondefault = false; } if (holdability_nondefault) //we don't test if holdability is supported, 'cuz it can never go nondefault if it's not. { physicalConnection.setHoldability( dflt_holdability ); holdability_nondefault = false; } try { physicalConnection.setReadOnly( false ); } catch ( Throwable t ) { if (logger.isLoggable( MLevel.FINE )) logger.log(MLevel.FINE, "A Throwable occurred while trying to reset the readOnly property of our Connection to false!", t); } try { if (supports_setTypeMap) physicalConnection.setTypeMap( Collections.EMPTY_MAP ); } catch ( Throwable t ) { if (logger.isLoggable( MLevel.FINE )) logger.log(MLevel.FINE, "A Throwable occurred while trying to reset the typeMap property of our Connection to Collections.EMPTY_MAP!", t); } } boolean closeAndRemoveResultSets(Set rsSet) { boolean okay = true; synchronized (rsSet) { for (Iterator ii = rsSet.iterator(); ii.hasNext(); ) { ResultSet rs = (ResultSet) ii.next(); try { rs.close(); } catch (SQLException e) { if (Debug.DEBUG) logger.log(MLevel.WARNING, "An exception occurred while cleaning up a ResultSet.", e); //e.printStackTrace(); okay = false; } finally { ii.remove(); } } } return okay; } void ensureOkay() throws SQLException { if (physicalConnection == null) throw new SQLException( invalidatingException == null ? "Connection is closed or broken." : "Connection is broken. Invalidating Exception: " + invalidatingException.toString()); } 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; } private SQLException cleanupUncachedActiveStatements() { //System.err.println("IN uncachedActiveStatements.size(): " + uncachedActiveStatements.size()); boolean okay = closeAndRemoveResourcesInSet(uncachedActiveStatements, STMT_CLOSE_METHOD); //System.err.println("OUT uncachedActiveStatements.size(): " + uncachedActiveStatements.size()); if (okay) return null; else return new SQLException("An exception occurred while trying to " + "clean up orphaned resources."); } ProxyConnection createProxyConnection() throws Exception { // we should always have a separate handler for each proxy connection, so // that object methods behave as expected... the handler covers // all object methods on behalf of the proxy. InvocationHandler handler = new ProxyConnectionInvocationHandler(); return (ProxyConnection) CON_PROXY_CTOR.newInstance( new Object[] {handler} ); } Statement createProxyStatement( Statement innerStmt ) throws Exception { return this.createProxyStatement( false, innerStmt ); } private static class StatementProxyingSetManagedResultSet extends SetManagedResultSet { private Statement proxyStatement; StatementProxyingSetManagedResultSet(Set activeResultSets) { super( activeResultSets ); } public void setProxyStatement( Statement proxyStatement ) { this.proxyStatement = proxyStatement; } public Statement getStatement() throws SQLException { return (proxyStatement == null ? super.getStatement() : proxyStatement); } } /* * TODO: factor all this convolution out into * C3P0Statement */ Statement createProxyStatement( //final Method cachedStmtProducingMethod, //final Object[] cachedStmtProducingMethodArgs, final boolean inner_is_cached, final Statement innerStmt) throws Exception { final Set activeResultSets = Collections.synchronizedSet( new HashSet() ); final Connection parentConnection = exposedProxy; if (Debug.DEBUG && parentConnection == null) { // System.err.print("PROBABLE C3P0 BUG -- "); // System.err.println(this + ": created a proxy Statement when there is no active, exposed proxy Connection???"); logger.warning("PROBABLE C3P0 BUG -- " + this + ": created a proxy Statement when there is no active, exposed proxy Connection???"); } //we can use this one wrapper under all circumstances //except jdbc3 CallableStatement multiple open ResultSets... //avoid object allocation in statement methods where possible. final StatementProxyingSetManagedResultSet mainResultSet = new StatementProxyingSetManagedResultSet( activeResultSets ); class WrapperStatementHelper { Statement wrapperStmt; Statement nakedInner; public WrapperStatementHelper(Statement wrapperStmt, Statement nakedInner) { this.wrapperStmt = wrapperStmt; this.nakedInner = nakedInner; if (! inner_is_cached) uncachedActiveStatements.add( wrapperStmt ); } private boolean closeAndRemoveActiveResultSets() { return closeAndRemoveResultSets( activeResultSets ); } public ResultSet wrap(ResultSet rs) { if (mainResultSet.getInner() == null) { mainResultSet.setInner(rs); mainResultSet.setProxyStatement( wrapperStmt ); return mainResultSet; } else { //for the case of multiple open ResultSets StatementProxyingSetManagedResultSet out = new StatementProxyingSetManagedResultSet( activeResultSets ); out.setInner( rs ); out.setProxyStatement( wrapperStmt ); return out; } } public void doClose() throws SQLException { boolean okay = closeAndRemoveActiveResultSets(); if (inner_is_cached) //this statement was cached scache.checkinStatement( innerStmt ); else { innerStmt.close(); uncachedActiveStatements.remove( wrapperStmt ); } if (!okay) throw new SQLException("Failed to close an orphaned ResultSet properly."); } 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; } } if (innerStmt instanceof CallableStatement) { class ProxyCallableStatement extends FilterCallableStatement implements C3P0ProxyStatement { WrapperStatementHelper wsh; ProxyCallableStatement(CallableStatement is) { super( is ); this.wsh = new WrapperStatementHelper(this, is); } public Connection getConnection() { return parentConnection; } public ResultSet getResultSet() throws SQLException { return wsh.wrap( super.getResultSet() ); } public ResultSet getGeneratedKeys() throws SQLException { return wsh.wrap( super.getGeneratedKeys() ); } public ResultSet executeQuery(String sql) throws SQLException { return wsh.wrap( super.executeQuery(sql) ); } public ResultSet executeQuery() throws SQLException { return wsh.wrap( super.executeQuery() ); } public Object rawStatementOperation(Method m, Object target, Object[] args) throws IllegalAccessException, InvocationTargetException, SQLException { return wsh.doRawStatementOperation( m, target, args); } public void close() throws SQLException { wsh.doClose(); } } return new ProxyCallableStatement((CallableStatement) innerStmt ); } else if (innerStmt instanceof PreparedStatement) { class ProxyPreparedStatement extends FilterPreparedStatement implements C3P0ProxyStatement { WrapperStatementHelper wsh; ProxyPreparedStatement(PreparedStatement ps) { super( ps ); this.wsh = new WrapperStatementHelper(this, ps); } public Connection getConnection() { return parentConnection; } public ResultSet getResultSet() throws SQLException { return wsh.wrap( super.getResultSet() ); } public ResultSet getGeneratedKeys() throws SQLException { return wsh.wrap( super.getGeneratedKeys() ); } public ResultSet executeQuery(String sql) throws SQLException { return wsh.wrap( super.executeQuery(sql) ); } public ResultSet executeQuery() throws SQLException { return wsh.wrap( super.executeQuery() ); } public Object rawStatementOperation(Method m, Object target, Object[] args) throws IllegalAccessException, InvocationTargetException, SQLException { return wsh.doRawStatementOperation( m, target, args); } public void close() throws SQLException { wsh.doClose(); } } return new ProxyPreparedStatement((PreparedStatement) innerStmt ); } else { class ProxyStatement extends FilterStatement implements C3P0ProxyStatement { WrapperStatementHelper wsh; ProxyStatement(Statement s) { super( s ); this.wsh = new WrapperStatementHelper(this, s); } public Connection getConnection() { return parentConnection; } public ResultSet getResultSet() throws SQLException { return wsh.wrap( super.getResultSet() ); } public ResultSet getGeneratedKeys() throws SQLException { return wsh.wrap( super.getGeneratedKeys() ); } public ResultSet executeQuery(String sql) throws SQLException { return wsh.wrap( super.executeQuery(sql) ); } public Object rawStatementOperation(Method m, Object target, Object[] args) throws IllegalAccessException, InvocationTargetException, SQLException { return wsh.doRawStatementOperation( m, target, args); } public void close() throws SQLException { wsh.doClose(); } } return new ProxyStatement( innerStmt ); } } final class ProxyConnectionInvocationHandler implements InvocationHandler { //MT: ThreadSafe, but reassigned -- protected by this' lock Connection activeConnection = physicalConnection; DatabaseMetaData metaData = null; boolean connection_error_signaled = false; /* * contains all unclosed ResultSets derived from this Connection's metadata * associated with the physical connection * * MT: protected by this' lock */ final Set activeMetaDataResultSets = new HashSet(); //being careful with doRawConnectionOperation //we initialize lazily, because this will be very rarely used Set doRawResultSets = null; boolean txn_known_resolved = true; public String toString() { return "C3P0ProxyConnection [Invocation Handler: " + super.toString() + ']'; } 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; } } private Exception doSilentClose(Object proxyConnection, boolean pooled_connection_is_dead) { return doSilentClose( proxyConnection, pooled_connection_is_dead, false ); } private Exception doSilentClose(Object proxyConnection, boolean pooled_connection_is_dead, boolean known_resolved_txn) { if ( activeConnection != null ) { synchronized ( C3P0PooledConnection.this ) //uh oh... this is a nested lock acq... is there a deadlock hazard here? { if ( C3P0PooledConnection.this.exposedProxy == proxyConnection ) { C3P0PooledConnection.this.exposedProxy = null; //System.err.println("Reset exposed proxy."); //DEBUG //origGet = null; } else //else case -- DEBUG only logger.warning("(c3p0 issue) doSilentClose( ... ) called on a proxyConnection " + "other than the current exposed proxy for its PooledConnection. [exposedProxy: " + exposedProxy + ", proxyConnection: " + proxyConnection); // System.err.println("[DEBUG] WARNING: doSilentClose( ... ) called on a proxyConnection " + // "other than the current exposed proxy for its PooledConnection. [exposedProxy: " + // exposedProxy + ", proxyConnection: " + proxyConnection); } Exception out = null; Exception exc1 = null, exc2 = null, exc3 = null, exc4 = null; try { if (! pooled_connection_is_dead) C3P0PooledConnection.this.reset(known_resolved_txn); } catch (Exception e) { exc1 = e; // if (Debug.DEBUG) // { // System.err.print("exc1 -- "); // exc1.printStackTrace(); // } } exc2 = cleanupUncachedActiveStatements(); // if (Debug.DEBUG && exc2 != null) // { // System.err.print("exc2 -- "); // exc2.printStackTrace(); // } String errSource; if (doRawResultSets != null) { activeMetaDataResultSets.addAll( doRawResultSets ); errSource = "DataBaseMetaData or raw Connection operation"; } else errSource = "DataBaseMetaData"; if (!closeAndRemoveResultSets( activeMetaDataResultSets )) exc3 = new SQLException("Failed to close some " + errSource + " Result Sets."); // if (Debug.DEBUG && exc3 != null) // { // System.err.print("exc3 -- "); // exc3.printStackTrace(); // } if (scache != null) { try { scache.checkinAll( physicalConnection ); } catch ( Exception e ) { exc4 = e; } // if (Debug.DEBUG && exc4 != null) // { // System.err.print("exc4 -- "); // exc4.printStackTrace(); // } } if (exc1 != null) { handleMaybeFatalToPooledConnection( exc1, proxyConnection, true ); out = exc1; } else if (exc2 != null) { handleMaybeFatalToPooledConnection( exc2, proxyConnection, true ); out = exc2; } else if (exc3 != null) { handleMaybeFatalToPooledConnection( exc3, proxyConnection, true ); out = exc3; } else if (exc4 != null) { handleMaybeFatalToPooledConnection( exc4, proxyConnection, true ); out = exc4; } // if (out != null) // { // System.err.print("out -- "); // out.printStackTrace(); // } activeConnection = null; return out; } else return null; } private SQLException handleMaybeFatalToPooledConnection( Throwable t, Object proxyConnection, boolean already_closed ) { //System.err.println("handleMaybeFatalToPooledConnection()"); SQLException sqle = SqlUtils.toSQLException( t ); int status = connectionTester.statusOnException( physicalConnection, sqle ); updateConnectionStatus( status ); if (status != ConnectionTester.CONNECTION_IS_OKAY) { if (Debug.DEBUG) { // System.err.print(C3P0PooledConnection.this + " will no longer be pooled because it has been " + // "marked invalid by the following Exception: "); // t.printStackTrace(); logger.log(MLevel.INFO, C3P0PooledConnection.this + " will no longer be pooled because it has been marked invalid by an Exception.", t ); } invalidatingException = sqle; /* ------ A users have complained that SQLExceptions ought not close their Connections underneath them under any circumstance. Signalling the Connection error after updating the Connection status should be sufficient from the pool's perspective, because the PooledConnection will be marked broken by the pool and will be destroyed on checkin. I think actually close()ing the Connection when it appears to be broken rather than waiting for users to close() it themselves is overly aggressive, so I'm commenting the old behavior out. The only potential downside to this approach is that users who do not close() in a finally clause properly might see their close()es skipped by exceptions that previously would have led to automatic close(). But relying on the automatic close() was never reliable (since it only ever happened when c3p0 determined a Connection to be absolutely broken), and is generally speaking a client error that c3p0 ought not be responsible for dealing with. I think it's right to leave this out. -- swaldman 2004-12-09 ------ if (! already_closed ) doSilentClose( proxyConnection, true ); */ if (! connection_error_signaled) { ces.fireConnectionErrorOccurred( sqle ); connection_error_signaled = true; } } return sqle; } } interface ProxyConnection extends C3P0ProxyConnection { void silentClose( boolean known_invalid ) throws SQLException; } public synchronized int getConnectionStatus() { return this.connection_status; } private synchronized void updateConnectionStatus(int status) { switch ( this.connection_status ) { case ConnectionTester.DATABASE_IS_INVALID: //can't get worse than this, do nothing. break; case ConnectionTester.CONNECTION_IS_INVALID: if (status == ConnectionTester.DATABASE_IS_INVALID) doBadUpdate(status); break; case ConnectionTester.CONNECTION_IS_OKAY: if (status != ConnectionTester.CONNECTION_IS_OKAY) doBadUpdate(status); break; default: throw new InternalError(this + " -- Illegal Connection Status: " + this.connection_status); } } //must be called from sync'ed method private void doBadUpdate(int new_status) { this.connection_status = new_status; try { this.close( true ); } catch (SQLException e) { // System.err.print("Broken Connection Close Error: "); // e.printStackTrace(); logger.log(MLevel.WARNING, "Broken Connection Close Error. ", e); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/C3P0PooledConnectionPool.java0000644000175000017500000011565310624366527025505 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import com.mchange.v2.c3p0.stmt.*; import com.mchange.v2.c3p0.ConnectionCustomizer; import com.mchange.v2.c3p0.SQLWarnings; import com.mchange.v2.c3p0.UnifiedConnectionTester; import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.LinkedList; import javax.sql.ConnectionEvent; import javax.sql.ConnectionEventListener; import javax.sql.ConnectionPoolDataSource; import javax.sql.PooledConnection; import com.mchange.v1.db.sql.ConnectionUtils; import com.mchange.v2.async.AsynchronousRunner; import com.mchange.v2.async.ThreadPoolAsynchronousRunner; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.c3p0.ConnectionTester; import com.mchange.v2.c3p0.QueryConnectionTester; import com.mchange.v2.resourcepool.CannotAcquireResourceException; import com.mchange.v2.resourcepool.ResourcePool; import com.mchange.v2.resourcepool.ResourcePoolException; import com.mchange.v2.resourcepool.ResourcePoolFactory; import com.mchange.v2.resourcepool.TimeoutException; import com.mchange.v2.sql.SqlUtils; public final class C3P0PooledConnectionPool { private final static boolean ASYNCHRONOUS_CONNECTION_EVENT_LISTENER = false; private final static Throwable[] EMPTY_THROWABLE_HOLDER = new Throwable[1]; final static MLogger logger = MLog.getLogger( C3P0PooledConnectionPool.class ); final ResourcePool rp; final ConnectionEventListener cl = new ConnectionEventListenerImpl(); final ConnectionTester connectionTester; final GooGooStatementCache scache; final int checkoutTimeout; final AsynchronousRunner sharedTaskRunner; final ThrowableHolderPool thp = new ThrowableHolderPool(); C3P0PooledConnectionPool( final ConnectionPoolDataSource cpds, final DbAuth auth, int min, int max, int start, int inc, int acq_retry_attempts, int acq_retry_delay, boolean break_after_acq_failure, int checkoutTimeout, //milliseconds int idleConnectionTestPeriod, //seconds int maxIdleTime, //seconds int maxIdleTimeExcessConnections, //seconds int maxConnectionAge, //seconds int propertyCycle, //seconds int unreturnedConnectionTimeout, //seconds boolean debugUnreturnedConnectionStackTraces, final boolean testConnectionOnCheckout, final boolean testConnectionOnCheckin, int maxStatements, int maxStatementsPerConnection, final ConnectionTester connectionTester, final ConnectionCustomizer connectionCustomizer, final String testQuery, final ResourcePoolFactory fact, ThreadPoolAsynchronousRunner taskRunner, final String parentDataSourceIdentityToken) throws SQLException { try { if (maxStatements > 0 && maxStatementsPerConnection > 0) this.scache = new DoubleMaxStatementCache( taskRunner, maxStatements, maxStatementsPerConnection ); else if (maxStatementsPerConnection > 0) this.scache = new PerConnectionMaxOnlyStatementCache( taskRunner, maxStatementsPerConnection ); else if (maxStatements > 0) this.scache = new GlobalMaxOnlyStatementCache( taskRunner, maxStatements ); else this.scache = null; this.connectionTester = connectionTester; this.checkoutTimeout = checkoutTimeout; this.sharedTaskRunner = taskRunner; class PooledConnectionResourcePoolManager implements ResourcePool.Manager { //SynchronizedIntHolder totalOpenedCounter = new SynchronizedIntHolder(); //SynchronizedIntHolder connectionCounter = new SynchronizedIntHolder(); //SynchronizedIntHolder failedCloseCounter = new SynchronizedIntHolder(); final boolean connectionTesterIsDefault = (connectionTester instanceof DefaultConnectionTester); final boolean c3p0PooledConnections = (cpds instanceof WrapperConnectionPoolDataSource); public Object acquireResource() throws Exception { PooledConnection out; if ( connectionCustomizer == null) { out = (auth.equals( C3P0ImplUtils.NULL_AUTH ) ? cpds.getPooledConnection() : cpds.getPooledConnection( auth.getUser(), auth.getPassword() ) ); } else { try { WrapperConnectionPoolDataSourceBase wcpds = (WrapperConnectionPoolDataSourceBase) cpds; out = (auth.equals( C3P0ImplUtils.NULL_AUTH ) ? wcpds.getPooledConnection( connectionCustomizer, parentDataSourceIdentityToken ) : wcpds.getPooledConnection( auth.getUser(), auth.getPassword(), connectionCustomizer, parentDataSourceIdentityToken ) ); } catch (ClassCastException e) { throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 ConnectionPoolDataSource." + " ConnectionPoolDataSource: " + cpds.getClass().getName(), e); } } //connectionCounter.increment(); //totalOpenedCounter.increment(); try { if (scache != null) { if (c3p0PooledConnections) ((AbstractC3P0PooledConnection) out).initStatementCache(scache); else { // System.err.print("Warning! StatementPooling not "); // System.err.print("implemented for external (non-c3p0) "); // System.err.println("ConnectionPoolDataSources."); logger.warning("StatementPooling not " + "implemented for external (non-c3p0) " + "ConnectionPoolDataSources."); } } // log and clear any SQLWarnings present upon acquisition Connection con = null; try { con = out.getConnection(); SQLWarnings.logAndClearWarnings( con ); } finally { //invalidate the proxy Connection ConnectionUtils.attemptClose( con ); } out.addConnectionEventListener( cl ); return out; } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.warning("A PooledConnection was acquired, but an Exception occurred while preparing it for use. " + "Attempting to destroy."); try { destroyResource( out ); } catch (Exception e2) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "An Exception occurred while trying to close partially acquired PooledConnection.", e2 ); } throw e; } finally { if (logger.isLoggable( MLevel.FINEST )) logger.finest(this + ".acquireResource() returning. " ); //"Currently open Connections: " + connectionCounter.getValue() + //"; Failed close count: " + failedCloseCounter.getValue() + //"; Total processed by this pool: " + totalOpenedCounter.getValue()); } } // REFURBISHMENT: // the PooledConnection refurbishes itself when // its Connection view is closed, prior to being // checked back in to the pool. But we still may want to // test to make sure it is still good. public void refurbishResourceOnCheckout( Object resc ) throws Exception { if ( testConnectionOnCheckout ) { if ( logger.isLoggable( MLevel.FINER ) ) finerLoggingTestPooledConnection( resc, "CHECKOUT" ); else testPooledConnection( resc ); } if ( connectionCustomizer != null ) { Connection physicalConnection = null; try { physicalConnection = ((AbstractC3P0PooledConnection) resc).getPhysicalConnection(); connectionCustomizer.onCheckOut( physicalConnection, parentDataSourceIdentityToken ); } catch (ClassCastException e) { throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 PooledConnection." + " PooledConnection: " + resc + "; ConnectionPoolDataSource: " + cpds.getClass().getName(), e); } } } public void refurbishResourceOnCheckin( Object resc ) throws Exception { if ( connectionCustomizer != null ) { Connection physicalConnection = null; try { physicalConnection = ((AbstractC3P0PooledConnection) resc).getPhysicalConnection(); connectionCustomizer.onCheckIn( physicalConnection, parentDataSourceIdentityToken ); SQLWarnings.logAndClearWarnings( physicalConnection ); } catch (ClassCastException e) { throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 PooledConnection." + " PooledConnection: " + resc + "; ConnectionPoolDataSource: " + cpds.getClass().getName(), e); } } else { PooledConnection pc = (PooledConnection) resc; Connection con = null; try { //we don't want any callbacks while we're clearing warnings pc.removeConnectionEventListener( cl ); con = pc.getConnection(); SQLWarnings.logAndClearWarnings(con); } finally { // close the proxy Connection ConnectionUtils.attemptClose(con); pc.addConnectionEventListener( cl ); } } if ( testConnectionOnCheckin ) { if ( logger.isLoggable( MLevel.FINER ) ) finerLoggingTestPooledConnection( resc, "CHECKIN" ); else testPooledConnection( resc ); } } public void refurbishIdleResource( Object resc ) throws Exception { if ( logger.isLoggable( MLevel.FINER ) ) finerLoggingTestPooledConnection( resc, "IDLE CHECK" ); else testPooledConnection( resc ); } private void finerLoggingTestPooledConnection(Object resc, String testImpetus) throws Exception { logger.finer("Testing PooledConnection [" + resc + "] on " + testImpetus + "."); try { testPooledConnection( resc ); logger.finer("Test of PooledConnection [" + resc + "] on "+testImpetus+" has SUCCEEDED."); } catch (Exception e) { logger.log(MLevel.FINER, "Test of PooledConnection [" + resc + "] on "+testImpetus+" has FAILED.", e); e.fillInStackTrace(); throw e; } } private void testPooledConnection(Object resc) throws Exception { PooledConnection pc = (PooledConnection) resc; Throwable[] throwableHolder = EMPTY_THROWABLE_HOLDER; int status; Connection conn = null; Throwable rootCause = null; try { //we don't want any callbacks while we're testing the resource pc.removeConnectionEventListener( cl ); conn = pc.getConnection(); //checkout proxy connection // if this is a c3p0 pooled-connection, let's get underneath the // proxy wrapper, and test the physical connection sometimes. // this is faster, when the testQuery would not otherwise be cached, // and it avoids a potential statusOnException() double-check by the // PooledConnection implementation should the test query provoke an // Exception Connection testConn; if (scache != null) //when there is a statement cache... { // if it's the slow, default query, faster to test the raw Connection if (testQuery == null && connectionTesterIsDefault && c3p0PooledConnections) testConn = ((AbstractC3P0PooledConnection) pc).getPhysicalConnection(); else //test will likely be faster on the proxied Connection, because the test query is probably cached testConn = conn; } else //where there's no statement cache, better to use the physical connection, if we can get it { if (c3p0PooledConnections) testConn = ((AbstractC3P0PooledConnection) pc).getPhysicalConnection(); else testConn = conn; } if ( testQuery == null ) status = connectionTester.activeCheckConnection( testConn ); else { if (connectionTester instanceof UnifiedConnectionTester) { throwableHolder = thp.getThrowableHolder(); status = ((UnifiedConnectionTester) connectionTester).activeCheckConnection( testConn, testQuery, throwableHolder ); } else if (connectionTester instanceof QueryConnectionTester) status = ((QueryConnectionTester) connectionTester).activeCheckConnection( testConn, testQuery ); else { // System.err.println("[c3p0] WARNING: testQuery '" + testQuery + // "' ignored. Please set a ConnectionTester that implements " + // "com.mchange.v2.c3p0.advanced.QueryConnectionTester, or use the " + // "DefaultConnectionTester, to test with the testQuery."); logger.warning("[c3p0] testQuery '" + testQuery + "' ignored. Please set a ConnectionTester that implements " + "com.mchange.v2.c3p0.QueryConnectionTester, or use the " + "DefaultConnectionTester, to test with the testQuery."); status = connectionTester.activeCheckConnection( testConn ); } } } catch (Exception e) { if (Debug.DEBUG) logger.log(MLevel.FINE, "A Connection test failed with an Exception.", e); //e.printStackTrace(); status = ConnectionTester.CONNECTION_IS_INVALID; // System.err.println("rootCause ------>"); // e.printStackTrace(); rootCause = e; } finally { if (rootCause == null) rootCause = throwableHolder[0]; else if (throwableHolder[0] != null && logger.isLoggable(MLevel.FINE)) logger.log(MLevel.FINE, "Internal Connection Test Exception", throwableHolder[0]); if (throwableHolder != EMPTY_THROWABLE_HOLDER) thp.returnThrowableHolder( throwableHolder ); ConnectionUtils.attemptClose( conn ); //invalidate proxy connection pc.addConnectionEventListener( cl ); //should we move this to CONNECTION_IS_OKAY case? (it should work either way) } switch (status) { case ConnectionTester.CONNECTION_IS_OKAY: break; //no problem, babe case ConnectionTester.DATABASE_IS_INVALID: rp.resetPool(); //intentional cascade... case ConnectionTester.CONNECTION_IS_INVALID: Exception throwMe; if (rootCause == null) throwMe = new SQLException("Connection is invalid"); else throwMe = SqlUtils.toSQLException("Connection is invalid", rootCause); throw throwMe; default: throw new Error("Bad Connection Tester (" + connectionTester + ") " + "returned invalid status (" + status + ")."); } } public void destroyResource(Object resc) throws Exception { try { if ( connectionCustomizer != null ) { Connection physicalConnection = null; try { physicalConnection = ((AbstractC3P0PooledConnection) resc).getPhysicalConnection(); connectionCustomizer.onDestroy( physicalConnection, parentDataSourceIdentityToken ); } catch (ClassCastException e) { throw SqlUtils.toSQLException("Cannot use a ConnectionCustomizer with a non-c3p0 PooledConnection." + " PooledConnection: " + resc + "; ConnectionPoolDataSource: " + cpds.getClass().getName(), e); } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "An exception occurred while executing the onDestroy() method of " + connectionCustomizer + ". c3p0 will attempt to destroy the target Connection regardless, but this issue " + " should be investigated and fixed.", e ); } } if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Preparing to destroy PooledConnection: " + resc); ((PooledConnection) resc).close(); // inaccurate, as Connections can be removed more than once //connectionCounter.decrement(); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Successfully destroyed PooledConnection: " + resc ); //". Currently open Connections: " + connectionCounter.getValue() + //"; Failed close count: " + failedCloseCounter.getValue() + //"; Total processed by this pool: " + totalOpenedCounter.getValue()); } catch (Exception e) { //failedCloseCounter.increment(); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Failed to destroy PooledConnection: " + resc ); //". Currently open Connections: " + connectionCounter.getValue() + //"; Failed close count: " + failedCloseCounter.getValue() + //"; Total processed by this pool: " + totalOpenedCounter.getValue()); throw e; } } } ResourcePool.Manager manager = new PooledConnectionResourcePoolManager(); synchronized (fact) { fact.setMin( min ); fact.setMax( max ); fact.setStart( start ); fact.setIncrement( inc ); fact.setIdleResourceTestPeriod( idleConnectionTestPeriod * 1000); fact.setResourceMaxIdleTime( maxIdleTime * 1000 ); fact.setExcessResourceMaxIdleTime( maxIdleTimeExcessConnections * 1000 ); fact.setResourceMaxAge( maxConnectionAge * 1000 ); fact.setExpirationEnforcementDelay( propertyCycle * 1000 ); fact.setDestroyOverdueResourceTime( unreturnedConnectionTimeout * 1000 ); fact.setDebugStoreCheckoutStackTrace( debugUnreturnedConnectionStackTraces ); fact.setAcquisitionRetryAttempts( acq_retry_attempts ); fact.setAcquisitionRetryDelay( acq_retry_delay ); fact.setBreakOnAcquisitionFailure( break_after_acq_failure ); rp = fact.createPool( manager ); } } catch (ResourcePoolException e) { throw SqlUtils.toSQLException(e); } } public PooledConnection checkoutPooledConnection() throws SQLException { //System.err.println(this + " -- CHECKOUT"); try { return (PooledConnection) rp.checkoutResource( checkoutTimeout ); } catch (TimeoutException e) { throw SqlUtils.toSQLException("An attempt by a client to checkout a Connection has timed out.", e); } catch (CannotAcquireResourceException e) { throw SqlUtils.toSQLException("Connections could not be acquired from the underlying database!", "08001", e); } catch (Exception e) { throw SqlUtils.toSQLException(e); } } public void checkinPooledConnection(PooledConnection pcon) throws SQLException { //System.err.println(this + " -- CHECKIN"); try { rp.checkinResource( pcon ); } catch (ResourcePoolException e) { throw SqlUtils.toSQLException(e); } } public float getEffectivePropertyCycle() throws SQLException { try { return rp.getEffectiveExpirationEnforcementDelay() / 1000f; } catch (ResourcePoolException e) { throw SqlUtils.toSQLException(e); } } public int getNumThreadsAwaitingCheckout() throws SQLException { try { return rp.getNumCheckoutWaiters(); } catch (ResourcePoolException e) { throw SqlUtils.toSQLException(e); } } public int getStatementCacheNumStatements() { return scache == null ? 0 : scache.getNumStatements(); } public int getStatementCacheNumCheckedOut() { return scache == null ? 0 : scache.getNumStatementsCheckedOut(); } public int getStatementCacheNumConnectionsWithCachedStatements() { return scache == null ? 0 : scache.getNumConnectionsWithCachedStatements(); } public String dumpStatementCacheStatus() { return scache == null ? "Statement caching disabled." : scache.dumpStatementCacheStatus(); } public void close() throws SQLException { close( true ); } public void close( boolean close_outstanding_connections ) throws SQLException { // System.err.println(this + " closing."); Exception throwMe = null; try { if (scache != null) scache.close(); } catch (SQLException e) { throwMe = e; } try { rp.close( close_outstanding_connections ); } catch (ResourcePoolException e) { if ( throwMe != null && logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while closing the StatementCache.", throwMe); throwMe = e; } if (throwMe != null) throw SqlUtils.toSQLException( throwMe ); } class ConnectionEventListenerImpl implements ConnectionEventListener { // // We might want to check Connections in asynchronously, // because this is called // (indirectly) from a sync'ed method of NewPooledConnection, but // NewPooledConnection may be closed synchronously from a sync'ed // method of the resource pool, leading to a deadlock. Checking // Connections in asynchronously breaks the cycle. // // But then we want checkins to happen quickly and reliably, // whereas pool shutdowns are rare, so perhaps it's best to // leave this synchronous, and let the closing of pooled // resources on pool closes happen asynchronously to break // the deadlock. // // For now we're leaving both versions around, but with faster // and more reliable synchronous checkin enabled, and async closing // of resources in BasicResourcePool.close(). // public void connectionClosed(final ConnectionEvent evt) { //System.err.println("Checking in: " + evt.getSource()); if (ASYNCHRONOUS_CONNECTION_EVENT_LISTENER) { Runnable r = new Runnable() { public void run() { doCheckinResource( evt ); } }; sharedTaskRunner.postRunnable( r ); } else doCheckinResource( evt ); } private void doCheckinResource(ConnectionEvent evt) { try { rp.checkinResource( evt.getSource() ); } catch (Exception e) { //e.printStackTrace(); logger.log( MLevel.WARNING, "An Exception occurred while trying to check a PooledConection into a ResourcePool.", e ); } } // // We might want to update the pool asynchronously, because this is called // (indirectly) from a sync'ed method of NewPooledConnection, but // NewPooledConnection may be closed synchronously from a sync'ed // method of the resource pool, leading to a deadlock. Updating // pool status asynchronously breaks the cycle. // // But then we want checkins to happen quickly and reliably, // whereas pool shutdowns are rare, so perhaps it's best to // leave all ConnectionEvent handling synchronous, and let the closing of pooled // resources on pool closes happen asynchronously to break // the deadlock. // // For now we're leaving both versions around, but with faster // and more reliable synchrounous ConnectionEventHandling enabled, and async closing // of resources in BasicResourcePool.close(). // public void connectionErrorOccurred(final ConnectionEvent evt) { // System.err.println("CONNECTION ERROR OCCURRED!"); // System.err.println(); if ( logger.isLoggable( MLevel.FINE ) ) logger.fine("CONNECTION ERROR OCCURRED!"); final PooledConnection pc = (PooledConnection) evt.getSource(); int status; if (pc instanceof C3P0PooledConnection) status = ((C3P0PooledConnection) pc).getConnectionStatus(); else if (pc instanceof NewPooledConnection) status = ((NewPooledConnection) pc).getConnectionStatus(); else //default to invalid connection, but not invalid database status = ConnectionTester.CONNECTION_IS_INVALID; final int final_status = status; if (ASYNCHRONOUS_CONNECTION_EVENT_LISTENER) { Runnable r = new Runnable() { public void run() { doMarkPoolStatus( pc, final_status ); } }; sharedTaskRunner.postRunnable( r ); } else doMarkPoolStatus( pc, final_status ); } private void doMarkPoolStatus(PooledConnection pc, int status) { try { switch (status) { case ConnectionTester.CONNECTION_IS_OKAY: throw new RuntimeException("connectionErrorOcccurred() should only be " + "called for errors fatal to the Connection."); case ConnectionTester.CONNECTION_IS_INVALID: rp.markBroken( pc ); break; case ConnectionTester.DATABASE_IS_INVALID: if (logger.isLoggable(MLevel.WARNING)) logger.warning("A ConnectionTest has failed, reporting that all previously acquired Connections are likely invalid. " + "The pool will be reset."); rp.resetPool(); break; default: throw new RuntimeException("Bad Connection Tester (" + connectionTester + ") " + "returned invalid status (" + status + ")."); } } catch ( ResourcePoolException e ) { //System.err.println("Uh oh... our resource pool is probably broken!"); //e.printStackTrace(); logger.log(MLevel.WARNING, "Uh oh... our resource pool is probably broken!", e); } } } public int getNumConnections() throws SQLException { try { return rp.getPoolSize(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public int getNumIdleConnections() throws SQLException { try { return rp.getAvailableCount(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public int getNumBusyConnections() throws SQLException { try { synchronized ( rp ) { return (rp.getAwaitingCheckinCount() - rp.getExcludedCount()); } } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public int getNumUnclosedOrphanedConnections() throws SQLException { try { return rp.getExcludedCount(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public long getStartTime() throws SQLException { try { return rp.getStartTime(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public long getUpTime() throws SQLException { try { return rp.getUpTime(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public long getNumFailedCheckins() throws SQLException { try { return rp.getNumFailedCheckins(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public long getNumFailedCheckouts() throws SQLException { try { return rp.getNumFailedCheckouts(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public long getNumFailedIdleTests() throws SQLException { try { return rp.getNumFailedIdleTests(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public Throwable getLastCheckinFailure() throws SQLException { try { return rp.getLastCheckinFailure(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public Throwable getLastCheckoutFailure() throws SQLException { try { return rp.getLastCheckoutFailure(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public Throwable getLastIdleTestFailure() throws SQLException { try { return rp.getLastIdleCheckFailure(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public Throwable getLastConnectionTestFailure() throws SQLException { try { return rp.getLastResourceTestFailure(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } public Throwable getLastAcquisitionFailure() throws SQLException { try { return rp.getLastAcquisitionFailure(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } /** * Discards all Connections managed by the pool * and reacquires new Connections to populate. * Current checked out Connections will still * be valid, and should still be checked into the * pool (so the pool can destroy them). */ public void reset() throws SQLException { try { rp.resetPool(); } catch ( Exception e ) { //e.printStackTrace(); logger.log( MLevel.WARNING, null, e ); throw SqlUtils.toSQLException( e ); } } final static class ThrowableHolderPool { LinkedList l = new LinkedList(); synchronized Throwable[] getThrowableHolder() { if (l.size() == 0) return new Throwable[1]; else return (Throwable[]) l.remove(0); } synchronized void returnThrowableHolder(Throwable[] th) { th[0] = null; l.add(th); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/C3P0PooledConnectionPoolManager.java0000644000175000017500000012164710624366530026772 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.beans.*; import java.util.*; import java.lang.reflect.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v2.c3p0.cfg.*; import com.mchange.v2.async.*; import com.mchange.v2.coalesce.*; import com.mchange.v1.db.sql.*; import com.mchange.v2.log.*; import com.mchange.v1.lang.BooleanUtils; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.resourcepool.ResourcePoolFactory; import com.mchange.v2.resourcepool.BasicResourcePoolFactory; public final class C3P0PooledConnectionPoolManager { private final static MLogger logger = MLog.getLogger( C3P0PooledConnectionPoolManager.class ); private final static boolean POOL_EVENT_SUPPORT = false; private final static CoalesceChecker COALESCE_CHECKER = IdentityTokenizedCoalesceChecker.INSTANCE; // unsync'ed coalescer -- we synchronize the static factory method that uses it final static Coalescer COALESCER = CoalescerFactory.createCoalescer( COALESCE_CHECKER, true, false ); final static int DFLT_NUM_TASK_THREADS_PER_DATA_SOURCE = 3; //MT: protected by this' lock ThreadPoolAsynchronousRunner taskRunner; Timer timer; ResourcePoolFactory rpfact; Map authsToPools; /* MT: independently thread-safe, never reassigned post-ctor or factory */ final ConnectionPoolDataSource cpds; final Map propNamesToReadMethods; final Map flatPropertyOverrides; final Map userOverrides; final DbAuth defaultAuth; final String parentDataSourceIdentityToken; /* MT: end independently thread-safe, never reassigned post-ctor or factory */ /* MT: unchanging after constructor completes */ int num_task_threads = DFLT_NUM_TASK_THREADS_PER_DATA_SOURCE; /* MT: end unchanging after constructor completes */ public int getThreadPoolSize() { return taskRunner.getThreadCount(); } public int getThreadPoolNumActiveThreads() { return taskRunner.getActiveCount(); } public int getThreadPoolNumIdleThreads() { return taskRunner.getIdleCount(); } public int getThreadPoolNumTasksPending() { return taskRunner.getPendingTaskCount(); } public String getThreadPoolStackTraces() { return taskRunner.getStackTraces(); } public String getThreadPoolStatus() { return taskRunner.getStatus(); } private synchronized void poolsInit() { this.timer = new Timer( true ); int matt = this.getMaxAdministrativeTaskTime( null ); if ( matt > 0 ) { int matt_ms = matt * 1000; this.taskRunner = new ThreadPoolAsynchronousRunner( num_task_threads, true, // daemon thread matt_ms, // wait before interrupt() matt_ms * 3, // wait before deadlock declared if no tasks clear matt_ms * 6, // wait before deadlock tasks are interrupted (again) // after the hung thread has been cleared and replaced // (in hopes of getting the thread to terminate for // garbage collection) timer ); } else this.taskRunner = new ThreadPoolAsynchronousRunner( num_task_threads, true, timer ); //this.taskRunner = new RoundRobinAsynchronousRunner( num_task_threads, true ); //this.rpfact = ResourcePoolFactory.createInstance( taskRunner, timer ); if (POOL_EVENT_SUPPORT) this.rpfact = ResourcePoolFactory.createInstance( taskRunner, null, timer ); else this.rpfact = BasicResourcePoolFactory.createNoEventSupportInstance( taskRunner, timer ); this.authsToPools = new HashMap(); } private void poolsDestroy() { poolsDestroy( true ); } private synchronized void poolsDestroy( boolean close_outstanding_connections ) { //System.err.println("poolsDestroy() -- " + this); for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) { try { ((C3P0PooledConnectionPool) ii.next()).close( close_outstanding_connections ); } catch ( Exception e ) { //e.printStackTrace(); logger.log(MLevel.WARNING, "An Exception occurred while trying to clean up a pool!", e); } } this.taskRunner.close( true ); this.timer.cancel(); this.taskRunner = null; this.timer = null; this.rpfact = null; this.authsToPools = null; } public C3P0PooledConnectionPoolManager(ConnectionPoolDataSource cpds, Map flatPropertyOverrides, // Map of properties, usually null Map forceUserOverrides, // userNames to Map of properties, usually null int num_task_threads, String parentDataSourceIdentityToken) throws SQLException { try { this.cpds = cpds; this.flatPropertyOverrides = flatPropertyOverrides; this.num_task_threads = num_task_threads; this.parentDataSourceIdentityToken = parentDataSourceIdentityToken; DbAuth auth = null; if ( flatPropertyOverrides != null ) { String overrideUser = (String) flatPropertyOverrides.get("overrideDefaultUser"); String overridePassword = (String) flatPropertyOverrides.get("overrideDefaultPassword"); if (overrideUser == null) { overrideUser = (String) flatPropertyOverrides.get("user"); overridePassword = (String) flatPropertyOverrides.get("password"); } if (overrideUser != null) auth = new DbAuth( overrideUser, overridePassword ); } if (auth == null) auth = C3P0ImplUtils.findAuth( cpds ); this.defaultAuth = auth; Map tmp = new HashMap(); BeanInfo bi = Introspector.getBeanInfo( cpds.getClass() ); PropertyDescriptor[] pds = bi.getPropertyDescriptors(); PropertyDescriptor pd = null; for (int i = 0, len = pds.length; i < len; ++i) { pd = pds[i]; String name = pd.getName(); Method m = pd.getReadMethod(); if (m != null) tmp.put( name, m ); } this.propNamesToReadMethods = tmp; if (forceUserOverrides == null) { Method uom = (Method) propNamesToReadMethods.get( "userOverridesAsString" ); if (uom != null) { String uoas = (String) uom.invoke( cpds, null ); //System.err.println("uoas: " + uoas); Map uo = C3P0ImplUtils.parseUserOverridesAsString( uoas ); this.userOverrides = uo; } else this.userOverrides = Collections.EMPTY_MAP; } else this.userOverrides = forceUserOverrides; poolsInit(); } catch (Exception e) { if (Debug.DEBUG) logger.log(MLevel.FINE, null, e); //e.printStackTrace(); throw SqlUtils.toSQLException(e); } } public synchronized C3P0PooledConnectionPool getPool(String username, String password, boolean create) throws SQLException { if (create) return getPool( username, password ); else { DbAuth checkAuth = new DbAuth( username, password ); C3P0PooledConnectionPool out = (C3P0PooledConnectionPool) authsToPools.get(checkAuth); if (out == null) throw new SQLException("No pool has been initialized for databse user '" + username + "' with the specified password."); else return out; } } public C3P0PooledConnectionPool getPool(String username, String password) throws SQLException { return getPool( new DbAuth( username, password ) ); } public synchronized C3P0PooledConnectionPool getPool(DbAuth auth) throws SQLException { C3P0PooledConnectionPool out = (C3P0PooledConnectionPool) authsToPools.get(auth); if (out == null) { out = createPooledConnectionPool(auth); authsToPools.put( auth, out ); } return out; } public synchronized Set getManagedAuths() { return Collections.unmodifiableSet( authsToPools.keySet() ); } public synchronized int getNumManagedAuths() { return authsToPools.size(); } public C3P0PooledConnectionPool getPool() throws SQLException { return getPool( defaultAuth ); } public synchronized int getNumIdleConnectionsAllAuths() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getNumIdleConnections(); return out; } public synchronized int getNumBusyConnectionsAllAuths() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getNumBusyConnections(); return out; } public synchronized int getNumConnectionsAllAuths() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getNumConnections(); return out; } public synchronized int getNumUnclosedOrphanedConnectionsAllAuths() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getNumUnclosedOrphanedConnections(); return out; } public synchronized int getStatementCacheNumStatementsAllUsers() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getStatementCacheNumStatements(); return out; } public synchronized int getStatementCacheNumCheckedOutStatementsAllUsers() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getStatementCacheNumCheckedOut(); return out; } public synchronized int getStatementCacheNumConnectionsWithCachedStatementsAllUsers() throws SQLException { int out = 0; for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) out += ((C3P0PooledConnectionPool) ii.next()).getStatementCacheNumConnectionsWithCachedStatements(); return out; } public synchronized void softResetAllAuths() throws SQLException { for (Iterator ii = authsToPools.values().iterator(); ii.hasNext(); ) ((C3P0PooledConnectionPool) ii.next()).reset(); } public void close() { this.close( true ); } public synchronized void close( boolean close_outstanding_connections ) { // System.err.println("close()ing " + this); if (authsToPools != null) poolsDestroy( close_outstanding_connections ); } protected synchronized void finalize() { // System.err.println("finalizing... " + this); this.close(); } private Object getObject(String propName, String userName) { Object out = null; if (userName != null) { //userOverrides are usually config file defined, unless rarely used forceUserOverrides is supplied! Map specificUserOverrides = (Map) userOverrides.get( userName ); if (specificUserOverrides != null) out = specificUserOverrides.get( propName ); } if (out == null && flatPropertyOverrides != null) //flatPropertyOverrides is a rarely used mechanism for forcing a config out = flatPropertyOverrides.get( propName ); //if the ConnectionPoolDataSource has config parameter defined as a property use it //(unless there was a user-specific or force override found above) if (out == null) { try { Method m = (Method) propNamesToReadMethods.get( propName ); if (m != null) { Object readProp = m.invoke( cpds, null ); if (readProp != null) out = readProp.toString(); } } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log(MLevel.WARNING, "An exception occurred while trying to read property '" + propName + "' from ConnectionPoolDataSource: " + cpds + ". Default config value will be used.", e ); } } //if the ConnectionPoolDataSource DID NOT have config parameter defined as a property //(and there was no user-specific or force override) //use config-defined default if (out == null) out = C3P0Config.getUnspecifiedUserProperty( propName, null ); return out; } private String getString(String propName, String userName) { Object o = getObject( propName, userName); return (o == null ? null : o.toString()); } private int getInt(String propName, String userName) throws Exception { Object o = getObject( propName, userName); if (o instanceof Integer) return ((Integer) o).intValue(); else if (o instanceof String) return Integer.parseInt( (String) o ); else throw new Exception("Unexpected object found for putative int property '" + propName +"': " + o); } private boolean getBoolean(String propName, String userName) throws Exception { Object o = getObject( propName, userName); if (o instanceof Boolean) return ((Boolean) o).booleanValue(); else if (o instanceof String) return BooleanUtils.parseBoolean( (String) o ); else throw new Exception("Unexpected object found for putative boolean property '" + propName +"': " + o); } public String getAutomaticTestTable(String userName) { return getString("automaticTestTable", userName ); } public String getPreferredTestQuery(String userName) { return getString("preferredTestQuery", userName ); } private int getInitialPoolSize(String userName) { try { return getInt("initialPoolSize", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.initialPoolSize(); } } public int getMinPoolSize(String userName) { try { return getInt("minPoolSize", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.minPoolSize(); } } private int getMaxPoolSize(String userName) { try { return getInt("maxPoolSize", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxPoolSize(); } } private int getMaxStatements(String userName) { try { return getInt("maxStatements", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxStatements(); } } private int getMaxStatementsPerConnection(String userName) { try { return getInt("maxStatementsPerConnection", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxStatementsPerConnection(); } } private int getAcquireIncrement(String userName) { try { return getInt("acquireIncrement", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.acquireIncrement(); } } private int getAcquireRetryAttempts(String userName) { try { return getInt("acquireRetryAttempts", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.acquireRetryAttempts(); } } private int getAcquireRetryDelay(String userName) { try { return getInt("acquireRetryDelay", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.acquireRetryDelay(); } } private boolean getBreakAfterAcquireFailure(String userName) { try { return getBoolean("breakAfterAcquireFailure", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch boolean property", e); return C3P0Defaults.breakAfterAcquireFailure(); } } private int getCheckoutTimeout(String userName) { try { return getInt("checkoutTimeout", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.checkoutTimeout(); } } private int getIdleConnectionTestPeriod(String userName) { try { return getInt("idleConnectionTestPeriod", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.idleConnectionTestPeriod(); } } private int getMaxIdleTime(String userName) { try { return getInt("maxIdleTime", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxIdleTime(); } } private int getUnreturnedConnectionTimeout(String userName) { try { return getInt("unreturnedConnectionTimeout", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.unreturnedConnectionTimeout(); } } private boolean getTestConnectionOnCheckout(String userName) { try { return getBoolean("testConnectionOnCheckout", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch boolean property", e); return C3P0Defaults.testConnectionOnCheckout(); } } private boolean getTestConnectionOnCheckin(String userName) { try { return getBoolean("testConnectionOnCheckin", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch boolean property", e); return C3P0Defaults.testConnectionOnCheckin(); } } private boolean getDebugUnreturnedConnectionStackTraces(String userName) { try { return getBoolean("debugUnreturnedConnectionStackTraces", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch boolean property", e); return C3P0Defaults.debugUnreturnedConnectionStackTraces(); } } private String getConnectionTesterClassName(String userName) { return getString("connectionTesterClassName", userName ); } private ConnectionTester getConnectionTester(String userName) { return C3P0Registry.getConnectionTester( getConnectionTesterClassName( userName ) ); } private String getConnectionCustomizerClassName(String userName) { return getString("connectionCustomizerClassName", userName ); } private ConnectionCustomizer getConnectionCustomizer(String userName) throws SQLException { return C3P0Registry.getConnectionCustomizer( getConnectionCustomizerClassName( userName ) ); } private int getMaxIdleTimeExcessConnections(String userName) { try { return getInt("maxIdleTimeExcessConnections", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxIdleTimeExcessConnections(); } } private int getMaxAdministrativeTaskTime(String userName) { try { return getInt("maxAdministrativeTaskTime", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxAdministrativeTaskTime(); } } private int getMaxConnectionAge(String userName) { try { return getInt("maxConnectionAge", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.maxConnectionAge(); } } private int getPropertyCycle(String userName) { try { return getInt("propertyCycle", userName ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not fetch int property", e); return C3P0Defaults.propertyCycle(); } } // called only from sync'ed methods private C3P0PooledConnectionPool createPooledConnectionPool(DbAuth auth) throws SQLException { String userName = auth.getUser(); String automaticTestTable = getAutomaticTestTable( userName ); String realTestQuery; if (automaticTestTable != null) { realTestQuery = initializeAutomaticTestTable( automaticTestTable, auth ); if (this.getPreferredTestQuery( userName ) != null) { if ( logger.isLoggable( MLevel.WARNING ) ) { logger.logp(MLevel.WARNING, C3P0PooledConnectionPoolManager.class.getName(), "createPooledConnectionPool", "[c3p0] Both automaticTestTable and preferredTestQuery have been set! " + "Using automaticTestTable, and ignoring preferredTestQuery. Real test query is ''{0}''.", realTestQuery ); } } } else { // when there is an automaticTestTable to be constructed, we // have little choice but to grab a Connection on initialization // to ensure that the table exists before the pool tries to // test Connections. in c3p0-0.9.1-pre10, i added the check below // to grab and destroy a cxn even when we don't // need one, to ensure that db access params are correct before // we start up a pool. a user who frequently creates and destroys // PooledDataSources complained about the extra initialization // time. the main use of this test was to prevent superfluous // bad pools from being intialized when JMX users type bad // authentification information into a query method. This is // now prevented in AbstractPoolBackedDataSource. Still, it is // easy for clients to start pools uselessly by asking for // Connections with bad authentification information. We adopt // the compromise position of "trusting" the DataSource's default // authentification info (as defined by defaultAuth), but ensuring // that authentification succeeds via the check below when non-default // authentification info is provided. if (! defaultAuth.equals( auth )) ensureFirstConnectionAcquisition( auth ); realTestQuery = this.getPreferredTestQuery( userName ); } C3P0PooledConnectionPool out = new C3P0PooledConnectionPool( cpds, auth, this.getMinPoolSize( userName ), this.getMaxPoolSize( userName ), this.getInitialPoolSize( userName ), this.getAcquireIncrement( userName ), this.getAcquireRetryAttempts( userName ), this.getAcquireRetryDelay( userName ), this.getBreakAfterAcquireFailure( userName ), this.getCheckoutTimeout( userName ), this.getIdleConnectionTestPeriod( userName ), this.getMaxIdleTime( userName ), this.getMaxIdleTimeExcessConnections( userName ), this.getMaxConnectionAge( userName ), this.getPropertyCycle( userName ), this.getUnreturnedConnectionTimeout( userName ), this.getDebugUnreturnedConnectionStackTraces( userName ), this.getTestConnectionOnCheckout( userName ), this.getTestConnectionOnCheckin( userName ), this.getMaxStatements( userName ), this.getMaxStatementsPerConnection( userName ), this.getConnectionTester( userName ), this.getConnectionCustomizer( userName ), realTestQuery, rpfact, taskRunner, parentDataSourceIdentityToken ); return out; } // only called from sync'ed methods private String initializeAutomaticTestTable(String automaticTestTable, DbAuth auth) throws SQLException { PooledConnection throwawayPooledConnection = auth.equals( defaultAuth ) ? cpds.getPooledConnection() : cpds.getPooledConnection(auth.getUser(), auth.getPassword()); Connection c = null; PreparedStatement testStmt = null; PreparedStatement createStmt = null; ResultSet mdrs = null; ResultSet rs = null; boolean exists; boolean has_rows; String out; try { c = throwawayPooledConnection.getConnection(); DatabaseMetaData dmd = c.getMetaData(); String q = dmd.getIdentifierQuoteString(); String quotedTableName = q + automaticTestTable + q; out = "SELECT * FROM " + quotedTableName; mdrs = dmd.getTables( null, null, automaticTestTable, new String[] {"TABLE"} ); exists = mdrs.next(); //System.err.println("Table " + automaticTestTable + " exists? " + exists); if (exists) { testStmt = c.prepareStatement( out ); rs = testStmt.executeQuery(); has_rows = rs.next(); if (has_rows) throw new SQLException("automatic test table '" + automaticTestTable + "' contains rows, and it should not! Please set this " + "parameter to the name of a table c3p0 can create on its own, " + "that is not used elsewhere in the database!"); } else { String createSql = "CREATE TABLE " + quotedTableName + " ( a CHAR(1) )"; try { createStmt = c.prepareStatement( createSql ); createStmt.executeUpdate(); } catch (SQLException e) { if (logger.isLoggable( MLevel.WARNING )) logger.log(MLevel.WARNING, "An attempt to create an automatic test table failed. Create SQL: " + createSql, e ); throw e; } } return out; } finally { ResultSetUtils.attemptClose( mdrs ); ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( testStmt ); StatementUtils.attemptClose( createStmt ); ConnectionUtils.attemptClose( c ); try{ if (throwawayPooledConnection != null) throwawayPooledConnection.close(); } catch ( Exception e ) { //e.printStackTrace(); logger.log(MLevel.WARNING, "A PooledConnection failed to close.", e); } } } private void ensureFirstConnectionAcquisition(DbAuth auth) throws SQLException { PooledConnection throwawayPooledConnection = auth.equals( defaultAuth ) ? cpds.getPooledConnection() : cpds.getPooledConnection(auth.getUser(), auth.getPassword()); Connection c = null; try { c = throwawayPooledConnection.getConnection(); } finally { ConnectionUtils.attemptClose( c ); try{ if (throwawayPooledConnection != null) throwawayPooledConnection.close(); } catch ( Exception e ) { //e.printStackTrace(); logger.log(MLevel.WARNING, "A PooledConnection failed to close.", e); } } } } //public static find(ConnectionPoolDataSource cpds, //DbAuth defaultAuth, //may be null //int maxStatements, //int minPoolSize, //int maxPoolSize, //int idleConnectionTestPeriod, //int maxIdleTime, //int acquireIncrement, //boolean testConnectionOnCheckout, //boolean autoCommitOnClose, //boolean forceIgnoreUnresolvedTransactions, //ConnectionTester connectionTester) //{ //C3P0PooledConnectionPoolManager nascent = new C3P0PooledConnectionPoolManager( cpds, //defaultAuth, //maxStatements, //minPoolSize, //maxPoolSize, //idleConnectionTestPeriod, //maxIdleTime, //acquireIncrement, //testConnectionOnCheckout, //autoCommitOnClose, //forceIgnoreUnresolvedTransactions, //connectionTester); //C3P0PooledConnectionPoolManager out = (C3P0PooledConnectionPoolManager) coalescer.coalesce( nascent ); //if ( out == nascent ) //the new guy is the ONE //out.poolInit(); //return out; //} //private C3P0PooledConnectionPoolManager(ConnectionPoolDataSource cpds, //DbAuth defaultAuth, //may be null //int maxStatements, //int minPoolSize, //int maxPoolSize, //int idleConnectionTestPeriod, //int maxIdleTime, //int acquireIncrement, //boolean testConnectionOnCheckout, //boolean autoCommitOnClose, //boolean forceIgnoreUnresolvedTransactions, //ConnectionTester connectionTester) //{ //this.cpds = cpds; //this.defaultAuth = (defaultAuth == null ? C3P0ImplUtils.NULL_AUTH : defaultAuth); //this.maxStatements = maxStatements; //this.minPoolSize = minPoolSize; //this.maxPoolSize = maxPoolSize; //this.idleConnectionTestPeriod = idleConnectionTestPeriod; //this.maxIdleTime = maxIdleTime; //this.acquireIncrement = acquireIncrement; //this.testConnectionOnCheckout = testConnectionOnCheckout; //this.autoCommitOnClose = autoCommitOnClose; //this.testConnectionOnCheckout = testConnectionOnCheckout; //this.forceIgnoreUnresolvedTransactions = forceIgnoreUnresolvedTransactions; //} //private final static CoalesceChecker COALESCE_CHECKER = new CoalesceChecker() //{ //// note that we expect all ConnectionTesters of a single class to be effectively //// equivalent, since they are to be constructed via a no-arg ctor and no //// extra initialization is performed. thus we only compare the classes of ConnectionTesters. //public boolean checkCoalesce( Object a, Object b ) //{ //C3P0PooledConnectionPoolManager aa = (C3P0PooledConnectionPoolManager) a; //C3P0PooledConnectionPoolManager bb = (C3P0PooledConnectionPoolManager) b; //return //aa.poolOwnerIdentityToken.equals( bb.poolOwnerIdentityToken ) && //(aa.preferredTestQuery == null ? (bb.preferredTestQuery == null ) : (aa.preferredTestQuery.equals( bb.preferredTestQuery ))) && //(aa.automaticTestTable == null ? (bb.automaticTestTable == null ) : (aa.automaticTestTable.equals( bb.automaticTestTable ))) && //aa.sourceCpdsIdentityToken.equals( bb.sourceCpdsIdentityToken ) && //aa.num_task_threads == bb.num_task_threads && //aa.maxStatements == bb.maxStatements && //aa.maxStatementsPerConnection == bb.maxStatementsPerConnection && //aa.minPoolSize == bb.minPoolSize && //aa.idleConnectionTestPeriod == bb.idleConnectionTestPeriod && //aa.maxIdleTime == bb.maxIdleTime && //aa.checkoutTimeout == bb.checkoutTimeout && //aa.acquireIncrement == bb.acquireIncrement && //aa.acquireRetryAttempts == bb.acquireRetryAttempts && //aa.acquireRetryDelay == bb.acquireRetryDelay && //aa.breakAfterAcquireFailure == bb.breakAfterAcquireFailure && //aa.testConnectionOnCheckout == bb.testConnectionOnCheckout && //aa.testConnectionOnCheckin == bb.testConnectionOnCheckin && //aa.autoCommitOnClose == bb.autoCommitOnClose && //aa.forceIgnoreUnresolvedTransactions == bb.forceIgnoreUnresolvedTransactions && //aa.defaultAuth.equals( bb.defaultAuth ) && //aa.connectionTester.getClass().equals( bb.connectionTester.getClass() ); //}; //public int coalesceHash( Object a ) //{ //C3P0PooledConnectionPoolManager aa = (C3P0PooledConnectionPoolManager) a; //int out = //aa.poolOwnerIdentityToken.hashCode() ^ //(aa.preferredTestQuery == null ? 0 : aa.preferredTestQuery.hashCode()) ^ //(aa.automaticTestTable == null ? 0 : aa.automaticTestTable.hashCode()) ^ //aa.sourceCpdsIdentityToken.hashCode() ^ //aa.num_task_threads ^ //aa.maxStatements ^ //aa.maxStatementsPerConnection ^ //aa.minPoolSize ^ //aa.idleConnectionTestPeriod ^ //aa.maxIdleTime ^ //aa.checkoutTimeout ^ //aa.acquireIncrement ^ //aa.acquireRetryAttempts ^ //aa.acquireRetryDelay ^ //(aa.testConnectionOnCheckout ? 1<<0 : 0) ^ //(aa.testConnectionOnCheckin ? 1<<1 : 0) ^ //(aa.autoCommitOnClose ? 1<<2 : 0) ^ //(aa.forceIgnoreUnresolvedTransactions ? 1<<3 : 0) ^ //(aa.breakAfterAcquireFailure ? 1<<4 : 0) ^ //aa.defaultAuth.hashCode() ^ //aa.connectionTester.getClass().hashCode(); ////System.err.println("coalesceHash() --> " + out); //return out; //}; //}; //int maxStatements = PoolConfig.defaultMaxStatements(); //int maxStatementsPerConnection = PoolConfig.defaultMaxStatementsPerConnection(); //int minPoolSize = PoolConfig.defaultMinPoolSize(); //int maxPoolSize = PoolConfig.defaultMaxPoolSize(); //int idleConnectionTestPeriod = PoolConfig.defaultIdleConnectionTestPeriod(); //int maxIdleTime = PoolConfig.defaultMaxIdleTime(); //int checkoutTimeout = PoolConfig.defaultCheckoutTimeout(); //int acquireIncrement = PoolConfig.defaultAcquireIncrement(); //int acquireRetryAttempts = PoolConfig.defaultAcquireRetryAttempts(); //int acquireRetryDelay = PoolConfig.defaultAcquireRetryDelay(); //boolean breakAfterAcquireFailure = PoolConfig.defaultBreakAfterAcquireFailure(); //boolean testConnectionOnCheckout = PoolConfig.defaultTestConnectionOnCheckout(); //boolean testConnectionOnCheckin = PoolConfig.defaultTestConnectionOnCheckin(); //boolean autoCommitOnClose = PoolConfig.defaultAutoCommitOnClose(); //boolean forceIgnoreUnresolvedTransactions = PoolConfig.defaultForceIgnoreUnresolvedTransactions(); //String preferredTestQuery = PoolConfig.defaultPreferredTestQuery(); //String automaticTestTable = PoolConfig.defaultAutomaticTestTable(); //DbAuth defaultAuth = C3P0ImplUtils.NULL_AUTH; //ConnectionTester connectionTester = C3P0ImplUtils.defaultConnectionTester();; //// we look for non-standard props user and //// password, available as read-only props on //// our implementation of ConnectionPoolDataSource. //// //// If other implementations are used, the only //// hazard is the possibility that there will be //// two pools for the same real authorization credentials //// one for when the credentials are explicitly specified, //// and one for when the defaults are used. //this.defaultAuth = C3P0ImplUtils.findAuth( cpds ); //BeanInfo bi = Introspector.getBeanInfo( cpds.getClass() ); //PropertyDescriptor[] pds = bi.getPropertyDescriptors(); //for (int i = 0, len = pds.length; i < len; ++i) //{ //PropertyDescriptor pd = pds[i]; //Class propCl = pd.getPropertyType(); //String propName = pd.getName(); //Method readMethod = pd.getReadMethod(); //Object propVal; //if (propCl == int.class) //{ //propVal = readMethod.invoke( cpds, C3P0ImplUtils.NOARGS ); //int value = ((Integer) propVal).intValue(); //if ("maxStatements".equals(propName)) //this.maxStatements = value; //else if ("maxStatementsPerConnection".equals(propName)) //this.maxStatementsPerConnection = value; //else if ("minPoolSize".equals(propName)) //this.minPoolSize = value; //else if ("maxPoolSize".equals(propName)) //this.maxPoolSize = value; //else if ("idleConnectionTestPeriod".equals(propName)) //this.idleConnectionTestPeriod = value; //else if ("maxIdleTime".equals(propName)) //this.maxIdleTime = value; //else if ("checkoutTimeout".equals(propName)) //this.checkoutTimeout = value; //else if ("acquireIncrement".equals(propName)) //this.acquireIncrement = value; //else if ("acquireRetryAttempts".equals(propName)) //this.acquireRetryAttempts = value; //else if ("acquireRetryDelay".equals(propName)) //this.acquireRetryDelay = value; //// System.err.println( propName + " -> " + propVal ); //} //else if (propCl == String.class) //{ //propVal = readMethod.invoke( cpds, C3P0ImplUtils.NOARGS ); //String value = (String) propVal; //if ("connectionTesterClassName".equals(propName)) //this.connectionTester = //(ConnectionTester) Class.forName( value ).newInstance(); //else if ("preferredTestQuery".equals(propName)) //this.preferredTestQuery = value; //else if ("automaticTestTable".equals(propName)) //this.automaticTestTable = value; //// System.err.println( propName + " -> " + propVal ); //} //else if (propCl == boolean.class) //{ //propVal = readMethod.invoke( cpds, C3P0ImplUtils.NOARGS ); //boolean value = ((Boolean) propVal).booleanValue(); //if ("testConnectionOnCheckout".equals(propName)) //this.testConnectionOnCheckout = value; //else if ("testConnectionOnCheckin".equals(propName)) //this.testConnectionOnCheckin = value; //else if ("autoCommitOnClose".equals(propName)) //this.autoCommitOnClose = value; //else if ("forceIgnoreUnresolvedTransactions".equals(propName)) //this.forceIgnoreUnresolvedTransactions = value; //else if ("breakAfterAcquireFailure".equals(propName)) //this.breakAfterAcquireFailure = value; //// System.err.println( propName + " -> " + propVal ); //} //} c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/DbAuth.java0000644000175000017500000000477310624366530022164 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.io.*; import com.mchange.v2.lang.ObjectUtils; import com.mchange.v2.ser.UnsupportedVersionException; public final class DbAuth implements Serializable { transient String username; transient String password; public DbAuth(String username, String password) { this.username = username; this.password = password; } public String getUser() { return username; } public String getPassword() { return password; } public boolean equals(Object o) { if (this == o) return true; else if (o != null && this.getClass() == o.getClass()) { DbAuth other = (DbAuth) o; return ObjectUtils.eqOrBothNull(this.username, other.username) && ObjectUtils.eqOrBothNull(this.password, other.password); } else return false; } public int hashCode() { return ObjectUtils.hashOrZero(username) ^ ObjectUtils.hashOrZero(password); } //Serialization static final long serialVersionUID = 1; //override to take control of versioning private final static short VERSION = 0x0001; private void writeObject(ObjectOutputStream out) throws IOException { out.writeShort(VERSION); out.writeObject(username); //may be null out.writeObject(password); //may be null } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { short version = in.readShort(); switch (version) { case 0x0001: this.username = (String) in.readObject(); this.password = (String) in.readObject(); break; default: throw new UnsupportedVersionException(this, version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/DefaultConnectionTester.java0000644000175000017500000002337110624366530025603 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.sql.*; import java.util.*; import com.mchange.v2.log.*; import com.mchange.v2.c3p0.AbstractConnectionTester; import com.mchange.v2.c3p0.FullQueryConnectionTester; import com.mchange.v1.db.sql.ResultSetUtils; import com.mchange.v1.db.sql.StatementUtils; public class DefaultConnectionTester extends AbstractConnectionTester { final static MLogger logger = MLog.getLogger( DefaultConnectionTester.class ); final static int HASH_CODE = DefaultConnectionTester.class.getName().hashCode(); final static Set INVALID_DB_STATES; static { Set temp = new HashSet(); temp.add("08001"); //SQL State "Unable to connect to data source" temp.add("08007"); //SQL State "Connection failure during transaction" // MySql appently uses this state to indicate a stale, expired // connection when the database is fine, so we'll not presume // this SQL state signals an invalid database. //temp.add("08S01"); //SQL State "Communication link failure" INVALID_DB_STATES = Collections.unmodifiableSet( temp ); } public int activeCheckConnection(Connection c, String query, Throwable[] rootCauseOutParamHolder) { // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) ) // logger.finer("Entering DefaultConnectionTester.activeCheckConnection(Connection c, String query). [query=" + query + "]"); if (query == null) return activeCheckConnectionNoQuery( c, rootCauseOutParamHolder); else { Statement stmt = null; ResultSet rs = null; try { //if (Math.random() < 0.1) // throw new NullPointerException("Test."); stmt = c.createStatement(); rs = stmt.executeQuery( query ); //rs.next(); return CONNECTION_IS_OKAY; } catch (SQLException e) { if (Debug.DEBUG && logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Connection " + c + " failed Connection test with an Exception! [query=" + query + "]", e ); if (rootCauseOutParamHolder != null) rootCauseOutParamHolder[0] = e; String state = e.getSQLState(); if ( INVALID_DB_STATES.contains( state ) ) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "SQL State '" + state + "' of Exception which occurred during a Connection test (test with query '" + query + "') implies that the database is invalid, " + "and the pool should refill itself with fresh Connections.", e); return DATABASE_IS_INVALID; } else return CONNECTION_IS_INVALID; } catch (Exception e) { if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "Connection " + c + " failed Connection test with an Exception!", e ); if (rootCauseOutParamHolder != null) rootCauseOutParamHolder[0] = e; return CONNECTION_IS_INVALID; } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( stmt ); // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) ) // logger.finer("Exiting DefaultConnectionTester.activeCheckConnection(Connection c, String query). [query=" + query + "]"); } } } public int statusOnException(Connection c, Throwable t, String query, Throwable[] rootCauseOutParamHolder) { // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) ) // logger.finer("Entering DefaultConnectionTester.statusOnException(Connection c, Throwable t, String query) " + queryInfo(query)); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) ) logger.log(MLevel.FINER, "Testing a Connection in response to an Exception:", t); try { if (t instanceof SQLException) { String state = ((SQLException) t).getSQLState(); if ( INVALID_DB_STATES.contains( state ) ) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "SQL State '" + state + "' of Exception tested by statusOnException() implies that the database is invalid, " + "and the pool should refill itself with fresh Connections.", t); return DATABASE_IS_INVALID; } else return activeCheckConnection(c, query, rootCauseOutParamHolder); } else //something is broke { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Connection test failed because test-provoking Throwable is an unexpected, non-SQLException.", t); if (rootCauseOutParamHolder != null) rootCauseOutParamHolder[0] = t; return CONNECTION_IS_INVALID; } } catch (Exception e) { if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "Connection " + c + " failed Connection test with an Exception!", e ); if (rootCauseOutParamHolder != null) rootCauseOutParamHolder[0] = e; return CONNECTION_IS_INVALID; } finally { // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) // { // if ( logger.isLoggable( MLevel.FINER ) ) // logger.finer("Exiting DefaultConnectionTester.statusOnException(Connection c, Throwable t, String query) " + queryInfo(query)); // } } } private static String queryInfo(String query) { return (query == null ? "[using default system-table query]" : "[query=" + query + "]"); } private int activeCheckConnectionNoQuery(Connection c, Throwable[] rootCauseOutParamHolder) { // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) ) // logger.finer("Entering DefaultConnectionTester.activeCheckConnection(Connection c). [using default system-table query]"); ResultSet rs = null; try { rs = c.getMetaData().getTables( null, null, "PROBABLYNOT", new String[] {"TABLE"} ); return CONNECTION_IS_OKAY; } catch (SQLException e) { if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "Connection " + c + " failed default system-table Connection test with an Exception!", e ); if (rootCauseOutParamHolder != null) rootCauseOutParamHolder[0] = e; String state = e.getSQLState(); if ( INVALID_DB_STATES.contains( state ) ) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "SQL State '" + state + "' of Exception which occurred during a Connection test (fallback DatabaseMetaData test) implies that the database is invalid, " + "and the pool should refill itself with fresh Connections.", e); return DATABASE_IS_INVALID; } else return CONNECTION_IS_INVALID; } catch (Exception e) { if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "Connection " + c + " failed default system-table Connection test with an Exception!", e ); if (rootCauseOutParamHolder != null) rootCauseOutParamHolder[0] = e; return CONNECTION_IS_INVALID; } finally { ResultSetUtils.attemptClose( rs ); // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) ) // logger.finer("Exiting DefaultConnectionTester.activeCheckConnection(Connection c). [using default system-table query]"); } } public boolean equals( Object o ) { return ( o != null && o.getClass() == DefaultConnectionTester.class ); } public int hashCode() { return HASH_CODE; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/IdentityTokenResolvable.java0000644000175000017500000000405710624366527025627 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import com.mchange.v2.c3p0.*; import java.io.ObjectStreamException; /** * This is a convenient base class for all classes * that wish to establish an initial identity which * will be the basis of a one-per vm identity: i.e. * in any vm there should only ever be a single object * with a given identity token (except transiently during * canonicalization) * * It would be convenient to put the getter/setter methods * for the identity token here, but unfortunately we have no * way of setting up the for Referenceability in multiple * levels of a class hierarchy. So we leave the getters/setters, * and variable initialization to code-generators. */ public abstract class IdentityTokenResolvable extends AbstractIdentityTokenized { public static Object doResolve(IdentityTokenized itd) { return C3P0Registry.reregister( itd ); } protected Object readResolve() throws ObjectStreamException { //System.err.println("READ RESOLVE!!!!"); Object out = doResolve( this ); verifyResolve( out ); //System.err.println("ORIG: " + this); //System.err.println("RSLV: " + out); return out; } protected void verifyResolve( Object o ) throws ObjectStreamException {} }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/IdentityTokenized.java0000644000175000017500000000177310624366527024466 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; public interface IdentityTokenized { public String getIdentityToken(); public void setIdentityToken(String idToken); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/IdentityTokenizedCoalesceChecker.java0000644000175000017500000000334110624366527027403 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import com.mchange.v2.coalesce.*; public final class IdentityTokenizedCoalesceChecker implements CoalesceChecker { public static IdentityTokenizedCoalesceChecker INSTANCE = new IdentityTokenizedCoalesceChecker(); public boolean checkCoalesce( Object a, Object b ) { IdentityTokenized aa = (IdentityTokenized) a; IdentityTokenized bb = (IdentityTokenized) b; String ta = aa.getIdentityToken(); String tb = bb.getIdentityToken(); if (ta == null || tb == null) throw new NullPointerException( "[c3p0 bug] An IdentityTokenized object has no identity token set?!?! " + (ta == null ? ta : tb) ); else return ta.equals(tb); } public int coalesceHash( Object a ) { String t = ((IdentityTokenized) a).getIdentityToken(); return (t != null ? t.hashCode() : 0); } private IdentityTokenizedCoalesceChecker() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/InternalPooledConnection.java0000644000175000017500000000222210624366527025745 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import javax.sql.*; import com.mchange.v2.c3p0.stmt.*; interface InternalPooledConnection extends PooledConnection { public void initStatementCache( GooGooStatementCache scache ); public GooGooStatementCache getStatementCache(); public int getConnectionStatus(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/NewPooledConnection.java0000644000175000017500000007435510624366530024734 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v2.c3p0.stmt.*; import com.mchange.v2.c3p0.util.*; import com.mchange.v2.log.*; import java.lang.reflect.Method; import com.mchange.v2.lang.ObjectUtils; import com.mchange.v2.sql.SqlUtils; public final class NewPooledConnection extends AbstractC3P0PooledConnection{ private final static MLogger logger = MLog.getLogger( NewPooledConnection.class ); private final static SQLException NORMAL_CLOSE_PLACEHOLDER = new SQLException("This pooled Connection was explicitly close()ed by " + "a client, not invalidated due to an error."); //MT: protected by class lock static Set holdabilityBugKeys = null; //MT: thread-safe post-constructor constants final Connection physicalConnection; final ConnectionTester connectionTester; final boolean autoCommitOnClose; final boolean forceIgnoreUnresolvedTransactions; final String preferredTestQuery; final boolean supports_setHoldability; final boolean supports_setReadOnly; final boolean supports_setTypeMap; final int dflt_txn_isolation; final String dflt_catalog; final int dflt_holdability; final boolean dflt_readOnly; final Map dflt_typeMap; final ConnectionEventSupport ces; //MT: protected by this' lock GooGooStatementCache scache = null; Throwable invalidatingException = null; int connection_status = ConnectionTester.CONNECTION_IS_OKAY; Set uncachedActiveStatements = new HashSet(); //cached statements are managed by the cache Map resultSetsForStatements = new HashMap(); //for both cached and uncached statements Set metaDataResultSets = new HashSet(); Set rawConnectionResultSets = null; //very rarely used, so we lazy initialize... boolean connection_error_signaled = false; //MT: thread-safe, volatile volatile NewProxyConnection exposedProxy = null; volatile boolean isolation_lvl_nondefault = false; volatile boolean catalog_nondefault = false; volatile boolean holdability_nondefault = false; volatile boolean readOnly_nondefault = false; volatile boolean typeMap_nondefault = false; // public API public NewPooledConnection(Connection con, ConnectionTester connectionTester, boolean autoCommitOnClose, boolean forceIgnoreUnresolvedTransactions, String preferredTestQuery, ConnectionCustomizer cc, String pdsIdt) throws SQLException { try { if (cc != null) cc.onAcquire( con, pdsIdt ); } catch (Exception e) { throw SqlUtils.toSQLException(e); } this.physicalConnection = con; this.connectionTester = connectionTester; this.autoCommitOnClose = autoCommitOnClose; this.forceIgnoreUnresolvedTransactions = forceIgnoreUnresolvedTransactions; this.preferredTestQuery = preferredTestQuery; this.supports_setHoldability = C3P0ImplUtils.supportsMethod(con, "setHoldability", new Class[]{ int.class }); this.supports_setReadOnly = C3P0ImplUtils.supportsMethod(con, "setReadOnly", new Class[]{ boolean.class }); this.supports_setTypeMap = C3P0ImplUtils.supportsMethod(con, "setTypeMap", new Class[]{ Map.class }); this.dflt_txn_isolation = con.getTransactionIsolation(); this.dflt_catalog = con.getCatalog(); this.dflt_holdability = (supports_setHoldability ? carefulCheckHoldability(con) : ResultSet.CLOSE_CURSORS_AT_COMMIT); this.dflt_readOnly = (supports_setReadOnly ? carefulCheckReadOnly(con) : false); this.dflt_typeMap = (supports_setTypeMap && (carefulCheckTypeMap(con) == null) ? null : Collections.EMPTY_MAP); this.ces = new ConnectionEventSupport(this); } private static int carefulCheckHoldability(Connection con) { try { return con.getHoldability(); } catch (Exception e) { if (false) { if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, con + " threw an Exception when we tried to check its default " + "holdability. This is not usually a problem! It just means the Connection " + "doesn't support the holdability property, and c3p0 works around this.", e); } return ResultSet.CLOSE_CURSORS_AT_COMMIT; } catch (Error e) // Some DB2 drivers apparently throw an Error here, but I'm not comfortable swallowing Errors { synchronized (NewPooledConnection.class) { if (holdabilityBugKeys == null) holdabilityBugKeys = new HashSet(); String hbk = holdabilityBugKey(con, e); if (! holdabilityBugKeys.contains(hbk) ) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, con + " threw an Error when we tried to check its default " + "holdability. This is probably due to a bug in your JDBC driver that c3p0 can harmlessly " + "work around (reported for some DB2 drivers). Please verify that the error stack trace is consistent" + "with the getHoldability() method not being properly implemented, and is not due to some deeper problem. " + "This message will not be repeated for Connections of type " + con.getClass().getName() + " that " + "provoke errors of type " + e.getClass().getName() + " when getHoldability() is called.", e); holdabilityBugKeys.add(hbk); } } return ResultSet.CLOSE_CURSORS_AT_COMMIT; } } private static String holdabilityBugKey(Connection con, Error err) { return con.getClass().getName() + '|' + err.getClass().getName(); } private static boolean carefulCheckReadOnly(Connection con) { try { return con.isReadOnly(); } catch (Exception e) { if (false) { if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, con + " threw an Exception when we tried to check its default " + "read only state. This is not usually a problem! It just means the Connection " + "doesn't support the readOnly property, and c3p0 works around this.", e); } return false; } } private static Map carefulCheckTypeMap(Connection con) { try { return con.getTypeMap(); } catch (Exception e) { if (false) { if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, con + " threw an Exception when we tried to check its default " + "type map. This is not usually a problem! It just means the Connection " + "doesn't support the typeMap property, and c3p0 works around this.", e); } return null; } } public synchronized Connection getConnection() throws SQLException { try { //throw new SQLException("NOT IMPLEMENTED"); if ( exposedProxy == null ) { exposedProxy = new NewProxyConnection( physicalConnection, this ); } else { // System.err.println("c3p0 -- Uh oh... getConnection() was called on a PooledConnection when " + // "it had already provided a client with a Connection that has not yet been " + // "closed. This probably indicates a bug in the connection pool!!!"); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning("c3p0 -- Uh oh... getConnection() was called on a PooledConnection when " + "it had already provided a client with a Connection that has not yet been " + "closed. This probably indicates a bug in the connection pool!!!"); } return exposedProxy; } catch ( Exception e ) { SQLException sqle = handleThrowable( e ); throw sqle; } } public synchronized int getConnectionStatus() { return connection_status; } public synchronized void closeAll() throws SQLException { try { closeAllCachedStatements(); } catch ( Exception e ) { SQLException sqle = handleThrowable( e ); throw sqle; } } public synchronized void close() throws SQLException { close( null ); } public void addConnectionEventListener(ConnectionEventListener cel) { ces.addConnectionEventListener( cel ); } public void removeConnectionEventListener(ConnectionEventListener cel) { ces.removeConnectionEventListener( cel ); } // api for C3P0PooledConnectionPool public synchronized void initStatementCache( GooGooStatementCache scache ) { this.scache = scache; } public synchronized GooGooStatementCache getStatementCache() { return scache; } //api for NewProxyConnections void markNewTxnIsolation( int lvl ) //intentionally unsync'd -- isolation_lvl_nondefault is marked volatile { this.isolation_lvl_nondefault = (lvl != dflt_txn_isolation); //System.err.println("isolation_lvl_nondefault: " + isolation_lvl_nondefault); } void markNewCatalog( String catalog ) //intentionally unsync'd -- catalog_nondefault is marked volatile { this.catalog_nondefault = ObjectUtils.eqOrBothNull(catalog, dflt_catalog); } void markNewHoldability( int holdability ) //intentionally unsync'd -- holdability_nondefault is marked volatile { this.holdability_nondefault = (holdability != dflt_holdability); } void markNewReadOnly( boolean readOnly ) //intentionally unsync'd -- readOnly_nondefault is marked volatile { this.readOnly_nondefault = (readOnly != dflt_readOnly); } void markNewTypeMap( Map typeMap ) //intentionally unsync'd -- typeMap_nondefault is marked volatile { this.typeMap_nondefault = (typeMap != dflt_typeMap); } synchronized Object checkoutStatement( Method stmtProducingMethod, Object[] args ) throws SQLException { return scache.checkoutStatement( physicalConnection, stmtProducingMethod, args ); } synchronized void checkinStatement( Statement stmt ) throws SQLException { cleanupStatementResultSets( stmt ); scache.checkinStatement( stmt ); } synchronized void markActiveUncachedStatement( Statement stmt ) { uncachedActiveStatements.add( stmt ); } synchronized void markInactiveUncachedStatement( Statement stmt ) { cleanupStatementResultSets( stmt ); uncachedActiveStatements.remove( stmt ); } synchronized void markActiveResultSetForStatement( Statement stmt, ResultSet rs ) { Set rss = resultSets( stmt, true ); rss.add( rs ); } synchronized void markInactiveResultSetForStatement( Statement stmt, ResultSet rs ) { Set rss = resultSets( stmt, false ); if (rss == null) { if (logger.isLoggable( MLevel.FINE )) logger.fine( "ResultSet " + rs + " was apparently closed after the Statement that created it had already been closed." ); } else if ( ! rss.remove( rs ) ) throw new InternalError("Marking a ResultSet inactive that we did not know was opened!"); } synchronized void markActiveRawConnectionResultSet( ResultSet rs ) { if (rawConnectionResultSets == null) rawConnectionResultSets = new HashSet(); rawConnectionResultSets.add( rs ); } synchronized void markInactiveRawConnectionResultSet( ResultSet rs ) { if ( ! rawConnectionResultSets.remove( rs ) ) throw new InternalError("Marking a raw Connection ResultSet inactive that we did not know was opened!"); } synchronized void markActiveMetaDataResultSet( ResultSet rs ) { metaDataResultSets.add( rs ); } synchronized void markInactiveMetaDataResultSet( ResultSet rs ) { metaDataResultSets.remove( rs ); } // internal synchronization to avoid sync'ed event multicasts void markClosedProxyConnection( NewProxyConnection npc, boolean txn_known_resolved ) { SQLException trouble = null; try { synchronized( this ) { try { if (npc != exposedProxy) throw new InternalError("C3P0 Error: An exposed proxy asked a PooledConnection that was not its parents to clean up its resources!"); List closeExceptions = new LinkedList(); cleanupResultSets( closeExceptions ); cleanupUncachedStatements( closeExceptions ); checkinAllCachedStatements( closeExceptions ); if ( closeExceptions.size() > 0 ) { // System.err.println("[c3p0] The following Exceptions occurred while trying to clean up a Connection's stranded resources:"); if ( logger.isLoggable( MLevel.INFO ) ) logger.info("[c3p0] The following Exceptions occurred while trying to clean up a Connection's stranded resources:"); for ( Iterator ii = closeExceptions.iterator(); ii.hasNext(); ) { Throwable t = (Throwable) ii.next(); // System.err.print("[c3p0 -- conection resource close Exception]: "); // t.printStackTrace(); if ( logger.isLoggable( MLevel.INFO ) ) logger.log( MLevel.INFO, "[c3p0 -- conection resource close Exception]", t ); } } reset( txn_known_resolved ); } catch (SQLException e) //Connection failed to reset! { //e.printStackTrace(); if (Debug.DEBUG && logger.isLoggable( MLevel.FINE )) logger.log(MLevel.FINE, "An exception occurred while reseting a closed Connection. Invalidating Connection.", e); updateConnectionStatus( ConnectionTester.CONNECTION_IS_INVALID ); } } } finally { if (trouble != null) fireConnectionErrorOccurred( trouble ); //should not be invoked from a sync'ed block else { exposedProxy = null; //volatile fireConnectionClosed(); //should not be invoked from a sync'ed block } } } private void reset( boolean txn_known_resolved ) throws SQLException { C3P0ImplUtils.resetTxnState( physicalConnection, forceIgnoreUnresolvedTransactions, autoCommitOnClose, txn_known_resolved ); if (isolation_lvl_nondefault) { physicalConnection.setTransactionIsolation( dflt_txn_isolation ); isolation_lvl_nondefault = false; //System.err.println("reset txn isolation: " + dflt_txn_isolation); } if (catalog_nondefault) { physicalConnection.setCatalog( dflt_catalog ); catalog_nondefault = false; } if (holdability_nondefault) //this cannot go to true if holdability is not supported, so we don't have to check. { physicalConnection.setHoldability( dflt_holdability ); holdability_nondefault = false; } if (readOnly_nondefault) { physicalConnection.setReadOnly( dflt_readOnly ); readOnly_nondefault = false; } if (typeMap_nondefault) { physicalConnection.setTypeMap( dflt_typeMap ); typeMap_nondefault = false; } } synchronized boolean isStatementCaching() { return scache != null; } //synchrnized internally to avoid holding locks during event multicast SQLException handleThrowable( Throwable t ) { boolean fire_cxn_error = false; SQLException sqle = null; try { synchronized (this) { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, this + " handling a throwable.", t ); sqle = SqlUtils.toSQLException( t ); //logger.warning("handle throwable ct: " + connectionTester); int status; if (connectionTester instanceof FullQueryConnectionTester) status = ((FullQueryConnectionTester) connectionTester).statusOnException( physicalConnection, sqle, preferredTestQuery ); else status = connectionTester.statusOnException( physicalConnection, sqle ); updateConnectionStatus( status ); if (status != ConnectionTester.CONNECTION_IS_OKAY) { if (Debug.DEBUG) { // System.err.print(this + " invalidated by Exception: "); // t.printStackTrace(); if ( logger.isLoggable( MLevel.FINE ) ) logger.log(MLevel.FINE, this + " invalidated by Exception.", t); } /* ------ A users have complained that SQLExceptions ought not close their Connections underneath them under any circumstance. Signalling the Connection error after updating the Connection status should be sufficient from the pool's perspective, because the PooledConnection will be marked broken by the pool and will be destroyed on checkin. I think actually close()ing the Connection when it appears to be broken rather than waiting for users to close() it themselves is overly aggressive, so I'm commenting the old behavior out. The only potential downside to this approach is that users who do not close() in a finally clause properly might see their close()es skipped by exceptions that previously would have led to automatic close(). But relying on the automatic close() was never reliable (since it only ever happened when c3p0 determined a Connection to be absolutely broken), and is generally speaking a client error that c3p0 ought not be responsible for dealing with. I think it's right to leave this out. -- swaldman 2004-12-09 ------ try { close( t ); } catch (SQLException e) { e.printStackTrace(); throw new InternalError("C3P0 Error: NewPooledConnection's private close() method should " + "suppress any Exceptions if a throwable cause is provided."); } */ if (! connection_error_signaled) fire_cxn_error = true; else { // System.err.println("[c3p0] Warning: PooledConnection that has already signalled a Connection error is still in use!"); // System.err.println("[c3p0] Another error has occurred [ " + t + " ] which will not be reported to listeners!"); if ( logger.isLoggable( MLevel.WARNING ) ) { logger.log(MLevel.WARNING, "[c3p0] A PooledConnection that has already signalled a Connection error is still in use!"); logger.log(MLevel.WARNING, "[c3p0] Another error has occurred [ " + t + " ] which will not be reported to listeners!", t); } } } }// end sync'ed block }// end try block finally { if (fire_cxn_error) { fireConnectionErrorOccurred( sqle ); //should not be invoked from a sync'ed block connection_error_signaled = true; } } return sqle; } // private methods // should NOT be called from sync'ed method private void fireConnectionClosed() { assert (! Thread.holdsLock(this)); ces.fireConnectionClosed(); } // should NOT be called from sync'ed method private void fireConnectionErrorOccurred(SQLException error) { assert (! Thread.holdsLock(this)); ces.fireConnectionErrorOccurred( error ); } // methods below must be called from sync'ed methods /* * If a throwable cause is provided, the PooledConnection is known to be broken (cause is an invalidating exception) * and this method will not throw any exceptions, even if some resource closes fail. * * If cause is null, then we think the PooledConnection is healthy, and we will report (throw) an exception * if resources unexpectedlay fail to close. */ private void close( Throwable cause ) throws SQLException { if ( this.invalidatingException == null ) { List closeExceptions = new LinkedList(); // cleanup ResultSets cleanupResultSets( closeExceptions ); // cleanup uncached Statements cleanupUncachedStatements( closeExceptions ); // cleanup cached Statements try { closeAllCachedStatements(); } catch ( SQLException e ) { closeExceptions.add(e); } // cleanup physicalConnection try { physicalConnection.close(); } catch ( SQLException e ) { if (logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Failed to close physical Connection: " + physicalConnection, e ); closeExceptions.add(e); } // update our state to bad status and closed, and log any exceptions if ( connection_status == ConnectionTester.CONNECTION_IS_OKAY ) connection_status = ConnectionTester.CONNECTION_IS_INVALID; if ( cause == null ) { this.invalidatingException = NORMAL_CLOSE_PLACEHOLDER; if ( logger.isLoggable( MLevel.FINEST ) ) logger.log( MLevel.FINEST, this + " closed by a client.", new Exception("DEBUG -- CLOSE BY CLIENT STACK TRACE") ); logCloseExceptions( null, closeExceptions ); if (closeExceptions.size() > 0) throw new SQLException("Some resources failed to close properly while closing " + this); } else { this.invalidatingException = cause; if (Debug.TRACE >= Debug.TRACE_MED) logCloseExceptions( cause, closeExceptions ); else logCloseExceptions( cause, null ); } } } private void cleanupResultSets( List closeExceptions ) { cleanupAllStatementResultSets( closeExceptions ); cleanupUnclosedResultSetsSet( metaDataResultSets, closeExceptions ); if ( rawConnectionResultSets != null ) cleanupUnclosedResultSetsSet( rawConnectionResultSets, closeExceptions ); } private void cleanupUnclosedResultSetsSet( Set rsSet, List closeExceptions ) { for ( Iterator ii = rsSet.iterator(); ii.hasNext(); ) { ResultSet rs = (ResultSet) ii.next(); try { rs.close(); } catch ( SQLException e ) { closeExceptions.add(e); } ii.remove(); } } private void cleanupStatementResultSets( Statement stmt ) { Set rss = resultSets( stmt, false ); if ( rss != null ) { for ( Iterator ii = rss.iterator(); ii.hasNext(); ) { try { ((ResultSet) ii.next()).close(); } catch ( Exception e ) { // System.err.print("ResultSet close() failed: "); // e.printStackTrace(); if ( logger.isLoggable( MLevel.INFO ) ) logger.log(MLevel.INFO, "ResultSet close() failed.", e); } } } resultSetsForStatements.remove( stmt ); } private void cleanupAllStatementResultSets( List closeExceptions ) { for ( Iterator ii = resultSetsForStatements.keySet().iterator(); ii.hasNext(); ) { Object stmt = ii.next(); Set rss = (Set) resultSetsForStatements.get( stmt ); for (Iterator jj = rss.iterator(); jj.hasNext(); ) { ResultSet rs = (ResultSet) jj.next(); try { rs.close(); } catch ( SQLException e ) { closeExceptions.add(e); } } } resultSetsForStatements.clear(); } private void cleanupUncachedStatements( List closeExceptions ) { for ( Iterator ii = uncachedActiveStatements.iterator(); ii.hasNext(); ) { Statement stmt = (Statement) ii.next(); try { stmt.close(); } catch ( SQLException e ) { closeExceptions.add(e); } ii.remove(); } } private void checkinAllCachedStatements( List closeExceptions ) { try { if (scache != null) scache.checkinAll( physicalConnection ); } catch ( SQLException e ) { closeExceptions.add(e); } } private void closeAllCachedStatements() throws SQLException { if (scache != null) scache.closeAll( physicalConnection ); } private void updateConnectionStatus(int status) { switch ( this.connection_status ) { case ConnectionTester.DATABASE_IS_INVALID: //can't get worse than this, do nothing. break; case ConnectionTester.CONNECTION_IS_INVALID: if (status == ConnectionTester.DATABASE_IS_INVALID) this.connection_status = status; break; case ConnectionTester.CONNECTION_IS_OKAY: if (status != ConnectionTester.CONNECTION_IS_OKAY) this.connection_status = status; break; default: throw new InternalError(this + " -- Illegal Connection Status: " + this.connection_status); } } private Set resultSets( Statement stmt, boolean create ) { Set out = (Set) resultSetsForStatements.get( stmt ); if ( out == null && create ) { out = new HashSet(); resultSetsForStatements.put( stmt, out ); } return out; } // used by C3P0PooledConnectionPool Connection getPhysicalConnection() { return physicalConnection; } // static utility functions private static void logCloseExceptions( Throwable cause, Collection exceptions ) { if ( logger.isLoggable( MLevel.INFO ) ) { if (cause != null) { // System.err.println("[c3p0] A PooledConnection died due to the following error!"); // cause.printStackTrace(); logger.log(MLevel.INFO, "[c3p0] A PooledConnection died due to the following error!", cause); } if ( exceptions != null && exceptions.size() > 0) { if ( cause == null ) logger.info("[c3p0] Exceptions occurred while trying to close a PooledConnection's resources normally."); //System.err.println("[c3p0] The following Exceptions occurred while trying to close a PooledConnection's resources normally."); else logger.info("[c3p0] Exceptions occurred while trying to close a Broken PooledConnection."); //System.err.println("[c3p0] The following Exceptions occurred while trying to close a broken PooledConnection."); for ( Iterator ii = exceptions.iterator(); ii.hasNext(); ) { Throwable t = (Throwable) ii.next(); // System.err.print("[c3p0 -- close Exception]: "); // t.printStackTrace(); logger.log(MLevel.INFO, "[c3p0] NewPooledConnection close Exception.", t); } } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/NullStatementSetManagedResultSet.java0000644000175000017500000000266110624366530027412 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ /* * Created on Apr 6, 2004 * * To change the template for this generated file go to * Window>Preferences>Java>Code Generation>Code and Comments */ package com.mchange.v2.c3p0.impl; import java.sql.ResultSet; import java.sql.Statement; import java.util.Set; final class NullStatementSetManagedResultSet extends SetManagedResultSet { NullStatementSetManagedResultSet(Set activeResultSets) { super( activeResultSets ); } NullStatementSetManagedResultSet(ResultSet inner, Set activeResultSets) { super( inner, activeResultSets); } public Statement getStatement() { return null; } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/SetManagedDatabaseMetaData.java0000644000175000017500000001176310624366530026050 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.sql.*; import java.util.Set; import com.mchange.v2.sql.filter.FilterDatabaseMetaData; final class SetManagedDatabaseMetaData extends FilterDatabaseMetaData { Set activeResultSets; Connection returnableProxy; SetManagedDatabaseMetaData( DatabaseMetaData inner, Set activeResultSets, Connection returnableProxy ) { super( inner ); this.activeResultSets = activeResultSets; this.returnableProxy = returnableProxy; } public Connection getConnection() throws SQLException { return returnableProxy; } public ResultSet getProcedures(String a, String b, String c) throws SQLException { return new NullStatementSetManagedResultSet( inner.getProcedures(a, b, c), activeResultSets ); } public ResultSet getProcedureColumns(String a, String b, String c, String d) throws SQLException { return new NullStatementSetManagedResultSet( inner.getProcedureColumns(a, b, c, d), activeResultSets ); } public ResultSet getTables(String a, String b, String c, String[] d) throws SQLException { return new NullStatementSetManagedResultSet( inner.getTables(a, b, c, d), activeResultSets ); } public ResultSet getSchemas() throws SQLException { return new NullStatementSetManagedResultSet( inner.getSchemas(), activeResultSets ); } public ResultSet getCatalogs() throws SQLException { return new NullStatementSetManagedResultSet( inner.getCatalogs(), activeResultSets ); } public ResultSet getTableTypes() throws SQLException { return new NullStatementSetManagedResultSet( inner.getTableTypes(), activeResultSets ); } public ResultSet getColumns(String a, String b, String c, String d) throws SQLException { return new NullStatementSetManagedResultSet( inner.getColumns(a, b, c, d), activeResultSets ); } public ResultSet getColumnPrivileges(String a, String b, String c, String d) throws SQLException { return new NullStatementSetManagedResultSet( inner.getColumnPrivileges(a, b, c, d), activeResultSets ); } public ResultSet getTablePrivileges(String a, String b, String c) throws SQLException { return new NullStatementSetManagedResultSet( inner.getTablePrivileges(a, b, c), activeResultSets ); } public ResultSet getBestRowIdentifier(String a, String b, String c, int d, boolean e) throws SQLException { return new NullStatementSetManagedResultSet( inner.getBestRowIdentifier(a, b, c, d, e), activeResultSets ); } public ResultSet getVersionColumns(String a, String b, String c) throws SQLException { return new NullStatementSetManagedResultSet( inner.getVersionColumns(a, b, c), activeResultSets ); } public ResultSet getPrimaryKeys(String a, String b, String c) throws SQLException { return new NullStatementSetManagedResultSet( inner.getPrimaryKeys(a, b, c), activeResultSets ); } public ResultSet getImportedKeys(String a, String b, String c) throws SQLException { return new NullStatementSetManagedResultSet( inner.getImportedKeys(a, b, c), activeResultSets ); } public ResultSet getExportedKeys(String a, String b, String c) throws SQLException { return new NullStatementSetManagedResultSet( inner.getExportedKeys(a, b, c), activeResultSets ); } public ResultSet getCrossReference(String a, String b, String c, String d, String e, String f) throws SQLException { return new NullStatementSetManagedResultSet( inner.getCrossReference(a, b, c, d, e, f), activeResultSets ); } public ResultSet getTypeInfo() throws SQLException { return new NullStatementSetManagedResultSet( inner.getTypeInfo(), activeResultSets ); } public ResultSet getIndexInfo(String a, String b, String c, boolean d, boolean e) throws SQLException { return new NullStatementSetManagedResultSet( inner.getIndexInfo(a, b, c, d, e), activeResultSets ); } public ResultSet getUDTs(String a, String b, String c, int[] d) throws SQLException { return new NullStatementSetManagedResultSet( inner.getUDTs(a, b, c, d), activeResultSets ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/SetManagedResultSet.java0000644000175000017500000000312210624366530024663 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.sql.*; import java.util.Set; import com.mchange.v2.sql.filter.FilterResultSet; abstract class SetManagedResultSet extends FilterResultSet { Set activeResultSets; SetManagedResultSet(Set activeResultSets) { this.activeResultSets = activeResultSets; } SetManagedResultSet(ResultSet inner, Set activeResultSets) { super( inner ); this.activeResultSets = activeResultSets; } public synchronized void setInner(ResultSet inner) { this.inner = inner; activeResultSets.add( inner ); } public synchronized void close() throws SQLException { if ( inner != null ) { inner.close(); activeResultSets.remove( inner ); inner = null; } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/impl/SnatchFromSetResultSet.java0000644000175000017500000000263410624366527025410 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.impl; import java.sql.*; import java.util.Set; import com.mchange.v2.sql.filter.FilterResultSet; final class SnatchFromSetResultSet extends FilterResultSet { Set activeResultSets; SnatchFromSetResultSet(Set activeResultSets) { this.activeResultSets = activeResultSets; } public synchronized void setInner(ResultSet inner) { this.inner = inner; activeResultSets.add( inner ); } public synchronized void close() throws SQLException { inner.close(); activeResultSets.remove( inner ); inner = null; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/jboss/0000755000175000017500000000000010673162231020312 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/jboss/C3P0PooledDataSource.java0000644000175000017500000003655410624366530024761 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.jboss; import com.mchange.v2.c3p0.*; import com.mchange.v2.log.*; import java.beans.PropertyVetoException; import java.sql.Connection; import java.sql.SQLException; import java.io.PrintWriter; import java.util.Properties; import javax.sql.DataSource; import javax.naming.InitialContext; import javax.naming.Name; import javax.naming.Context; import javax.naming.NameAlreadyBoundException; import javax.naming.NamingException; public class C3P0PooledDataSource implements C3P0PooledDataSourceMBean { private final static MLogger logger = MLog.getLogger( C3P0PooledDataSource.class ); String jndiName; ComboPooledDataSource combods = new ComboPooledDataSource(); private void rebind() throws NamingException { rebind(null); } private void rebind(String unbindName) throws NamingException { InitialContext ictx = new InitialContext(); if (unbindName != null) ictx.unbind( unbindName ); if (jndiName != null) { // Thanks to David D. Kilzer for this code to auto-create // subcontext paths! Name name = ictx.getNameParser( jndiName ).parse( jndiName ); Context ctx = ictx; for (int i = 0, max = name.size() - 1; i < max; i++) { try { ctx = ctx.createSubcontext( name.get( i ) ); } catch (NameAlreadyBoundException ignore) { ctx = (Context) ctx.lookup( name.get( i ) ); } } ictx.rebind( jndiName, combods ); } } // Jndi Setup Names public void setJndiName(String jndiName) throws NamingException { String unbindName = this.jndiName; this.jndiName = jndiName; rebind( unbindName ); } public String getJndiName() { return jndiName; } // DriverManagerDataSourceProperties (count: 4) public String getDescription() { return combods.getDescription(); } public void setDescription( String description ) throws NamingException { combods.setDescription( description ); rebind(); } public String getDriverClass() { return combods.getDriverClass(); } public void setDriverClass( String driverClass ) throws PropertyVetoException, NamingException { combods.setDriverClass( driverClass ); rebind(); } public String getJdbcUrl() { return combods.getJdbcUrl(); } public void setJdbcUrl( String jdbcUrl ) throws NamingException { combods.setJdbcUrl( jdbcUrl ); rebind(); } // DriverManagerDataSource "virtual properties" based on properties public String getUser() { return combods.getUser(); } public void setUser( String user ) throws NamingException { combods.setUser( user ); rebind(); } public String getPassword() { return combods.getPassword(); } public void setPassword( String password ) throws NamingException { combods.setPassword( password ); rebind(); } // WrapperConnectionPoolDataSource properties (count: 21) public int getCheckoutTimeout() { return combods.getCheckoutTimeout(); } public void setCheckoutTimeout( int checkoutTimeout ) throws NamingException { combods.setCheckoutTimeout( checkoutTimeout ); rebind(); } public int getAcquireIncrement() { return combods.getAcquireIncrement(); } public void setAcquireIncrement( int acquireIncrement ) throws NamingException { combods.setAcquireIncrement( acquireIncrement ); rebind(); } public int getAcquireRetryAttempts() { return combods.getAcquireRetryAttempts(); } public void setAcquireRetryAttempts( int acquireRetryAttempts ) throws NamingException { combods.setAcquireRetryAttempts( acquireRetryAttempts ); rebind(); } public int getAcquireRetryDelay() { return combods.getAcquireRetryDelay(); } public void setAcquireRetryDelay( int acquireRetryDelay ) throws NamingException { combods.setAcquireRetryDelay( acquireRetryDelay ); rebind(); } public boolean isAutoCommitOnClose() { return combods.isAutoCommitOnClose(); } public void setAutoCommitOnClose( boolean autoCommitOnClose ) throws NamingException { combods.setAutoCommitOnClose( autoCommitOnClose ); rebind(); } public String getConnectionTesterClassName() { return combods.getConnectionTesterClassName(); } public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException, NamingException { combods.setConnectionTesterClassName( connectionTesterClassName ); rebind(); } public String getAutomaticTestTable() { return combods.getAutomaticTestTable(); } public void setAutomaticTestTable( String automaticTestTable ) throws NamingException { combods.setAutomaticTestTable( automaticTestTable ); rebind(); } public boolean isForceIgnoreUnresolvedTransactions() { return combods.isForceIgnoreUnresolvedTransactions(); } public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) throws NamingException { combods.setForceIgnoreUnresolvedTransactions( forceIgnoreUnresolvedTransactions ); rebind(); } public int getIdleConnectionTestPeriod() { return combods.getIdleConnectionTestPeriod(); } public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) throws NamingException { combods.setIdleConnectionTestPeriod( idleConnectionTestPeriod ); rebind(); } public int getInitialPoolSize() { return combods.getInitialPoolSize(); } public void setInitialPoolSize( int initialPoolSize ) throws NamingException { combods.setInitialPoolSize( initialPoolSize ); rebind(); } public int getMaxIdleTime() { return combods.getMaxIdleTime(); } public void setMaxIdleTime( int maxIdleTime ) throws NamingException { combods.setMaxIdleTime( maxIdleTime ); rebind(); } public int getMaxPoolSize() { return combods.getMaxPoolSize(); } public void setMaxPoolSize( int maxPoolSize ) throws NamingException { combods.setMaxPoolSize( maxPoolSize ); rebind(); } public int getMaxStatements() { return combods.getMaxStatements(); } public void setMaxStatements( int maxStatements ) throws NamingException { combods.setMaxStatements( maxStatements ); rebind(); } public int getMaxStatementsPerConnection() { return combods.getMaxStatementsPerConnection(); } public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) throws NamingException { combods.setMaxStatementsPerConnection( maxStatementsPerConnection ); rebind(); } public int getMinPoolSize() { return combods.getMinPoolSize(); } public void setMinPoolSize( int minPoolSize ) throws NamingException { combods.setMinPoolSize( minPoolSize ); rebind(); } public int getPropertyCycle() { return combods.getPropertyCycle(); } public void setPropertyCycle( int propertyCycle ) throws NamingException { combods.setPropertyCycle( propertyCycle ); rebind(); } public boolean isBreakAfterAcquireFailure() { return combods.isBreakAfterAcquireFailure(); } public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) throws NamingException { combods.setBreakAfterAcquireFailure( breakAfterAcquireFailure ); rebind(); } public boolean isTestConnectionOnCheckout() { return combods.isTestConnectionOnCheckout(); } public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) throws NamingException { combods.setTestConnectionOnCheckout( testConnectionOnCheckout ); rebind(); } public boolean isTestConnectionOnCheckin() { return combods.isTestConnectionOnCheckin(); } public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) throws NamingException { combods.setTestConnectionOnCheckin( testConnectionOnCheckin ); rebind(); } public boolean isUsesTraditionalReflectiveProxies() { return combods.isUsesTraditionalReflectiveProxies(); } public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) throws NamingException { combods.setUsesTraditionalReflectiveProxies( usesTraditionalReflectiveProxies ); rebind(); } public String getPreferredTestQuery() { return combods.getPreferredTestQuery(); } public void setPreferredTestQuery( String preferredTestQuery ) throws NamingException { combods.setPreferredTestQuery( preferredTestQuery ); rebind(); } // PoolBackedDataSource properties (count: 2) public String getDataSourceName() { return combods.getDataSourceName(); } public void setDataSourceName( String name ) throws NamingException { combods.setDataSourceName( name ); rebind(); } public int getNumHelperThreads() { return combods.getNumHelperThreads(); } public void setNumHelperThreads( int numHelperThreads ) throws NamingException { combods.setNumHelperThreads( numHelperThreads ); rebind(); } // shared properties (count: 1) public String getFactoryClassLocation() { return combods.getFactoryClassLocation(); } public void setFactoryClassLocation( String factoryClassLocation ) throws NamingException { combods.setFactoryClassLocation( factoryClassLocation ); rebind(); } // PooledDataSource statistics public int getNumUserPools() throws SQLException { return combods.getNumUserPools(); } public int getNumConnectionsDefaultUser() throws SQLException { return combods.getNumConnectionsDefaultUser(); } public int getNumIdleConnectionsDefaultUser() throws SQLException { return combods.getNumIdleConnectionsDefaultUser(); } public int getNumBusyConnectionsDefaultUser() throws SQLException { return combods.getNumBusyConnectionsDefaultUser(); } public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException { return combods.getNumUnclosedOrphanedConnectionsDefaultUser(); } public int getNumConnections(String username, String password) throws SQLException { return combods.getNumConnections(username, password); } public int getNumIdleConnections(String username, String password) throws SQLException { return combods.getNumIdleConnections(username, password); } public int getNumBusyConnections(String username, String password) throws SQLException { return combods.getNumBusyConnections(username, password); } public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException { return combods.getNumUnclosedOrphanedConnections(username, password); } public int getNumConnectionsAllUsers() throws SQLException { return combods.getNumConnectionsAllUsers(); } public int getNumIdleConnectionsAllUsers() throws SQLException { return combods.getNumIdleConnectionsAllUsers(); } public int getNumBusyConnectionsAllUsers() throws SQLException { return combods.getNumBusyConnectionsAllUsers(); } public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException { return combods.getNumUnclosedOrphanedConnectionsAllUsers(); } // PooledDataSource operations public void softResetDefaultUser() throws SQLException { combods.softResetDefaultUser(); } public void softReset(String username, String password) throws SQLException { combods.softReset(username, password); } public void softResetAllUsers() throws SQLException { combods.softResetAllUsers(); } public void hardReset() throws SQLException { combods.hardReset(); } public void close() throws SQLException { combods.close(); } //JBoss only... (but these methods need not be called for the mbean to work) public void create() throws Exception { } // the mbean works without this, but if called we start populating the pool early public void start() throws Exception { //System.err.println("Bound C3P0 PooledDataSource to name '" + jndiName + "'. Starting..."); logger.log(MLevel.INFO, "Bound C3P0 PooledDataSource to name ''{0}''. Starting...", jndiName); combods.getNumBusyConnectionsDefaultUser(); //just touch the datasource to start it up. } public void stop() { } public void destroy() { try { combods.close(); logger.log(MLevel.INFO, "Destroyed C3P0 PooledDataSource with name ''{0}''.", jndiName); } catch (Exception e) { logger.log(MLevel.INFO, "Failed to destroy C3P0 PooledDataSource.", e); } } public String getConnectionCustomizerClassName() { return combods.getConnectionCustomizerClassName(); } public float getEffectivePropertyCycle(String username, String password) throws SQLException { return combods.getEffectivePropertyCycle(username, password); } public float getEffectivePropertyCycleDefaultUser() throws SQLException { return combods.getEffectivePropertyCycleDefaultUser(); } public int getMaxAdministrativeTaskTime() { return combods.getMaxAdministrativeTaskTime(); } public int getMaxConnectionAge() { return combods.getMaxConnectionAge(); } public int getMaxIdleTimeExcessConnections() { return combods.getMaxIdleTimeExcessConnections(); } public int getUnreturnedConnectionTimeout() { return combods.getUnreturnedConnectionTimeout(); } public boolean isDebugUnreturnedConnectionStackTraces() { return combods.isDebugUnreturnedConnectionStackTraces(); } public void setConnectionCustomizerClassName(String connectionCustomizerClassName) throws NamingException { combods.setConnectionCustomizerClassName(connectionCustomizerClassName); rebind(); } public void setDebugUnreturnedConnectionStackTraces(boolean debugUnreturnedConnectionStackTraces) throws NamingException { combods.setDebugUnreturnedConnectionStackTraces(debugUnreturnedConnectionStackTraces); rebind(); } public void setMaxAdministrativeTaskTime(int maxAdministrativeTaskTime) throws NamingException { combods.setMaxAdministrativeTaskTime(maxAdministrativeTaskTime); rebind(); } public void setMaxConnectionAge(int maxConnectionAge) throws NamingException { combods.setMaxConnectionAge( maxConnectionAge ); rebind(); } public void setMaxIdleTimeExcessConnections(int maxIdleTimeExcessConnections) throws NamingException { combods.setMaxIdleTimeExcessConnections(maxIdleTimeExcessConnections); rebind(); } public void setUnreturnedConnectionTimeout(int unreturnedConnectionTimeout) throws NamingException { combods.setUnreturnedConnectionTimeout(unreturnedConnectionTimeout); rebind(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/jboss/C3P0PooledDataSourceMBean.java0000644000175000017500000001740110624366527025660 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.jboss; import com.mchange.v2.c3p0.*; import java.beans.PropertyVetoException; import java.sql.SQLException; import java.util.Properties; import javax.naming.NamingException; public interface C3P0PooledDataSourceMBean { // Jndi Setup public void setJndiName(String jndiName) throws NamingException; public String getJndiName(); // DriverManagerDataSourceProperties public String getDescription(); public void setDescription( String description ) throws NamingException; public String getDriverClass(); public void setDriverClass( String driverClass ) throws PropertyVetoException, NamingException; public String getJdbcUrl(); public void setJdbcUrl( String jdbcUrl ) throws NamingException; // DriverManagerDataSource "virtual properties" based on properties public String getUser(); public void setUser( String user ) throws NamingException; public String getPassword(); public void setPassword( String password ) throws NamingException; // WrapperConnectionPoolDataSource properties public int getUnreturnedConnectionTimeout(); public void setUnreturnedConnectionTimeout(int unreturnedConnectionTimeout) throws NamingException; public boolean isDebugUnreturnedConnectionStackTraces(); public void setDebugUnreturnedConnectionStackTraces(boolean debugUnreturnedConnectionStackTraces) throws NamingException; public String getConnectionCustomizerClassName(); public void setConnectionCustomizerClassName( String connectionCustomizerClassName ) throws NamingException; public int getMaxConnectionAge(); public void setMaxConnectionAge( int maxConnectionAge ) throws NamingException; public int getMaxIdleTimeExcessConnections(); public void setMaxIdleTimeExcessConnections( int maxIdleTimeExcessConnections ) throws NamingException; public int getMaxAdministrativeTaskTime(); public void setMaxAdministrativeTaskTime( int maxAdministrativeTaskTime ) throws NamingException; public int getCheckoutTimeout(); public void setCheckoutTimeout( int checkoutTimeout ) throws NamingException; public int getAcquireIncrement(); public void setAcquireIncrement( int acquireIncrement ) throws NamingException; public int getAcquireRetryAttempts(); public void setAcquireRetryAttempts( int acquireRetryAttempts ) throws NamingException; public int getAcquireRetryDelay(); public void setAcquireRetryDelay( int acquireRetryDelay ) throws NamingException; public boolean isAutoCommitOnClose(); public void setAutoCommitOnClose( boolean autoCommitOnClose ) throws NamingException; public String getConnectionTesterClassName(); public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException, NamingException; public String getAutomaticTestTable(); public void setAutomaticTestTable( String automaticTestTable ) throws NamingException; public boolean isForceIgnoreUnresolvedTransactions(); public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) throws NamingException; public int getIdleConnectionTestPeriod(); public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) throws NamingException; public int getInitialPoolSize(); public void setInitialPoolSize( int initialPoolSize ) throws NamingException; public int getMaxIdleTime(); public void setMaxIdleTime( int maxIdleTime ) throws NamingException; public int getMaxPoolSize(); public void setMaxPoolSize( int maxPoolSize ) throws NamingException; public int getMaxStatements(); public void setMaxStatements( int maxStatements ) throws NamingException; public int getMaxStatementsPerConnection(); public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) throws NamingException; public int getMinPoolSize(); public void setMinPoolSize( int minPoolSize ) throws NamingException; public int getPropertyCycle(); public void setPropertyCycle( int propertyCycle ) throws NamingException; public boolean isBreakAfterAcquireFailure(); public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) throws NamingException; public boolean isTestConnectionOnCheckout(); public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) throws NamingException; public boolean isTestConnectionOnCheckin(); public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) throws NamingException; public boolean isUsesTraditionalReflectiveProxies(); public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) throws NamingException; public String getPreferredTestQuery(); public void setPreferredTestQuery( String preferredTestQuery ) throws NamingException; // PoolBackedDataSource properties (count: 2) public int getNumHelperThreads(); public void setNumHelperThreads( int numHelperThreads ) throws NamingException; // shared properties (count: 1) public String getFactoryClassLocation(); public void setFactoryClassLocation( String factoryClassLocation ) throws NamingException; // PooledDataSource statistics public int getNumUserPools() throws SQLException; public int getNumConnectionsDefaultUser() throws SQLException; public int getNumIdleConnectionsDefaultUser() throws SQLException; public int getNumBusyConnectionsDefaultUser() throws SQLException; public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException; public int getNumConnections(String username, String password) throws SQLException; public int getNumIdleConnections(String username, String password) throws SQLException; public int getNumBusyConnections(String username, String password) throws SQLException; public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException; public float getEffectivePropertyCycle(String username, String password) throws SQLException; public int getNumBusyConnectionsAllUsers() throws SQLException; public int getNumIdleConnectionsAllUsers() throws SQLException; public int getNumConnectionsAllUsers() throws SQLException; public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException; public float getEffectivePropertyCycleDefaultUser() throws SQLException; // PooledDataSource operations public void softResetDefaultUser() throws SQLException; public void softReset(String username, String password) throws SQLException; public void softResetAllUsers() throws SQLException; public void hardReset() throws SQLException; public void close() throws SQLException; //JBoss only... (but these methods need not be called for the mbean to work) public void create() throws Exception; public void start() throws Exception; public void stop(); public void destroy(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/0000755000175000017500000000000010673162231021306 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/ActiveManagementCoordinator.java0000644000175000017500000001325010624366530027572 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import java.lang.management.*; import javax.management.*; import com.mchange.v2.log.*; import com.mchange.v2.c3p0.*; public class ActiveManagementCoordinator implements ManagementCoordinator { private final static String C3P0_REGISTRY_NAME = "com.mchange.v2.c3p0:type=C3P0Registry"; //MT: thread-safe final static MLogger logger = MLog.getLogger( ActiveManagementCoordinator.class ); MBeanServer mbs; public ActiveManagementCoordinator() throws Exception { this.mbs = ManagementFactory.getPlatformMBeanServer(); } public void attemptManageC3P0Registry() { try { ObjectName name = new ObjectName(C3P0_REGISTRY_NAME ); C3P0RegistryManager mbean = new C3P0RegistryManager(); if (mbs.isRegistered(name)) { if (logger.isLoggable(MLevel.WARNING)) { logger.warning("A C3P0Registry mbean is already registered. " + "This probably means that an application using c3p0 was undeployed, " + "but not all PooledDataSources were closed prior to undeployment. " + "This may lead to resource leaks over time. Please take care to close " + "all PooledDataSources."); } mbs.unregisterMBean(name); } mbs.registerMBean(mbean, name); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to set up C3P0RegistryManager mBean. " + "[c3p0 will still function normally, but management via JMX may not be possible.]", e); } } public void attemptUnmanageC3P0Registry() { try { ObjectName name = new ObjectName(C3P0_REGISTRY_NAME ); if (mbs.isRegistered(name)) { mbs.unregisterMBean(name); if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "C3P0Registry mbean unregistered."); } else if (logger.isLoggable(MLevel.FINE)) logger.fine("The C3P0Registry mbean was not found in the registry, so could not be unregistered."); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while trying to unregister the C3P0RegistryManager mBean." + e); } } public void attemptManagePooledDataSource(PooledDataSource pds) { String name = getPdsObjectNameStr( pds ); try { //PooledDataSourceManager mbean = new PooledDataSourceManager( pds ); //mbs.registerMBean(mbean, ObjectName.getInstance(name)); //if (logger.isLoggable(MLevel.FINER)) // logger.log(MLevel.FINER, "MBean: " + name + " registered."); // DynamicPooledDataSourceManagerMBean registers itself on construction (and logs its own registration) DynamicPooledDataSourceManagerMBean mbean = new DynamicPooledDataSourceManagerMBean( pds, name, mbs ); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to set up a PooledDataSourceManager mBean. [" + name + "] " + "[c3p0 will still functioning normally, but management via JMX may not be possible.]", e); } } public void attemptUnmanagePooledDataSource(PooledDataSource pds) { String nameStr = getPdsObjectNameStr( pds ); try { ObjectName name = new ObjectName( nameStr ); if (mbs.isRegistered(name)) { mbs.unregisterMBean(name); if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "MBean: " + nameStr + " unregistered."); } else if (logger.isLoggable(MLevel.FINE)) logger.fine("The mbean " + nameStr + " was not found in the registry, so could not be unregistered."); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while unregistering mBean. [" + nameStr + "] " + e); } } private String getPdsObjectNameStr(PooledDataSource pds) { return "com.mchange.v2.c3p0:type=PooledDataSource[" + pds.getIdentityToken() + "]"; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/C3P0RegistryManager.java0000644000175000017500000000502310624366527025654 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import java.util.*; import java.sql.SQLException; import com.mchange.v2.c3p0.C3P0Registry; import com.mchange.v2.c3p0.subst.C3P0Substitutions; public class C3P0RegistryManager implements C3P0RegistryManagerMBean { public String[] getAllIdentityTokens() { Set tokens = C3P0Registry.allIdentityTokens(); return (String[]) tokens.toArray( new String[ tokens.size() ] ); } public Set getAllIdentityTokenized() { return C3P0Registry.allIdentityTokenized(); } public Set getAllPooledDataSources() { return C3P0Registry.allPooledDataSources(); } public int getAllIdentityTokenCount() { return C3P0Registry.allIdentityTokens().size(); } public int getAllIdentityTokenizedCount() { return C3P0Registry.allIdentityTokenized().size(); } public int getAllPooledDataSourcesCount() { return C3P0Registry.allPooledDataSources().size(); } public String[] getAllIdentityTokenizedStringified() { return stringifySet( C3P0Registry.allIdentityTokenized() ); } public String[] getAllPooledDataSourcesStringified() { return stringifySet( C3P0Registry.allPooledDataSources() ); } public int getNumPooledDataSources() throws SQLException { return C3P0Registry.getNumPooledDataSources(); } public int getNumPoolsAllDataSources() throws SQLException { return C3P0Registry.getNumPoolsAllDataSources(); } public String getC3p0Version() { return C3P0Substitutions.VERSION ; } private String[] stringifySet(Set s) { String[] out = new String[ s.size() ]; int i = 0; for (Iterator ii = s.iterator(); ii.hasNext(); ) out[i++] = ii.next().toString(); return out; } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/C3P0RegistryManagerMBean.java0000644000175000017500000000301310624366530026546 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import java.sql.SQLException; import java.util.Set; public interface C3P0RegistryManagerMBean { public String[] getAllIdentityTokens(); public Set getAllIdentityTokenized(); public Set getAllPooledDataSources(); public int getAllIdentityTokenCount(); public int getAllIdentityTokenizedCount(); public int getAllPooledDataSourcesCount(); public String[] getAllIdentityTokenizedStringified(); public String[] getAllPooledDataSourcesStringified(); public int getNumPooledDataSources() throws SQLException; public int getNumPoolsAllDataSources() throws SQLException; public String getC3p0Version(); }././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/DynamicPooledDataSourceManagerMBean.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/DynamicPooledDataSourceManagerMBean.jav0000644000175000017500000006160210624366530030721 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.*; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; import javax.management.InvalidAttributeValueException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanConstructorInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.ReflectionException; import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import com.mchange.v1.lang.ClassUtils; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.DriverManagerDataSource; import com.mchange.v2.c3p0.PooledDataSource; import com.mchange.v2.c3p0.PoolBackedDataSource; import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource; import com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.log.MLevel; import com.mchange.v2.management.ManagementUtils; public class DynamicPooledDataSourceManagerMBean implements DynamicMBean { final static MLogger logger = MLog.getLogger( DynamicPooledDataSourceManagerMBean.class ); final static Set HIDE_PROPS; final static Set HIDE_OPS; final static Set FORCE_OPS; final static Set FORCE_READ_ONLY_PROPS; static { Set hpTmp = new HashSet(); hpTmp.add("connectionPoolDataSource"); hpTmp.add("nestedDataSource"); hpTmp.add("reference"); hpTmp.add("connection"); hpTmp.add("password"); hpTmp.add("pooledConnection"); hpTmp.add("properties"); hpTmp.add("logWriter"); hpTmp.add("lastAcquisitionFailureDefaultUser"); hpTmp.add("lastCheckoutFailureDefaultUser"); hpTmp.add("lastCheckinFailureDefaultUser"); hpTmp.add("lastIdleTestFailureDefaultUser"); hpTmp.add("lastConnectionTestFailureDefaultUser"); HIDE_PROPS = Collections.unmodifiableSet( hpTmp ); Class[] userPassArgs = new Class[] { String.class, String.class }; Set hoTmp = new HashSet(); try { hoTmp.add(PooledDataSource.class.getMethod("close", new Class[] { boolean.class }) ); hoTmp.add(PooledDataSource.class.getMethod("getConnection", userPassArgs ) ); hoTmp.add(PooledDataSource.class.getMethod("getLastAcquisitionFailure", userPassArgs ) ); hoTmp.add(PooledDataSource.class.getMethod("getLastCheckinFailure", userPassArgs ) ); hoTmp.add(PooledDataSource.class.getMethod("getLastCheckoutFailure", userPassArgs ) ); hoTmp.add(PooledDataSource.class.getMethod("getLastIdleTestFailure", userPassArgs ) ); hoTmp.add(PooledDataSource.class.getMethod("getLastConnectionTestFailure", userPassArgs ) ); } catch (Exception e) { logger.log(MLevel.WARNING, "Tried to hide an operation from being exposed by mbean, but failed to find the operation!", e); } HIDE_OPS = Collections.unmodifiableSet(hoTmp); Set fropTmp = new HashSet(); fropTmp.add("identityToken"); FORCE_READ_ONLY_PROPS = Collections.unmodifiableSet(fropTmp); Set foTmp = new HashSet(); FORCE_OPS = Collections.unmodifiableSet(foTmp); } final static MBeanOperationInfo[] OP_INFS = extractOpInfs(); MBeanInfo info = null; PooledDataSource pds; String mbeanName; MBeanServer mbs; ConnectionPoolDataSource cpds; DataSource unpooledDataSource; //attr names to attr infos Map pdsAttrInfos; Map cpdsAttrInfos; Map unpooledDataSourceAttrInfos; PropertyChangeListener pcl = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { String propName = evt.getPropertyName(); Object val = evt.getNewValue(); if ("nestedDataSource".equals(propName) || "connectionPoolDataSource".equals(propName)) reinitialize(); } }; public DynamicPooledDataSourceManagerMBean(PooledDataSource pds, String mbeanName, MBeanServer mbs) throws Exception { this.pds = pds; this.mbeanName = mbeanName; this.mbs = mbs; if (pds instanceof ComboPooledDataSource) /* do nothing */; else if (pds instanceof AbstractPoolBackedDataSource) ((AbstractPoolBackedDataSource) pds).addPropertyChangeListener(pcl); else logger.warning(this + "managing an unexpected PooledDataSource. Only top-level attributes will be available. PooledDataSource: " + pds); Exception e = reinitialize(); if (e != null) throw e; } private synchronized Exception reinitialize() { try { // for ComboPooledDataSource, everything we care about is exposed via the PooledDataSource // for other implementations, we have to pay attention to nested DataSources if (!(pds instanceof ComboPooledDataSource) && pds instanceof AbstractPoolBackedDataSource) { if (this.cpds instanceof WrapperConnectionPoolDataSource) //implies non-null, this is a reinit ((WrapperConnectionPoolDataSource) this.cpds).removePropertyChangeListener(pcl); // yeah, we reassign instantly, but for my comfort... this.cpds = null; this.unpooledDataSource = null; this.cpds = ((AbstractPoolBackedDataSource) pds).getConnectionPoolDataSource(); if (cpds instanceof WrapperConnectionPoolDataSource) { this.unpooledDataSource = ((WrapperConnectionPoolDataSource) cpds).getNestedDataSource(); ((WrapperConnectionPoolDataSource) this.cpds).addPropertyChangeListener(pcl); } } pdsAttrInfos = extractAttributeInfos( pds ); cpdsAttrInfos = extractAttributeInfos( cpds ); unpooledDataSourceAttrInfos = extractAttributeInfos( unpooledDataSource ); Set allAttrNames = new HashSet(); allAttrNames.addAll(pdsAttrInfos.keySet()); allAttrNames.addAll(cpdsAttrInfos.keySet()); allAttrNames.addAll(unpooledDataSourceAttrInfos.keySet()); Set allAttrs = new HashSet(); for(Iterator ii = allAttrNames.iterator(); ii.hasNext();) { String name = (String) ii.next(); Object attrInfo; attrInfo = pdsAttrInfos.get(name); if (attrInfo == null) attrInfo = cpdsAttrInfos.get(name); if (attrInfo == null) attrInfo = unpooledDataSourceAttrInfos.get(name); allAttrs.add(attrInfo); } String className = this.getClass().getName(); MBeanAttributeInfo[] attrInfos = (MBeanAttributeInfo[]) allAttrs.toArray(new MBeanAttributeInfo[ allAttrs.size() ]); Class[] ctorArgClasses = {PooledDataSource.class, String.class, MBeanServer.class}; MBeanConstructorInfo[] constrInfos = new MBeanConstructorInfo[] { new MBeanConstructorInfo("Constructor from PooledDataSource", this.getClass().getConstructor(ctorArgClasses)) }; this.info = new MBeanInfo( this.getClass().getName(), "An MBean to monitor and manage a PooledDataSource", attrInfos, constrInfos, OP_INFS, null); // we need to reregister when the attributes we support may have changed, to be sure // that the MBeanInfo is reread. try { ObjectName oname = ObjectName.getInstance( mbeanName ); if (mbs.isRegistered( oname )) { mbs.unregisterMBean( oname ); if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "MBean: " + mbeanName + " unregistered, in order to be reregistered after update."); } mbs.registerMBean( this, oname ); if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "MBean: " + mbeanName + " registered."); return null; } catch (Exception e) { if ( logger.isLoggable(MLevel.WARNING) ) logger.log(MLevel.WARNING, "An Exception occurred while registering/reregistering mbean " + mbeanName + ". MBean may not be registered, or may not work properly.", e ); return e; } } catch (NoSuchMethodException e) { if (logger.isLoggable(MLevel.SEVERE)) logger.log( MLevel.SEVERE, "Huh? We can't find our own constructor?? The one we're in?", e); return e; } } // this method is fragile, makes assumptions that may have to change with // the PooledDataSource interface. It presumes that methods that look like // JavaBean properties should be skipped as attributes, that methods with // two string arguments are always username and password, that methods with // a return value are simple getters, while void methods are modifiers. At the // time of this writing, these assumptions all hold for PooledDataSource. // But beware the future. private static MBeanOperationInfo[] extractOpInfs() { MBeanParameterInfo user = new MBeanParameterInfo("user", "java.lang.String", "The database username of a pool-owner."); MBeanParameterInfo pwd = new MBeanParameterInfo("password", "java.lang.String", "The database password of a pool-owner."); MBeanParameterInfo[] userPass = {user, pwd}; MBeanParameterInfo[] empty = {}; Method[] meths = PooledDataSource.class.getMethods(); Set attrInfos = new TreeSet(ManagementUtils.OP_INFO_COMPARATOR); for (int i = 0; i < meths.length; ++i) { Method meth = meths[i]; if (HIDE_OPS.contains(meth)) continue; String mname = meth.getName(); Class[] params = meth.getParameterTypes(); if (! FORCE_OPS.contains(mname)) { //get rid of things we'd have picked up as attributes if (mname.startsWith("set") && params.length == 1) continue; if ((mname.startsWith("get") || mname.startsWith("is")) && params.length == 0) continue; } Class retType = meth.getReturnType(); int impact = (retType == void.class ? MBeanOperationInfo.ACTION : MBeanOperationInfo.INFO); MBeanParameterInfo[] pi; if (params.length == 2 && params[0] == String.class && params[1] == String.class) pi = userPass; else if (params.length == 0) pi = empty; else pi = null; MBeanOperationInfo opi; if (pi != null) opi = new MBeanOperationInfo( mname, // name null, // desc pi, retType.getName(), impact ); else { //System.err.println("autobuilding opi from meth " + meth); opi = new MBeanOperationInfo(meth.toString(), meth); } //System.err.println("Created MBeanOperationInfo: " + opi + " [" + opi.getName() + ']'); attrInfos.add( opi ); } return (MBeanOperationInfo[]) attrInfos.toArray( new MBeanOperationInfo[ attrInfos.size() ] ); } public synchronized Object getAttribute(String attr) throws AttributeNotFoundException, MBeanException, ReflectionException { try { AttrRec rec = attrRecForAttribute(attr); if (rec == null) throw new AttributeNotFoundException(attr); else { MBeanAttributeInfo ai = rec.attrInfo; if (! ai.isReadable() ) throw new IllegalArgumentException(attr + " not readable."); else { String name = ai.getName(); String pfx = ai.isIs() ? "is" : "get"; String mname = pfx + Character.toUpperCase(name.charAt(0)) + name.substring(1); Object target = rec.target; Method m = target.getClass().getMethod(mname, null); return m.invoke(target, null); } } } catch (Exception e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Failed to get requested attribute: " + attr, e); throw new MBeanException(e); } } public synchronized AttributeList getAttributes(String[] attrs) { AttributeList al = new AttributeList(); for (int i = 0, len = attrs.length; i < len; ++i) { String attr = attrs[i]; try { Object val = getAttribute(attr); al.add(new Attribute(attr, val)); } catch (Exception e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Failed to get requested attribute (for list): " + attr, e); } } return al; } private AttrRec attrRecForAttribute(String attr) { assert (Thread.holdsLock(this)); if (pdsAttrInfos.containsKey(attr)) return new AttrRec(pds, (MBeanAttributeInfo) pdsAttrInfos.get(attr)); else if (cpdsAttrInfos.containsKey(attr)) return new AttrRec(cpds, (MBeanAttributeInfo) cpdsAttrInfos.get(attr)); else if (unpooledDataSourceAttrInfos.containsKey(attr)) return new AttrRec(unpooledDataSource, (MBeanAttributeInfo) unpooledDataSourceAttrInfos.get(attr)); else return null; } public synchronized MBeanInfo getMBeanInfo() { if (info == null) reinitialize(); return info; } public synchronized Object invoke(String operation, Object[] paramVals, String[] signature) throws MBeanException, ReflectionException { try { int slen = signature.length; Class[] paramTypes = new Class[ slen ]; for (int i = 0; i < slen; ++i) paramTypes[i] = ClassUtils.forName( signature[i] ); //all operations should be on pds Method m = pds.getClass().getMethod(operation, paramTypes); return m.invoke(pds, paramVals); } catch (NoSuchMethodException e) { // although not generally legal as of the latest JMX spec, // someone could be trying to work with attributes through // invoke. If so, we try to deal try { boolean two = false; if (signature.length == 0 && ( operation.startsWith("get") || (two = operation.startsWith("is")) )) { int i = two ? 2 : 3; String attr = Character.toLowerCase(operation.charAt(i)) + operation.substring(i + 1); return getAttribute( attr ); } else if (signature.length == 1 && operation.startsWith("set")) { setAttribute(new Attribute(Character.toLowerCase(operation.charAt(3)) + operation.substring(4), paramVals[0])); return null; } else throw new MBeanException(e); } catch (Exception e2) { throw new MBeanException(e2); } } catch (Exception e) { throw new MBeanException(e); } } public synchronized void setAttribute(Attribute attrObj) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { try { String attr = attrObj.getName(); if (attr == "factoryClassLocation") // special case { if (pds instanceof ComboPooledDataSource) { ((ComboPooledDataSource) pds).setFactoryClassLocation((String) attrObj.getValue()); return; } else if (pds instanceof AbstractPoolBackedDataSource) { String val = (String) attrObj.getValue(); AbstractPoolBackedDataSource apbds = ((AbstractPoolBackedDataSource) pds); apbds.setFactoryClassLocation( val ); ConnectionPoolDataSource checkDs1 = apbds.getConnectionPoolDataSource(); if (checkDs1 instanceof WrapperConnectionPoolDataSource) { WrapperConnectionPoolDataSource wcheckDs1 = (WrapperConnectionPoolDataSource) checkDs1; wcheckDs1.setFactoryClassLocation( val ); DataSource checkDs2 = wcheckDs1.getNestedDataSource(); if (checkDs2 instanceof DriverManagerDataSource) ((DriverManagerDataSource) checkDs2).setFactoryClassLocation( val ); } return; } // else try treating factoryClassLocation like any other attribute // on the presumption that some future, unexpected DataSource that // exposes this property will not require the property to be set at // multiple levels, as PoolBackedDataSource does... } AttrRec rec = attrRecForAttribute(attr); if (rec == null) throw new AttributeNotFoundException(attr); else { MBeanAttributeInfo ai = rec.attrInfo; if (! ai.isWritable() ) throw new IllegalArgumentException(attr + " not writable."); else { Class attrType = ClassUtils.forName( rec.attrInfo.getType() ); String name = ai.getName(); String pfx = "set"; String mname = pfx + Character.toUpperCase(name.charAt(0)) + name.substring(1); Object target = rec.target; Method m = target.getClass().getMethod(mname, new Class[] {attrType}); m.invoke(target, new Object[] { attrObj.getValue() }); // if we were unable to set this attribute directly in the PooledDataSource, // we are updating a property of a nested DataSource, and we should reset // the pool manager of the PooledDataSource implementation so that these // properties are reread and the changes take effect. if (target != pds) { if (pds instanceof AbstractPoolBackedDataSource) ((AbstractPoolBackedDataSource) pds).resetPoolManager(false); else if (logger.isLoggable(MLevel.WARNING)) logger.warning("MBean set a nested ConnectionPoolDataSource or DataSource parameter on an unknown PooledDataSource type. " + "Could not reset the pool manager, so the changes may not take effect. " + "" + "c3p0 may need to be updated for PooledDataSource type " + pds.getClass() + "."); } } } } catch (Exception e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Failed to set requested attribute: " + attrObj, e); throw new MBeanException(e); } } public synchronized AttributeList setAttributes(AttributeList al) { AttributeList out = new AttributeList(); for (int i = 0, len = al.size(); i < len; ++i) { Attribute attrObj = (Attribute) al.get(i); try { this.setAttribute( attrObj ); out.add(attrObj); } catch (Exception e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Failed to set requested attribute (from list): " + attrObj, e); } } return out; } private static Map extractAttributeInfos(Object bean) { if ( bean != null) { try { Map out = new HashMap(); BeanInfo beanInfo = Introspector.getBeanInfo( bean.getClass(), Object.class ); //so we don't see getClass() as a property PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); //System.err.println("ignoreProps: " + ignoreProps ); for( int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; String name; String desc; Method getter; Method setter; name = pd.getName(); if (HIDE_PROPS.contains( name )) continue; desc = getDescription( name ); getter = pd.getReadMethod(); setter = pd.getWriteMethod(); if (FORCE_READ_ONLY_PROPS.contains(name)) setter = null; /* * Note that it's not a problem that these * getters and setters are not against this class * the MBeanAttributInfo just uses the method * names and attribute type to construct itself, * and does not hold the methods themselves for * future invocation. */ try { out.put( name, new MBeanAttributeInfo(name, desc, getter, setter) ); } catch (javax.management.IntrospectionException e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "IntrospectionException while setting up MBean attribute '" + name + "'", e); } } return Collections.synchronizedMap(out); } catch (java.beans.IntrospectionException e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "IntrospectionException while setting up MBean attributes for " + bean, e); return Collections.EMPTY_MAP; } } else return Collections.EMPTY_MAP; } // TODO: use a ResourceBundle for attribute descriptions. // (Extra credit -- build from xml file, build docs same way) private static String getDescription(String attrName) { return null; } private static class AttrRec { Object target; MBeanAttributeInfo attrInfo; AttrRec(Object target, MBeanAttributeInfo attrInfo) { this.target = target; this.attrInfo = attrInfo; } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/ManagementCoordinator.java0000644000175000017500000000230610624366530026436 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import com.mchange.v2.c3p0.PooledDataSource; public interface ManagementCoordinator { public void attemptManageC3P0Registry(); public void attemptUnmanageC3P0Registry(); public void attemptManagePooledDataSource(PooledDataSource pds); public void attemptUnmanagePooledDataSource( PooledDataSource pds ); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/NullManagementCoordinator.java0000644000175000017500000000241410624366530027271 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import com.mchange.v2.c3p0.PooledDataSource; public class NullManagementCoordinator implements ManagementCoordinator { public void attemptManageC3P0Registry() {} public void attemptUnmanageC3P0Registry() {} public void attemptManagePooledDataSource(PooledDataSource pds) {} public void attemptUnmanagePooledDataSource( PooledDataSource pds ) {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/PooledDataSourceManager.java0000644000175000017500000001117010624366527026653 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import java.sql.SQLException; import java.util.Collection; import com.mchange.v2.c3p0.PooledDataSource; public class PooledDataSourceManager implements PooledDataSourceManagerMBean { PooledDataSource pds; public PooledDataSourceManager( PooledDataSource pds ) { this.pds = pds; } public String getIdentityToken() { return pds.getIdentityToken(); } public String getDataSourceName() { return pds.getDataSourceName(); } public void setDataSourceName(String dataSourceName) { pds.setDataSourceName( dataSourceName ); } public int getNumConnectionsDefaultUser() throws SQLException { return pds.getNumConnectionsDefaultUser(); } public int getNumIdleConnectionsDefaultUser() throws SQLException { return pds.getNumIdleConnectionsDefaultUser(); } public int getNumBusyConnectionsDefaultUser() throws SQLException { return pds.getNumBusyConnectionsDefaultUser(); } public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException { return pds.getNumUnclosedOrphanedConnectionsDefaultUser(); } public float getEffectivePropertyCycleDefaultUser() throws SQLException { return pds.getEffectivePropertyCycleDefaultUser(); } public int getThreadPoolSize() throws SQLException { return pds.getThreadPoolSize(); } public int getThreadPoolNumActiveThreads() throws SQLException { return pds.getThreadPoolNumActiveThreads(); } public int getThreadPoolNumIdleThreads() throws SQLException { return pds.getThreadPoolNumIdleThreads(); } public int getThreadPoolNumTasksPending() throws SQLException { return pds.getThreadPoolNumTasksPending(); } public String sampleThreadPoolStackTraces() throws SQLException { return pds.sampleThreadPoolStackTraces(); } public String sampleThreadPoolStatus() throws SQLException { return pds.sampleThreadPoolStatus(); } public void softResetDefaultUser() throws SQLException { pds.softResetDefaultUser(); } public int getNumConnections(String username, String password) throws SQLException { return pds.getNumConnections( username, password ); } public int getNumIdleConnections(String username, String password) throws SQLException { return pds.getNumIdleConnections( username, password ); } public int getNumBusyConnections(String username, String password) throws SQLException { return pds.getNumBusyConnections( username, password ); } public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException { return pds.getNumUnclosedOrphanedConnections( username, password ); } public float getEffectivePropertyCycle(String username, String password) throws SQLException { return pds.getEffectivePropertyCycle( username, password ); } public void softReset(String username, String password) throws SQLException { pds.softReset( username, password ); } public int getNumBusyConnectionsAllUsers() throws SQLException { return pds.getNumBusyConnectionsAllUsers(); } public int getNumIdleConnectionsAllUsers() throws SQLException { return pds.getNumIdleConnectionsAllUsers(); } public int getNumConnectionsAllUsers() throws SQLException { return pds.getNumConnectionsAllUsers(); } public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException { return pds.getNumUnclosedOrphanedConnectionsAllUsers(); } public void softResetAllUsers() throws SQLException { pds.softResetAllUsers(); } public int getNumUserPools() throws SQLException { return pds.getNumUserPools(); } public Collection getAllUsers() throws SQLException { return pds.getAllUsers(); } public void hardReset() throws SQLException { pds.hardReset(); } public void close() throws SQLException { pds.close(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/management/PooledDataSourceManagerMBean.java0000644000175000017500000000576210624366527027570 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.management; import java.sql.SQLException; import java.util.Collection; public interface PooledDataSourceManagerMBean { public String getIdentityToken(); public String getDataSourceName(); public void setDataSourceName(String dataSourceName); public int getNumConnectionsDefaultUser() throws SQLException; public int getNumIdleConnectionsDefaultUser() throws SQLException; public int getNumBusyConnectionsDefaultUser() throws SQLException; public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException; public float getEffectivePropertyCycleDefaultUser() throws SQLException; public void softResetDefaultUser() throws SQLException; public int getNumConnections(String username, String password) throws SQLException; public int getNumIdleConnections(String username, String password) throws SQLException; public int getNumBusyConnections(String username, String password) throws SQLException; public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException; public float getEffectivePropertyCycle(String username, String password) throws SQLException; public void softReset(String username, String password) throws SQLException; public int getNumBusyConnectionsAllUsers() throws SQLException; public int getNumIdleConnectionsAllUsers() throws SQLException; public int getNumConnectionsAllUsers() throws SQLException; public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException; public int getThreadPoolSize() throws SQLException; public int getThreadPoolNumActiveThreads() throws SQLException; public int getThreadPoolNumIdleThreads() throws SQLException; public int getThreadPoolNumTasksPending() throws SQLException; public String sampleThreadPoolStackTraces() throws SQLException; public String sampleThreadPoolStatus() throws SQLException; public void softResetAllUsers() throws SQLException; public int getNumUserPools() throws SQLException; public Collection getAllUsers() throws SQLException; public void hardReset() throws SQLException; public void close() throws SQLException; }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/mbean/0000755000175000017500000000000010673162231020254 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/mbean/C3P0PooledDataSource.java0000644000175000017500000003174610624366527024727 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.mbean; import com.mchange.v2.c3p0.*; import com.mchange.v2.log.*; import java.beans.PropertyVetoException; import java.sql.Connection; import java.sql.SQLException; import java.io.PrintWriter; import java.util.Properties; import javax.sql.DataSource; import javax.naming.InitialContext; import javax.naming.Name; import javax.naming.Context; import javax.naming.NameAlreadyBoundException; import javax.naming.NamingException; /** * @deprecated Please use com.mchange.v2.c3p0.jboss.C3P0PooledDataSource */ public class C3P0PooledDataSource implements C3P0PooledDataSourceMBean { private final static MLogger logger = MLog.getLogger( C3P0PooledDataSource.class ); String jndiName; ComboPooledDataSource combods = new ComboPooledDataSource(); private void rebind() throws NamingException { rebind(null); } private void rebind(String unbindName) throws NamingException { InitialContext ictx = new InitialContext(); if (unbindName != null) ictx.unbind( unbindName ); if (jndiName != null) { // Thanks to David D. Kilzer for this code to auto-create // subcontext paths! Name name = ictx.getNameParser( jndiName ).parse( jndiName ); Context ctx = ictx; for (int i = 0, max = name.size() - 1; i < max; i++) { try { ctx = ctx.createSubcontext( name.get( i ) ); } catch (NameAlreadyBoundException ignore) { ctx = (Context) ctx.lookup( name.get( i ) ); } } ictx.rebind( jndiName, combods ); } } // Jndi Setup Names public void setJndiName(String jndiName) throws NamingException { String unbindName = this.jndiName; this.jndiName = jndiName; rebind( unbindName ); } public String getJndiName() { return jndiName; } // DriverManagerDataSourceProperties (count: 4) public String getDescription() { return combods.getDescription(); } public void setDescription( String description ) throws NamingException { combods.setDescription( description ); rebind(); } public String getDriverClass() { return combods.getDriverClass(); } public void setDriverClass( String driverClass ) throws PropertyVetoException, NamingException { combods.setDriverClass( driverClass ); rebind(); } public String getJdbcUrl() { return combods.getJdbcUrl(); } public void setJdbcUrl( String jdbcUrl ) throws NamingException { combods.setJdbcUrl( jdbcUrl ); rebind(); } // DriverManagerDataSource "virtual properties" based on properties public String getUser() { return combods.getUser(); } public void setUser( String user ) throws NamingException { combods.setUser( user ); rebind(); } public String getPassword() { return combods.getPassword(); } public void setPassword( String password ) throws NamingException { combods.setPassword( password ); rebind(); } // WrapperConnectionPoolDataSource properties (count: 21) public int getCheckoutTimeout() { return combods.getCheckoutTimeout(); } public void setCheckoutTimeout( int checkoutTimeout ) throws NamingException { combods.setCheckoutTimeout( checkoutTimeout ); rebind(); } public int getAcquireIncrement() { return combods.getAcquireIncrement(); } public void setAcquireIncrement( int acquireIncrement ) throws NamingException { combods.setAcquireIncrement( acquireIncrement ); rebind(); } public int getAcquireRetryAttempts() { return combods.getAcquireRetryAttempts(); } public void setAcquireRetryAttempts( int acquireRetryAttempts ) throws NamingException { combods.setAcquireRetryAttempts( acquireRetryAttempts ); rebind(); } public int getAcquireRetryDelay() { return combods.getAcquireRetryDelay(); } public void setAcquireRetryDelay( int acquireRetryDelay ) throws NamingException { combods.setAcquireRetryDelay( acquireRetryDelay ); rebind(); } public boolean isAutoCommitOnClose() { return combods.isAutoCommitOnClose(); } public void setAutoCommitOnClose( boolean autoCommitOnClose ) throws NamingException { combods.setAutoCommitOnClose( autoCommitOnClose ); rebind(); } public String getConnectionTesterClassName() { return combods.getConnectionTesterClassName(); } public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException, NamingException { combods.setConnectionTesterClassName( connectionTesterClassName ); rebind(); } public String getAutomaticTestTable() { return combods.getAutomaticTestTable(); } public void setAutomaticTestTable( String automaticTestTable ) throws NamingException { combods.setAutomaticTestTable( automaticTestTable ); rebind(); } public boolean isForceIgnoreUnresolvedTransactions() { return combods.isForceIgnoreUnresolvedTransactions(); } public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) throws NamingException { combods.setForceIgnoreUnresolvedTransactions( forceIgnoreUnresolvedTransactions ); rebind(); } public int getIdleConnectionTestPeriod() { return combods.getIdleConnectionTestPeriod(); } public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) throws NamingException { combods.setIdleConnectionTestPeriod( idleConnectionTestPeriod ); rebind(); } public int getInitialPoolSize() { return combods.getInitialPoolSize(); } public void setInitialPoolSize( int initialPoolSize ) throws NamingException { combods.setInitialPoolSize( initialPoolSize ); rebind(); } public int getMaxIdleTime() { return combods.getMaxIdleTime(); } public void setMaxIdleTime( int maxIdleTime ) throws NamingException { combods.setMaxIdleTime( maxIdleTime ); rebind(); } public int getMaxPoolSize() { return combods.getMaxPoolSize(); } public void setMaxPoolSize( int maxPoolSize ) throws NamingException { combods.setMaxPoolSize( maxPoolSize ); rebind(); } public int getMaxStatements() { return combods.getMaxStatements(); } public void setMaxStatements( int maxStatements ) throws NamingException { combods.setMaxStatements( maxStatements ); rebind(); } public int getMaxStatementsPerConnection() { return combods.getMaxStatementsPerConnection(); } public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) throws NamingException { combods.setMaxStatementsPerConnection( maxStatementsPerConnection ); rebind(); } public int getMinPoolSize() { return combods.getMinPoolSize(); } public void setMinPoolSize( int minPoolSize ) throws NamingException { combods.setMinPoolSize( minPoolSize ); rebind(); } public int getPropertyCycle() { return combods.getPropertyCycle(); } public void setPropertyCycle( int propertyCycle ) throws NamingException { combods.setPropertyCycle( propertyCycle ); rebind(); } public boolean isBreakAfterAcquireFailure() { return combods.isBreakAfterAcquireFailure(); } public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) throws NamingException { combods.setBreakAfterAcquireFailure( breakAfterAcquireFailure ); rebind(); } public boolean isTestConnectionOnCheckout() { return combods.isTestConnectionOnCheckout(); } public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) throws NamingException { combods.setTestConnectionOnCheckout( testConnectionOnCheckout ); rebind(); } public boolean isTestConnectionOnCheckin() { return combods.isTestConnectionOnCheckin(); } public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) throws NamingException { combods.setTestConnectionOnCheckin( testConnectionOnCheckin ); rebind(); } public boolean isUsesTraditionalReflectiveProxies() { return combods.isUsesTraditionalReflectiveProxies(); } public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) throws NamingException { combods.setUsesTraditionalReflectiveProxies( usesTraditionalReflectiveProxies ); rebind(); } public String getPreferredTestQuery() { return combods.getPreferredTestQuery(); } public void setPreferredTestQuery( String preferredTestQuery ) throws NamingException { combods.setPreferredTestQuery( preferredTestQuery ); rebind(); } // PoolBackedDataSource properties (count: 2) public String getDataSourceName() { return combods.getDataSourceName(); } public void setDataSourceName( String name ) throws NamingException { combods.setDataSourceName( name ); rebind(); } public int getNumHelperThreads() { return combods.getNumHelperThreads(); } public void setNumHelperThreads( int numHelperThreads ) throws NamingException { combods.setNumHelperThreads( numHelperThreads ); rebind(); } // shared properties (count: 1) public String getFactoryClassLocation() { return combods.getFactoryClassLocation(); } public void setFactoryClassLocation( String factoryClassLocation ) throws NamingException { combods.setFactoryClassLocation( factoryClassLocation ); rebind(); } // PooledDataSource statistics public int getNumUserPools() throws SQLException { return combods.getNumUserPools(); } public int getNumConnectionsDefaultUser() throws SQLException { return combods.getNumConnectionsDefaultUser(); } public int getNumIdleConnectionsDefaultUser() throws SQLException { return combods.getNumIdleConnectionsDefaultUser(); } public int getNumBusyConnectionsDefaultUser() throws SQLException { return combods.getNumBusyConnectionsDefaultUser(); } public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException { return combods.getNumUnclosedOrphanedConnectionsDefaultUser(); } public int getNumConnections(String username, String password) throws SQLException { return combods.getNumConnections(username, password); } public int getNumIdleConnections(String username, String password) throws SQLException { return combods.getNumIdleConnections(username, password); } public int getNumBusyConnections(String username, String password) throws SQLException { return combods.getNumBusyConnections(username, password); } public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException { return combods.getNumUnclosedOrphanedConnections(username, password); } public int getNumConnectionsAllUsers() throws SQLException { return combods.getNumConnectionsAllUsers(); } public int getNumIdleConnectionsAllUsers() throws SQLException { return combods.getNumIdleConnectionsAllUsers(); } public int getNumBusyConnectionsAllUsers() throws SQLException { return combods.getNumBusyConnectionsAllUsers(); } public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException { return combods.getNumUnclosedOrphanedConnectionsAllUsers(); } // PooledDataSource operations public void softResetDefaultUser() throws SQLException { combods.softResetDefaultUser(); } public void softReset(String username, String password) throws SQLException { combods.softReset(username, password); } public void softResetAllUsers() throws SQLException { combods.softResetAllUsers(); } public void hardReset() throws SQLException { combods.hardReset(); } public void close() throws SQLException { combods.close(); } //JBoss only... (but these methods need not be called for the mbean to work) public void create() throws Exception { } // the mbean works without this, but if called we start populating the pool early public void start() throws Exception { //System.err.println("Bound C3P0 PooledDataSource to name '" + jndiName + "'. Starting..."); logger.log(MLevel.INFO, "Bound C3P0 PooledDataSource to name ''{0}''. Starting...", jndiName); combods.getNumBusyConnectionsDefaultUser(); //just touch the datasource to start it up. } public void stop() { } public void destroy() { } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/mbean/C3P0PooledDataSourceMBean.java0000644000175000017500000001543510624366530025621 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.mbean; import com.mchange.v2.c3p0.*; import java.beans.PropertyVetoException; import java.sql.SQLException; import java.util.Properties; import javax.naming.NamingException; /** * @deprecated Please use com.mchange.v2.c3p0.jboss.C3P0PooledDataSourceMBean */ public interface C3P0PooledDataSourceMBean { // Jndi Setup public void setJndiName(String jndiName) throws NamingException; public String getJndiName(); // DriverManagerDataSourceProperties public String getDescription(); public void setDescription( String description ) throws NamingException; public String getDriverClass(); public void setDriverClass( String driverClass ) throws PropertyVetoException, NamingException; public String getJdbcUrl(); public void setJdbcUrl( String jdbcUrl ) throws NamingException; // DriverManagerDataSource "virtual properties" based on properties public String getUser(); public void setUser( String user ) throws NamingException; public String getPassword(); public void setPassword( String password ) throws NamingException; // WrapperConnectionPoolDataSource properties public int getCheckoutTimeout(); public void setCheckoutTimeout( int checkoutTimeout ) throws NamingException; public int getAcquireIncrement(); public void setAcquireIncrement( int acquireIncrement ) throws NamingException; public int getAcquireRetryAttempts(); public void setAcquireRetryAttempts( int acquireRetryAttempts ) throws NamingException; public int getAcquireRetryDelay(); public void setAcquireRetryDelay( int acquireRetryDelay ) throws NamingException; public boolean isAutoCommitOnClose(); public void setAutoCommitOnClose( boolean autoCommitOnClose ) throws NamingException; public String getConnectionTesterClassName(); public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException, NamingException; public String getAutomaticTestTable(); public void setAutomaticTestTable( String automaticTestTable ) throws NamingException; public boolean isForceIgnoreUnresolvedTransactions(); public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) throws NamingException; public int getIdleConnectionTestPeriod(); public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) throws NamingException; public int getInitialPoolSize(); public void setInitialPoolSize( int initialPoolSize ) throws NamingException; public int getMaxIdleTime(); public void setMaxIdleTime( int maxIdleTime ) throws NamingException; public int getMaxPoolSize(); public void setMaxPoolSize( int maxPoolSize ) throws NamingException; public int getMaxStatements(); public void setMaxStatements( int maxStatements ) throws NamingException; public int getMaxStatementsPerConnection(); public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) throws NamingException; public int getMinPoolSize(); public void setMinPoolSize( int minPoolSize ) throws NamingException; public int getPropertyCycle(); public void setPropertyCycle( int propertyCycle ) throws NamingException; public boolean isBreakAfterAcquireFailure(); public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) throws NamingException; public boolean isTestConnectionOnCheckout(); public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) throws NamingException; public boolean isTestConnectionOnCheckin(); public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) throws NamingException; public boolean isUsesTraditionalReflectiveProxies(); public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) throws NamingException; public String getPreferredTestQuery(); public void setPreferredTestQuery( String preferredTestQuery ) throws NamingException; // PoolBackedDataSource properties (count: 2) public int getNumHelperThreads(); public void setNumHelperThreads( int numHelperThreads ) throws NamingException; // shared properties (count: 1) public String getFactoryClassLocation(); public void setFactoryClassLocation( String factoryClassLocation ) throws NamingException; // PooledDataSource statistics public int getNumUserPools() throws SQLException; public int getNumConnectionsDefaultUser() throws SQLException; public int getNumIdleConnectionsDefaultUser() throws SQLException; public int getNumBusyConnectionsDefaultUser() throws SQLException; public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException; public int getNumConnections(String username, String password) throws SQLException; public int getNumIdleConnections(String username, String password) throws SQLException; public int getNumBusyConnections(String username, String password) throws SQLException; public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException; public int getNumBusyConnectionsAllUsers() throws SQLException; public int getNumIdleConnectionsAllUsers() throws SQLException; public int getNumConnectionsAllUsers() throws SQLException; public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException; // PooledDataSource operations public void softResetDefaultUser() throws SQLException; public void softReset(String username, String password) throws SQLException; public void softResetAllUsers() throws SQLException; public void hardReset() throws SQLException; public void close() throws SQLException; //JBoss only... (but these methods need not be called for the mbean to work) public void create() throws Exception; public void start() throws Exception; public void stop(); public void destroy(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/0000755000175000017500000000000010673162231020161 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/DoubleMaxStatementCache.java0000644000175000017500000000550710624366527025536 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.*; import com.mchange.v2.async.AsynchronousRunner; public final class DoubleMaxStatementCache extends GooGooStatementCache { //MT: protected by this' lock int max_statements; Deathmarch globalDeathmarch = new Deathmarch(); int max_statements_per_connection; DeathmarchConnectionStatementManager dcsm; public DoubleMaxStatementCache(AsynchronousRunner blockingTaskAsyncRunner, int max_statements, int max_statements_per_connection) { super( blockingTaskAsyncRunner ); this.max_statements = max_statements; this.max_statements_per_connection = max_statements_per_connection; } //called only in parent's constructor protected ConnectionStatementManager createConnectionStatementManager() { return (this.dcsm = new DeathmarchConnectionStatementManager()); } //called by parent only with this' lock void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ) { globalDeathmarch.deathmarchStatement( pstmt ); dcsm.getDeathmarch( physicalConnection ).deathmarchStatement( pstmt ); } void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ) { globalDeathmarch.undeathmarchStatement( pstmt ); dcsm.getDeathmarch( physicalConnection ).undeathmarchStatement( pstmt ); } boolean prepareAssimilateNewStatement(Connection pcon) { int cxn_stmt_count = dcsm.getNumStatementsForConnection( pcon ); if (cxn_stmt_count < max_statements_per_connection) //okay... we can cache another for the connection, but how 'bout globally? { int global_size = this.countCachedStatements(); return ( global_size < max_statements || (global_size == max_statements && globalDeathmarch.cullNext()) ); } else //we can only cache if we can clear one from the Connection (which implies clearing one globally, so we needn't check max_statements) return (cxn_stmt_count == max_statements_per_connection && dcsm.getDeathmarch( pcon ).cullNext()); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/GlobalMaxOnlyStatementCache.java0000644000175000017500000000403110624366527026355 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.*; import com.mchange.v2.async.AsynchronousRunner; public final class GlobalMaxOnlyStatementCache extends GooGooStatementCache { //MT: protected by this' lock int max_statements; Deathmarch globalDeathmarch = new Deathmarch(); public GlobalMaxOnlyStatementCache(AsynchronousRunner blockingTaskAsyncRunner, int max_statements) { super( blockingTaskAsyncRunner ); this.max_statements = max_statements; } //called only in parent's constructor protected ConnectionStatementManager createConnectionStatementManager() { return new SimpleConnectionStatementManager(); } //called by parent only with this' lock void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ) { globalDeathmarch.deathmarchStatement( pstmt ); } void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ) { globalDeathmarch.undeathmarchStatement( pstmt ); } boolean prepareAssimilateNewStatement(Connection pcon) { int global_size = this.countCachedStatements(); return ( global_size < max_statements || (global_size == max_statements && globalDeathmarch.cullNext()) ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/GooGooStatementCache.java0000644000175000017500000007102010624366530025032 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.util.*; import java.sql.*; import java.lang.reflect.*; import com.mchange.v2.async.AsynchronousRunner; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.util.ResourceClosedException; import com.mchange.v2.log.*; import com.mchange.v1.db.sql.StatementUtils; import java.io.StringWriter; import java.io.PrintWriter; import java.io.IOException; import com.mchange.v2.io.IndentedWriter; public abstract class GooGooStatementCache { private final static MLogger logger = MLog.getLogger( GooGooStatementCache.class ); private final static int DESTROY_NEVER = 0; private final static int DESTROY_IF_CHECKED_IN = 1 << 0; private final static int DESTROY_IF_CHECKED_OUT = 1 << 1; private final static int DESTROY_ALWAYS = (DESTROY_IF_CHECKED_IN | DESTROY_IF_CHECKED_OUT); /* MT: protected by this's lock */ // contains all statements in the cache, // organized by connection ConnectionStatementManager cxnStmtMgr; // contains all statements in the cache, // bound to the keys that produced them HashMap stmtToKey = new HashMap(); // maps all known keys to their set of statements // and to a queue of statements, if any, available // for checkout HashMap keyToKeyRec = new HashMap(); // contains all checked out statements -- in the cache, // but not currently available for checkout, nor for // culling in case of overflow HashSet checkedOut = new HashSet(); /* MT: end protected by this' lock */ /* MT: protected by its own lock */ AsynchronousRunner blockingTaskAsyncRunner; // This set is used to ensure that multiple threads // do not try to remove the same statement from the // cache, if for example a Statement is both deathmarched // away and its parent Connection is closed. // // ALL ACCESS SHOULD BE EXPLICITLY SYNCHRONIZED // ON removalPending's lock! HashSet removalPending = new HashSet(); /* MT: end protected by its own lock */ public GooGooStatementCache(AsynchronousRunner blockingTaskAsyncRunner) { this.blockingTaskAsyncRunner = blockingTaskAsyncRunner; this.cxnStmtMgr = createConnectionStatementManager(); } public synchronized int getNumStatements() { return this.isClosed() ? -1 : countCachedStatements(); } public synchronized int getNumStatementsCheckedOut() { return this.isClosed() ? -1 : checkedOut.size(); } public synchronized int getNumConnectionsWithCachedStatements() { return isClosed() ? -1 : cxnStmtMgr.getNumConnectionsWithCachedStatements(); } public synchronized String dumpStatementCacheStatus() { if (isClosed()) return this + "status: Closed."; else { StringWriter sw = new StringWriter(2048); IndentedWriter iw = new IndentedWriter( sw ); try { iw.print(this); iw.println(" status:"); iw.upIndent(); iw.println("core stats:"); iw.upIndent(); iw.print("num cached statements: "); iw.println( this.countCachedStatements() ); iw.print("num cached statements in use: "); iw.println( checkedOut.size() ); iw.print("num connections with cached statements: "); iw.println(cxnStmtMgr.getNumConnectionsWithCachedStatements()); iw.downIndent(); iw.println("cached statement dump:"); iw.upIndent(); for (Iterator ii = cxnStmtMgr.connectionSet().iterator(); ii.hasNext();) { Connection pcon = (Connection) ii.next(); iw.print(pcon); iw.println(':'); iw.upIndent(); for (Iterator jj = cxnStmtMgr.statementSet(pcon).iterator(); jj.hasNext();) iw.println(jj.next()); iw.downIndent(); } iw.downIndent(); iw.downIndent(); return sw.toString(); } catch (IOException e) { if (logger.isLoggable(MLevel.SEVERE)) logger.log(MLevel.SEVERE, "Huh? We've seen an IOException writing to s StringWriter?!", e); return e.toString(); } } } abstract ConnectionStatementManager createConnectionStatementManager(); public synchronized Object checkoutStatement( Connection physicalConnection, Method stmtProducingMethod, Object[] args ) throws SQLException, ResourceClosedException { try { Object out = null; StatementCacheKey key = StatementCacheKey.find( physicalConnection, stmtProducingMethod, args ); LinkedList l = checkoutQueue( key ); if (l == null || l.isEmpty()) //we need a new statement { // we might wait() here... // don't presume atomicity before and after! out = acquireStatement( physicalConnection, stmtProducingMethod, args ); if ( prepareAssimilateNewStatement( physicalConnection ) ) assimilateNewCheckedOutStatement( key, physicalConnection, out ); // else case: we can't assimilate the statement... // so, we just return our newly created statement, without caching it. // on check-in, it will simply be destroyed... this is an "overload statement" } else //okay, we can use an old one { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) logger.finest(this.getClass().getName() + " ----> CACHE HIT"); //System.err.println("-------------> CACHE HIT!"); out = l.get(0); l.remove(0); if (! checkedOut.add( out )) throw new RuntimeException("Internal inconsistency: " + "Checking out a statement marked " + "as already checked out!"); removeStatementFromDeathmarches( out, physicalConnection ); } if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { //System.err.print("checkoutStatement(): "); //printStats(); if (logger.isLoggable(MLevel.FINEST)) logger.finest("checkoutStatement: " + statsString()); } return out; } catch (NullPointerException npe) { if (checkedOut == null) //we're closed { if (logger.isLoggable(MLevel.FINE)) logger.log( MLevel.FINE, "A client attempted to work with a closed Statement cache, " + "" + "provoking a NullPointerException. c3p0 recovers, but this should be rare.", npe); throw new ResourceClosedException( npe ); } else throw npe; } } public synchronized void checkinStatement( Object pstmt ) throws SQLException { if (checkedOut == null) //we're closed { synchronousDestroyStatement( pstmt ); return; } else if (! checkedOut.remove( pstmt ) ) { if (! ourResource( pstmt ) ) //this is not our resource, or it is an overload statement destroyStatement( pstmt ); // so we just destroy //in the else case, it's already checked-in, so we ignore return; } try { refreshStatement( (PreparedStatement) pstmt ); } catch (Exception e) { if (Debug.DEBUG) { // System.err.println("Problem with checked-in Statement, discarding."); // e.printStackTrace(); if (logger.isLoggable(MLevel.INFO)) logger.log(MLevel.INFO, "Problem with checked-in Statement, discarding.", e); } // swaldman -- 2004-01-31: readd problem statement to checkedOut for consistency // the statement is not yet checked-in, but it is removed from checked out, and this // violates the consistency assumption of removeStatement(). Thanks to Zach Scott for // calling attention to this issue. checkedOut.add( pstmt ); removeStatement( pstmt, DESTROY_ALWAYS ); //force destruction of the statement even though it appears checked-out return; } StatementCacheKey key = (StatementCacheKey) stmtToKey.get( pstmt ); if (Debug.DEBUG && key == null) throw new RuntimeException("Internal inconsistency: " + "A checked-out statement has no key associated with it!"); LinkedList l = checkoutQueue( key ); l.add( pstmt ); addStatementToDeathmarches( pstmt, key.physicalConnection ); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { // System.err.print("checkinStatement(): "); // printStats(); if (logger.isLoggable(MLevel.FINEST)) logger.finest("checkinStatement(): " + statsString()); } } public synchronized void checkinAll(Connection pcon) throws SQLException { //new Exception("checkinAll()").printStackTrace(); Set stmtSet = cxnStmtMgr.statementSet( pcon ); if (stmtSet != null) { for (Iterator ii = stmtSet.iterator(); ii.hasNext(); ) { Object stmt = ii.next(); if (checkedOut.contains( stmt )) checkinStatement( stmt ); } } if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { // System.err.print("checkinAll(): "); // printStats(); if (logger.isLoggable(MLevel.FINEST)) logger.log(MLevel.FINEST, "checkinAll(): " + statsString()); } } /* * we only selectively sync' parts of this method, because we wish to wait for * Statements we wish to destroy the Statements synchronously, but without * holding the pool's lock. */ public void closeAll(Connection pcon) throws SQLException { // System.err.println( this + ": closeAll( " + pcon + " )" ); // new Exception("closeAll()").printStackTrace(); // assert !Thread.holdsLock( this ); if (! this.isClosed()) { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { if (logger.isLoggable(MLevel.FINEST)) { logger.log(MLevel.FINEST, "ENTER METHOD: closeAll( " + pcon + " )! -- num_connections: " + cxnStmtMgr.getNumConnectionsWithCachedStatements()); //logger.log(MLevel.FINEST, "Set of statements for connection: " + cSet + (cSet != null ? "; size: " + cSet.size() : "")); } } Set stmtSet = null; synchronized (this) { Set cSet = cxnStmtMgr.statementSet( pcon ); if (cSet != null) { //the removeStatement(...) removes from cSet, so we can't be iterating over cSet directly stmtSet = new HashSet( cSet ); //System.err.println("SIZE FOR CONNECTION SET: " + stmtSet.size()); for (Iterator ii = stmtSet.iterator(); ii.hasNext(); ) { Object stmt = ii.next(); // we remove without destroying, leaving the destruction // until when we lose the pool's lock removeStatement( stmt, DESTROY_NEVER ); } } } if ( stmtSet != null ) { for (Iterator ii = stmtSet.iterator(); ii.hasNext(); ) { Object stmt = ii.next(); synchronousDestroyStatement( stmt ); } } if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { if (logger.isLoggable(MLevel.FINEST)) logger.finest("closeAll(): " + statsString()); } } // else // { // if (logger.isLoggable(MLevel.FINER)) // logger.log(MLevel.FINER, // this + ": call to closeAll() when statment cache is already closed! [not harmful! debug only!]", // new Exception("DUPLICATE CLOSE DEBUG STACK TRACE.")); // } } public synchronized void close() throws SQLException { //System.err.println( this + ": close()" ); if (! isClosed()) { for (Iterator ii = stmtToKey.keySet().iterator(); ii.hasNext(); ) synchronousDestroyStatement( ii.next() ); cxnStmtMgr = null; stmtToKey = null; keyToKeyRec = null; checkedOut = null; } else { if (logger.isLoggable(MLevel.FINE)) logger.log(MLevel.FINE, this + ": duplicate call to close() [not harmful! -- debug only!]", new Exception("DUPLICATE CLOSE DEBUG STACK TRACE.")); } } public synchronized boolean isClosed() { return cxnStmtMgr == null; } /* non-public methods that needn't be called with this' lock below */ private void destroyStatement( final Object pstmt ) { class StatementCloseTask implements Runnable { public void run() { StatementUtils.attemptClose( (PreparedStatement) pstmt ); } } Runnable r = new StatementCloseTask(); blockingTaskAsyncRunner.postRunnable(r); } private void synchronousDestroyStatement( final Object pstmt ) { StatementUtils.attemptClose( (PreparedStatement) pstmt ); } /* end non-public methods that needn't be called with this' lock */ /* non-public methods that MUST be called with this' lock */ abstract boolean prepareAssimilateNewStatement(Connection pcon); abstract void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ); abstract void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ); final int countCachedStatements() { return stmtToKey.size(); } private void assimilateNewCheckedOutStatement( StatementCacheKey key, Connection pConn, Object ps ) { stmtToKey.put( ps, key ); HashSet ks = keySet( key ); if (ks == null) keyToKeyRec.put( key, new KeyRec() ); else { //System.err.println("-------> Multiply prepared statement! " + key.stmtText ); if (logger.isLoggable(MLevel.INFO)) logger.info("Multiply prepared statement! " + key.stmtText ); if (Debug.DEBUG && logger.isLoggable(MLevel.FINE)) logger.fine("(The same statement has already been prepared by this Connection, " + "and that other instance has not yet been closed, so the statement pool " + "has to prepare a second PreparedStatement object rather than reusing " + "the previously-cached Statement. The new Statement will be cached, in case " + "you frequently need multiple copies of this Statement.)"); } keySet( key ).add( ps ); cxnStmtMgr.addStatementForConnection( ps, pConn ); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { // System.err.println("cxnStmtMgr.statementSet( " + pConn + " ).size(): " + // cxnStmtMgr.statementSet( pConn ).size()); if (logger.isLoggable(MLevel.FINEST)) logger.finest("cxnStmtMgr.statementSet( " + pConn + " ).size(): " + cxnStmtMgr.statementSet( pConn ).size()); } checkedOut.add( ps ); } private void removeStatement( Object ps , int destruction_policy ) { synchronized (removalPending) { if ( removalPending.contains( ps ) ) return; else removalPending.add(ps); } StatementCacheKey sck = (StatementCacheKey) stmtToKey.remove( ps ); removeFromKeySet( sck, ps ); Connection pConn = sck.physicalConnection; boolean checked_in = !checkedOut.contains( ps ); if ( checked_in ) { removeStatementFromDeathmarches( ps, pConn ); removeFromCheckoutQueue( sck , ps ); if ((destruction_policy & DESTROY_IF_CHECKED_IN) != 0) destroyStatement( ps ); } else { checkedOut.remove( ps ); if ((destruction_policy & DESTROY_IF_CHECKED_OUT) != 0) destroyStatement( ps ); } boolean check = cxnStmtMgr.removeStatementForConnection( ps, pConn ); if (Debug.DEBUG && check == false) { //new Exception("WARNING: removed a statement that apparently wasn't in a statement set!!!").printStackTrace(); if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, this + " removed a statement that apparently wasn't in a statement set!!!", new Exception("LOG STACK TRACE")); } synchronized (removalPending) { removalPending.remove(ps); } } private Object acquireStatement(final Connection pConn, final Method stmtProducingMethod, final Object[] args ) throws SQLException { try { final Object[] outHolder = new Object[1]; final SQLException[] exceptionHolder = new SQLException[1]; class StmtAcquireTask implements Runnable { public void run() { try { outHolder[0] = stmtProducingMethod.invoke( pConn, args ); } catch ( InvocationTargetException e ) { Throwable targetException = e.getTargetException(); if ( targetException instanceof SQLException ) exceptionHolder[0] = (SQLException) targetException; else exceptionHolder[0] = SqlUtils.toSQLException(targetException); } catch ( Exception e ) { exceptionHolder[0] = SqlUtils.toSQLException(e); } finally { synchronized ( GooGooStatementCache.this ) { GooGooStatementCache.this.notifyAll(); } } } } Runnable r = new StmtAcquireTask(); blockingTaskAsyncRunner.postRunnable(r); while ( outHolder[0] == null && exceptionHolder[0] == null ) this.wait(); //give up our lock while the Statement gets prepared if (exceptionHolder[0] != null) throw exceptionHolder[0]; else { Object out = outHolder[0]; return out; } } catch ( InterruptedException e ) { throw SqlUtils.toSQLException( e ); } } private KeyRec keyRec( StatementCacheKey key ) { return ((KeyRec) keyToKeyRec.get( key )); } private HashSet keySet( StatementCacheKey key ) { KeyRec rec = keyRec( key ); return (rec == null ? null : rec.allStmts); } private boolean removeFromKeySet( StatementCacheKey key, Object pstmt ) { boolean out; HashSet stmtSet = keySet( key ); out = stmtSet.remove( pstmt ); if (stmtSet.isEmpty() && checkoutQueue( key ).isEmpty()) keyToKeyRec.remove( key ); return out; } private LinkedList checkoutQueue( StatementCacheKey key ) { KeyRec rec = keyRec( key ); return ( rec == null ? null : rec.checkoutQueue ); } private boolean removeFromCheckoutQueue( StatementCacheKey key, Object pstmt ) { boolean out; LinkedList q = checkoutQueue( key ); out = q.remove( pstmt ); if (q.isEmpty() && keySet( key ).isEmpty()) keyToKeyRec.remove( key ); return out; } private boolean ourResource( Object ps ) { return stmtToKey.keySet().contains( ps ); } private void refreshStatement( PreparedStatement ps ) throws Exception { ps.clearParameters(); } private void printStats() { //new Exception("printStats()").printStackTrace(); int total_size = this.countCachedStatements(); int checked_out_size = checkedOut.size(); int num_connections = cxnStmtMgr.getNumConnectionsWithCachedStatements(); int num_keys = keyToKeyRec.size(); System.err.print(this.getClass().getName() + " stats -- "); System.err.print("total size: " + total_size); System.err.print("; checked out: " + checked_out_size); System.err.print("; num connections: " + num_connections); System.err.println("; num keys: " + num_keys); } private String statsString() { int total_size = this.countCachedStatements(); int checked_out_size = checkedOut.size(); int num_connections = cxnStmtMgr.getNumConnectionsWithCachedStatements(); int num_keys = keyToKeyRec.size(); StringBuffer sb = new StringBuffer(255); sb.append(this.getClass().getName()); sb.append(" stats -- "); sb.append("total size: "); sb.append(total_size); sb.append("; checked out: "); sb.append(checked_out_size); sb.append("; num connections: "); sb.append(num_connections); sb.append("; num keys: "); sb.append(num_keys); return sb.toString(); } private static class KeyRec { HashSet allStmts = new HashSet(); LinkedList checkoutQueue = new LinkedList(); } protected class Deathmarch { TreeMap longsToStmts = new TreeMap(); HashMap stmtsToLongs = new HashMap(); long last_long = -1; public void deathmarchStatement( Object ps ) { //System.err.println("deathmarchStatement( " + ps + " )"); if (Debug.DEBUG) { Long old = (Long) stmtsToLongs.get( ps ); if (old != null) throw new RuntimeException("Internal inconsistency: " + "A statement is being double-deathmatched. no checked-out statements should be in a deathmarch already; " + "no already checked-in statement should be deathmarched!"); } Long youth = getNextLong(); stmtsToLongs.put( ps, youth ); longsToStmts.put( youth, ps ); } public void undeathmarchStatement( Object ps ) { Long old = (Long) stmtsToLongs.remove( ps ); if (Debug.DEBUG && old == null) throw new RuntimeException("Internal inconsistency: " + "A (not new) checking-out statement is not in deathmarch."); Object check = longsToStmts.remove( old ); if (Debug.DEBUG && old == null) throw new RuntimeException("Internal inconsistency: " + "A (not new) checking-out statement is not in deathmarch."); } public boolean cullNext() { if ( longsToStmts.isEmpty() ) return false; else { Long l = (Long) longsToStmts.firstKey(); Object ps = longsToStmts.get( l ); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { // System.err.println("CULLING: " + // ((StatementCacheKey) stmtToKey.get(ps)).stmtText); if (logger.isLoggable(MLevel.FINEST)) logger.finest("CULLING: " + ((StatementCacheKey) stmtToKey.get(ps)).stmtText); } // we do not undeathmarch the statement ourselves, because removeStatement( ... ) // should remove from all deathmarches... removeStatement( ps, DESTROY_ALWAYS ); if (Debug.DEBUG && this.contains( ps )) throw new RuntimeException("Inconsistency!!! Statement culled from deathmarch failed to be removed by removeStatement( ... )!"); return true; } } public boolean contains( Object ps ) { return stmtsToLongs.keySet().contains( ps ); } public int size() { return longsToStmts.size(); } private Long getNextLong() { return new Long( ++last_long ); } } protected static abstract class ConnectionStatementManager { Map cxnToStmtSets = new HashMap(); public int getNumConnectionsWithCachedStatements() { return cxnToStmtSets.size(); } public Set connectionSet() { return cxnToStmtSets.keySet(); } public Set statementSet( Connection pcon ) { return (Set) cxnToStmtSets.get( pcon ); } public int getNumStatementsForConnection( Connection pcon ) { Set stmtSet = statementSet( pcon ); return (stmtSet == null ? 0 : stmtSet.size()); } public void addStatementForConnection( Object ps, Connection pcon ) { Set stmtSet = statementSet( pcon ); if (stmtSet == null) { stmtSet = new HashSet(); cxnToStmtSets.put( pcon, stmtSet ); } stmtSet.add( ps ); } public boolean removeStatementForConnection( Object ps, Connection pcon ) { boolean out; Set stmtSet = statementSet( pcon ); if ( stmtSet != null ) { out = stmtSet.remove( ps ); if (stmtSet.isEmpty()) cxnToStmtSets.remove( pcon ); } else out = false; return out; } } // i want this as optimized as possible, so i'm adopting the philosophy that all // classes are abstract or final, to help enable compiler inlining... protected static final class SimpleConnectionStatementManager extends ConnectionStatementManager {} protected final class DeathmarchConnectionStatementManager extends ConnectionStatementManager { Map cxnsToDms = new HashMap(); public void addStatementForConnection( Object ps, Connection pcon ) { super.addStatementForConnection( ps, pcon ); Deathmarch dm = (Deathmarch) cxnsToDms.get( pcon ); if (dm == null) { dm = new Deathmarch(); cxnsToDms.put( pcon, dm ); } } public boolean removeStatementForConnection( Object ps, Connection pcon ) { boolean out = super.removeStatementForConnection( ps, pcon ); if (out) { if ( statementSet( pcon ) == null ) cxnsToDms.remove( pcon ); } return out; } public Deathmarch getDeathmarch( Connection pcon ) { return (Deathmarch) cxnsToDms.get( pcon ); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/MemoryCoalescedStatementCacheKey.java0000644000175000017500000001233610624366527027400 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.Connection; import java.sql.ResultSet; import java.lang.reflect.Method; import com.mchange.v2.coalesce.*; final class MemoryCoalescedStatementCacheKey extends StatementCacheKey { //MT: not thread-safe, but protected within the find() method // by StatementCacheKey.class lock final static Coalescer keyCoalescer = CoalescerFactory.createCoalescer( true, false ); static StatementCacheKey _find( Connection pcon, Method stmtProducingMethod, Object[] args ) { ///BEGIN FIND LOGIC/// String stmtText = (String) args[0]; boolean is_callable = stmtProducingMethod.getName().equals("prepareCall"); int result_set_type; int result_set_concurrency; int[] columnIndexes; String[] columnNames; Integer autogeneratedKeys; Integer resultSetHoldability; if (args.length == 1) { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (args.length == 2) { Class[] argTypes = stmtProducingMethod.getParameterTypes(); if (argTypes[1].isArray()) { Class baseType = argTypes[1].getComponentType(); if (baseType == int.class) //second arg is columnIndexes { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = (int[]) args[1]; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (baseType == String.class) { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = (String[]) args[1]; autogeneratedKeys = null; resultSetHoldability = null; } else throw new IllegalArgumentException("c3p0 probably needs to be updated for some new " + "JDBC spec! As of JDBC3, we expect two arg statement " + "producing methods where the second arg is either " + "an int, int array, or String array."); } else //it should be a boxed int, autogeneratedKeys { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = null; autogeneratedKeys = (Integer) args[1]; resultSetHoldability = null; } } else if (args.length == 3) { result_set_type = ((Integer) args[1]).intValue(); result_set_concurrency = ((Integer) args[2]).intValue(); columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (args.length == 4) { result_set_type = ((Integer) args[1]).intValue(); result_set_concurrency = ((Integer) args[2]).intValue(); columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = (Integer) args[3]; } else throw new IllegalArgumentException("Unexpected number of args to " + stmtProducingMethod.getName() ); ///END FIND LOGIC/// StatementCacheKey uncanonical = new MemoryCoalescedStatementCacheKey( pcon, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); return (StatementCacheKey) keyCoalescer.coalesce( uncanonical ); } MemoryCoalescedStatementCacheKey( Connection physicalConnection, String stmtText, boolean is_callable, int result_set_type, int result_set_concurrency, int[] columnIndexes, String[] columnNames, Integer autogeneratedKeys, Integer resultSetHoldability ) { super( physicalConnection, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); } public boolean equals( Object o ) { return StatementCacheKey.equals( this, o ); } public int hashCode() { return StatementCacheKey.hashCode( this ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/PerConnectionMaxOnlyStatementCache.java0000644000175000017500000000433610624366527027733 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.*; import com.mchange.v2.async.AsynchronousRunner; public final class PerConnectionMaxOnlyStatementCache extends GooGooStatementCache { //MT: protected by this' lock int max_statements_per_connection; DeathmarchConnectionStatementManager dcsm; public PerConnectionMaxOnlyStatementCache(AsynchronousRunner blockingTaskAsyncRunner, int max_statements_per_connection) { super( blockingTaskAsyncRunner ); this.max_statements_per_connection = max_statements_per_connection; } //called only in parent's constructor protected ConnectionStatementManager createConnectionStatementManager() { return (this.dcsm = new DeathmarchConnectionStatementManager()); } //called by parent only with this' lock void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ) { dcsm.getDeathmarch( physicalConnection ).deathmarchStatement( pstmt ); } void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ) { dcsm.getDeathmarch( physicalConnection ).undeathmarchStatement( pstmt ); } boolean prepareAssimilateNewStatement(Connection pcon) { int cxn_stmt_count = dcsm.getNumStatementsForConnection( pcon ); return ( cxn_stmt_count < max_statements_per_connection || (cxn_stmt_count == max_statements_per_connection && dcsm.getDeathmarch( pcon ).cullNext()) ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/SimpleStatementCacheKey.java0000644000175000017500000001152410624366530025546 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.Connection; import java.sql.ResultSet; import java.lang.reflect.Method; final class SimpleStatementCacheKey extends StatementCacheKey { static StatementCacheKey _find( Connection pcon, Method stmtProducingMethod, Object[] args ) { ///BEGIN FIND LOGIC/// String stmtText = (String) args[0]; boolean is_callable = stmtProducingMethod.getName().equals("prepareCall"); int result_set_type; int result_set_concurrency; int[] columnIndexes; String[] columnNames; Integer autogeneratedKeys; Integer resultSetHoldability; if (args.length == 1) { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (args.length == 2) { Class[] argTypes = stmtProducingMethod.getParameterTypes(); if (argTypes[1].isArray()) { Class baseType = argTypes[1].getComponentType(); if (baseType == int.class) //second arg is columnIndexes { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = (int[]) args[1]; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (baseType == String.class) { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = (String[]) args[1]; autogeneratedKeys = null; resultSetHoldability = null; } else throw new IllegalArgumentException("c3p0 probably needs to be updated for some new " + "JDBC spec! As of JDBC3, we expect two arg statement " + "producing methods where the second arg is either " + "an int, int array, or String array."); } else //it should be a boxed int, autogeneratedKeys { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = null; autogeneratedKeys = (Integer) args[1]; resultSetHoldability = null; } } else if (args.length == 3) { result_set_type = ((Integer) args[1]).intValue(); result_set_concurrency = ((Integer) args[2]).intValue(); columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (args.length == 4) { result_set_type = ((Integer) args[1]).intValue(); result_set_concurrency = ((Integer) args[2]).intValue(); columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = (Integer) args[3]; } else throw new IllegalArgumentException("Unexpected number of args to " + stmtProducingMethod.getName() ); ///END FIND LOGIC/// return new SimpleStatementCacheKey( pcon, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); } SimpleStatementCacheKey( Connection physicalConnection, String stmtText, boolean is_callable, int result_set_type, int result_set_concurrency, int[] columnIndexes, String[] columnNames, Integer autogeneratedKeys, Integer resultSetHoldability ) { super( physicalConnection, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); } public boolean equals( Object o ) { return StatementCacheKey.equals( this, o ); } public int hashCode() { return StatementCacheKey.hashCode( this ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/StatementCache.java0000644000175000017500000000266010624366527023732 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.lang.reflect.*; import java.sql.*; import com.mchange.v1.util.ClosableResource; public interface StatementCache extends ClosableResource { public Object checkoutStatement( Connection physicalConnection, Method stmtProducingMethod, Object[] args ) throws SQLException; public void checkinStatement( Object pstmt ) throws SQLException; public void checkinAll( Connection pcon ) throws SQLException; public void closeAll( Connection pcon ) throws SQLException; public void close() throws SQLException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/StatementCacheBenchmark.java0000644000175000017500000001025410624366530025535 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; public final class StatementCacheBenchmark { final static String EMPTY_TABLE_CREATE = "CREATE TABLE emptyyukyuk (a varchar(8), b varchar(8))"; final static String EMPTY_TABLE_SELECT = "SELECT * FROM emptyyukyuk"; final static String EMPTY_TABLE_DROP = "DROP TABLE emptyyukyuk"; final static String EMPTY_TABLE_CONDITIONAL_SELECT = "SELECT * FROM emptyyukyuk where a = ?"; final static int NUM_ITERATIONS = 2000; public static void main(String[] argv) { DataSource ds_unpooled = null; DataSource ds_pooled = null; try { String jdbc_url = null; String username = null; String password = null; if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); ds_unpooled = DriverManagerDataSourceFactory.create(jdbc_url, username, password); ds_pooled = PoolBackedDataSourceFactory.create(jdbc_url, username, password, 5, 20, 5, 0, 100 ); create(ds_pooled); perform( ds_pooled, "pooled" ); perform( ds_unpooled, "unpooled" ); } catch( Exception e ) { e.printStackTrace(); } finally { try { drop(ds_pooled); } catch (Exception e) { e.printStackTrace(); } } } private static void perform( DataSource ds, String name ) throws SQLException { Connection c = null; PreparedStatement ps = null; try { c = ds.getConnection(); long start = System.currentTimeMillis(); for (int i = 0; i < NUM_ITERATIONS; ++i) { PreparedStatement test = c.prepareStatement( EMPTY_TABLE_CONDITIONAL_SELECT ); test.close(); } long end = System.currentTimeMillis(); System.err.println(name + " --> " + (end - start) / (float) NUM_ITERATIONS + " [" + NUM_ITERATIONS + " iterations]"); } finally { StatementUtils.attemptClose( ps ); ConnectionUtils.attemptClose( c ); } } private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + StatementCacheBenchmark.class.getName() + " [ ]" ); System.exit(-1); } static void create(DataSource ds) throws SQLException { System.err.println("Creating test schema."); Connection con = null; PreparedStatement ps1 = null; try { con = ds.getConnection(); ps1 = con.prepareStatement(EMPTY_TABLE_CREATE); ps1.executeUpdate(); System.err.println("Test schema created."); } finally { StatementUtils.attemptClose( ps1 ); ConnectionUtils.attemptClose( con ); } } static void drop(DataSource ds) throws SQLException { Connection con = null; PreparedStatement ps1 = null; try { con = ds.getConnection(); ps1 = con.prepareStatement(EMPTY_TABLE_DROP); ps1.executeUpdate(); } finally { StatementUtils.attemptClose( ps1 ); ConnectionUtils.attemptClose( con ); } System.err.println("Test schema dropped."); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/StatementCacheKey.java0000644000175000017500000001451110624366527024401 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.Connection; import java.lang.reflect.Method; import java.util.Arrays; import com.mchange.v1.util.ArrayUtils; import com.mchange.v2.lang.ObjectUtils; abstract class StatementCacheKey { static final int SIMPLE = 0; static final int MEMORY_COALESCED = 1; static final int VALUE_IDENTITY = 2; //NOTE: subclasses rely upon their _find logic being protected by StatementCacheKey.class' lock! public synchronized static StatementCacheKey find( Connection pcon, Method stmtProducingMethod, Object[] args ) { switch ( VALUE_IDENTITY ) { case SIMPLE: return SimpleStatementCacheKey._find( pcon, stmtProducingMethod, args ); case MEMORY_COALESCED: return MemoryCoalescedStatementCacheKey._find( pcon, stmtProducingMethod, args ); case VALUE_IDENTITY: return ValueIdentityStatementCacheKey._find( pcon, stmtProducingMethod, args ); default: throw new InternalError("StatementCacheKey.find() is misconfigured."); } } //MT: instances are treated as immutable once they // have been initialized and handed to // a client. (Factories may reinitialize // instances that never get released to // clients -- those factories must prevent // concurrent access to these recycled, // nascent keys.) Connection physicalConnection; String stmtText; boolean is_callable; int result_set_type; int result_set_concurrency; int[] columnIndexes; //jdbc3, null means default String[] columnNames; //jdbc3, null means default Integer autogeneratedKeys; //jdbc3, null means driver default, which the spec does not sepcify Integer resultSetHoldability; //jdbc3, null means driver default, which the spec does not sepcify StatementCacheKey() {} StatementCacheKey( Connection physicalConnection, String stmtText, boolean is_callable, int result_set_type, int result_set_concurrency, int[] columnIndexes, String[] columnNames, Integer autogeneratedKeys, Integer resultSetHoldability ) { init( physicalConnection, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); } void init( Connection physicalConnection, String stmtText, boolean is_callable, int result_set_type, int result_set_concurrency, int[] columnIndexes, //jdbc3 String[] columnNames, //jdbc3 Integer autogeneratedKeys, //jdbc3 Integer resultSetHoldability) //jdbc3 { this.physicalConnection = physicalConnection; this.stmtText = stmtText; this.is_callable = is_callable; this.result_set_type = result_set_type; this.result_set_concurrency = result_set_concurrency; this.columnIndexes = columnIndexes; this.columnNames = columnNames; this.autogeneratedKeys = autogeneratedKeys; this.resultSetHoldability = resultSetHoldability; } static boolean equals(StatementCacheKey _this, Object o) { //TODO: assert( _this != null ) if ( _this == o ) return true; if (o instanceof StatementCacheKey) { StatementCacheKey sck = (StatementCacheKey) o; // System.err.println( sck.physicalConnection + " " + // _this.physicalConnection + " equals? " + // sck.physicalConnection.equals( _this.physicalConnection ) ); return sck.physicalConnection.equals(_this.physicalConnection) && sck.stmtText.equals(_this.stmtText) && sck.is_callable == _this.is_callable && sck.result_set_type == _this.result_set_type && sck.result_set_concurrency == _this.result_set_concurrency && Arrays.equals( sck.columnIndexes, _this.columnIndexes ) && Arrays.equals( sck.columnNames, _this.columnNames ) && ObjectUtils.eqOrBothNull( sck.autogeneratedKeys, _this.autogeneratedKeys ) && ObjectUtils.eqOrBothNull( sck.resultSetHoldability, _this.resultSetHoldability ); } else return false; } static int hashCode(StatementCacheKey _this) { return _this.physicalConnection.hashCode() ^ _this.stmtText.hashCode() ^ (_this.is_callable ? 1 : 0) ^ _this.result_set_type ^ _this.result_set_concurrency ^ ArrayUtils.hashOrZeroArray( _this.columnIndexes ) ^ ArrayUtils.hashOrZeroArray( _this.columnNames ) ^ ObjectUtils.hashOrZero( _this.autogeneratedKeys ) ^ //this is okay -- genuine constants are non-zer0 ObjectUtils.hashOrZero( _this.resultSetHoldability ); //this is okay -- genuine constants are non-zer0 } public String toString() { StringBuffer out = new StringBuffer(128); out.append("[" + this.getClass().getName() + ": "); out.append("physicalConnection->" + physicalConnection); out.append(", stmtText->" + stmtText); out.append(", is_callable->" + is_callable); out.append(", result_set_type->" + result_set_type); out.append(", result_set_concurrency->" + result_set_concurrency); out.append(", columnIndexes->" + ArrayUtils.toString(columnIndexes)); out.append(", columnNames->" + ArrayUtils.toString(columnNames)); out.append(", autogeneratedKeys->" + autogeneratedKeys); out.append(", resultSetHoldability->" + resultSetHoldability); out.append(']'); return out.toString(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/stmt/ValueIdentityStatementCacheKey.java0000644000175000017500000001470610624366530027110 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.stmt; import java.sql.Connection; import java.sql.ResultSet; import java.lang.reflect.Method; import com.mchange.v2.coalesce.*; import java.sql.Connection; import java.sql.ResultSet; import java.lang.reflect.Method; import com.mchange.v2.coalesce.*; final class ValueIdentityStatementCacheKey extends StatementCacheKey { //MT: not thread-safe, but protected within the find() method // by StatementCacheKey.class lock final static Coalescer keyCoalescer; //MT: modified only within StatementCacheKey.class-locked find() method static ValueIdentityStatementCacheKey spare = new ValueIdentityStatementCacheKey(); static { CoalesceChecker cc = new CoalesceChecker() { public boolean checkCoalesce( Object a, Object b ) { return StatementCacheKey.equals( (StatementCacheKey) a, b ); } public int coalesceHash( Object a ) { return ((ValueIdentityStatementCacheKey) a).cached_hash; } }; //make weak, unsync'ed coalescer keyCoalescer = CoalescerFactory.createCoalescer( cc, true, false ); } static StatementCacheKey _find( Connection pcon, Method stmtProducingMethod, Object[] args ) { ///BEGIN FIND LOGIC/// String stmtText = (String) args[0]; boolean is_callable = stmtProducingMethod.getName().equals("prepareCall"); int result_set_type; int result_set_concurrency; int[] columnIndexes; String[] columnNames; Integer autogeneratedKeys; Integer resultSetHoldability; if (args.length == 1) { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (args.length == 2) { Class[] argTypes = stmtProducingMethod.getParameterTypes(); if (argTypes[1].isArray()) { Class baseType = argTypes[1].getComponentType(); if (baseType == int.class) //second arg is columnIndexes { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = (int[]) args[1]; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (baseType == String.class) { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = (String[]) args[1]; autogeneratedKeys = null; resultSetHoldability = null; } else throw new IllegalArgumentException("c3p0 probably needs to be updated for some new " + "JDBC spec! As of JDBC3, we expect two arg statement " + "producing methods where the second arg is either " + "an int, int array, or String array."); } else //it should be a boxed int, autogeneratedKeys { result_set_type = ResultSet.TYPE_FORWARD_ONLY; result_set_concurrency = ResultSet.CONCUR_READ_ONLY; columnIndexes = null; columnNames = null; autogeneratedKeys = (Integer) args[1]; resultSetHoldability = null; } } else if (args.length == 3) { result_set_type = ((Integer) args[1]).intValue(); result_set_concurrency = ((Integer) args[2]).intValue(); columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = null; } else if (args.length == 4) { result_set_type = ((Integer) args[1]).intValue(); result_set_concurrency = ((Integer) args[2]).intValue(); columnIndexes = null; columnNames = null; autogeneratedKeys = null; resultSetHoldability = (Integer) args[3]; } else throw new IllegalArgumentException("Unexpected number of args to " + stmtProducingMethod.getName() ); ///END FIND LOGIC/// // we keep around a "spare" and initialize it over and over again // rather than allocating, because usually we'll find the statement we're // looking for is already in the coalescer, and we can avoid the // allocation altogether. spare.init( pcon, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); StatementCacheKey out = (StatementCacheKey) keyCoalescer.coalesce( spare ); // System.err.println( "StatementCacheKey -> " + out ); // System.err.println( "Key is coalesced already? " + (out != spare) ); // System.err.println( "Keys in coalescer: " + keyCoalescer.countCoalesced() ); if (out == spare) spare = new ValueIdentityStatementCacheKey(); return out; } void init( Connection physicalConnection, String stmtText, boolean is_callable, int result_set_type, int result_set_concurrency, int[] columnIndexes, String[] columnNames, Integer autogeneratedKeys, Integer resultSetHoldability ) { super.init( physicalConnection, stmtText, is_callable, result_set_type, result_set_concurrency, columnIndexes, columnNames, autogeneratedKeys, resultSetHoldability ); this.cached_hash = StatementCacheKey.hashCode( this ); } // extra instance varieable int cached_hash; // Note that we DON'T override equals() or hashCode() here -- each instance let the coalescer guarantee a // single instance exists that would equals() it (that is, itself), and we rely on Object's default equals() and // hashCode methods do their thangs. } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/subst/0000755000175000017500000000000010673162231020332 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/subst/C3P0Substitutions.java0000644000175000017500000000230310624366527024472 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.subst; public final class C3P0Substitutions { public final static String VERSION = "@c3p0.version@"; public final static String DEBUG = "@c3p0.debug@"; public final static String TRACE = "@c3p0.trace@"; public final static String TIMESTAMP = "@c3p0.timestamp@"; private C3P0Substitutions() {} }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/0000755000175000017500000000000010673162231020151 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/junit/0000755000175000017500000000000010673162231021302 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/junit/C3P0JUnitTestCaseBase.java0000644000175000017500000000336010624366527026027 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test.junit; import com.mchange.v2.c3p0.*; import junit.framework.TestCase; public abstract class C3P0JUnitTestCaseBase extends TestCase { protected ComboPooledDataSource cpds; protected void setUp() { //we let this stuff get setup in c3p0.properties now /* String url = System.getProperty("c3p0.test.jdbc.url"); String user = System.getProperty("c3p0.test.jdbc.user"); String password = System.getProperty("c3p0.test.jdbc.password"); */ //C3P0JUnitTestConfig.loadDrivers(); cpds = new ComboPooledDataSource(); /* cpds.setJdbcUrl( url ); cpds.setUser( user ); cpds.setPassword( password ); */ } protected void tearDown() { try { cpds.close(); } catch ( Exception e ) { System.err.println("Exception on DataSource close in JUnit test tearDown():"); e.printStackTrace(); } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/junit/ConnectionPropertiesResetJUnitTestCase.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/junit/ConnectionPropertiesResetJUnitTestCase.0000644000175000017500000000630110624366527031102 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test.junit; import java.sql.*; import java.util.*; import junit.framework.*; public final class ConnectionPropertiesResetJUnitTestCase extends C3P0JUnitTestCaseBase { final static Map TM; static { Map tmp = new HashMap(); tmp.put("FAKE", SQLData.class); TM = Collections.unmodifiableMap( tmp ); } public void testAllConnectionDefaultsReset() { // System.err.println("XOXO err"); // System.out.println("XOXO out"); cpds.setInitialPoolSize(5); cpds.setMinPoolSize(5); cpds.setMaxPoolSize(5); cpds.setMaxIdleTime(0); cpds.setTestConnectionOnCheckout(false); cpds.setTestConnectionOnCheckin(false); cpds.setIdleConnectionTestPeriod(0); String dfltCat; int dflt_txn_isolation; try { Connection con = null; try { con = cpds.getConnection(); dfltCat = con.getCatalog(); dflt_txn_isolation = con.getTransactionIsolation(); try { con.setReadOnly(true); } catch (Exception e) { /* setReadOnly() not supported */ } try { con.setTypeMap(TM); } catch (Exception e) { /* setTypeMap() not supported */ } try { con.setCatalog("C3P0TestCatalogXXX"); } catch (Exception e) { /* setCatalog() not supported */ } try { con.setTransactionIsolation( dflt_txn_isolation == Connection.TRANSACTION_SERIALIZABLE ? Connection.TRANSACTION_READ_COMMITTED : Connection.TRANSACTION_SERIALIZABLE ); } catch (Exception e) { /* setTransactionIsolation() not fully supported */ } } finally { try { if (con != null) con.close(); } catch (Exception e) {} } Connection[] cons = new Connection[5]; for (int i = 0; i < 5; ++i) { cons[i] = cpds.getConnection(); assertFalse( "Connection from pool should not be readOnly!", cons[i].isReadOnly() ); // some drivers return null rather than an empty type map Map typeMap = cons[i].getTypeMap(); assertTrue( "Connection from pool should have an empty type map!", (typeMap == null ? true : typeMap.isEmpty() ) ); assertEquals( "Connection from pool should have default catalog set!", dfltCat, cons[i].getCatalog() ); assertEquals( "Connection from pool should have default txn isolation set!", dflt_txn_isolation, cons[i].getTransactionIsolation() ); cons[i].close(); } } catch (Exception e) { e.printStackTrace(); fail( e.getMessage() ); } } }././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/junit/MarshallUnmarshallDataSourcesJUnitTestCase.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/junit/MarshallUnmarshallDataSourcesJUnitTestC0000644000175000017500000001140410624366527031104 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test.junit; import java.util.*; import javax.naming.Reference; import junit.framework.*; import com.mchange.v2.ser.SerializableUtils; import com.mchange.v2.beans.BeansUtils; import com.mchange.v2.naming.ReferenceableUtils; import com.mchange.v2.c3p0.ComboPooledDataSource; public final class MarshallUnmarshallDataSourcesJUnitTestCase extends C3P0JUnitTestCaseBase { final static Collection EXCLUDE_PROPS = Arrays.asList( new String[]{ "allUsers", "connection", "connectionPoolDataSource", "effectivePropertyCycleDefaultUser", "lastCheckinFailureDefaultUser", "lastCheckoutFailureDefaultUser", "lastConnectionTestFailureDefaultUser", "lastIdleTestFailureDefaultUser", "logWriter", "numBusyConnections", "numBusyConnectionsAllUsers", "numBusyConnectionsDefaultUser", "numConnections", "numConnectionsAllUsers", "numConnectionsDefaultUser", "numFailedCheckinsDefaultUser", "numFailedCheckoutsDefaultUser", "numFailedIdleTestsDefaultUser", "numIdleConnections", "numIdleConnectionsAllUsers", "numIdleConnectionsDefaultUser", "numUnclosedOrphanedConnections", "numUnclosedOrphanedConnectionsAllUsers", "numUnclosedOrphanedConnectionsDefaultUser", "numUserPools", "startTimeMillisDefaultUser", "statementCacheNumCheckedOutDefaultUser", "statementCacheNumCheckedOutStatementsAllUsers", "statementCacheNumConnectionsWithCachedStatementsAllUsers", "statementCacheNumConnectionsWithCachedStatementsDefaultUser", "statementCacheNumStatementsAllUsers", "statementCacheNumStatementsDefaultUser", "threadPoolSize", "threadPoolNumActiveThreads", "threadPoolNumIdleThreads", "threadPoolNumTasksPending", "threadPoolStackTraces", "threadPoolStatus", "upTimeMillisDefaultUser" } ); public void testSerializationRoundTrip() { try { cpds.setIdentityToken("poop"); //simulate a never-before-seen data source, so it's a new registration on deserialization byte[] pickled = SerializableUtils.toByteArray(cpds); ComboPooledDataSource unpickled = (ComboPooledDataSource) SerializableUtils.fromByteArray( pickled ); assertTrue( "Marshalled and unmarshalled DataSources should have the same properties!", BeansUtils.equalsByAccessibleProperties( cpds, unpickled, EXCLUDE_PROPS ) ); } catch (Exception e) { e.printStackTrace(); fail( e.getMessage() ); } } public void testRefDerefRoundTrip() { try { cpds.setIdentityToken("scoop"); //simulate a never-before-seen data source, so it's a new registration on deserialization Reference ref = cpds.getReference(); ComboPooledDataSource unpickled = (ComboPooledDataSource) ReferenceableUtils.referenceToObject( ref, null, null, null ); assertTrue( "Marshalled and unmarshalled DataSources should have the same properties!", BeansUtils.equalsByAccessibleProperties( cpds, unpickled, EXCLUDE_PROPS ) ); } catch (Exception e) { e.printStackTrace(); fail( e.getMessage() ); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/AlwaysFailConnectionTester.java0000644000175000017500000000400710624366530026264 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.sql.Connection; import com.mchange.v2.c3p0.QueryConnectionTester; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; public final class AlwaysFailConnectionTester implements QueryConnectionTester { final static MLogger logger = MLog.getLogger( AlwaysFailConnectionTester.class ); { logger.log(MLevel.WARNING, "Instantiated: " + this, new Exception("Instantiation Stack Trace.") ); } public int activeCheckConnection(Connection c) { logger.warning(this + ": activeCheckConnection(Connection c)"); return CONNECTION_IS_INVALID; } public int statusOnException(Connection c, Throwable t) { logger.warning(this + ": statusOnException(Connection c, Throwable t)"); return CONNECTION_IS_INVALID; } public int activeCheckConnection(Connection c, String preferredTestQuery) { logger.warning(this + ": activeCheckConnection(Connection c, String preferredTestQuery)"); return CONNECTION_IS_INVALID; } public boolean equals( Object o ) { return (o instanceof AlwaysFailConnectionTester); } public int hashCode() { return 1; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/C3P0BenchmarkApp.java0000644000175000017500000005007610624366527023757 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; import com.mchange.v2.c3p0.DriverManagerDataSource; public final class C3P0BenchmarkApp { final static String EMPTY_TABLE_CREATE = "CREATE TABLE emptyyukyuk (a varchar(8), b varchar(8))"; final static String EMPTY_TABLE_SELECT = "SELECT * FROM emptyyukyuk"; final static String EMPTY_TABLE_DROP = "DROP TABLE emptyyukyuk"; final static String EMPTY_TABLE_CONDITIONAL_SELECT = "SELECT * FROM emptyyukyuk where a = ?"; final static String N_ENTRY_TABLE_CREATE = "CREATE TABLE n_entryyukyuk (a INTEGER)"; final static String N_ENTRY_TABLE_INSERT = "INSERT INTO n_entryyukyuk VALUES ( ? )"; final static String N_ENTRY_TABLE_SELECT = "SELECT * FROM n_entryyukyuk"; final static String N_ENTRY_TABLE_DROP = "DROP TABLE n_entryyukyuk"; //final static int NUM_ITERATIONS = 20; final static int NUM_ITERATIONS = 2000; //final static int NUM_ITERATIONS = 10000; //final static int NUM_ITERATIONS = 20000; //final static int NUM_ITERATIONS = 100000; public static void main(String[] argv) { if (argv.length > 0) { System.err.println( C3P0BenchmarkApp.class.getName() + " now requires no args. Please set everything in standard c3p0 config files."); return; } // com.mchange.v2.log.MLog.getLogger( C3P0BenchmarkApp.class ).info("this is some info."); // com.mchange.v2.log.MLog.getLogger( C3P0BenchmarkApp.class ).log(com.mchange.v2.log.MLevel.WARNING, "this is a warning.", new Exception("test")); // com.mchange.v2.log.MLog.getLogger( C3P0BenchmarkApp.class ).log(com.mchange.v2.log.MLevel.FINE, "this is fine."); // System.getProperties().put("sprong", java.awt.Color.blue); // System.getProperties().put(java.awt.Color.blue, "sprong"); DataSource ds_unpooled = null; DataSource ds_pooled = null; try { /* String jdbc_url = null; String username = null; String password = null; if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); */ // ds_unpooled = DriverManagerDataSourceFactory.create(jdbc_url, username, password); // ds_pooled // // = PoolBackedDataSourceFactory.create(jdbc_url, username, password); // = PoolBackedDataSourceFactory.create(jdbc_url, // username, // password, // 5, // 20, // 5, // 0, // 100 ); //ds_unpooled = DataSources.unpooledDataSource(jdbc_url, username, password); //ds_pooled = DataSources.pooledDataSource( ds_unpooled ); ds_unpooled = new DriverManagerDataSource(); //DataSource ds_unpooled_screwy = C3P0TestUtils.unreliableCommitDataSource( ds_unpooled ); //ds_pooled = DataSources.pooledDataSource( ds_unpooled_screwy ); // PoolConfig pc = new PoolConfig(); // pc.setMaxStatements(200); // pc.setCheckoutTimeout(500); // ds_pooled = DataSources.pooledDataSource( ds_unpooled, pc ); // ds_pooled = DataSources.pooledDataSource( ds_unpooled, "foo", "goo" ); //ds_pooled = DataSources.pooledDataSource(ds_unpooled); //ComboPooledDataSource cpds = new ComboPooledDataSource("dumbTestConfig"); ComboPooledDataSource cpds = new ComboPooledDataSource(); //cpds.setJdbcUrl( jdbc_url ); //cpds.setUser( username ); //cpds.setPassword( password ); ds_pooled = cpds; // ComboPooledDataSource cpds2 = new ComboPooledDataSource(); // System.err.println("Made second ComboPooledDataSource."); // cpds.getNumIdleConnectionsDefaultUser(); // cpds2.getNumIdleConnectionsDefaultUser(); // Properties badProps = new Properties(); // badProps.put("badprop", null); // DataSource appendix = DataSources.pooledDataSource(ds_unpooled, badProps); create(ds_pooled); System.out.println("Please wait. Tests can be very slow."); List l = new ArrayList(); l.add( new ConnectionAcquisitionTest() ); l.add( new StatementCreateTest() ); l.add( new StatementEmptyTableSelectTest() ); //l.add( new DataBaseMetaDataListNonexistentTablesTest() ); l.add( new PreparedStatementEmptyTableSelectTest() ); l.add( new PreparedStatementAcquireTest() ); l.add( new ResultSetReadTest() ); l.add( new FiveThreadPSQueryTestTest() ); for (int i = 0, len = l.size(); i < len; ++i) ((Test) l.get(i)).perform( ds_unpooled, ds_pooled, NUM_ITERATIONS ); } catch( Throwable t ) { System.err.print("Aborting tests on Throwable -- "); t.printStackTrace(); if (t instanceof Error) throw (Error) t; } finally { //System.err.println( "pooled data sources: " + C3P0Registry.getPooledDataSources() ); try { drop(ds_pooled); } catch (Exception e) { e.printStackTrace(); } try { DataSources.destroy(ds_pooled); } catch (Exception e) { e.printStackTrace(); } try { DataSources.destroy(ds_unpooled); } catch (Exception e) { e.printStackTrace(); } } } /* private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + C3P0BenchmarkApp.class.getName() + " [ ]" ); System.exit(-1); } */ static void create(DataSource ds) throws SQLException { System.err.println("Creating test schema."); Connection con = null; PreparedStatement ps1 = null; PreparedStatement ps2 = null; PreparedStatement ps3 = null; try { con = ds.getConnection(); ps1 = con.prepareStatement(EMPTY_TABLE_CREATE); ps2 = con.prepareStatement(N_ENTRY_TABLE_CREATE); ps3 = con.prepareStatement(N_ENTRY_TABLE_INSERT); ps1.executeUpdate(); ps2.executeUpdate(); for (int i = 0; i < NUM_ITERATIONS; ++i) { ps3.setInt(1, i ); ps3.executeUpdate(); System.err.print('.'); } System.err.println(); System.err.println("Test schema created."); } finally { StatementUtils.attemptClose( ps1 ); StatementUtils.attemptClose( ps2 ); StatementUtils.attemptClose( ps3 ); ConnectionUtils.attemptClose( con ); } } static void drop(DataSource ds) throws SQLException { Connection con = null; PreparedStatement ps1 = null; PreparedStatement ps2 = null; try { con = ds.getConnection(); ps1 = con.prepareStatement(EMPTY_TABLE_DROP); ps2 = con.prepareStatement(N_ENTRY_TABLE_DROP); ps1.executeUpdate(); ps2.executeUpdate(); // should be superfluous 'cuz should be autocommit //con.commit(); System.err.println("Test schema dropped."); } finally { StatementUtils.attemptClose( ps1 ); StatementUtils.attemptClose( ps2 ); ConnectionUtils.attemptClose( con ); } } static abstract class Test { String name; Test(String name) { this.name = name; } public void perform(DataSource unpooled, DataSource pooled, int iterations) throws Exception { double msecs_unpooled = test(unpooled, iterations) / ((double) iterations); double msecs_pooled = test(pooled, iterations) / ((double) iterations); System.out.println(name + " [ " + iterations + " iterations ]:"); System.out.println('\t' + "unpooled: " + msecs_unpooled + " msecs"); System.out.println('\t' + " pooled: " + msecs_pooled + " msecs"); System.out.println('\t' + "speed-up factor: " + msecs_unpooled / msecs_pooled + " times"); System.out.println('\t' + "speed-up absolute: " + (msecs_unpooled - msecs_pooled) + " msecs"); System.out.println(); // PooledDataSource pds = (PooledDataSource) pooled; // System.out.println( pds.getNumConnections() ); // System.out.println( pds.getNumIdleConnections() ); // System.out.println( pds.getNumBusyConnections() ); // System.out.println( pds.getNumConnectionsAllAuths() ); } protected abstract long test(DataSource ds, int n) throws Exception; } static class ConnectionAcquisitionTest extends Test { ConnectionAcquisitionTest() { super("Connection Acquisition and Cleanup"); } protected long test(DataSource ds, int n) throws Exception { long start; long end; start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) { Connection con = null; try { con = ds.getConnection(); } finally { ConnectionUtils.attemptClose( con ); } //System.err.print(i + "\t"); } end = System.currentTimeMillis(); return end - start; } } static class StatementCreateTest extends Test { StatementCreateTest() { super("Statement Creation and Cleanup"); } protected long test(DataSource ds, int n) throws SQLException { Connection con = null; try { con = ds.getConnection(); return test( con , n ); } finally { ConnectionUtils.attemptClose( con ); } //{} } long test(Connection con, int n) throws SQLException { long start; long end; Statement stmt = null; start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) { try { stmt = con.createStatement(); } finally { StatementUtils.attemptClose( stmt ); } } end = System.currentTimeMillis(); return end - start; } } static class StatementEmptyTableSelectTest extends Test { StatementEmptyTableSelectTest() { super("Empty Table Statement Select (on a single Statement)"); } protected long test(DataSource ds, int n) throws SQLException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); //System.err.println( stmt.getClass().getName() ); return test( stmt , n ); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } } long test(Statement stmt, int n) throws SQLException { long start; long end; start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) stmt.executeQuery(EMPTY_TABLE_SELECT).close(); end = System.currentTimeMillis(); return end - start; } } static class DataBaseMetaDataListNonexistentTablesTest extends Test { DataBaseMetaDataListNonexistentTablesTest() { super("DataBaseMetaDataListNonexistentTablesTest"); } protected long test(DataSource ds, int n) throws SQLException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); return test( con , n ); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } } long test(Connection con, int n) throws SQLException { ResultSet rs = null; try { long start; long end; start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) rs = con.getMetaData().getTables( null, null, "PROBABLYNOT", new String[] {"TABLE"} ); end = System.currentTimeMillis(); return end - start; } finally { ResultSetUtils.attemptClose( rs ); } } } static class PreparedStatementAcquireTest extends Test { PreparedStatementAcquireTest() { super("Acquire and Cleanup a PreparedStatement (same statement, many times)"); } protected long test(DataSource ds, int n) throws SQLException { long start; long end; Connection con = null; PreparedStatement pstmt = null; try { con = ds.getConnection(); start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) { try { pstmt = con.prepareStatement(EMPTY_TABLE_CONDITIONAL_SELECT); } /* Leftover random abuses from ad hoc testing... { pstmt = con.prepareStatement(EMPTY_TABLE_CONDITIONAL_SELECT, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE, ResultSet.HOLD_CURSORS_OVER_COMMIT); } { pstmt = con.prepareStatement(N_ENTRY_TABLE_INSERT); } */ finally { StatementUtils.attemptClose( pstmt ); } } end = System.currentTimeMillis(); return end - start; } finally { ConnectionUtils.attemptClose( con ); } } } static class PreparedStatementEmptyTableSelectTest extends Test { PreparedStatementEmptyTableSelectTest() { super("Empty Table PreparedStatement Select (on a single PreparedStatement)"); } protected long test(DataSource ds, int n) throws SQLException { Connection con = null; PreparedStatement pstmt = null; try { con = ds.getConnection(); pstmt = con.prepareStatement(EMPTY_TABLE_SELECT); // Leftover from ad-hoc testing... // // pstmt = con.prepareStatement(EMPTY_TABLE_SELECT, // ResultSet.TYPE_SCROLL_SENSITIVE, // ResultSet.CONCUR_UPDATABLE, // ResultSet.HOLD_CURSORS_OVER_COMMIT); return test( pstmt , n ); } finally { StatementUtils.attemptClose( pstmt ); ConnectionUtils.attemptClose( con ); } } long test(PreparedStatement pstmt, int n) throws SQLException { long start; long end; start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) pstmt.executeQuery().close(); end = System.currentTimeMillis(); return end - start; } } static class ResultSetReadTest extends Test { ResultSetReadTest() { super("Reading one row / one entry from a result set"); } protected long test(DataSource ds, int n) throws SQLException { if (n > 10000) throw new IllegalArgumentException("10K max."); long start; long end; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { con = ds.getConnection(); pstmt = con.prepareStatement(N_ENTRY_TABLE_SELECT); rs = pstmt.executeQuery(); start = System.currentTimeMillis(); for (int i = 0; i < n; ++i) { if (! rs.next() ) System.err.println("huh?"); rs.getInt(1); } end = System.currentTimeMillis(); return end - start; } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( pstmt ); ConnectionUtils.attemptClose( con ); } } } static class FiveThreadPSQueryTestTest extends Test { // only for stupid test to simulate (illegal) concurrent access to a Statement // volatile Statement stmt; FiveThreadPSQueryTestTest() { super( "Five threads getting a connection, executing a query, " + System.getProperty( "line.separator" ) + "and retrieving results concurrently via a prepared statement (in a transaction)." ); } protected long test(final DataSource ds, final int n) throws Exception { class QueryThread extends Thread { QueryThread(int num) { super("QueryThread-" + num);} public void run() { Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; for (int i = 0; i < (n / 5); ++i) { try { con = ds.getConnection(); // System.err.println("before txn isolation set: " + con.getTransactionIsolation()); // con.setTransactionIsolation( Connection.TRANSACTION_SERIALIZABLE ); // //con.setTransactionIsolation( Connection.TRANSACTION_READ_UNCOMMITTED ); // System.err.println("after txn isolation set: " + con.getTransactionIsolation()); con.setAutoCommit( false ); pstmt = con.prepareStatement( EMPTY_TABLE_CONDITIONAL_SELECT ); // if (Math.random() < 0.5) // stmt = pstmt; // else if (stmt != null) // stmt.getResultSet(); // if (Math.random() < 0.1 && con instanceof C3P0ProxyConnection) // con.close(); pstmt.setString(1, "boo"); rs = pstmt.executeQuery(); while( rs.next() ) System.err.println("Huh?? Empty table has values?"); //System.out.println(this + " " + i); // if (ds instanceof PooledDataSource) // { // PooledDataSource pds = (PooledDataSource) ds; // System.err.println("numConnections: " + pds.getNumConnections() ); // System.err.println("numIdleConnections: " + pds.getNumIdleConnections() ); // System.err.println("numBusyConnections: " + pds.getNumBusyConnections() ); // System.err.println(); // } con.commit(); } catch (Exception e) { System.err.print("FiveThreadPSQueryTestTest exception -- "); e.printStackTrace(); try { if (con != null) con.rollback(); } catch (SQLException e2) { System.err.print("Rollback on exception failed! -- "); e2.printStackTrace(); } } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( pstmt ); ConnectionUtils.attemptClose( con ); con = null; // StatementUtils.attemptClose( pstmt ); //dup close // ConnectionUtils.attemptClose( con ); //dup close // try { System.err.println( pstmt.getConnection() ); } catch (Exception e) {e.printStackTrace();} // ResultSetUtils.attemptClose( rs ); } } //System.out.println(this + " finished."); } } long start = System.currentTimeMillis(); Thread[] ts = new Thread[5]; for (int i = 0; i < 5; ++i) { ts[i] = new QueryThread(i); ts[i].start(); } for (int i = 0; i < 5; ++i) ts[i].join(); return System.currentTimeMillis() - start; } } // static class TenByTwoResultSetReadTest extends Test // { // TenByTwoResultSetReadTest() // { super("Reading all entryies from a 10 row 2 col result set"); } // protected long test(DataSource ds, int n) throws SQLException // { // long start; // long end; // long start_ctrl; // long end_ctrl; // Connection con = null; // PreparedStatement pstmt = null; // ResultSet rs = null; // start = System.currentTimeMillis(); // for (int i = 0; i < n; ++i) // { // try // { // con = ds.getConnection(); // pstmt = con.prepareStatement(N_ENTRY_TABLE_SELECT); // rs = pstmt.executeQuery(); // while( rs.next() ) // { // rs.getInt(1); // rs.getInt(2); // } // } // finally // { // ResultSetUtils.attemptClose( rs ); // StatementUtils.attemptClose( pstmt ); // ConnectionUtils.attemptClose( con ); // } // } // end = System.currentTimeMillis(); // start_ctrl = System.currentTimeMillis(); // for (int i = 0; i < n; ++i) // { // try // { // con = ds.getConnection(); // pstmt = con.prepareStatement(N_ENTRY_TABLE_SELECT); // rs = pstmt.executeQuery(); // } // finally // { // ResultSetUtils.attemptClose( rs ); // StatementUtils.attemptClose( pstmt ); // ConnectionUtils.attemptClose( con ); // } // } // end_ctrl = System.currentTimeMillis(); // return (end - start) - (end_ctrl - start_ctrl); // } // } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/ConnectionDispersionTest.java0000644000175000017500000001357710624366527026042 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; public final class ConnectionDispersionTest { private final static int DELAY_TIME = 120000; //private final static int DELAY_TIME = 300000; private final static int NUM_THREADS = 600; //private final static int NUM_THREADS = 300; //private final static int NUM_THREADS = 50; private final static Integer ZERO = new Integer(0); private static boolean should_go = false; private static DataSource cpds; private static int ready_count = 0; private static synchronized void setDataSource(DataSource ds) { cpds = ds; } private static synchronized DataSource getDataSource() { return cpds; } private static synchronized int ready() { return ++ready_count; } private static synchronized boolean isReady() { return ready_count == NUM_THREADS; } private static synchronized void start() { should_go = true; ConnectionDispersionTest.class.notifyAll(); } private static synchronized void stop() { should_go = false; ConnectionDispersionTest.class.notifyAll(); } private static synchronized boolean shouldGo() { return should_go; } public static void main(String[] argv) { String jdbc_url = null; String username = null; String password = null; if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); try { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setJdbcUrl( jdbc_url ); ds.setUser( username ); ds.setPassword( password ); setDataSource( ds ); List threads = new ArrayList( NUM_THREADS ); for (int i = 0; i < NUM_THREADS; ++i) { Thread t = new CompeteThread(); t.start(); threads.add( t ); Thread.currentThread().yield(); } synchronized ( ConnectionDispersionTest.class ) { while (! isReady()) ConnectionDispersionTest.class.wait(); } System.err.println("Starting the race."); start(); System.err.println("Sleeping " + ((float) DELAY_TIME/1000) + " seconds to let the race run"); Thread.sleep(DELAY_TIME); System.err.println("Stopping the race."); stop(); for (int i = 0; i < NUM_THREADS; ++i) ((Thread) threads.get(i)).join(); Map outcomeMap = new TreeMap(); for (int i = 0; i < NUM_THREADS; ++i) { Integer outcome = new Integer( ((CompeteThread) threads.get(i)).getCount() ); Integer old = (Integer) outcomeMap.get( outcome ); if (old == null) old = ZERO; outcomeMap.put( outcome, new Integer(old.intValue() + 1) ); } int last = 0; for (Iterator ii = outcomeMap.keySet().iterator(); ii.hasNext(); ) { Integer outcome = (Integer) ii.next(); Integer count = (Integer) outcomeMap.get( outcome ); int oc = outcome.intValue(); int c = count.intValue(); for (; last < oc; ++last) System.out.println(String.valueOf(10000 + last).substring(1) + ": "); ++last; System.out.print(String.valueOf(10000 + oc).substring(1) + ": "); // if (oc < 10) // System.out.print(' '); for(int i = 0; i < c; ++i) System.out.print('*'); System.out.println(); } // List outcomes = new ArrayList(NUM_THREADS); // for (int i = 0; i < NUM_THREADS; ++i) // outcomes.add( new Integer( ((CompeteThread) threads.get(i)).getCount() ) ); // Collections.sort( outcomes ); // System.out.println("Connection counts:"); // for (int i = 0; i < NUM_THREADS; ++i) // System.out.println( outcomes.get(i) + " (" + i + ")"); } catch (Exception e) { e.printStackTrace(); } } static class CompeteThread extends Thread { DataSource ds; int count; synchronized void increment() { ++count; } synchronized int getCount() { return count; } public void run() { try { this.ds = getDataSource(); synchronized ( ConnectionDispersionTest.class ) { ready(); ConnectionDispersionTest.class.wait(); } while ( shouldGo() ) { Connection c = null; ResultSet rs = null; try { c = ds.getConnection(); increment(); rs = c.getMetaData().getTables( null, null, "PROBABLYNOT", new String[] {"TABLE"} ); } catch (SQLException e) { e.printStackTrace(); } finally { try {if (rs != null) rs.close(); } catch (Exception e) { e.printStackTrace(); } try {if (c != null) c.close(); } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } } private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + ConnectionDispersionTest.class.getName() + " [ ]" ); System.exit(-1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/FreezableDriverManagerDataSource.java0000644000175000017500000002226210624366530027345 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.util.Properties; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.c3p0.cfg.C3P0Config; import com.mchange.v2.c3p0.impl.DriverManagerDataSourceBase; // this is a copy-paste hack job to do a quick simulation of how c3p0 responds when // getConnection() freezes but does not fail. public final class FreezableDriverManagerDataSource extends DriverManagerDataSourceBase implements DataSource { final static MLogger logger = MLog.getLogger( FreezableDriverManagerDataSource.class ); final static File FREEZE_FILE = new File("/tmp/c3p0_freeze_file"); //MT: protected by this' lock Driver driver; //MT: protected by this' lock boolean driver_class_loaded = false; public FreezableDriverManagerDataSource() { this( true ); } public FreezableDriverManagerDataSource(boolean autoregister) { super( autoregister ); setUpPropertyListeners(); String user = C3P0Config.initializeStringPropertyVar("user", null); String password = C3P0Config.initializeStringPropertyVar("password", null); if (user != null) this.setUser( user ); if (password != null) this.setPassword( password ); } private void waitNoFreezeFile() throws SQLException { try { while (true) { if (! FREEZE_FILE.exists()) break; Thread.sleep(1000); } } catch (InterruptedException e) { logger.log(MLevel.WARNING, "Frozen cxn acquire interrupted.", e); throw new SQLException( e.toString() ); } } private void setUpPropertyListeners() { PropertyChangeListener driverClassListener = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { Object val = evt.getNewValue(); if ( "driverClass".equals( evt.getPropertyName() ) ) setDriverClassLoaded( false ); } }; this.addPropertyChangeListener( driverClassListener ); } private synchronized boolean isDriverClassLoaded() { return driver_class_loaded; } private synchronized void setDriverClassLoaded(boolean dcl) { this.driver_class_loaded = dcl; } private void ensureDriverLoaded() throws SQLException { try { if (! isDriverClassLoaded()) { if (driverClass != null) Class.forName( driverClass ); setDriverClassLoaded( true ); } } catch (ClassNotFoundException e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Could not load driverClass " + driverClass, e); } } // should NOT be sync'ed -- driver() is sync'ed and that's enough // sync'ing the method creates the danger that one freeze on connect // blocks access to the entire DataSource public Connection getConnection() throws SQLException { ensureDriverLoaded(); waitNoFreezeFile(); Connection out = driver().connect( jdbcUrl, properties ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } // should NOT be sync'ed -- driver() is sync'ed and that's enough // sync'ing the method creates the danger that one freeze on connect // blocks access to the entire DataSource public Connection getConnection(String username, String password) throws SQLException { ensureDriverLoaded(); waitNoFreezeFile(); Connection out = driver().connect( jdbcUrl, overrideProps(username, password) ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } public PrintWriter getLogWriter() throws SQLException { return DriverManager.getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { DriverManager.setLogWriter( out ); } public int getLoginTimeout() throws SQLException { return DriverManager.getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { DriverManager.setLoginTimeout( seconds ); } //overrides public synchronized void setJdbcUrl(String jdbcUrl) { //System.err.println( "setJdbcUrl( " + jdbcUrl + " )"); //new Exception("DEBUG STACK TRACE").printStackTrace(); super.setJdbcUrl( jdbcUrl ); clearDriver(); } //"virtual properties" public synchronized void setUser(String user) { String oldUser = this.getUser(); if (! eqOrBothNull( user, oldUser )) { if (user != null) properties.put( SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user ); else properties.remove( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); pcs.firePropertyChange("user", oldUser, user); } } public synchronized String getUser() { // System.err.println("getUser() -- DriverManagerDataSource@" + System.identityHashCode( this ) + // " using Properties@" + System.identityHashCode( properties )); // new Exception("STACK TRACE DUMP").printStackTrace(); return properties.getProperty( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); } public synchronized void setPassword(String password) { String oldPass = this.getPassword(); if (! eqOrBothNull( password, oldPass )) { if (password != null) properties.put( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password ); else properties.remove( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); pcs.firePropertyChange("password", oldPass, password); } } public synchronized String getPassword() { return properties.getProperty( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); } private final Properties overrideProps(String user, String password) { Properties overriding = (Properties) properties.clone(); //we are relying on a defensive clone in our base class!!! if (user != null) overriding.put(SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user); else overriding.remove(SqlUtils.DRIVER_MANAGER_USER_PROPERTY); if (password != null) overriding.put(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password); else overriding.remove(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY); return overriding; } private synchronized Driver driver() throws SQLException { //System.err.println( "driver() <-- " + this ); if (driver == null) driver = DriverManager.getDriver( jdbcUrl ); return driver; } private synchronized void clearDriver() { driver = null; } private static boolean eqOrBothNull( Object a, Object b ) { return (a == b || (a != null && a.equals(b))); } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: setUpPropertyListeners(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/JavaBeanRefTest.java0000644000175000017500000000327510624366527024001 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import javax.naming.*; import com.mchange.v2.naming.*; import com.mchange.v2.c3p0.*; import com.mchange.v2.c3p0.impl.*; public final class JavaBeanRefTest { public static void main(String[] argv) { try { ComboPooledDataSource cpds = new ComboPooledDataSource(); Reference ref = cpds.getReference(); ComboPooledDataSource cpdsJBOF = (ComboPooledDataSource) (new JavaBeanObjectFactory()).getObjectInstance( ref, null, null, null ); ComboPooledDataSource cpdsCJBOF = (ComboPooledDataSource) (new C3P0JavaBeanObjectFactory()).getObjectInstance( ref, null, null, null ); System.err.println( "cpds: " + cpds ); System.err.println( "cpdsJBOF: " + cpdsJBOF ); System.err.println( "cpdsCJBOF: " + cpdsCJBOF ); } catch (Exception e) { e.printStackTrace(); } } private JavaBeanRefTest() {} }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/JndiBindTest.java0000644000175000017500000000552510624366530023350 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import javax.naming.*; import javax.sql.*; import com.mchange.v2.c3p0.*; public final class JndiBindTest { public static void main(String[] argv) { try { String driverClass = null; String jdbc_url = null; String username = null; String password = null; String dmds_name = null; String cpds_name = null; String pbds_name = null; if (argv.length == 7) { driverClass = argv[0]; jdbc_url = argv[1]; username = argv[2]; password = argv[3]; dmds_name = argv[4]; cpds_name = argv[5]; pbds_name = argv[6]; } else if (argv.length == 5) { driverClass = argv[0]; jdbc_url = argv[1]; username = null; password = null; dmds_name = argv[2]; cpds_name = argv[3]; pbds_name = argv[4]; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); DataSource dmds = DriverManagerDataSourceFactory.create( driverClass, jdbc_url, username, password ); WrapperConnectionPoolDataSource cpds = new WrapperConnectionPoolDataSource(); cpds.setNestedDataSource(dmds); DataSource pbds = PoolBackedDataSourceFactory.create( driverClass, jdbc_url, username, password ); InitialContext ctx = new InitialContext(); ctx.rebind( dmds_name , dmds ); System.out.println( "DriverManagerDataSource bounds as " + dmds_name ); ctx.rebind( cpds_name , cpds ); System.out.println( "ConnectionPoolDataSource bounds as " + cpds_name ); ctx.rebind( pbds_name , pbds ); System.out.println( "PoolDataSource bounds as " + pbds_name ); } catch (Exception e) { e.printStackTrace(); } } private static void usage() { System.err.println("java " + JndiBindTest.class.getName() + " \\"); System.err.println("\t \\"); System.err.println("\t [ ] \\"); System.err.println("\t " ); System.exit(-1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/JndiLookupTest.java0000644000175000017500000000427710624366527023756 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import javax.naming.*; import javax.sql.*; import com.mchange.v2.c3p0.*; public final class JndiLookupTest { public static void main(String[] argv) { try { String dmds_name = null; String cpds_name = null; String pbds_name = null; if (argv.length == 3) { dmds_name = argv[0]; cpds_name = argv[1]; pbds_name = argv[2]; } else usage(); InitialContext ctx = new InitialContext(); DataSource dmds = (DataSource) ctx.lookup( dmds_name ); dmds.getConnection().close(); System.out.println( "DriverManagerDataSource " + dmds_name + " sucessfully looked up and checked."); ConnectionPoolDataSource cpds = (ConnectionPoolDataSource) ctx.lookup( cpds_name ); cpds.getPooledConnection().close(); System.out.println( "ConnectionPoolDataSource " + cpds_name + " sucessfully looked up and checked."); DataSource pbds = (DataSource) ctx.lookup( pbds_name ); pbds.getConnection().close(); System.out.println( "PoolBackedDataSource " + pbds_name + " sucessfully looked up and checked."); } catch (Exception e) { e.printStackTrace(); } } private static void usage() { System.err.println("java " + JndiLookupTest.class.getName() + " \\"); System.err.println("\t " ); System.exit(-1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/ListTablesTest.java0000644000175000017500000000315610624366527023741 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.sql.*; import javax.sql.*; import javax.naming.*; import com.mchange.v1.db.sql.*; public final class ListTablesTest { public static void main(String[] argv) { try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(argv[0]); System.err.println( ds.getClass() ); Connection con = null; ResultSet rs = null; try { con = ds.getConnection(); DatabaseMetaData md = con.getMetaData(); rs = md.getTables( null, null, "%", null); while (rs.next()) System.out.println(rs.getString(3)); } finally { ResultSetUtils.attemptClose( rs ); ConnectionUtils.attemptClose( con ); } } catch (Exception e) { e.printStackTrace(); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/LoadPoolBackedDataSource.java0000644000175000017500000001420710624366527025610 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; import com.mchange.v2.c3p0.DriverManagerDataSource; public final class LoadPoolBackedDataSource { final static int NUM_THREADS = 50; final static int ITERATIONS_PER_THREAD = 1000; static Random random = new Random(); static DataSource ds; public static void main(String[] argv) { if (argv.length > 0) { System.err.println( LoadPoolBackedDataSource.class.getName() + " now requires no args. Please set everything in standard c3p0 config files."); return; } String jdbc_url = null; String username = null; String password = null; /* if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); */ try { //DataSource ds_unpooled = DataSources.unpooledDataSource(jdbc_url, username, password); DataSource ds_unpooled = DataSources.unpooledDataSource(); ds = DataSources.pooledDataSource( ds_unpooled ); Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); stmt.executeUpdate("CREATE TABLE testpbds ( a varchar(16), b varchar(16) )"); System.err.println( "LoadPoolBackedDataSource -- TEST SCHEMA CREATED" ); } catch (SQLException e) { e.printStackTrace(); System.err.println("relation testpbds already exists, or something " + "bad happened."); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } Thread[] threads = new Thread[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; ++i) { Thread t = new ChurnThread(); threads[i] = t; t.start(); System.out.println("THREAD MADE [" + i + "]"); Thread.sleep(1000); } for (int i = 0; i < NUM_THREADS; ++i) threads[i].join(); } catch (Exception e) { e.printStackTrace(); } finally { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); stmt.executeUpdate("DROP TABLE testpbds"); System.err.println( "LoadPoolBackedDataSource -- TEST SCHEMA DROPPED" ); } catch (Exception e) { e.printStackTrace(); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } } } static class ChurnThread extends Thread { public void run() { try { for( int i = 0; i < ITERATIONS_PER_THREAD; ++i ) { Connection con = null; try { con = ds.getConnection(); int select = random.nextInt(3); switch (select) { case 0: executeSelect( con ); break; case 1: executeInsert( con ); break; case 2: executeDelete( con ); break; } PooledDataSource pds = (PooledDataSource) ds; System.out.println( pds.getNumConnectionsDefaultUser() ); System.out.println( pds.getNumIdleConnectionsDefaultUser() ); System.out.println( pds.getNumBusyConnectionsDefaultUser() ); System.out.println( pds.getNumConnectionsAllUsers() ); } finally { ConnectionUtils.attemptClose( con ); } //Thread.sleep( random.nextInt( 1000 ) ); } } catch (Exception e) { e.printStackTrace(); } } } static void executeInsert(Connection con) throws SQLException { Statement stmt = null; try { stmt = con.createStatement(); stmt.executeUpdate("INSERT INTO testpbds VALUES ('" + random.nextInt() + "', '" + random.nextInt() + "')"); System.out.println("INSERTION"); } finally { StatementUtils.attemptClose( stmt ); } } static void executeDelete(Connection con) throws SQLException { Statement stmt = null; try { stmt = con.createStatement(); stmt.executeUpdate("DELETE FROM testpbds;"); System.out.println("DELETION"); } finally { StatementUtils.attemptClose( stmt ); } } static void executeSelect(Connection con) throws SQLException { long l = System.currentTimeMillis(); Statement stmt = null; ResultSet rs = null; try { stmt = con.createStatement(); rs = stmt.executeQuery("SELECT count(*) FROM testpbds"); rs.next(); //we assume one row, one col System.out.println("SELECT [count=" + rs.getInt(1) + ", time=" + (System.currentTimeMillis() - l) + " msecs]"); } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( stmt ); } } private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + LoadPoolBackedDataSource.class.getName() + " [ ]" ); System.exit(-1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/OneThreadRepeatedInsertOrQueryTest.java0000644000175000017500000000773510624366527027741 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; public final class OneThreadRepeatedInsertOrQueryTest { final static String INSERT_STMT = "INSERT INTO testpbds VALUES ( ? , ? )"; final static String SELECT_STMT = "SELECT count(*) FROM testpbds"; static Random random = new Random(); static DataSource ds; public static void main(String[] argv) { String jdbc_url = null; String username = null; String password = null; if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); try { DataSource ds_unpooled = DataSources.unpooledDataSource(jdbc_url, username, password); ds = DataSources.pooledDataSource( ds_unpooled ); Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); stmt.executeUpdate("CREATE TABLE testpbds ( a varchar(16), b varchar(16) )"); } catch (SQLException e) { e.printStackTrace(); System.err.println("relation testpbds already exists, or something " + "bad happened."); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } while(true) { con = null; try { con = ds.getConnection(); boolean select = random.nextBoolean(); if (select) executeSelect( con ); else executeInsert( con ); } catch (Exception e) { e.printStackTrace(); } finally { ConnectionUtils.attemptClose( con ); } //Thread.sleep( random.nextInt( 1000 ) ); } } catch (Exception e) { e.printStackTrace(); } } static void executeInsert(Connection con) throws SQLException { PreparedStatement pstmt = null; try { pstmt = con.prepareStatement(INSERT_STMT); pstmt.setInt(1, random.nextInt()); pstmt.setInt(2, random.nextInt()); pstmt.executeUpdate(); System.out.println("INSERTION"); } finally { // make sure forgetting this doesn't starve // statement cache, as long as the connection // closes... StatementUtils.attemptClose( pstmt ); } } static void executeSelect(Connection con) throws SQLException { long l = System.currentTimeMillis(); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = con.prepareStatement(SELECT_STMT); rs = pstmt.executeQuery(); rs.next(); //we assume one row, one col System.out.println("SELECT [count=" + rs.getInt(1) + ", time=" + (System.currentTimeMillis() - l) + " msecs]"); } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( pstmt ); } } private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + OneThreadRepeatedInsertOrQueryTest.class.getName() + " [ ]" ); System.exit(-1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/PSLoadPoolBackedDataSource.java0000644000175000017500000001327110624366530026045 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; public final class PSLoadPoolBackedDataSource { final static String INSERT_STMT = "INSERT INTO testpbds VALUES ( ? , ? )"; final static String SELECT_STMT = "SELECT count(*) FROM testpbds"; final static String DELETE_STMT = "DELETE FROM testpbds"; static Random random = new Random(); static DataSource ds; public static void main(String[] argv) { if (argv.length > 0) { System.err.println( PSLoadPoolBackedDataSource.class.getName() + " now requires no args. Please set everything in standard c3p0 config files."); return; } String jdbc_url = null; String username = null; String password = null; /* if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); */ try { //DataSource ds_unpooled = DataSources.unpooledDataSource(jdbc_url, username, password); //DataSource ds_unpooled = new FreezableDriverManagerDataSource(); DataSource ds_unpooled = DataSources.unpooledDataSource(); ds = DataSources.pooledDataSource( ds_unpooled ); //new java.io.BufferedReader(new java.io.InputStreamReader(System.in)).readLine(); Connection con = null; Statement stmt = null; try { con = ds_unpooled.getConnection(); stmt = con.createStatement(); stmt.executeUpdate("CREATE TABLE testpbds ( a varchar(16), b varchar(16) )"); } catch (SQLException e) { e.printStackTrace(); System.err.println("relation testpbds already exists, or something " + "bad happened."); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } //for (int i = 0; i < 5; ++i) for (int i = 0; i < 50; ++i) { Thread t = new ChurnThread(); t.start(); System.out.println("THREAD MADE [" + i + "]"); Thread.sleep(1000); } } catch (Exception e) { e.printStackTrace(); } } static class ChurnThread extends Thread { public void run() { try { while(true) { Connection con = null; try { con = ds.getConnection(); int select = random.nextInt(3); switch (select) { case 0: executeSelect( con ); break; case 1: executeInsert( con ); break; case 2: executeDelete( con ); break; } } catch (Exception e) { e.printStackTrace(); } finally { ConnectionUtils.attemptClose( con ); } //Thread.sleep( random.nextInt( 1000 ) ); } } catch (Exception e) { e.printStackTrace(); } } } static void executeInsert(Connection con) throws SQLException { PreparedStatement pstmt = null; try { pstmt = con.prepareStatement(INSERT_STMT); pstmt.setInt(1, random.nextInt()); pstmt.setInt(2, random.nextInt()); pstmt.executeUpdate(); System.out.println("INSERTION"); } finally { // make sure forgetting this doesn't starve // statement cache, as long as the connection // closes... StatementUtils.attemptClose( pstmt ); } } static void executeSelect(Connection con) throws SQLException { long l = System.currentTimeMillis(); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = con.prepareStatement(SELECT_STMT); rs = pstmt.executeQuery(); rs.next(); //we assume one row, one col System.out.println("SELECT [count=" + rs.getInt(1) + ", time=" + (System.currentTimeMillis() - l) + " msecs]"); } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( pstmt ); } } static void executeDelete(Connection con) throws SQLException { PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = con.prepareStatement(DELETE_STMT); int deleted = pstmt.executeUpdate(); System.out.println("DELETE [" + deleted + " rows]"); } finally { ResultSetUtils.attemptClose( rs ); StatementUtils.attemptClose( pstmt ); } } /* private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + PSLoadPoolBackedDataSource.class.getName() + " [ ]" ); System.exit(-1); } */ } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/ProxyWrappersTest.java0000644000175000017500000000421010624366527024530 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; public final class ProxyWrappersTest { public static void main(String[] argv) { ComboPooledDataSource cpds = null; Connection c = null; try { cpds = new ComboPooledDataSource(); cpds.setDriverClass( "org.postgresql.Driver" ); cpds.setJdbcUrl( "jdbc:postgresql://localhost/c3p0-test" ); cpds.setUser("swaldman"); cpds.setPassword("test"); cpds.setMinPoolSize(5); cpds.setAcquireIncrement(5); cpds.setMaxPoolSize(20); c = cpds.getConnection(); c.setAutoCommit( false ); Statement stmt = c.createStatement(); stmt.executeUpdate("CREATE TABLE pwtest_table (col1 char(5), col2 char(5))"); ResultSet rs = stmt.executeQuery("SELECT * FROM pwtest_table"); System.err.println("rs: " + rs); System.err.println("rs.getStatement(): " + rs.getStatement()); System.err.println("rs.getStatement().getConnection(): " + rs.getStatement().getConnection()); } catch( Exception e ) { e.printStackTrace(); } finally { try { if (c!= null) c.rollback(); } catch (Exception e) { e.printStackTrace(); } try { if (cpds!= null) cpds.close(); } catch (Exception e) { e.printStackTrace(); } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/RawConnectionOpTest.java0000644000175000017500000000726210624366527024745 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.lang.reflect.Method; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.C3P0ProxyConnection; import com.mchange.v2.c3p0.C3P0ProxyStatement; import com.mchange.v2.c3p0.util.TestUtils; public final class RawConnectionOpTest { public static void main(String[] argv) { try { String jdbc_url = null; String username = null; String password = null; if (argv.length == 3) { jdbc_url = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbc_url = argv[0]; username = null; password = null; } else usage(); if (! jdbc_url.startsWith("jdbc:") ) usage(); ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setJdbcUrl( jdbc_url ); cpds.setUser( username ); cpds.setPassword( password ); cpds.setMaxPoolSize( 10 ); // cpds.setUsesTraditionalReflectiveProxies( true ); C3P0ProxyConnection conn = (C3P0ProxyConnection) cpds.getConnection(); Method toStringMethod = Object.class.getMethod("toString", new Class[]{}); Method identityHashCodeMethod = System.class.getMethod("identityHashCode", new Class[] {Object.class}); System.out.println("rawConnection.toString() -> " + conn.rawConnectionOperation(toStringMethod, C3P0ProxyConnection.RAW_CONNECTION, new Object[]{})); Integer ihc = (Integer) conn.rawConnectionOperation(identityHashCodeMethod, null, new Object[]{C3P0ProxyConnection.RAW_CONNECTION}); System.out.println("System.identityHashCode( rawConnection ) -> " + Integer.toHexString( ihc.intValue() )); C3P0ProxyStatement stmt = (C3P0ProxyStatement) conn.createStatement(); System.out.println("rawStatement.toString() -> " + stmt.rawStatementOperation(toStringMethod, C3P0ProxyStatement.RAW_STATEMENT, new Object[]{})); Integer ihc2 = (Integer) stmt.rawStatementOperation(identityHashCodeMethod, null, new Object[]{C3P0ProxyStatement.RAW_STATEMENT}); System.out.println("System.identityHashCode( rawStatement ) -> " + Integer.toHexString( ihc2.intValue() )); conn.close(); for (int i = 0; i < 10; ++i) { C3P0ProxyConnection check = null; try { check = (C3P0ProxyConnection) cpds.getConnection(); //System.err.println( TestUtils.samePhysicalConnection( conn, check ) ); System.err.println( TestUtils.physicalConnectionIdentityHashCode( check ) == ihc.intValue() ); } finally { /* if (check != null) check.close(); */ } } } catch (Exception e) { e.printStackTrace(); } } private static void usage() { System.err.println("java " + RawConnectionOpTest.class.getName() + " \\"); System.err.println("\t \\"); System.err.println("\t [ ]"); System.exit(-1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/StatsTest.java0000644000175000017500000000602710624366527022771 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.util.*; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; public final class StatsTest { static void display( ComboPooledDataSource cpds ) throws Exception { System.err.println("numConnections: " + cpds.getNumConnections()); System.err.println("numBusyConnections: " + cpds.getNumBusyConnections()); System.err.println("numIdleConnections: " + cpds.getNumIdleConnections()); System.err.println("numUnclosedOrphanedConnections: " + cpds.getNumUnclosedOrphanedConnections()); System.err.println(); } public static void main(String[] argv) { try { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setJdbcUrl( argv[0] ); cpds.setUser( argv[1] ); cpds.setPassword( argv[2] ); cpds.setMinPoolSize(5); cpds.setAcquireIncrement(5); cpds.setMaxPoolSize(20); System.err.println("Initial..."); display( cpds ); Thread.sleep(2000); HashSet hs = new HashSet(); for (int i = 0; i < 20; ++i) { Connection c = cpds.getConnection(); hs.add( c ); System.err.println( "Adding (" + (i + 1) + ") " + c ); display( cpds ); Thread.sleep(1000); // if (i == 9) // { // //System.err.println("hardReset()ing"); // //cpds.hardReset(); // System.err.println("softReset()ing"); // cpds.softReset(); // } } int count = 0; for (Iterator ii = hs.iterator(); ii.hasNext(); ) { Connection c = ((Connection) ii.next()); System.err.println("Removing " + ++count); ii.remove(); try { c.getMetaData().getTables( null, null, "PROBABLYNOT", new String[] {"TABLE"} ); } catch (Exception e) { System.err.println( e ); System.err.println(); continue; } finally { c.close(); } display( cpds ); } System.err.println("Closing data source, \"forcing\" garbage collection, and sleeping for 5 seconds..."); cpds.close(); System.gc(); System.err.println("Main Thread: Sleeping for five seconds!"); Thread.sleep(5000); // System.gc(); // Thread.sleep(5000); System.err.println("Bye!"); } catch( Exception e ) { e.printStackTrace(); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/TestConnectionCustomizer.java0000644000175000017500000000300210624366527026045 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import com.mchange.v2.c3p0.*; import java.sql.Connection; public class TestConnectionCustomizer extends AbstractConnectionCustomizer { public void onAcquire( Connection c, String pdsIdt ) { System.err.println("Acquired " + c + " [" + pdsIdt + "]"); } public void onDestroy( Connection c, String pdsIdt ) { System.err.println("Destroying " + c + " [" + pdsIdt + "]"); } public void onCheckOut( Connection c, String pdsIdt ) { System.err.println("Checked out " + c + " [" + pdsIdt + "]"); } public void onCheckIn( Connection c, String pdsIdt ) { System.err.println("Checking in " + c + " [" + pdsIdt + "]"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/test/TestRefSerStuff.java0000644000175000017500000001160310624366530024057 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.test; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.*; import com.mchange.v1.db.sql.*; import javax.naming.Reference; import javax.naming.Referenceable; import com.mchange.v2.naming.ReferenceableUtils; import com.mchange.v2.ser.SerializableUtils; import com.mchange.v2.c3p0.DriverManagerDataSource; import com.mchange.v2.c3p0.PoolBackedDataSource; public final class TestRefSerStuff { static void create(DataSource ds) throws SQLException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); stmt.executeUpdate("CREATE TABLE TRSS_TABLE ( a_col VARCHAR(16) )"); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } } static void drop(DataSource ds) throws SQLException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); stmt.executeUpdate("DROP TABLE TRSS_TABLE"); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } } static void doSomething(DataSource ds) throws SQLException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); int i = stmt.executeUpdate("INSERT INTO TRSS_TABLE VALUES ('" + System.currentTimeMillis() + "')"); if (i != 1) throw new SQLException("Insert failed somehow strange!"); } finally { StatementUtils.attemptClose( stmt ); ConnectionUtils.attemptClose( con ); } } /* private static void usage() { System.err.println("java " + "-Djdbc.drivers= " + TestRefSerStuff.class.getName() + " [ ]" ); System.exit(-1); } */ static void doTest(DataSource checkMe) throws Exception { doSomething( checkMe ); System.err.println("\tcreated: " + checkMe); DataSource afterSer = (DataSource) SerializableUtils.testSerializeDeserialize( checkMe ); doSomething( afterSer ); System.err.println("\tafter ser: " + afterSer ); Reference ref = ((Referenceable) checkMe).getReference(); // System.err.println("ref: " + ref); // System.err.println("Factory Class: " + ref.getFactoryClassName()); DataSource afterRef = (DataSource) ReferenceableUtils.referenceToObject( ref, null, null, null ); // System.err.println("afterRef data source: " + afterRef); doSomething( afterRef ); System.err.println("\tafter ref: " + afterRef ); } public static void main( String[] argv ) { if (argv.length > 0) { System.err.println( TestRefSerStuff.class.getName() + " now requires no args. Please set everything in standard c3p0 config files."); return; } /* String jdbcUrl = null; String username = null; String password = null; if (argv.length == 3) { jdbcUrl = argv[0]; username = argv[1]; password = argv[2]; } else if (argv.length == 1) { jdbcUrl = argv[0]; username = null; password = null; } else usage(); if (! jdbcUrl.startsWith("jdbc:") ) usage(); */ try { DriverManagerDataSource dmds = new DriverManagerDataSource(); //dmds.setJdbcUrl( jdbcUrl ); //dmds.setUser( username ); //dmds.setPassword( password ); try { drop( dmds ); } catch (Exception e) { /* Ignore */ } create( dmds ); System.err.println("DriverManagerDataSource:"); doTest( dmds ); WrapperConnectionPoolDataSource wcpds = new WrapperConnectionPoolDataSource(); wcpds.setNestedDataSource( dmds ); PoolBackedDataSource pbds = new PoolBackedDataSource(); pbds.setConnectionPoolDataSource( wcpds ); System.err.println("PoolBackedDataSource:"); doTest( pbds ); ComboPooledDataSource cpds = new ComboPooledDataSource(); doTest( cpds ); } catch ( Exception e ) { e.printStackTrace(); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/util/0000755000175000017500000000000010673162231020147 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/util/CloseReportingConnectionWrapper.java0000644000175000017500000000240010624366527027340 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.util; import java.sql.*; import com.mchange.v2.sql.filter.*; public class CloseReportingConnectionWrapper extends FilterConnection { public CloseReportingConnectionWrapper( Connection conn ) { super( conn ); } public void close() throws SQLException { //System.err.print("ADRIAN -- "); new SQLWarning("Connection.close() called!").printStackTrace(); super.close(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/util/ConnectionEventSupport.java0000644000175000017500000000414410624366527025525 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.util; import java.util.*; import java.sql.*; import javax.sql.*; public class ConnectionEventSupport { PooledConnection source; HashSet mlisteners = new HashSet(); public ConnectionEventSupport(PooledConnection source) { this.source = source; } public synchronized void addConnectionEventListener(ConnectionEventListener mlistener) {mlisteners.add(mlistener);} public synchronized void removeConnectionEventListener(ConnectionEventListener mlistener) {mlisteners.remove(mlistener);} public void fireConnectionClosed() { Set mlCopy; synchronized (this) { mlCopy = (Set) mlisteners.clone(); } ConnectionEvent evt = new ConnectionEvent(source); for (Iterator i = mlCopy.iterator(); i.hasNext();) { ConnectionEventListener cl = (ConnectionEventListener) i.next(); cl.connectionClosed(evt); } } public void fireConnectionErrorOccurred(SQLException error) { Set mlCopy; synchronized (this) { mlCopy = (Set) mlisteners.clone(); } ConnectionEvent evt = new ConnectionEvent(source, error); for (Iterator i = mlCopy.iterator(); i.hasNext();) { ConnectionEventListener cl = (ConnectionEventListener) i.next(); cl.connectionErrorOccurred(evt); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/util/TestUtils.java0000644000175000017500000001261210624366530022760 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0.util; import java.sql.*; import javax.sql.*; import java.lang.reflect.*; import java.util.Random; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.c3p0.C3P0ProxyConnection; public final class TestUtils { private final static Method OBJECT_EQUALS; private final static Method IDENTITY_HASHCODE; private final static Method IPCFP; static { try { OBJECT_EQUALS = Object.class.getMethod("equals", new Class[] { Object.class }); IDENTITY_HASHCODE = System.class.getMethod("identityHashCode", new Class[] {Object.class}); // is this okay? getting a method from a class while it is still being initialized? IPCFP = TestUtils.class.getMethod("isPhysicalConnectionForProxy", new Class[] {Connection.class, C3P0ProxyConnection.class}); } catch ( Exception e ) { e.printStackTrace(); throw new RuntimeException("Huh? Can't reflectively get ahold of expected methods?"); } } /** * In general, if this method returns true for two distinct C3P0ProxyConnections, it indicates a c3p0 bug. * Once a proxy Connection is close()ed, it should not permit any sort of operation. Prior to Connection * close(), there should be at most one valid proxy Connection associated with a given physical Connection. */ public static boolean samePhysicalConnection( C3P0ProxyConnection con1, C3P0ProxyConnection con2 ) throws SQLException { try { Object out = con1.rawConnectionOperation( IPCFP, null, new Object[] { C3P0ProxyConnection.RAW_CONNECTION, con2 } ); return ((Boolean) out).booleanValue(); } catch (Exception e) { e.printStackTrace(); throw SqlUtils.toSQLException( e ); } } public static boolean isPhysicalConnectionForProxy( Connection physicalConnection, C3P0ProxyConnection proxy ) throws SQLException { try { Object out = proxy.rawConnectionOperation( OBJECT_EQUALS, physicalConnection, new Object[] { C3P0ProxyConnection.RAW_CONNECTION } ); return ((Boolean) out).booleanValue(); } catch (Exception e) { e.printStackTrace(); throw SqlUtils.toSQLException( e ); } } public static int physicalConnectionIdentityHashCode( C3P0ProxyConnection conn ) throws SQLException { try { Object out = conn.rawConnectionOperation( IDENTITY_HASHCODE, null, new Object[] { C3P0ProxyConnection.RAW_CONNECTION } ); return ((Integer) out).intValue(); } catch (Exception e) { e.printStackTrace(); throw SqlUtils.toSQLException( e ); } } public static DataSource unreliableCommitDataSource(DataSource ds) throws Exception { return (DataSource) Proxy.newProxyInstance( TestUtils.class.getClassLoader(), new Class[] { DataSource.class }, new StupidDataSourceInvocationHandler( ds ) ); } private TestUtils() {} static class StupidDataSourceInvocationHandler implements InvocationHandler { DataSource ds; Random r = new Random(); StupidDataSourceInvocationHandler(DataSource ds) { this.ds = ds; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ( "getConnection".equals(method.getName()) ) { Connection conn = (Connection) method.invoke( ds, args ); return Proxy.newProxyInstance( TestUtils.class.getClassLoader(), new Class[] { Connection.class }, new StupidConnectionInvocationHandler( conn ) ); } else return method.invoke( ds, args ); } } static class StupidConnectionInvocationHandler implements InvocationHandler { Connection conn; Random r = new Random(); boolean invalid = false; StupidConnectionInvocationHandler(Connection conn) { this.conn = conn; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("close".equals(method.getName())) { if (invalid) { new Exception("Duplicate close() called on Connection!!!").printStackTrace(); } else { //new Exception("CLOSE CALLED ON UNPOOLED DATASOURCE CONNECTION!").printStackTrace(); invalid = true; } return null; } else if ( invalid ) throw new SQLException("Connection closed -- cannot " + method.getName()); else if ( "commit".equals(method.getName()) && r.nextInt(100) == 0 ) { conn.rollback(); throw new SQLException("Random commit exception!!!"); } else if (r.nextInt(200) == 0) { conn.rollback(); conn.close(); throw new SQLException("Random Fatal Exception Occurred!!!"); } else return method.invoke( conn, args ); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/AbstractConnectionCustomizer.java0000644000175000017500000000321610624366527025721 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; import java.sql.SQLException; /** * An abstract implementation of the * ConnectionCustomizer interface * in which all methods are no-ops. * * Just a convenience class since * most clients will only need to * implement a single method. */ public abstract class AbstractConnectionCustomizer implements ConnectionCustomizer { public void onAcquire( Connection c, String parentDataSourceIdentityToken ) throws Exception {} public void onDestroy( Connection c, String parentDataSourceIdentityToken ) throws Exception {} public void onCheckOut( Connection c, String parentDataSourceIdentityToken ) throws Exception {} public void onCheckIn( Connection c, String parentDataSourceIdentityToken ) throws Exception {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/AbstractConnectionTester.java0000644000175000017500000000726310624366527025031 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; /** *

Having expanded the once-simple ConnectionTester interface to support both * user-specified queries and return of root cause Exceptions (via an out-param), * this interface has grown unnecessarily complex.

* *

If you wish to implement a custom Connection tester, here is the simple * way to do it

* *
    *
  1. Extend {@link com.mchange.v2.c3p0.AbstractConnectionTester}
  2. *
  3. Override only the two abstract methods
  4. *
      *
    • public int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
    • *
    • public int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
    • *
    *
  5. Take care to ensure that your methods are defined to allow preferredTestQuery and * rootCauseOutParamHolder to be null.
  6. *
* *

Parameter rootCauseOutParamHolder is an optional parameter, which if supplied, will be a Throwable array whose size * it at least one. If a Connection test fails because of some Exception, the Connection tester may set this Exception as the * zero-th element of the array to provide information about why and how the test failed.

*/ public abstract class AbstractConnectionTester implements UnifiedConnectionTester { /** * Override, but remember that preferredTestQuery and rootCauseOutParamHolder * can be null. */ public abstract int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder); /** * Override, but remember that preferredTestQuery and rootCauseOutParamHolder * can be null. */ public abstract int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder); //usually just leave the rest of these as-is public int activeCheckConnection(Connection c) { return activeCheckConnection( c, null, null); } public int activeCheckConnection(Connection c, Throwable[] rootCauseOutParamHolder) { return activeCheckConnection( c, null, rootCauseOutParamHolder); } public int activeCheckConnection(Connection c, String preferredTestQuery) { return activeCheckConnection( c, preferredTestQuery, null); } public int statusOnException(Connection c, Throwable t) { return statusOnException( c, t, null, null); } public int statusOnException(Connection c, Throwable t, Throwable[] rootCauseOutParamHolder) { return statusOnException( c, t, null, rootCauseOutParamHolder); } public int statusOnException(Connection c, Throwable t, String preferredTestQuery) { return statusOnException( c, t, preferredTestQuery, null); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/C3P0ProxyConnection.java0000644000175000017500000000763510624366530023603 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; import java.sql.SQLException; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; /** *

Most clients need never use or know about this interface -- c3p0-provided Connections * can be treated like any other Connection.

* *

An interface implemented by proxy Connections returned * by c3p0 PooledDataSources. It provides protected access to the underlying * dbms-vendor specific Connection, which may be useful if you want to * access non-standard API offered by your jdbc driver. */ public interface C3P0ProxyConnection extends Connection { /** * A token representing an unwrapped, unproxied jdbc Connection * for use in {@link #rawConnectionOperation} */ public final static Object RAW_CONNECTION = new Object(); /** *

Allows one to work with the unproxied, raw Connection. Some * database companies never got over the "common interfaces mean * no more vendor lock-in!" thing, and offer non-standard API * on their Connections. This method permits you to "pierce" the * connection-pooling layer to call non-standard methods on the * original Connection, or to pass the original Connections to * functions that are not implementation neutral.

* *

To use this functionality, you'll need to cast a Connection * retrieved from a c3p0 PooledDataSource to a * C3P0ProxyConnection.

* *

This method works by making a reflective call of method m on * Object target (which may be null for static methods), passing * and argument list args. For the method target, or for any argument, * you may substitute the special token C3P0ProxyConnection.RAW_CONNECTION

* *

Any Statements or ResultSets returned by the operation will be proxied * and c3p0-managed, meaning that these resources will be automatically closed * if the user does not close them first when this Connection is checked back * into the pool. Any other resources returned by the operation are the user's * responsibility to clean up!

* *

Incautious use of this method can corrupt the Connection pool, by breaking the invariant * that all checked-in Connections should be equivalent. If your vendor supplies API * that allows you to modify the state or configuration of a Connection in some nonstandard way, * you might use this method to do so, and then check the Connection back into the pool. * When you fetch another Connection from the PooledDataSource, it will be undefined * whether the Connection returned will have your altered configuration, or the default * configuration of a "fresh" Connection. Thus, it is inadvisable to use this method to call * nonstandard mutators. */ public Object rawConnectionOperation(Method m, Object target, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException; }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/C3P0ProxyStatement.java0000644000175000017500000001006710624366527023447 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Statement; import java.sql.SQLException; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; /** *

Most clients need never use or know about this interface -- c3p0-provided Statements * can be treated like any other Statement.

* *

An interface implemented by proxy Connections returned * by c3p0 PooledDataSources. It provides protected access to the underlying * dbms-vendor specific Connection, which may be useful if you want to * access non-standard API offered by your jdbc driver. */ public interface C3P0ProxyStatement extends Statement { /** * A token representing an unwrapped, unproxied jdbc Connection * for use in {@link #rawStatementOperation} */ public final static Object RAW_STATEMENT = new Object(); /** *

Allows one to work with the unproxied, raw vendor-provided Statement . Some * database companies never got over the "common interfaces mean * no more vendor lock-in!" thing, and offer non-standard API * on their Statements. This method permits you to "pierce" the * connection-pooling layer to call non-standard methods on the * original Statement, or to pass the original Statement to * functions that are not implementation neutral.

* *

To use this functionality, you'll need to cast a Statement * retrieved from a c3p0-provided Connection to a * C3P0ProxyStatement.

* *

This method works by making a reflective call of method m on * Object target (which may be null for static methods), passing * and argument list args. For the method target, or for any argument, * you may substitute the special token C3P0ProxyStatement.RAW_STATEMENT

* *

Any ResultSets returned by the operation will be proxied * and c3p0-managed, meaning that these resources will be automatically closed * if the user does not close them first when this Statement is closed or checked * into the statement cache. Any other resources returned by the operation are the user's * responsibility to clean up!

* *

If you have turned statement pooling on, incautious use of this method can corrupt the * PreparedStatement cache, by breaking the invariant * that all cached PreparedStatements should be equivalent to a PreparedStatement newly created * with the same arguments to prepareStatement(...) or prepareCall(...). If your vendor supplies API * that allows you to modify the state or configuration of a Statement in some nonstandard way, * and you do not undo this modification prior to closing the Statement or the Connection that * prepared it, future preparers of the same Statement may or may not see your modification, * depending on your use of the cache. Thus, it is inadvisable to use this method to call * nonstandard mutators on PreparedStatements if statement pooling is turned on.. */ public Object rawStatementOperation(Method m, Object target, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/C3P0Registry.java0000644000175000017500000003146110624366527022252 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.util.*; import com.mchange.v2.coalesce.*; import com.mchange.v2.log.*; import com.mchange.v2.c3p0.cfg.C3P0ConfigUtils; import com.mchange.v2.c3p0.impl.*; import java.sql.SQLException; import com.mchange.v2.c3p0.impl.IdentityTokenized; import com.mchange.v2.c3p0.subst.C3P0Substitutions; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.util.DoubleWeakHashMap; import com.mchange.v2.c3p0.management.*; /* * The primary purpose of C3P0Registry is to maintain a mapping of "identityTokens" * to c3p0 DataSources so that if the same DataSource is looked up (and deserialized * or dereferenced) via JNDI, c3p0 can ensure that the same instance is always returned. * But there are subtle issues here. If C3P0Registry maintains hard references to * DataSources, then they can never be garbage collected. But if c3p0 retains only * weak references, then applications that look up DataSources, then dereference them, * and then re-look them up again (not a great idea, but not uncommon) might see * distinct DataSources over multiple lookups. * * C3P0 resolves this issue has followed: At first creation or lookup of a PooledDataSource, * c3p0 creates a hard reference to that DataSource. So long as the DataSource has not * been close()ed or DataSources.destroy()ed, subsequent lookups will consistently * return the same DataSource. If the DataSource is never closed, then there is a potential * memory leak (as well as the potential Thread leak and Connection leak). But if * the DataSource is close()ed, only weak refernces to the DataSource will be retained. * A lookup of a DataSource after it has been close()ed within the current VM may * return the previously close()ed instance, or may return a fresh instance, depending * on whether the weak reference has been cleared. In other words, the result of * looking up a DataSource after having close()ed it in the current VM is undefined. * * Note that unpooled c3p0 DataSources are always held by weak references, since * they are never explicitly close()ed. The result of looking up an unpooled DataSource, * modifying it, dereferencing it, and then relooking up is therefore undefined as well. * * These issues are mostly academic. Under normal use scenarios, how c3p0 deals with * maintaining its registry doesn't much matter. In the past, c3p0 maintained hard * references to DataSources indefinitely. At least one user ran into side effects * of the unwanted retention of old DataSources (in a process left to run for months * at a time, and frequently reconstructing multiple DataSources), so now we take care * to ensure that when users properly close() and dereference DataSources, they can * indeed be garbage collected. */ public final class C3P0Registry { private final static String MC_PARAM = "com.mchange.v2.c3p0.management.ManagementCoordinator"; //MT: thread-safe final static MLogger logger = MLog.getLogger( C3P0Registry.class ); //MT: protected by class' lock static boolean banner_printed = false; //MT: protected by class' lock static boolean registry_mbean_registered = false; //MT: thread-safe, immutable private static CoalesceChecker CC = IdentityTokenizedCoalesceChecker.INSTANCE; //MT: protected by class' lock //a weak, unsynchronized coalescer private static Coalescer idtCoalescer = CoalescerFactory.createCoalescer(CC, true , false); //MT: protected by class' lock private static Map tokensToTokenized = new DoubleWeakHashMap(); //MT: protected by class' lock private static HashSet unclosedPooledDataSources = new HashSet(); //MT: protected by its own lock private static Map classNamesToConnectionTesters = Collections.synchronizedMap( new HashMap() ); //MT: protected by its own lock private static Map classNamesToConnectionCustomizers = Collections.synchronizedMap( new HashMap() ); private static ManagementCoordinator mc; static { classNamesToConnectionTesters.put(C3P0Defaults.connectionTesterClassName(), C3P0Defaults.connectionTester()); String userManagementCoordinator = C3P0ConfigUtils.getPropFileConfigProperty(MC_PARAM); if (userManagementCoordinator != null) { try { mc = (ManagementCoordinator) Class.forName(userManagementCoordinator).newInstance(); } catch (Exception e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Could not instantiate user-specified ManagementCoordinator " + userManagementCoordinator + ". Using NullManagementCoordinator (c3p0 JMX management disabled!)", e ); mc = new NullManagementCoordinator(); } } else { try { Class.forName("java.lang.management.ManagementFactory"); mc = (ManagementCoordinator) Class.forName( "com.mchange.v2.c3p0.management.ActiveManagementCoordinator" ).newInstance(); } catch (Exception e) { if ( logger.isLoggable( MLevel.INFO ) ) logger.log( MLevel.INFO, "jdk1.5 management interfaces unavailable... JMX support disabled.", e); mc = new NullManagementCoordinator(); } } } public static ConnectionTester getConnectionTester( String className ) { try { ConnectionTester out = (ConnectionTester) classNamesToConnectionTesters.get( className ); if (out == null) { out = (ConnectionTester) Class.forName( className ).newInstance(); classNamesToConnectionTesters.put( className, out ); } return out; } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Could not create for find ConnectionTester with class name '" + className + "'. Using default.", e ); return C3P0Defaults.connectionTester(); } } public static ConnectionCustomizer getConnectionCustomizer( String className ) throws SQLException { if ( className == null ) return null; else { try { ConnectionCustomizer out = (ConnectionCustomizer) classNamesToConnectionCustomizers.get( className ); if (out == null) { out = (ConnectionCustomizer) Class.forName( className ).newInstance(); classNamesToConnectionCustomizers.put( className, out ); } return out; } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Could not create for find ConnectionCustomizer with class name '" + className + "'.", e ); throw SqlUtils.toSQLException( e ); } } } // must be called from a static sync'ed method private static void banner() { if (! banner_printed ) { if (logger.isLoggable( MLevel.INFO ) ) logger.info("Initializing c3p0-" + C3P0Substitutions.VERSION + " [built " + C3P0Substitutions.TIMESTAMP + "; debug? " + C3P0Substitutions.DEBUG + "; trace: " + C3P0Substitutions.TRACE +']'); banner_printed = true; } } // must be called from a static, sync'ed method private static void attemptRegisterRegistryMBean() { if (! registry_mbean_registered) { mc.attemptManageC3P0Registry(); registry_mbean_registered = true; } } // must be called with class' lock private static boolean isIncorporated( IdentityTokenized idt ) { return tokensToTokenized.keySet().contains( idt.getIdentityToken() ); } // must be called with class' lock private static void incorporate( IdentityTokenized idt ) { tokensToTokenized.put( idt.getIdentityToken(), idt ); if (idt instanceof PooledDataSource) { unclosedPooledDataSources.add( idt ); mc.attemptManagePooledDataSource( (PooledDataSource) idt ); } } public static synchronized IdentityTokenized reregister(IdentityTokenized idt) { if (idt instanceof PooledDataSource) { banner(); attemptRegisterRegistryMBean(); } if (idt.getIdentityToken() == null) throw new RuntimeException("[c3p0 issue] The identityToken of a registered object should be set prior to registration."); IdentityTokenized coalesceCheck = (IdentityTokenized) idtCoalescer.coalesce(idt); if (! isIncorporated( coalesceCheck )) incorporate( coalesceCheck ); return coalesceCheck; } public static synchronized void markClosed(PooledDataSource pds) { unclosedPooledDataSources.remove(pds); mc.attemptUnmanagePooledDataSource( pds ); if (unclosedPooledDataSources.isEmpty()) { mc.attemptUnmanageC3P0Registry(); registry_mbean_registered = false; } } public synchronized static Set getPooledDataSources() { return (Set) unclosedPooledDataSources.clone(); } public synchronized static Set pooledDataSourcesByName( String dataSourceName ) { Set out = new HashSet(); for (Iterator ii = unclosedPooledDataSources.iterator(); ii.hasNext(); ) { PooledDataSource pds = (PooledDataSource) ii.next(); if ( pds.getDataSourceName().equals( dataSourceName ) ) out.add( pds ); } return out; } public synchronized static PooledDataSource pooledDataSourceByName( String dataSourceName ) { for (Iterator ii = unclosedPooledDataSources.iterator(); ii.hasNext(); ) { PooledDataSource pds = (PooledDataSource) ii.next(); if ( pds.getDataSourceName().equals( dataSourceName ) ) return pds; } return null; } public synchronized static Set allIdentityTokens() { Set out = Collections.unmodifiableSet( tokensToTokenized.keySet() ); //System.err.println( "allIdentityTokens(): " + out ); return out; } public synchronized static Set allIdentityTokenized() { HashSet out = new HashSet(); out.addAll( tokensToTokenized.values() ); //System.err.println( "allIdentityTokenized(): " + out ); return Collections.unmodifiableSet( out ); } public synchronized static Set allPooledDataSources() { Set out = Collections.unmodifiableSet( unclosedPooledDataSources ); //System.err.println( "allPooledDataSources(): " + out ); return out; } public synchronized static int getNumPooledDataSources() { return unclosedPooledDataSources.size(); } public synchronized static int getNumPoolsAllDataSources() throws SQLException { int count = 0; for (Iterator ii = unclosedPooledDataSources.iterator(); ii.hasNext();) { PooledDataSource pds = (PooledDataSource) ii.next(); count += pds.getNumUserPools(); } return count; } public synchronized int getNumThreadsAllThreadPools() throws SQLException { int count = 0; for (Iterator ii = unclosedPooledDataSources.iterator(); ii.hasNext();) { PooledDataSource pds = (PooledDataSource) ii.next(); count += pds.getNumHelperThreads(); } return count; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/ComboPooledDataSource.java0000644000175000017500000005723210624366527024235 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.beans.*; import java.io.*; import java.sql.*; import java.util.*; import javax.naming.*; import com.mchange.v2.log.*; import com.mchange.v2.naming.*; import com.mchange.v2.c3p0.impl.*; import javax.sql.DataSource; import com.mchange.v2.beans.BeansUtils; import com.mchange.v2.c3p0.cfg.C3P0Config; /** *

For the meaning of most of these properties, please see c3p0's top-level documentation!

*/ public final class ComboPooledDataSource extends AbstractPoolBackedDataSource implements PooledDataSource, Serializable, Referenceable { final static MLogger logger = MLog.getLogger( ComboPooledDataSource.class ); final static Set TO_STRING_IGNORE_PROPS = new HashSet( Arrays.asList( new String[] { "connection", "lastAcquisitionFailureDefaultUser", "lastCheckinFailureDefaultUser", "lastCheckoutFailureDefaultUser", "lastConnectionTestFailureDefaultUser", "lastIdleTestFailureDefaultUser", "logWriter", "loginTimeout", "numBusyConnections", "numBusyConnectionsAllUsers", "numBusyConnectionsDefaultUser", "numConnections", "numConnectionsAllUsers", "numConnectionsDefaultUser", "numFailedCheckinsDefaultUser", "numFailedCheckoutsDefaultUser", "numFailedIdleTestsDefaultUser", "numIdleConnections", "numIdleConnectionsAllUsers", "numIdleConnectionsDefaultUser", "numUnclosedOrphanedConnections", "numUnclosedOrphanedConnectionsAllUsers", "numUnclosedOrphanedConnectionsDefaultUser", "numUserPools", "effectivePropertyCycleDefaultUser", "startTimeMillisDefaultUser", "statementCacheNumCheckedOutDefaultUser", "statementCacheNumCheckedOutStatementsAllUsers", "statementCacheNumConnectionsWithCachedStatementsAllUsers", "statementCacheNumConnectionsWithCachedStatementsDefaultUser", "statementCacheNumStatementsAllUsers", "statementCacheNumStatementsDefaultUser", "threadPoolSize", "threadPoolNumActiveThreads", "threadPoolNumIdleThreads", "threadPoolNumTasksPending", "threadPoolStackTraces", "threadPoolStatus", "overrideDefaultUser", "overrideDefaultPassword", "password", "reference", "upTimeMillisDefaultUser", "user", "userOverridesAsString", "allUsers", "connectionPoolDataSource" } ) ); // not reassigned post-ctor; mutable elements protected by their own locks // when (very rarely) necessery, we sync this -> wcpds -> dmds // note that serialization of these guys happens via out superclass // we just have to make sure they get properly reset on deserialization transient DriverManagerDataSource dmds; transient WrapperConnectionPoolDataSource wcpds; public ComboPooledDataSource() { this( true ); } public ComboPooledDataSource( boolean autoregister ) { super( autoregister ); // System.err.println("...Initializing ComboPooledDataSource."); dmds = new DriverManagerDataSource(); wcpds = new WrapperConnectionPoolDataSource(); wcpds.setNestedDataSource( dmds ); try { this.setConnectionPoolDataSource( wcpds ); } catch (PropertyVetoException e) { logger.log(MLevel.WARNING, "Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet!", e); throw new RuntimeException("Hunh??? This can't happen. We haven't set up any listeners to veto the property change yet! " + e); } // set things up in case there are future changes to our ConnectionPoolDataSource // setUpPropertyEvents(); } private void setUpPropertyEvents() { VetoableChangeListener wcpdsConsistencyEnforcer = new VetoableChangeListener() { // always called within synchronized mutators of the parent class... needn't explicitly sync here public void vetoableChange( PropertyChangeEvent evt ) throws PropertyVetoException { String propName = evt.getPropertyName(); Object val = evt.getNewValue(); if ( "connectionPoolDataSource".equals( propName ) ) { if (val instanceof WrapperConnectionPoolDataSource) { DataSource nested = (DataSource) ((WrapperConnectionPoolDataSource)val).getNestedDataSource(); if (! (nested instanceof DriverManagerDataSource) ) throw new PropertyVetoException("ComboPooledDataSource requires that its unpooled DataSource " + " be set at all times, and that it be a" + " com.mchange.v2.c3p0.DriverManagerDataSource. Bad: " + nested, evt); } else throw new PropertyVetoException("ComboPooledDataSource requires that its ConnectionPoolDataSource " + " be set at all times, and that it be a" + " com.mchange.v2.c3p0.WrapperConnectionPoolDataSource. Bad: " + val, evt); } } }; this.addVetoableChangeListener( wcpdsConsistencyEnforcer ); PropertyChangeListener wcpdsStateUpdater = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { updateLocalVarsFromCpdsProp(); } }; this.addPropertyChangeListener( wcpdsStateUpdater ); } private void updateLocalVarsFromCpdsProp() { this.wcpds = (WrapperConnectionPoolDataSource) this.getConnectionPoolDataSource(); this.dmds = (DriverManagerDataSource) wcpds.getNestedDataSource(); } public ComboPooledDataSource(String configName) { this(); initializeNamedConfig( configName ); } // // workaround sun big id #6342411 (in which reflective // // access to a public method of a non-public class fails, // // even if the non-public class is accessed via a public // // subclass) // public String getDataSourceName() // { return super.getDataSourceName(); } // DriverManagerDataSourceProperties (count: 4) public String getDescription() { return dmds.getDescription(); } public void setDescription( String description ) { dmds.setDescription( description ); } public String getDriverClass() { return dmds.getDriverClass(); } public void setDriverClass( String driverClass ) throws PropertyVetoException { dmds.setDriverClass( driverClass ); // System.err.println("setting driverClass: " + driverClass); } public String getJdbcUrl() { // System.err.println("getting jdbcUrl: " + dmds.getJdbcUrl()); return dmds.getJdbcUrl(); } public void setJdbcUrl( String jdbcUrl ) { dmds.setJdbcUrl( jdbcUrl ); this.resetPoolManager( false ); // System.err.println("setting jdbcUrl: " + jdbcUrl + " [dmds@" + C3P0ImplUtils.identityToken( dmds ) + "]"); // if (jdbcUrl == null) // new Exception("*** NULL SETTER ***").printStackTrace(); } public Properties getProperties() { //System.err.println("getting properties: " + dmds.getProperties()); return dmds.getProperties(); } public void setProperties( Properties properties ) { //System.err.println("setting properties: " + properties); dmds.setProperties( properties ); this.resetPoolManager(false); } // DriverManagerDataSource "virtual properties" based on properties public String getUser() { return dmds.getUser(); } public void setUser( String user ) { dmds.setUser( user ); this.resetPoolManager( false ); } public String getPassword() { return dmds.getPassword(); } public void setPassword( String password ) { dmds.setPassword( password ); this.resetPoolManager( false ); } // WrapperConnectionPoolDataSource properties public int getCheckoutTimeout() { return wcpds.getCheckoutTimeout(); } public void setCheckoutTimeout( int checkoutTimeout ) { wcpds.setCheckoutTimeout( checkoutTimeout ); this.resetPoolManager( false ); } public int getAcquireIncrement() { return wcpds.getAcquireIncrement(); } public void setAcquireIncrement( int acquireIncrement ) { wcpds.setAcquireIncrement( acquireIncrement ); this.resetPoolManager( false ); } public int getAcquireRetryAttempts() { return wcpds.getAcquireRetryAttempts(); } public void setAcquireRetryAttempts( int acquireRetryAttempts ) { wcpds.setAcquireRetryAttempts( acquireRetryAttempts ); this.resetPoolManager( false ); } public int getAcquireRetryDelay() { return wcpds.getAcquireRetryDelay(); } public void setAcquireRetryDelay( int acquireRetryDelay ) { wcpds.setAcquireRetryDelay( acquireRetryDelay ); this.resetPoolManager( false ); } public boolean isAutoCommitOnClose() { return wcpds.isAutoCommitOnClose(); } public void setAutoCommitOnClose( boolean autoCommitOnClose ) { wcpds.setAutoCommitOnClose( autoCommitOnClose ); this.resetPoolManager( false ); } public String getConnectionTesterClassName() { return wcpds.getConnectionTesterClassName(); } public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException { wcpds.setConnectionTesterClassName( connectionTesterClassName ); this.resetPoolManager( false ); } public String getAutomaticTestTable() { return wcpds.getAutomaticTestTable(); } public void setAutomaticTestTable( String automaticTestTable ) { wcpds.setAutomaticTestTable( automaticTestTable ); this.resetPoolManager( false ); } public boolean isForceIgnoreUnresolvedTransactions() { return wcpds.isForceIgnoreUnresolvedTransactions(); } public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) { wcpds.setForceIgnoreUnresolvedTransactions( forceIgnoreUnresolvedTransactions ); this.resetPoolManager( false ); } public int getIdleConnectionTestPeriod() { return wcpds.getIdleConnectionTestPeriod(); } public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) { wcpds.setIdleConnectionTestPeriod( idleConnectionTestPeriod ); this.resetPoolManager( false ); } public int getInitialPoolSize() { return wcpds.getInitialPoolSize(); } public void setInitialPoolSize( int initialPoolSize ) { wcpds.setInitialPoolSize( initialPoolSize ); this.resetPoolManager( false ); } public int getMaxIdleTime() { return wcpds.getMaxIdleTime(); } public void setMaxIdleTime( int maxIdleTime ) { wcpds.setMaxIdleTime( maxIdleTime ); this.resetPoolManager( false ); } public int getMaxPoolSize() { return wcpds.getMaxPoolSize(); } public void setMaxPoolSize( int maxPoolSize ) { wcpds.setMaxPoolSize( maxPoolSize ); this.resetPoolManager( false ); } public int getMaxStatements() { return wcpds.getMaxStatements(); } public void setMaxStatements( int maxStatements ) { wcpds.setMaxStatements( maxStatements ); this.resetPoolManager( false ); } public int getMaxStatementsPerConnection() { return wcpds.getMaxStatementsPerConnection(); } public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) { wcpds.setMaxStatementsPerConnection( maxStatementsPerConnection ); this.resetPoolManager( false ); } public int getMinPoolSize() { return wcpds.getMinPoolSize(); } public void setMinPoolSize( int minPoolSize ) { wcpds.setMinPoolSize( minPoolSize ); this.resetPoolManager( false ); } public String getOverrideDefaultUser() { return wcpds.getOverrideDefaultUser(); } public void setOverrideDefaultUser(String overrideDefaultUser) { wcpds.setOverrideDefaultUser( overrideDefaultUser ); this.resetPoolManager( false ); } public String getOverrideDefaultPassword() { return wcpds.getOverrideDefaultPassword(); } public void setOverrideDefaultPassword(String overrideDefaultPassword) { wcpds.setOverrideDefaultPassword( overrideDefaultPassword ); this.resetPoolManager( false ); } public int getPropertyCycle() { return wcpds.getPropertyCycle(); } public void setPropertyCycle( int propertyCycle ) { wcpds.setPropertyCycle( propertyCycle ); this.resetPoolManager( false ); } public boolean isBreakAfterAcquireFailure() { return wcpds.isBreakAfterAcquireFailure(); } public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) { wcpds.setBreakAfterAcquireFailure( breakAfterAcquireFailure ); this.resetPoolManager( false ); } public boolean isTestConnectionOnCheckout() { return wcpds.isTestConnectionOnCheckout(); } public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) { wcpds.setTestConnectionOnCheckout( testConnectionOnCheckout ); this.resetPoolManager( false ); } public boolean isTestConnectionOnCheckin() { return wcpds.isTestConnectionOnCheckin(); } public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) { wcpds.setTestConnectionOnCheckin( testConnectionOnCheckin ); this.resetPoolManager( false ); } public boolean isUsesTraditionalReflectiveProxies() { return wcpds.isUsesTraditionalReflectiveProxies(); } public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) { wcpds.setUsesTraditionalReflectiveProxies( usesTraditionalReflectiveProxies ); this.resetPoolManager( false ); } public String getPreferredTestQuery() { return wcpds.getPreferredTestQuery(); } public void setPreferredTestQuery( String preferredTestQuery ) { wcpds.setPreferredTestQuery( preferredTestQuery ); this.resetPoolManager( false ); } public String getUserOverridesAsString() { return wcpds.getUserOverridesAsString(); } public void setUserOverridesAsString( String userOverridesAsString ) throws PropertyVetoException { wcpds.setUserOverridesAsString( userOverridesAsString ); this.resetPoolManager( false ); } public int getMaxAdministrativeTaskTime() { return wcpds.getMaxAdministrativeTaskTime(); } public void setMaxAdministrativeTaskTime( int maxAdministrativeTaskTime ) { wcpds.setMaxAdministrativeTaskTime( maxAdministrativeTaskTime ); this.resetPoolManager( false ); } public int getMaxIdleTimeExcessConnections() { return wcpds.getMaxIdleTimeExcessConnections(); } public void setMaxIdleTimeExcessConnections( int maxIdleTimeExcessConnections ) { wcpds.setMaxIdleTimeExcessConnections( maxIdleTimeExcessConnections ); this.resetPoolManager( false ); } public int getMaxConnectionAge() { return wcpds.getMaxConnectionAge(); } public void setMaxConnectionAge( int maxConnectionAge ) { wcpds.setMaxConnectionAge( maxConnectionAge ); this.resetPoolManager( false ); } public String getConnectionCustomizerClassName() { return wcpds.getConnectionCustomizerClassName(); } public void setConnectionCustomizerClassName( String connectionCustomizerClassName ) { wcpds.setConnectionCustomizerClassName( connectionCustomizerClassName ); this.resetPoolManager( false ); } public int getUnreturnedConnectionTimeout() { return wcpds.getUnreturnedConnectionTimeout(); } public void setUnreturnedConnectionTimeout(int unreturnedConnectionTimeout) { wcpds.setUnreturnedConnectionTimeout( unreturnedConnectionTimeout ); this.resetPoolManager( false ); } public boolean isDebugUnreturnedConnectionStackTraces() { return wcpds.isDebugUnreturnedConnectionStackTraces(); } public void setDebugUnreturnedConnectionStackTraces(boolean debugUnreturnedConnectionStackTraces) { wcpds.setDebugUnreturnedConnectionStackTraces( debugUnreturnedConnectionStackTraces ); this.resetPoolManager( false ); } // shared properties (count: 1) public String getFactoryClassLocation() { return super.getFactoryClassLocation(); } public void setFactoryClassLocation( String factoryClassLocation ) { dmds.setFactoryClassLocation( factoryClassLocation ); wcpds.setFactoryClassLocation( factoryClassLocation ); super.setFactoryClassLocation( factoryClassLocation ); } public String toString() { //System.err.println("ComboPooledDataSource.toString()"); StringBuffer sb = new StringBuffer(512); sb.append( this.getClass().getName() ); sb.append(" [ "); try { BeansUtils.appendPropNamesAndValues(sb, this, TO_STRING_IGNORE_PROPS); } catch (Exception e) { sb.append( e.toString() ); //e.printStackTrace(); } sb.append(" ]"); // Map userOverrides = wcpds.getUserOverrides(); // if (userOverrides != null) // sb.append("; userOverrides: " + userOverrides.toString()); return sb.toString(); } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: updateLocalVarsFromCpdsProp(); setUpPropertyEvents(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } } //now, referenceability happens exactly the same way it does for PoolBackedDataSource //all this stuff (and the maintenance hassle of it) should be unnecessary /* // WrapperConnectionPoolDataSource properties -- count: 28 // // ("checkoutTimeout"); // ("acquireIncrement"); // ("acquireRetryAttempts"); // ("acquireRetryDelay"); // ("autoCommitOnClose"); // ("connectionTesterClassName"); // ("forceIgnoreUnresolvedTransactions"); // ("idleConnectionTestPeriod"); // ("initialPoolSize"); // ("maxIdleTime"); // ("maxPoolSize"); // ("maxStatements"); // ("maxStatementsPerConnection"); // ("minPoolSize"); // ("propertyCycle"); // ("breakAfterAcquireFailure"); // ("testConnectionOnCheckout"); // ("testConnectionOnCheckin"); // ("usesTraditionalReflectiveProxies"); // ("preferredTestQuery"); // ("automaticTestTable"); // ("userOverridesAsString"); // ("overrideDefaultUser"); // ("overrideDefaultPassword"); // ("maxAdministrativeTaskTime"); // ("maxIdleTimeExcessConnections"); // ("maxConnectionAge"); // ("connectionTesterClassName"); final static JavaBeanReferenceMaker referenceMaker = new JavaBeanReferenceMaker(); static { referenceMaker.setFactoryClassName( C3P0JavaBeanObjectFactory.class.getName() ); // DriverManagerDataSource properties (count: 4) referenceMaker.addReferenceProperty("description"); referenceMaker.addReferenceProperty("driverClass"); referenceMaker.addReferenceProperty("jdbcUrl"); referenceMaker.addReferenceProperty("properties"); // WrapperConnectionPoolDataSource properties (count: 27) referenceMaker.addReferenceProperty("checkoutTimeout"); referenceMaker.addReferenceProperty("acquireIncrement"); referenceMaker.addReferenceProperty("acquireRetryAttempts"); referenceMaker.addReferenceProperty("acquireRetryDelay"); referenceMaker.addReferenceProperty("autoCommitOnClose"); referenceMaker.addReferenceProperty("connectionTesterClassName"); referenceMaker.addReferenceProperty("forceIgnoreUnresolvedTransactions"); referenceMaker.addReferenceProperty("idleConnectionTestPeriod"); referenceMaker.addReferenceProperty("initialPoolSize"); referenceMaker.addReferenceProperty("maxIdleTime"); referenceMaker.addReferenceProperty("maxPoolSize"); referenceMaker.addReferenceProperty("maxStatements"); referenceMaker.addReferenceProperty("maxStatementsPerConnection"); referenceMaker.addReferenceProperty("minPoolSize"); referenceMaker.addReferenceProperty("propertyCycle"); referenceMaker.addReferenceProperty("breakAfterAcquireFailure"); referenceMaker.addReferenceProperty("testConnectionOnCheckout"); referenceMaker.addReferenceProperty("testConnectionOnCheckin"); referenceMaker.addReferenceProperty("usesTraditionalReflectiveProxies"); referenceMaker.addReferenceProperty("preferredTestQuery"); referenceMaker.addReferenceProperty("automaticTestTable"); referenceMaker.addReferenceProperty("userOverridesAsString"); referenceMaker.addReferenceProperty("overrideDefaultUser"); referenceMaker.addReferenceProperty("overrideDefaultPassword"); referenceMaker.addReferenceProperty("maxAdministrativeTaskTime"); referenceMaker.addReferenceProperty("maxIdleTimeExcessConnections"); referenceMaker.addReferenceProperty("maxConnectionAge"); // PoolBackedDataSource properties (count: 2) referenceMaker.addReferenceProperty("dataSourceName"); referenceMaker.addReferenceProperty("numHelperThreads"); // identity token referenceMaker.addReferenceProperty("identityToken"); // shared properties (count: 1) referenceMaker.addReferenceProperty("factoryClassLocation"); } public Reference getReference() throws NamingException { synchronized ( this ) { synchronized ( wcpds ) { synchronized( dmds ) { //System.err.println("ComboPooledDataSource.getReference()!!!!"); //new Exception("PRINT-STACK-TRACE").printStackTrace(); //javax.naming.Reference out = referenceMaker.createReference( this ); //System.err.println(out); //return out; return referenceMaker.createReference( this ); } } } } */ c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/ConnectionCustomizer.java0000644000175000017500000000531010624366527024232 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; import java.sql.SQLException; /** *

Implementations of this interface should * be immutable, and should offer public, * no argument constructors.

* *

The methods are handed raw, physical * database Connections, not c3p0-generated * proxies.

* *

Although c3p0 will ensure this with * respect to state controlled by * standard JDBC methods, any modifications * of vendor-specific state shold be made * consistently so that all Connections * in the pool are interchangable.

*/ public interface ConnectionCustomizer { /** *

Called immediately after a * Connection is acquired from the * underlying database for * incorporation into the pool.

* *

This method is only called once * per Connection. If standard JDBC * Connection properties are modified * [holdability, transactionIsolation, * readOnly], those modifications * will override defaults throughout * the Connection's tenure in the * pool.

*/ public void onAcquire( Connection c, String parentDataSourceIdentityToken ) throws Exception; /** * Called immediately before a * Connection is destroyed after * being removed from the pool. */ public void onDestroy( Connection c, String parentDataSourceIdentityToken ) throws Exception; /** * Called immediately before a * Connection is made available to * a client upon checkout. */ public void onCheckOut( Connection c, String parentDataSourceIdentityToken ) throws Exception; /** * Called immediately after a * Connection is checked in, * prior to reincorporation * into the pool. */ public void onCheckIn( Connection c, String parentDataSourceIdentityToken ) throws Exception; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/ConnectionTester.java0000644000175000017500000000424510624366530023334 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.io.Serializable; import java.sql.Connection; /** *

Define your own Connection tester if you want to * override c3p0's default behavior for testing the validity * of Connections and responding to Connection errors encountered.

* *

Recommended: If you'd like your ConnectionTester * to support the user-configured preferredTestQuery * parameter, please implement {@link com.mchange.v2.c3p0.UnifiedConnectionTester}. * *

ConnectionTesters should be Serializable, immutable, * and must have public, no-arg constructors.

* * @see com.mchange.v2.c3p0.UnifiedConnectionTester * @see com.mchange.v2.c3p0.AbstractConnectionTester */ public interface ConnectionTester extends Serializable { public final static int CONNECTION_IS_OKAY = 0; public final static int CONNECTION_IS_INVALID = -1; public final static int DATABASE_IS_INVALID = -8; public int activeCheckConnection(Connection c); public int statusOnException(Connection c, Throwable t); /** * Multiple testers that are of the same * class and use the same criteria for determining fatality * should test as equals(). */ public boolean equals( Object o ); /** * keep consistent with equals() */ public int hashCode(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/DataSources.java0000644000175000017500000003472110624366530022265 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import com.mchange.v2.log.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import java.sql.SQLException; import javax.sql.DataSource; import javax.sql.ConnectionPoolDataSource; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.beans.BeansUtils; /** *

A simple factory class for creating DataSources. Generally, users will call DataSources.unpooledDataSource() to get * a basic DataSource, and then get a pooled version by calling DataSources.pooledDataSource().

* *

Most users will not need to worry about configuration details. If you want to use a PreparedStatement cache, be sure to call * the version of DataSources.pooledDataSource() that accepts a statement_cache_size parameter, and set that to * be a number (much) greater than zero. (For maximum performance, you would set this to be several times the number kinds of * PreparedStatements you expect your application to use.)

* *

For those interested in detailed configuration, note that c3p0 pools can be configured by explicit method calls on PoolConfig objects, * by defining System properties, or by defining a c3p0.properties file in your resource path. See {@link com.mchange.v2.c3p0.PoolConfig} * for details.

* */ public final class DataSources { final static MLogger logger = MLog.getLogger( DataSources.class ); final static Set WRAPPER_CXN_POOL_DATA_SOURCE_OVERWRITE_PROPS; //22 -- includes factory class location final static Set POOL_BACKED_DATA_SOURCE_OVERWRITE_PROPS; //2 -- includes factory class location, excludes pool-owner id token static { // As of c3p0-0.9.1 // // This list is no longer updated, as the PoolConfig approach to setting up DataSources // is now deprecated. (This was getting to be hard to maintain as new config properties // were added.) String[] props = new String[] { "checkoutTimeout", //1 "acquireIncrement", //2 "acquireRetryAttempts", //3 "acquireRetryDelay", //4 "autoCommitOnClose", //5 "connectionTesterClassName", //6 "forceIgnoreUnresolvedTransactions", //7 "idleConnectionTestPeriod", //8 "initialPoolSize", //9 "maxIdleTime", //10 "maxPoolSize", //11 "maxStatements", //12 "maxStatementsPerConnection", //13 "minPoolSize", //14 "propertyCycle", //15 "breakAfterAcquireFailure", //16 "testConnectionOnCheckout", //17 "testConnectionOnCheckin", //18 "usesTraditionalReflectiveProxies", //19 "preferredTestQuery", //20 "automaticTestTable", //21 "factoryClassLocation" //22 }; WRAPPER_CXN_POOL_DATA_SOURCE_OVERWRITE_PROPS = Collections.unmodifiableSet( new HashSet( Arrays.asList( props ) ) ); // As of c3p0-0.9.1 // // This list is no longer updated, as the PoolConfig approach to setting up DataSources // is now deprecated. (This was getting to be hard to maintain as new config properties // were added.) props = new String[] { "numHelperThreads", "factoryClassLocation" }; POOL_BACKED_DATA_SOURCE_OVERWRITE_PROPS = Collections.unmodifiableSet( new HashSet( Arrays.asList( props ) ) ); } /** * Defines an unpooled DataSource all of whose paramateres (especially jdbcUrl) * should be set in config files. */ public static DataSource unpooledDataSource() throws SQLException { DriverManagerDataSource out = new DriverManagerDataSource(); return out; } public static DataSource unpooledDataSource(String jdbcUrl) throws SQLException { DriverManagerDataSource out = new DriverManagerDataSource(); out.setJdbcUrl( jdbcUrl ); return out; } /** * Defines an unpooled DataSource on the specified JDBC URL, authenticating with a username and password. */ public static DataSource unpooledDataSource(String jdbcUrl, String user, String password) throws SQLException { Properties props = new Properties(); props.put(SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user); props.put(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password); return unpooledDataSource( jdbcUrl, props ); } /** * Defines an unpooled DataSource on the specified JDBC URL. * * @param driverProps the usual DriverManager properties for your JDBC driver * (e.g. "user" and "password" for all drivers that support * authentication) * * @see java.sql.DriverManager */ public static DataSource unpooledDataSource(String jdbcUrl, Properties driverProps) throws SQLException { DriverManagerDataSource out = new DriverManagerDataSource(); out.setJdbcUrl( jdbcUrl ); out.setProperties( driverProps ); return out; } /** *

Creates a pooled version of an unpooled DataSource using default configuration information.

*

NOTE: By default, statement pooling is turned off, because for simple databases that do * not pre-parse and optimize PreparedStatements, statement caching is a net * performance loss. But if your database does optimize PreparedStatements * you'll want to turn StatementCaching on via {@link #pooledDataSource(javax.sql.DataSource, int)}.

* @return a DataSource that can be cast to a {@link PooledDataSource} if you are interested in pool statistics */ public static DataSource pooledDataSource( DataSource unpooledDataSource ) throws SQLException { return pooledDataSource( unpooledDataSource, null, (Map) null ); } /** *

Creates a pooled version of an unpooled DataSource using default configuration information * and the specified startement cache size. * Use a value greater than zero to turn statement caching on.

* * @return a DataSource that can be cast to a {@link PooledDataSource} if you are interested in pool statistics */ public static DataSource pooledDataSource( DataSource unpooledDataSource, int statement_cache_size ) throws SQLException { // PoolConfig pcfg = new PoolConfig(); // pcfg.setMaxStatements( statement_cache_size ); Map overrideProps = new HashMap(); overrideProps.put( "maxStatements", new Integer( statement_cache_size ) ); return pooledDataSource( unpooledDataSource, null, overrideProps ); } /** *

Creates a pooled version of an unpooled DataSource using configuration * information supplied explicitly by a {@link com.mchange.v2.c3p0.PoolConfig}. * * @return a DataSource that can be cast to a {@link PooledDataSource} if you are interested in pool statistics * * @deprecated if you want to set properties programmatically, please construct a ComboPooledDataSource and * set its properties rather than using PoolConfig */ public static DataSource pooledDataSource( DataSource unpooledDataSource, PoolConfig pcfg ) throws SQLException { try { WrapperConnectionPoolDataSource wcpds = new WrapperConnectionPoolDataSource(); wcpds.setNestedDataSource( unpooledDataSource ); // set PoolConfig info -- WrapperConnectionPoolDataSource properties BeansUtils.overwriteSpecificAccessibleProperties( pcfg, wcpds, WRAPPER_CXN_POOL_DATA_SOURCE_OVERWRITE_PROPS ); PoolBackedDataSource nascent_pbds = new PoolBackedDataSource(); nascent_pbds.setConnectionPoolDataSource( wcpds ); BeansUtils.overwriteSpecificAccessibleProperties( pcfg, nascent_pbds, POOL_BACKED_DATA_SOURCE_OVERWRITE_PROPS ); return nascent_pbds; } // catch ( PropertyVetoException e ) // { // e.printStackTrace(); // PropertyChangeEvent evt = e.getPropertyChangeEvent(); // throw new SQLException("Illegal value attempted for property " + evt.getPropertyName() + ": " + evt.getNewValue()); // } catch ( Exception e ) { //e.printStackTrace(); SQLException sqle = SqlUtils.toSQLException("Exception configuring pool-backed DataSource: " + e, e); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINE ) && e != sqle) logger.log( MLevel.FINE, "Converted exception to throwable SQLException", e ); throw sqle; } } /* public static DataSource pooledDataSource( DataSource unpooledDataSource, String overrideDefaultUser, String overrideDefaultPassword ) throws SQLException { Map overrideProps; if (overrideDefaultUser != null) { overrideProps = new HashMap(); overrideProps.put( "overrideDefaultUser", overrideDefaultUser ); overrideProps.put( "overrideDefaultPassword", overrideDefaultPassword ); } else overrideProps = null; return pooledDataSource( unpooledDataSource, null, overrideProps ); } */ public static DataSource pooledDataSource( DataSource unpooledDataSource, String configName ) throws SQLException { return pooledDataSource( unpooledDataSource, configName, null ); } public static DataSource pooledDataSource( DataSource unpooledDataSource, Map overrideProps ) throws SQLException { return pooledDataSource( unpooledDataSource, null, overrideProps ); } public static DataSource pooledDataSource( DataSource unpooledDataSource, String configName, Map overrideProps ) throws SQLException { try { WrapperConnectionPoolDataSource wcpds = new WrapperConnectionPoolDataSource(configName); wcpds.setNestedDataSource( unpooledDataSource ); if (overrideProps != null) BeansUtils.overwriteAccessiblePropertiesFromMap( overrideProps, wcpds, false, null, true, MLevel.WARNING, MLevel.WARNING, false); PoolBackedDataSource nascent_pbds = new PoolBackedDataSource(configName); nascent_pbds.setConnectionPoolDataSource( wcpds ); if (overrideProps != null) BeansUtils.overwriteAccessiblePropertiesFromMap( overrideProps, nascent_pbds, false, null, true, MLevel.WARNING, MLevel.WARNING, false); return nascent_pbds; } // catch ( PropertyVetoException e ) // { // e.printStackTrace(); // PropertyChangeEvent evt = e.getPropertyChangeEvent(); // throw new SQLException("Illegal value attempted for property " + evt.getPropertyName() + ": " + evt.getNewValue()); // } catch ( Exception e ) { //e.printStackTrace(); SQLException sqle = SqlUtils.toSQLException("Exception configuring pool-backed DataSource: " + e, e); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINE ) && e != sqle) logger.log( MLevel.FINE, "Converted exception to throwable SQLException", e ); throw sqle; } } /** *

Creates a pooled version of an unpooled DataSource using configuration * information supplied explicitly by a Java Properties object.

* * @return a DataSource that can be cast to a {@link PooledDataSource} if you are interested in pool statistics * @see com.mchange.v2.c3p0.PoolConfig */ public static DataSource pooledDataSource( DataSource unpooledDataSource, Properties props ) throws SQLException { //return pooledDataSource( unpooledDataSource, new PoolConfig( props ) ); Properties peeledProps = new Properties(); for (Iterator ii = props.keySet().iterator(); ii.hasNext(); ) { String propKey = (String) ii.next(); String propVal = props.getProperty( propKey ); String peeledKey = (propKey.startsWith("c3p0.") ? propKey.substring(5) : propKey ); peeledProps.put( peeledKey, propVal ); } return pooledDataSource( unpooledDataSource, null, peeledProps ); } /** *

Immediately releases resources (Threads and database Connections) that are * held by a C3P0 DataSource. * *

Only DataSources created by the poolingDataSource() method hold any * non-memory resources. Calling this method on unpooled DataSources is * effectively a no-op.

* *

You can safely presume that destroying a pooled DataSource that is wrapped around * another DataSource created by this library destroys both the outer and the wrapped * DataSource. There is no reason to hold a reference to a nested DataSource in order * to explicitly destroy it.

* * @see com.mchange.v2.c3p0.PoolConfig */ public static void destroy( DataSource pooledDataSource ) throws SQLException { destroy( pooledDataSource, false ); } /** * @deprecated forceDestroy() is no longer meaningful, as a set of pools is now * directly associated with a DataSource, and not potentially shared. * (This simplification was made possible by canonicalization of * JNDI-looked-up DataSources within a virtual machine.) Just use * DataSources.destroy(). * * @see #destroy */ public static void forceDestroy( DataSource pooledDataSource ) throws SQLException { destroy( pooledDataSource, true ); } private static void destroy( DataSource pooledDataSource, boolean force ) throws SQLException { if ( pooledDataSource instanceof PoolBackedDataSource) { ConnectionPoolDataSource cpds = ((PoolBackedDataSource) pooledDataSource).getConnectionPoolDataSource(); if (cpds instanceof WrapperConnectionPoolDataSource) destroy( ((WrapperConnectionPoolDataSource) cpds).getNestedDataSource(), force ); } if ( pooledDataSource instanceof PooledDataSource ) ((PooledDataSource) pooledDataSource).close( force ); } private DataSources() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/DriverManagerDataSource.java0000644000175000017500000002055510624366527024557 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.util.Properties; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.c3p0.cfg.C3P0Config; import com.mchange.v2.c3p0.impl.DriverManagerDataSourceBase; public final class DriverManagerDataSource extends DriverManagerDataSourceBase implements DataSource { final static MLogger logger = MLog.getLogger( DriverManagerDataSource.class ); //MT: protected by this' lock Driver driver; //MT: protected by this' lock boolean driver_class_loaded = false; public DriverManagerDataSource() { this( true ); } public DriverManagerDataSource(boolean autoregister) { super( autoregister ); setUpPropertyListeners(); String user = C3P0Config.initializeStringPropertyVar("user", null); String password = C3P0Config.initializeStringPropertyVar("password", null); if (user != null) this.setUser( user ); if (password != null) this.setPassword( password ); } private void setUpPropertyListeners() { PropertyChangeListener driverClassListener = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { if ( "driverClass".equals( evt.getPropertyName() ) ) setDriverClassLoaded( false ); } }; this.addPropertyChangeListener( driverClassListener ); } private synchronized boolean isDriverClassLoaded() { return driver_class_loaded; } private synchronized void setDriverClassLoaded(boolean dcl) { this.driver_class_loaded = dcl; } private void ensureDriverLoaded() throws SQLException { try { if (! isDriverClassLoaded()) { if (driverClass != null) Class.forName( driverClass ); setDriverClassLoaded( true ); } } catch (ClassNotFoundException e) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Could not load driverClass " + driverClass, e); } } // should NOT be sync'ed -- driver() is sync'ed and that's enough // sync'ing the method creates the danger that one freeze on connect // blocks access to the entire DataSource public Connection getConnection() throws SQLException { ensureDriverLoaded(); Connection out = driver().connect( jdbcUrl, properties ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } // should NOT be sync'ed -- driver() is sync'ed and that's enough // sync'ing the method creates the danger that one freeze on connect // blocks access to the entire DataSource public Connection getConnection(String username, String password) throws SQLException { ensureDriverLoaded(); Connection out = driver().connect( jdbcUrl, overrideProps(username, password) ); if (out == null) throw new SQLException("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + "driver [" + driver() + "]."); return out; } public PrintWriter getLogWriter() throws SQLException { return DriverManager.getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { DriverManager.setLogWriter( out ); } public int getLoginTimeout() throws SQLException { return DriverManager.getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { DriverManager.setLoginTimeout( seconds ); } //overrides public synchronized void setJdbcUrl(String jdbcUrl) { //System.err.println( "setJdbcUrl( " + jdbcUrl + " )"); //new Exception("DEBUG STACK TRACE").printStackTrace(); super.setJdbcUrl( jdbcUrl ); clearDriver(); } //"virtual properties" public synchronized void setUser(String user) { String oldUser = this.getUser(); if (! eqOrBothNull( user, oldUser )) { if (user != null) properties.put( SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user ); else properties.remove( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); pcs.firePropertyChange("user", oldUser, user); } } public synchronized String getUser() { // System.err.println("getUser() -- DriverManagerDataSource@" + System.identityHashCode( this ) + // " using Properties@" + System.identityHashCode( properties )); // new Exception("STACK TRACE DUMP").printStackTrace(); return properties.getProperty( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); } public synchronized void setPassword(String password) { String oldPass = this.getPassword(); if (! eqOrBothNull( password, oldPass )) { if (password != null) properties.put( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password ); else properties.remove( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); pcs.firePropertyChange("password", oldPass, password); } } public synchronized String getPassword() { return properties.getProperty( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); } private final Properties overrideProps(String user, String password) { Properties overriding = (Properties) properties.clone(); //we are relying on a defensive clone in our base class!!! if (user != null) overriding.put(SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user); else overriding.remove(SqlUtils.DRIVER_MANAGER_USER_PROPERTY); if (password != null) overriding.put(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password); else overriding.remove(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY); return overriding; } private synchronized Driver driver() throws SQLException { //System.err.println( "driver() <-- " + this ); if (driver == null) driver = DriverManager.getDriver( jdbcUrl ); return driver; } private synchronized void clearDriver() { driver = null; } private static boolean eqOrBothNull( Object a, Object b ) { return (a == b || (a != null && a.equals(b))); } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: setUpPropertyListeners(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/DriverManagerDataSourceFactory.java0000644000175000017500000001444510624366527026110 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.beans.PropertyChangeEvent; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; /** *

A static factory that creates DataSources which simply forward * calls to java.sql.DriverManager without any pooling or other fanciness.

* *

The DataSources returned are Refereneable and Serializable; they should * be suitable for placement in a wide variety of JNDI Naming Services.

* * @deprecated Use the new factories in {@link com.mchange.v2.c3p0.DataSources}. See examples. */ public final class DriverManagerDataSourceFactory { /** * Creates an unpooled DataSource that users java.sql.DriverManager * behind the scenes to acquire Connections. * * @param driverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param dfltUser a username (may be null) for authentication to the RDBMS * @param dfltPassword a password (may be null) for authentication to the RDBMS * @param refFactoryLoc a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. */ public static DataSource create(String driverClass, String jdbcUrl, String dfltUser, String dfltPassword, String refFactoryLoc) throws SQLException { DriverManagerDataSource out = new DriverManagerDataSource(); out.setDriverClass( driverClass ); out.setJdbcUrl( jdbcUrl ); out.setUser( dfltUser ); out.setPassword( dfltPassword ); out.setFactoryClassLocation( refFactoryLoc ); return out; } /** * Creates an unpooled DataSource that users java.sql.DriverManager * behind the scenes to acquire Connections. * * @param driverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param props propertis object that should be passed to DriverManager.getConnection() * @param refFactoryLoc a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. */ public static DataSource create(String driverClass, String jdbcUrl, Properties props, String refFactoryLoc) throws SQLException { DriverManagerDataSource out = new DriverManagerDataSource(); out.setDriverClass( driverClass ); out.setJdbcUrl( jdbcUrl ); out.setProperties( props ); out.setFactoryClassLocation( refFactoryLoc ); return out; } /** * Creates an unpooled DataSource that users java.sql.DriverManager * behind the scenes to acquire Connections. * * @param driverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param dfltUser a username (may be null) for authentication to the RDBMS * @param dfltPassword a password (may be null) for authentication to the RDBMS */ public static DataSource create(String driverClass, String jdbcUrl, String dfltUser, String dfltPassword) throws SQLException { return create( driverClass, jdbcUrl, dfltUser, dfltPassword, null ); } /** * Creates an unpooled DataSource that users java.sql.DriverManager * behind the scenes to acquire Connections. * * @param driverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. */ public static DataSource create(String driverClass, String jdbcUrl) throws SQLException { return DriverManagerDataSourceFactory.create( driverClass, jdbcUrl, (String) null, null); } /** * Creates an unpooled DataSource that users java.sql.DriverManager * behind the scenes to acquire Connections. * *

Warning: since you do not set the driver class, the resulting DataSource * will be less suitable for use via JNDI: JNDI clients will have to * know the driver class and make sure themselves that it is preloaded!!! * * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param dfltUser a username (may be null) for authentication to the RDBMS * @param dfltPassword a password (may be null) for authentication to the RDBMS */ public static DataSource create(String jdbcUrl, String dfltUser, String dfltPassword) throws SQLException { return DriverManagerDataSourceFactory.create( null, jdbcUrl, dfltUser, dfltPassword ); } /** * Creates an unpooled DataSource that users java.sql.DriverManager * behind the scenes to acquire Connections. * *

Warning: since you do not set the driver class, the resulting DataSource * will be less suitable for use via JNDI: JNDI clients will have to * know the driver class and make sure themselves that it is preloaded!!! * * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. */ public static DataSource create(String jdbcUrl) throws SQLException { return DriverManagerDataSourceFactory.create( null, jdbcUrl, (String) null, null ); } private DriverManagerDataSourceFactory() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/FullQueryConnectionTester.java0000644000175000017500000000207210624366527025207 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; public interface FullQueryConnectionTester extends QueryConnectionTester { public int statusOnException(Connection c, Throwable t, String preferredTestQuery); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/JndiRefConnectionPoolDataSource.java0000644000175000017500000002532110624366527026220 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import com.mchange.v2.c3p0.impl.*; import java.beans.PropertyVetoException; import java.io.PrintWriter; import java.io.Serializable; import java.sql.SQLException; import java.util.Arrays; import java.util.Collection; import java.util.Hashtable; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import javax.sql.ConnectionPoolDataSource; import javax.sql.PooledConnection; import com.mchange.v2.beans.BeansUtils; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.naming.JavaBeanReferenceMaker; import com.mchange.v2.naming.JavaBeanObjectFactory; import com.mchange.v2.naming.ReferenceMaker; public final class JndiRefConnectionPoolDataSource extends IdentityTokenResolvable implements ConnectionPoolDataSource, Serializable, Referenceable { final static MLogger logger = MLog.getLogger( JndiRefConnectionPoolDataSource.class ); final static Collection IGNORE_PROPS = Arrays.asList( new String[] {"reference", "pooledConnection"} ); JndiRefForwardingDataSource jrfds; WrapperConnectionPoolDataSource wcpds; String identityToken; public JndiRefConnectionPoolDataSource() { this( true ); } public JndiRefConnectionPoolDataSource( boolean autoregister ) { jrfds = new JndiRefForwardingDataSource(); wcpds = new WrapperConnectionPoolDataSource(); wcpds.setNestedDataSource( jrfds ); if (autoregister) { this.identityToken = C3P0ImplUtils.allocateIdentityToken( this ); C3P0Registry.reregister( this ); } } public boolean isJndiLookupCaching() { return jrfds.isCaching(); } public void setJndiLookupCaching( boolean caching ) { jrfds.setCaching( caching ); } public Hashtable getJndiEnv() { return jrfds.getJndiEnv(); } public void setJndiEnv( Hashtable jndiEnv ) { jrfds.setJndiEnv( jndiEnv ); } public Object getJndiName() { return jrfds.getJndiName(); } public void setJndiName( Object jndiName ) throws PropertyVetoException { jrfds.setJndiName( jndiName ); } public int getAcquireIncrement() { return wcpds.getAcquireIncrement(); } public void setAcquireIncrement( int acquireIncrement ) { wcpds.setAcquireIncrement( acquireIncrement ); } public int getAcquireRetryAttempts() { return wcpds.getAcquireRetryAttempts(); } public void setAcquireRetryAttempts( int ara ) { wcpds.setAcquireRetryAttempts( ara ); } public int getAcquireRetryDelay() { return wcpds.getAcquireRetryDelay(); } public void setAcquireRetryDelay( int ard ) { wcpds.setAcquireRetryDelay( ard ); } public boolean isAutoCommitOnClose() { return wcpds.isAutoCommitOnClose(); } public void setAutoCommitOnClose( boolean autoCommitOnClose ) { wcpds.setAutoCommitOnClose( autoCommitOnClose ); } public void setAutomaticTestTable( String att ) { wcpds.setAutomaticTestTable( att ); } public String getAutomaticTestTable() { return wcpds.getAutomaticTestTable(); } public void setBreakAfterAcquireFailure( boolean baaf ) { wcpds.setBreakAfterAcquireFailure( baaf ); } public boolean isBreakAfterAcquireFailure() { return wcpds.isBreakAfterAcquireFailure(); } public void setCheckoutTimeout( int ct ) { wcpds.setCheckoutTimeout( ct ); } public int getCheckoutTimeout() { return wcpds.getCheckoutTimeout(); } public String getConnectionTesterClassName() { return wcpds.getConnectionTesterClassName(); } public void setConnectionTesterClassName( String connectionTesterClassName ) throws PropertyVetoException { wcpds.setConnectionTesterClassName( connectionTesterClassName ); } public boolean isForceIgnoreUnresolvedTransactions() { return wcpds.isForceIgnoreUnresolvedTransactions(); } public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) { wcpds.setForceIgnoreUnresolvedTransactions( forceIgnoreUnresolvedTransactions ); } public String getIdentityToken() { return identityToken; } public void setIdentityToken(String identityToken) { this.identityToken = identityToken; } public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) { wcpds.setIdleConnectionTestPeriod( idleConnectionTestPeriod ); } public int getIdleConnectionTestPeriod() { return wcpds.getIdleConnectionTestPeriod(); } public int getInitialPoolSize() { return wcpds.getInitialPoolSize(); } public void setInitialPoolSize( int initialPoolSize ) { wcpds.setInitialPoolSize( initialPoolSize ); } public int getMaxIdleTime() { return wcpds.getMaxIdleTime(); } public void setMaxIdleTime( int maxIdleTime ) { wcpds.setMaxIdleTime( maxIdleTime ); } public int getMaxPoolSize() { return wcpds.getMaxPoolSize(); } public void setMaxPoolSize( int maxPoolSize ) { wcpds.setMaxPoolSize( maxPoolSize ); } public int getMaxStatements() { return wcpds.getMaxStatements(); } public void setMaxStatements( int maxStatements ) { wcpds.setMaxStatements( maxStatements ); } public int getMaxStatementsPerConnection() { return wcpds.getMaxStatementsPerConnection(); } public void setMaxStatementsPerConnection( int mspc ) { wcpds.setMaxStatementsPerConnection( mspc ); } public int getMinPoolSize() { return wcpds.getMinPoolSize(); } public void setMinPoolSize( int minPoolSize ) { wcpds.setMinPoolSize( minPoolSize ); } public String getPreferredTestQuery() { return wcpds.getPreferredTestQuery(); } public void setPreferredTestQuery( String ptq ) { wcpds.setPreferredTestQuery( ptq ); } public int getPropertyCycle() { return wcpds.getPropertyCycle(); } public void setPropertyCycle( int propertyCycle ) { wcpds.setPropertyCycle( propertyCycle ); } public boolean isTestConnectionOnCheckin() { return wcpds.isTestConnectionOnCheckin(); } public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) { wcpds.setTestConnectionOnCheckin( testConnectionOnCheckin ); } public boolean isTestConnectionOnCheckout() { return wcpds.isTestConnectionOnCheckout(); } public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) { wcpds.setTestConnectionOnCheckout( testConnectionOnCheckout ); } public boolean isUsesTraditionalReflectiveProxies() { return wcpds.isUsesTraditionalReflectiveProxies(); } public void setUsesTraditionalReflectiveProxies( boolean utrp ) { wcpds.setUsesTraditionalReflectiveProxies( utrp ); } public String getFactoryClassLocation() { return jrfds.getFactoryClassLocation(); } public void setFactoryClassLocation( String factoryClassLocation ) { jrfds.setFactoryClassLocation( factoryClassLocation ); wcpds.setFactoryClassLocation( factoryClassLocation ); } final static JavaBeanReferenceMaker referenceMaker = new JavaBeanReferenceMaker(); static { referenceMaker.setFactoryClassName( C3P0JavaBeanObjectFactory.class.getName() ); referenceMaker.addReferenceProperty("acquireIncrement"); referenceMaker.addReferenceProperty("acquireRetryAttempts"); referenceMaker.addReferenceProperty("acquireRetryDelay"); referenceMaker.addReferenceProperty("autoCommitOnClose"); referenceMaker.addReferenceProperty("automaticTestTable"); referenceMaker.addReferenceProperty("checkoutTimeout"); referenceMaker.addReferenceProperty("connectionTesterClassName"); referenceMaker.addReferenceProperty("factoryClassLocation"); referenceMaker.addReferenceProperty("forceIgnoreUnresolvedTransactions"); referenceMaker.addReferenceProperty("idleConnectionTestPeriod"); referenceMaker.addReferenceProperty("identityToken"); referenceMaker.addReferenceProperty("initialPoolSize"); referenceMaker.addReferenceProperty("jndiEnv"); referenceMaker.addReferenceProperty("jndiLookupCaching"); referenceMaker.addReferenceProperty("jndiName"); referenceMaker.addReferenceProperty("maxIdleTime"); referenceMaker.addReferenceProperty("maxPoolSize"); referenceMaker.addReferenceProperty("maxStatements"); referenceMaker.addReferenceProperty("maxStatementsPerConnection"); referenceMaker.addReferenceProperty("minPoolSize"); referenceMaker.addReferenceProperty("preferredTestQuery"); referenceMaker.addReferenceProperty("propertyCycle"); referenceMaker.addReferenceProperty("testConnectionOnCheckin"); referenceMaker.addReferenceProperty("testConnectionOnCheckout"); referenceMaker.addReferenceProperty("usesTraditionalReflectiveProxies"); } public Reference getReference() throws NamingException { return referenceMaker.createReference( this ); } //implementation of javax.sql.ConnectionPoolDataSource public PooledConnection getPooledConnection() throws SQLException { return wcpds.getPooledConnection(); } public PooledConnection getPooledConnection(String user, String password) throws SQLException { return wcpds.getPooledConnection( user, password ); } public PrintWriter getLogWriter() throws SQLException { return wcpds.getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { wcpds.setLogWriter( out ); } public void setLoginTimeout(int seconds) throws SQLException { wcpds.setLoginTimeout( seconds ); } public int getLoginTimeout() throws SQLException { return wcpds.getLoginTimeout(); } public String toString() { StringBuffer sb = new StringBuffer(512); sb.append( super.toString() ); sb.append(" ["); try { BeansUtils.appendPropNamesAndValues( sb, this, IGNORE_PROPS ); } catch (Exception e) { //e.printStackTrace(); if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "An exception occurred while extracting property names and values for toString()", e); sb.append( e.toString() ); } sb.append("]"); return sb.toString(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/JndiRefForwardingDataSource.java0000644000175000017500000001216010624366527025366 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.VetoableChangeListener; import java.beans.PropertyVetoException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.util.Hashtable; import javax.naming.Name; import javax.naming.NamingException; import javax.naming.InitialContext; import javax.sql.DataSource; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.sql.SqlUtils; import com.mchange.v2.c3p0.impl.JndiRefDataSourceBase; final class JndiRefForwardingDataSource extends JndiRefDataSourceBase implements DataSource { final static MLogger logger = MLog.getLogger( JndiRefForwardingDataSource.class ); //MT: protected by this' lock in all cases transient DataSource cachedInner; public JndiRefForwardingDataSource() { this( true ); } public JndiRefForwardingDataSource( boolean autoregister ) { super( autoregister ); setUpPropertyListeners(); } private void setUpPropertyListeners() { VetoableChangeListener l = new VetoableChangeListener() { public void vetoableChange( PropertyChangeEvent evt ) throws PropertyVetoException { Object val = evt.getNewValue(); if ( "jndiName".equals( evt.getPropertyName() ) ) { if (! (val instanceof Name || val instanceof String) ) throw new PropertyVetoException("jndiName must be a String or a javax.naming.Name", evt); } } }; this.addVetoableChangeListener( l ); PropertyChangeListener pcl = new PropertyChangeListener() { public void propertyChange( PropertyChangeEvent evt ) { cachedInner = null; } }; this.addPropertyChangeListener( pcl ); } //MT: called only from inner(), effectively synchrtonized private DataSource dereference() throws SQLException { Object jndiName = this.getJndiName(); Hashtable jndiEnv = this.getJndiEnv(); try { InitialContext ctx; if (jndiEnv != null) ctx = new InitialContext( jndiEnv ); else ctx = new InitialContext(); if (jndiName instanceof String) return (DataSource) ctx.lookup( (String) jndiName ); else if (jndiName instanceof Name) return (DataSource) ctx.lookup( (Name) jndiName ); else throw new SQLException("Could not find ConnectionPoolDataSource with " + "JNDI name: " + jndiName); } catch( NamingException e ) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while trying to look up a target DataSource via JNDI!", e ); throw SqlUtils.toSQLException( e ); } } private synchronized DataSource inner() throws SQLException { if (cachedInner != null) return cachedInner; else { DataSource out = dereference(); if (this.isCaching()) cachedInner = out; return out; } } public Connection getConnection() throws SQLException { return inner().getConnection(); } public Connection getConnection(String username, String password) throws SQLException { return inner().getConnection( username, password ); } public PrintWriter getLogWriter() throws SQLException { return inner().getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { inner().setLogWriter( out ); } public int getLoginTimeout() throws SQLException { return inner().getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { inner().setLoginTimeout( seconds ); } // serialization stuff -- set up bound/constrained property event handlers on deserialization private static final long serialVersionUID = 1; private static final short VERSION = 0x0001; private void writeObject( ObjectOutputStream oos ) throws IOException { oos.writeShort( VERSION ); } private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch (version) { case VERSION: setUpPropertyListeners(); break; default: throw new IOException("Unsupported Serialized Version: " + version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/PoolBackedDataSource.java0000644000175000017500000000240510624366530024020 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource; public final class PoolBackedDataSource extends AbstractPoolBackedDataSource implements PooledDataSource { public PoolBackedDataSource( boolean autoregister ) { super( autoregister ); } public PoolBackedDataSource() { this( true ); } public PoolBackedDataSource(String configName) { super( configName ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/PoolBackedDataSourceFactory.java0000644000175000017500000006457610624366527025377 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.sql.SqlUtils; /** * A class offering Factory methods for creating DataSources backed * by Connection and Statement Pools. * * @deprecated Use the new factories in {@link com.mchange.v2.c3p0.DataSources}. See examples. * */ public final class PoolBackedDataSourceFactory { /** * Creates a pool-backed DataSource that implements Referenceable * for binding to JNDI name services. For this to work, * unpooledDataSource must also implement Referenceable. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createReferenceable( DataSource unpooledDataSource, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements, String factoryLocation ) throws SQLException { try { WrapperConnectionPoolDataSource cpds = new WrapperConnectionPoolDataSource(); cpds.setNestedDataSource(unpooledDataSource); cpds.setMinPoolSize( minPoolSize ); cpds.setMaxPoolSize( maxPoolSize ); cpds.setAcquireIncrement( acquireIncrement ); cpds.setMaxIdleTime( maxIdleTime ); cpds.setMaxStatements( maxStatements ); cpds.setFactoryClassLocation( factoryLocation ); PoolBackedDataSource out = new PoolBackedDataSource(); out.setConnectionPoolDataSource( cpds ); return out; } catch (Exception e) { throw SqlUtils.toSQLException( e ); } } /** * Creates a pool-backed DataSource that uses default pool parameters and * implements Referenceable * for binding to JNDI name services. For this to work, * unpooledDataSource must also implement Referenceable. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createReferenceable( DataSource unpooledDataSource, String factoryLocation ) throws SQLException { try { WrapperConnectionPoolDataSource cpds = new WrapperConnectionPoolDataSource(); cpds.setNestedDataSource(unpooledDataSource); cpds.setFactoryClassLocation( factoryLocation ); PoolBackedDataSource out = new PoolBackedDataSource(); out.setConnectionPoolDataSource( cpds ); return out; } catch (Exception e) { throw SqlUtils.toSQLException( e ); } } /** * Creates a pool-backed DataSource that implements Referenceable. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createReferenceable(String jdbcDriverClass, String jdbcUrl, String user, String password, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements, String factoryLocation ) throws SQLException { DataSource nested = DriverManagerDataSourceFactory.create( jdbcDriverClass, jdbcUrl, user, password ); return createReferenceable( nested, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, factoryLocation ); } /** * Creates a pool-backed DataSource that implements Referenceable and uses * default pooling parameters. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createReferenceable(String jdbcDriverClass, String jdbcUrl, String user, String password, String factoryLocation ) throws SQLException { DataSource nested = DriverManagerDataSourceFactory.create( jdbcDriverClass, jdbcUrl, user, password ); return createReferenceable( nested, factoryLocation ); } /** * Creates a pool-backed DataSource that implements Serializable * for binding to JNDI name services. For this to work, * unpooledDataSource must also implement Serializable. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createSerializable( DataSource unpooledDataSource, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements) throws SQLException { try { WrapperConnectionPoolDataSource cpds = new WrapperConnectionPoolDataSource(); cpds.setNestedDataSource(unpooledDataSource); cpds.setMinPoolSize( minPoolSize ); cpds.setMaxPoolSize( maxPoolSize ); cpds.setAcquireIncrement( acquireIncrement ); cpds.setMaxIdleTime( maxIdleTime ); cpds.setMaxStatements( maxStatements ); PoolBackedDataSource out = new PoolBackedDataSource(); out.setConnectionPoolDataSource( cpds ); return out; } catch (Exception e) { throw SqlUtils.toSQLException( e ); } } /** * Creates a pool-backed DataSource that uses default pool parameters and * implements Serializable * for binding to JNDI name services. For this to work, * unpooledDataSource must also implement Serializable. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createSerializable( DataSource unpooledDataSource ) throws SQLException { try { WrapperConnectionPoolDataSource cpds = new WrapperConnectionPoolDataSource(); cpds.setNestedDataSource(unpooledDataSource); PoolBackedDataSource out = new PoolBackedDataSource(); out.setConnectionPoolDataSource( cpds ); return out; } catch (Exception e) { throw SqlUtils.toSQLException( e ); } } /** * Creates a pool-backed DataSource that implements Serializable. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createSerializable( String jdbcDriverClass, String jdbcUrl, String user, String password, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements) throws SQLException { DataSource nested = DriverManagerDataSourceFactory.create( jdbcDriverClass, jdbcUrl, user, password ); return createSerializable( nested, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements); } /** * Creates a pool-backed DataSource that implements Serializable and uses * default pooling parameters. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * * @deprecated all implementations are now both Referenceable and Serializable. * use create() */ public static DataSource createSerializable( String jdbcDriverClass, String jdbcUrl, String user, String password) throws SQLException { DataSource nested = DriverManagerDataSourceFactory.create( jdbcDriverClass, jdbcUrl, user, password ); return createSerializable( nested ); } /** * Creates a pool-backed DataSource using unpooledDataSource * as its source for Connections. Not necessarily suitable for JNDI binding. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. Used only if the JNDI service prefers * References to Serialized Objects when Objects are bound. */ public static DataSource create( DataSource unpooledDataSource, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements, String factoryLocation) throws SQLException { return createReferenceable( unpooledDataSource, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, factoryLocation ); } /** * Creates a pool-backed DataSource using unpooledDataSource * as its source for Connections. Not necessarily suitable for JNDI binding. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. */ public static DataSource create( DataSource unpooledDataSource, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements ) throws SQLException { return createReferenceable( unpooledDataSource, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, null ); } /** * Creates a pool-backed DataSource using unpooledDataSource * as its source for Connections and default values for pool params. * * @param unpooledDataSource an unpooledDataSource to use as the * primary source for connections. */ public static DataSource create( DataSource unpooledDataSource ) throws SQLException { return createSerializable( unpooledDataSource ); } /** * Creates a pool-backed DataSource. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. Used only if the JNDI service prefers * References to Serialized Objects when Objects are bound. */ public static DataSource create( String jdbcDriverClass, String jdbcUrl, String user, String password, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements, String factoryLocation ) throws SQLException { return createReferenceable( jdbcDriverClass, jdbcUrl, user, password, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, factoryLocation ); } /** * Creates a pool-backed DataSource. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. */ public static DataSource create( String jdbcDriverClass, String jdbcUrl, String user, String password, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements ) throws SQLException { return createReferenceable( jdbcDriverClass, jdbcUrl, user, password, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, null ); } /** * Creates a pool-backed DataSource. * *

Warning: If you use this method, you must make sure a JDBC driver * capable of resolving jdbcUrl has been preloaded!

* * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. * @param factoryLocation a codebase url where JNDI clients can find the * c3p0 libraries. Use null if clients will be expected to have the * libraries available locally. Used only if the JNDI service prefers * References to Serialized Objects when Objects are bound. */ public static DataSource create( String jdbcUrl, String user, String password, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements, String factoryLocation ) throws SQLException { return create( null, jdbcUrl, user, password, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, factoryLocation ); } /** * Creates a pool-backed DataSource. * *

Warning: If you use this method, you must make sure a JDBC driver * capable of resolving jdbcUrl has been preloaded!

* * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS * @param minPoolSize the minimum (and starting) number of Connections * that should be held in the pool. * @param maxPoolSize the maximum number of Connections * that should be held in the pool. * @param acquireIncrement the number of Connections that should be * acquired at a time when the pool runs out of Connections * @param maxIdleTime the maximum number of seconds a Connection should be * allowed to remain idle before it is expired from the pool. * A value of 0 means Connections never expire. * @param maxStatements the maximum number of PreparedStatements that should * be cached by this pool. A value of 0 means that Statement caching * should be disabled. */ public static DataSource create( String jdbcUrl, String user, String password, int minPoolSize, int maxPoolSize, int acquireIncrement, int maxIdleTime, int maxStatements ) throws SQLException { return create( null, jdbcUrl, user, password, minPoolSize, maxPoolSize, acquireIncrement, maxIdleTime, maxStatements, null ); } /** * Creates a pool-backed DataSource using default values for pool parameters. * Not necessarily suitable for JNDI binding. * * @param jdbcDriverClass a jdbc driver class that can resolve jdbcUrl. * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS */ public static DataSource create( String jdbcDriverClass, String jdbcUrl, String user, String password) throws SQLException { return createSerializable( jdbcDriverClass, jdbcUrl, user, password ); } /** * Creates a pool-backed DataSource using default pool parameters. * * *

Warning: If you use this method, you must make sure a JDBC driver * capable of resolving jdbcUrl has been preloaded!

* * @param jdbcUrl the jdbcUrl of the RDBMS that Connections should be made to. * @param user a username (may be null) for authentication to the RDBMS * @param password a password (may be null) for authentication to the RDBMS */ public static DataSource create( String jdbcUrl, String user, String password) throws SQLException { return create( null, jdbcUrl, user, password ); } private PoolBackedDataSourceFactory() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/PoolConfig.java0000644000175000017500000006247010624366527022117 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.util.Properties; import java.io.InputStream; import java.io.IOException; import com.mchange.v1.io.InputStreamUtils; import com.mchange.v2.c3p0.impl.C3P0Defaults; import com.mchange.v2.cfg.MultiPropertiesConfig; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; /** *

Encapsulates all the configuration information required by a c3p0 pooled DataSource.

* *

Newly constructed PoolConfig objects are preset with default values, * which you can define yourself (see below), * or you can rely on c3p0's built-in defaults. Just create a PoolConfig object, and change only the * properties you care about. Then pass it to the {@link com.mchange.v2.c3p0.DataSources#pooledDataSource(javax.sql.DataSource, com.mchange.v2.c3p0.PoolConfig)} * method, and you're off!

* *

For those interested in the details, configuration properties can be specified in several ways:

*
    *
  1. Any property can be set explicitly by calling the corresponding method on a PoolConfig object.
  2. *
  3. Any property will default to a value defined by a System Property, using the property name shown the table below.
  4. *
  5. Any property not set in either of the above ways will default to a value found in a user-supplied Java properties file, * which may be placed in the resource path of * the ClassLoader that loaded the c3p0 libraries under the name /c3p0.properties.
  6. *
  7. Any property not set in any of the above ways will be defined according c3p0's built-in defaults.
  8. *
* *

Please see c3p0's main documentation for a description of all available parameters.

* * @deprecated as of c3p0-0.9.1. To manipulate config programmaticall, please use ComboPooledDataSource * */ public final class PoolConfig { final static MLogger logger; public final static String INITIAL_POOL_SIZE = "c3p0.initialPoolSize"; public final static String MIN_POOL_SIZE = "c3p0.minPoolSize"; public final static String MAX_POOL_SIZE = "c3p0.maxPoolSize"; public final static String IDLE_CONNECTION_TEST_PERIOD = "c3p0.idleConnectionTestPeriod"; public final static String MAX_IDLE_TIME = "c3p0.maxIdleTime"; public final static String PROPERTY_CYCLE = "c3p0.propertyCycle"; public final static String MAX_STATEMENTS = "c3p0.maxStatements"; public final static String MAX_STATEMENTS_PER_CONNECTION = "c3p0.maxStatementsPerConnection"; public final static String CHECKOUT_TIMEOUT = "c3p0.checkoutTimeout"; public final static String ACQUIRE_INCREMENT = "c3p0.acquireIncrement"; public final static String ACQUIRE_RETRY_ATTEMPTS = "c3p0.acquireRetryAttempts"; public final static String ACQUIRE_RETRY_DELAY = "c3p0.acquireRetryDelay"; public final static String BREAK_AFTER_ACQUIRE_FAILURE = "c3p0.breakAfterAcquireFailure"; public final static String USES_TRADITIONAL_REFLECTIVE_PROXIES = "c3p0.usesTraditionalReflectiveProxies"; public final static String TEST_CONNECTION_ON_CHECKOUT = "c3p0.testConnectionOnCheckout"; public final static String TEST_CONNECTION_ON_CHECKIN = "c3p0.testConnectionOnCheckin"; public final static String CONNECTION_TESTER_CLASS_NAME = "c3p0.connectionTesterClassName"; public final static String AUTOMATIC_TEST_TABLE = "c3p0.automaticTestTable"; public final static String AUTO_COMMIT_ON_CLOSE = "c3p0.autoCommitOnClose"; public final static String FORCE_IGNORE_UNRESOLVED_TRANSACTIONS = "c3p0.forceIgnoreUnresolvedTransactions"; public final static String NUM_HELPER_THREADS = "c3p0.numHelperThreads"; public final static String PREFERRED_TEST_QUERY = "c3p0.preferredTestQuery"; public final static String FACTORY_CLASS_LOCATION = "c3p0.factoryClassLocation"; public final static String DEFAULT_CONFIG_RSRC_PATH = "/c3p0.properties"; final static PoolConfig DEFAULTS; static { logger = MLog.getLogger( PoolConfig.class ); Properties rsrcProps = findResourceProperties(); PoolConfig rsrcDefaults = extractConfig( rsrcProps, null ); Properties sysProps; try { sysProps = System.getProperties(); } catch ( SecurityException e ) { if (logger.isLoggable(MLevel.WARNING)) logger.log(MLevel.WARNING, "Read of system Properties blocked -- ignoring any c3p0 configuration via System properties! " + "(But any configuration via a c3p0.properties file is still okay!)", e); sysProps = new Properties(); //TODO -- an alternative approach to getting c3p0-specific sysprops if allowed } DEFAULTS = extractConfig( sysProps, rsrcDefaults ); } public static int defaultNumHelperThreads() { return DEFAULTS.getNumHelperThreads(); } public static String defaultPreferredTestQuery() { return DEFAULTS.getPreferredTestQuery(); } public static String defaultFactoryClassLocation() { return DEFAULTS.getFactoryClassLocation(); } public static int defaultMaxStatements() { return DEFAULTS.getMaxStatements(); } public static int defaultMaxStatementsPerConnection() { return DEFAULTS.getMaxStatementsPerConnection(); } public static int defaultInitialPoolSize() { return DEFAULTS.getInitialPoolSize(); } public static int defaultMinPoolSize() { return DEFAULTS.getMinPoolSize(); } public static int defaultMaxPoolSize() { return DEFAULTS.getMaxPoolSize(); } public static int defaultIdleConnectionTestPeriod() { return DEFAULTS.getIdleConnectionTestPeriod(); } public static int defaultMaxIdleTime() { return DEFAULTS.getMaxIdleTime(); } public static int defaultPropertyCycle() { return DEFAULTS.getPropertyCycle(); } public static int defaultCheckoutTimeout() { return DEFAULTS.getCheckoutTimeout(); } public static int defaultAcquireIncrement() { return DEFAULTS.getAcquireIncrement(); } public static int defaultAcquireRetryAttempts() { return DEFAULTS.getAcquireRetryAttempts(); } public static int defaultAcquireRetryDelay() { return DEFAULTS.getAcquireRetryDelay(); } public static boolean defaultBreakAfterAcquireFailure() { return DEFAULTS.isBreakAfterAcquireFailure(); } public static String defaultConnectionTesterClassName() { return DEFAULTS.getConnectionTesterClassName(); } public static String defaultAutomaticTestTable() { return DEFAULTS.getAutomaticTestTable(); } public static boolean defaultTestConnectionOnCheckout() { return DEFAULTS.isTestConnectionOnCheckout(); } public static boolean defaultTestConnectionOnCheckin() { return DEFAULTS.isTestConnectionOnCheckin(); } public static boolean defaultAutoCommitOnClose() { return DEFAULTS.isAutoCommitOnClose(); } public static boolean defaultForceIgnoreUnresolvedTransactions() { return DEFAULTS.isAutoCommitOnClose(); } public static boolean defaultUsesTraditionalReflectiveProxies() { return DEFAULTS.isUsesTraditionalReflectiveProxies(); } int maxStatements; int maxStatementsPerConnection; int initialPoolSize; int minPoolSize; int maxPoolSize; int idleConnectionTestPeriod; int maxIdleTime; int propertyCycle; int checkoutTimeout; int acquireIncrement; int acquireRetryAttempts; int acquireRetryDelay; boolean breakAfterAcquireFailure; boolean testConnectionOnCheckout; boolean testConnectionOnCheckin; boolean autoCommitOnClose; boolean forceIgnoreUnresolvedTransactions; boolean usesTraditionalReflectiveProxies; String connectionTesterClassName; String automaticTestTable; int numHelperThreads; String preferredTestQuery; String factoryClassLocation; private PoolConfig( Properties props, boolean init ) throws NumberFormatException { if (init) extractConfig( this, props, DEFAULTS ); } public PoolConfig( Properties props ) throws NumberFormatException { this( props, true ); } public PoolConfig() throws NumberFormatException { this( null, true ); } public int getNumHelperThreads() { return numHelperThreads; } public String getPreferredTestQuery() { return preferredTestQuery; } public String getFactoryClassLocation() { return factoryClassLocation; } public int getMaxStatements() { return maxStatements; } public int getMaxStatementsPerConnection() { return maxStatementsPerConnection; } public int getInitialPoolSize() { return initialPoolSize; } public int getMinPoolSize() { return minPoolSize; } public int getMaxPoolSize() { return maxPoolSize; } public int getIdleConnectionTestPeriod() { return idleConnectionTestPeriod; } public int getMaxIdleTime() { return maxIdleTime; } public int getPropertyCycle() { return propertyCycle; } public int getAcquireIncrement() { return acquireIncrement; } public int getCheckoutTimeout() { return checkoutTimeout; } public int getAcquireRetryAttempts() { return acquireRetryAttempts; } public int getAcquireRetryDelay() { return acquireRetryDelay; } public boolean isBreakAfterAcquireFailure() { return this.breakAfterAcquireFailure; } public boolean isUsesTraditionalReflectiveProxies() { return this.usesTraditionalReflectiveProxies; } public String getConnectionTesterClassName() { return connectionTesterClassName; } public String getAutomaticTestTable() { return automaticTestTable; } /** * @deprecated use isTestConnectionOnCheckout */ public boolean getTestConnectionOnCheckout() { return testConnectionOnCheckout; } public boolean isTestConnectionOnCheckout() { return this.getTestConnectionOnCheckout(); } public boolean isTestConnectionOnCheckin() { return testConnectionOnCheckin; } public boolean isAutoCommitOnClose() { return this.autoCommitOnClose; } public boolean isForceIgnoreUnresolvedTransactions() { return this.forceIgnoreUnresolvedTransactions; } public void setNumHelperThreads( int numHelperThreads ) { this.numHelperThreads = numHelperThreads; } public void setPreferredTestQuery( String preferredTestQuery ) { this.preferredTestQuery = preferredTestQuery; } public void setFactoryClassLocation( String factoryClassLocation ) { this.factoryClassLocation = factoryClassLocation; } public void setMaxStatements( int maxStatements ) { this.maxStatements = maxStatements; } public void setMaxStatementsPerConnection( int maxStatementsPerConnection ) { this.maxStatementsPerConnection = maxStatementsPerConnection; } public void setInitialPoolSize( int initialPoolSize ) { this.initialPoolSize = initialPoolSize; } public void setMinPoolSize( int minPoolSize ) { this.minPoolSize = minPoolSize; } public void setMaxPoolSize( int maxPoolSize ) { this.maxPoolSize = maxPoolSize; } public void setIdleConnectionTestPeriod( int idleConnectionTestPeriod ) { this.idleConnectionTestPeriod = idleConnectionTestPeriod; } public void setMaxIdleTime( int maxIdleTime ) { this.maxIdleTime = maxIdleTime; } public void setPropertyCycle( int propertyCycle ) { this.propertyCycle = propertyCycle; } public void setCheckoutTimeout( int checkoutTimeout ) { this.checkoutTimeout = checkoutTimeout; } public void setAcquireIncrement( int acquireIncrement ) { this.acquireIncrement = acquireIncrement; } public void setAcquireRetryAttempts( int acquireRetryAttempts ) { this.acquireRetryAttempts = acquireRetryAttempts; } public void setAcquireRetryDelay( int acquireRetryDelay ) { this.acquireRetryDelay = acquireRetryDelay; } public void setConnectionTesterClassName( String connectionTesterClassName ) { this.connectionTesterClassName = connectionTesterClassName; } public void setAutomaticTestTable( String automaticTestTable ) { this.automaticTestTable = automaticTestTable; } public void setBreakAfterAcquireFailure( boolean breakAfterAcquireFailure ) { this.breakAfterAcquireFailure = breakAfterAcquireFailure; } public void setUsesTraditionalReflectiveProxies( boolean usesTraditionalReflectiveProxies ) { this.usesTraditionalReflectiveProxies = usesTraditionalReflectiveProxies; } public void setTestConnectionOnCheckout( boolean testConnectionOnCheckout ) { this.testConnectionOnCheckout = testConnectionOnCheckout; } public void setTestConnectionOnCheckin( boolean testConnectionOnCheckin ) { this.testConnectionOnCheckin = testConnectionOnCheckin; } public void setAutoCommitOnClose( boolean autoCommitOnClose ) { this.autoCommitOnClose = autoCommitOnClose; } public void setForceIgnoreUnresolvedTransactions( boolean forceIgnoreUnresolvedTransactions ) { this.forceIgnoreUnresolvedTransactions = forceIgnoreUnresolvedTransactions; } private static PoolConfig extractConfig(Properties props, PoolConfig defaults) throws NumberFormatException { PoolConfig pcfg = new PoolConfig(null, false); extractConfig( pcfg, props, defaults ); return pcfg; } private static void extractConfig(PoolConfig pcfg, Properties props, PoolConfig defaults) throws NumberFormatException { String maxStatementsStr = null; String maxStatementsPerConnectionStr = null; String initialPoolSizeStr = null; String minPoolSizeStr = null; String maxPoolSizeStr = null; String idleConnectionTestPeriodStr = null; String maxIdleTimeStr = null; String propertyCycleStr = null; String checkoutTimeoutStr = null; String acquireIncrementStr = null; String acquireRetryAttemptsStr = null; String acquireRetryDelayStr = null; String breakAfterAcquireFailureStr = null; String usesTraditionalReflectiveProxiesStr = null; String testConnectionOnCheckoutStr = null; String testConnectionOnCheckinStr = null; String autoCommitOnCloseStr = null; String forceIgnoreUnresolvedTransactionsStr = null; String connectionTesterClassName = null; String automaticTestTable = null; String numHelperThreadsStr = null; String preferredTestQuery = null; String factoryClassLocation = null; if ( props != null ) { maxStatementsStr = props.getProperty(MAX_STATEMENTS); maxStatementsPerConnectionStr = props.getProperty(MAX_STATEMENTS_PER_CONNECTION); initialPoolSizeStr = props.getProperty(INITIAL_POOL_SIZE); minPoolSizeStr = props.getProperty(MIN_POOL_SIZE); maxPoolSizeStr = props.getProperty(MAX_POOL_SIZE); idleConnectionTestPeriodStr = props.getProperty(IDLE_CONNECTION_TEST_PERIOD); maxIdleTimeStr = props.getProperty(MAX_IDLE_TIME); propertyCycleStr = props.getProperty(PROPERTY_CYCLE); checkoutTimeoutStr = props.getProperty(CHECKOUT_TIMEOUT); acquireIncrementStr = props.getProperty(ACQUIRE_INCREMENT); acquireRetryAttemptsStr = props.getProperty(ACQUIRE_RETRY_ATTEMPTS); acquireRetryDelayStr = props.getProperty(ACQUIRE_RETRY_DELAY); breakAfterAcquireFailureStr = props.getProperty(BREAK_AFTER_ACQUIRE_FAILURE); usesTraditionalReflectiveProxiesStr = props.getProperty(USES_TRADITIONAL_REFLECTIVE_PROXIES); testConnectionOnCheckoutStr = props.getProperty(TEST_CONNECTION_ON_CHECKOUT); testConnectionOnCheckinStr = props.getProperty(TEST_CONNECTION_ON_CHECKIN); autoCommitOnCloseStr = props.getProperty(AUTO_COMMIT_ON_CLOSE); forceIgnoreUnresolvedTransactionsStr = props.getProperty(FORCE_IGNORE_UNRESOLVED_TRANSACTIONS); connectionTesterClassName = props.getProperty(CONNECTION_TESTER_CLASS_NAME); automaticTestTable = props.getProperty(AUTOMATIC_TEST_TABLE); numHelperThreadsStr = props.getProperty(NUM_HELPER_THREADS); preferredTestQuery = props.getProperty(PREFERRED_TEST_QUERY); factoryClassLocation = props.getProperty(FACTORY_CLASS_LOCATION); } // maxStatements if ( maxStatementsStr != null ) pcfg.setMaxStatements( Integer.parseInt( maxStatementsStr.trim() ) ); else if (defaults != null) pcfg.setMaxStatements( defaults.getMaxStatements() ); else pcfg.setMaxStatements( C3P0Defaults.maxStatements() ); // maxStatementsPerConnection if ( maxStatementsPerConnectionStr != null ) pcfg.setMaxStatementsPerConnection( Integer.parseInt( maxStatementsPerConnectionStr.trim() ) ); else if (defaults != null) pcfg.setMaxStatementsPerConnection( defaults.getMaxStatementsPerConnection() ); else pcfg.setMaxStatementsPerConnection( C3P0Defaults.maxStatementsPerConnection() ); // initialPoolSize if ( initialPoolSizeStr != null ) pcfg.setInitialPoolSize( Integer.parseInt( initialPoolSizeStr.trim() ) ); else if (defaults != null) pcfg.setInitialPoolSize( defaults.getInitialPoolSize() ); else pcfg.setInitialPoolSize( C3P0Defaults.initialPoolSize() ); // minPoolSize if ( minPoolSizeStr != null ) pcfg.setMinPoolSize( Integer.parseInt( minPoolSizeStr.trim() ) ); else if (defaults != null) pcfg.setMinPoolSize( defaults.getMinPoolSize() ); else pcfg.setMinPoolSize( C3P0Defaults.minPoolSize() ); // maxPoolSize if ( maxPoolSizeStr != null ) pcfg.setMaxPoolSize( Integer.parseInt( maxPoolSizeStr.trim() ) ); else if (defaults != null) pcfg.setMaxPoolSize( defaults.getMaxPoolSize() ); else pcfg.setMaxPoolSize( C3P0Defaults.maxPoolSize() ); // maxIdleTime if ( idleConnectionTestPeriodStr != null ) pcfg.setIdleConnectionTestPeriod( Integer.parseInt( idleConnectionTestPeriodStr.trim() ) ); else if (defaults != null) pcfg.setIdleConnectionTestPeriod( defaults.getIdleConnectionTestPeriod() ); else pcfg.setIdleConnectionTestPeriod( C3P0Defaults.idleConnectionTestPeriod() ); // maxIdleTime if ( maxIdleTimeStr != null ) pcfg.setMaxIdleTime( Integer.parseInt( maxIdleTimeStr.trim() ) ); else if (defaults != null) pcfg.setMaxIdleTime( defaults.getMaxIdleTime() ); else pcfg.setMaxIdleTime( C3P0Defaults.maxIdleTime() ); // propertyCycle if ( propertyCycleStr != null ) pcfg.setPropertyCycle( Integer.parseInt( propertyCycleStr.trim() ) ); else if (defaults != null) pcfg.setPropertyCycle( defaults.getPropertyCycle() ); else pcfg.setPropertyCycle( C3P0Defaults.propertyCycle() ); // checkoutTimeout if ( checkoutTimeoutStr != null ) pcfg.setCheckoutTimeout( Integer.parseInt( checkoutTimeoutStr.trim() ) ); else if (defaults != null) pcfg.setCheckoutTimeout( defaults.getCheckoutTimeout() ); else pcfg.setCheckoutTimeout( C3P0Defaults.checkoutTimeout() ); // acquireIncrement if ( acquireIncrementStr != null ) pcfg.setAcquireIncrement( Integer.parseInt( acquireIncrementStr.trim() ) ); else if (defaults != null) pcfg.setAcquireIncrement( defaults.getAcquireIncrement() ); else pcfg.setAcquireIncrement( C3P0Defaults.acquireIncrement() ); // acquireRetryAttempts if ( acquireRetryAttemptsStr != null ) pcfg.setAcquireRetryAttempts( Integer.parseInt( acquireRetryAttemptsStr.trim() ) ); else if (defaults != null) pcfg.setAcquireRetryAttempts( defaults.getAcquireRetryAttempts() ); else pcfg.setAcquireRetryAttempts( C3P0Defaults.acquireRetryAttempts() ); // acquireRetryDelay if ( acquireRetryDelayStr != null ) pcfg.setAcquireRetryDelay( Integer.parseInt( acquireRetryDelayStr.trim() ) ); else if (defaults != null) pcfg.setAcquireRetryDelay( defaults.getAcquireRetryDelay() ); else pcfg.setAcquireRetryDelay( C3P0Defaults.acquireRetryDelay() ); // breakAfterAcquireFailure if ( breakAfterAcquireFailureStr != null ) pcfg.setBreakAfterAcquireFailure( Boolean.valueOf(breakAfterAcquireFailureStr.trim()).booleanValue() ); else if (defaults != null) pcfg.setBreakAfterAcquireFailure( defaults.isBreakAfterAcquireFailure() ); else pcfg.setBreakAfterAcquireFailure( C3P0Defaults.breakAfterAcquireFailure() ); // usesTraditionalReflectiveProxies if ( usesTraditionalReflectiveProxiesStr != null ) pcfg.setUsesTraditionalReflectiveProxies( Boolean.valueOf(usesTraditionalReflectiveProxiesStr.trim()).booleanValue() ); else if (defaults != null) pcfg.setUsesTraditionalReflectiveProxies( defaults.isUsesTraditionalReflectiveProxies() ); else pcfg.setUsesTraditionalReflectiveProxies( C3P0Defaults.usesTraditionalReflectiveProxies() ); // testConnectionOnCheckout if ( testConnectionOnCheckoutStr != null ) pcfg.setTestConnectionOnCheckout( Boolean.valueOf(testConnectionOnCheckoutStr.trim()).booleanValue() ); else if (defaults != null) pcfg.setTestConnectionOnCheckout( defaults.isTestConnectionOnCheckout() ); else pcfg.setTestConnectionOnCheckout( C3P0Defaults.testConnectionOnCheckout() ); // testConnectionOnCheckin if ( testConnectionOnCheckinStr != null ) pcfg.setTestConnectionOnCheckin( Boolean.valueOf(testConnectionOnCheckinStr.trim()).booleanValue() ); else if (defaults != null) pcfg.setTestConnectionOnCheckin( defaults.isTestConnectionOnCheckin() ); else pcfg.setTestConnectionOnCheckin( C3P0Defaults.testConnectionOnCheckin() ); // autoCommitOnClose if ( autoCommitOnCloseStr != null ) pcfg.setAutoCommitOnClose( Boolean.valueOf(autoCommitOnCloseStr.trim()).booleanValue() ); else if (defaults != null) pcfg.setAutoCommitOnClose( defaults.isAutoCommitOnClose() ); else pcfg.setAutoCommitOnClose( C3P0Defaults.autoCommitOnClose() ); // forceIgnoreUnresolvedTransactions if ( forceIgnoreUnresolvedTransactionsStr != null ) pcfg.setForceIgnoreUnresolvedTransactions( Boolean.valueOf( forceIgnoreUnresolvedTransactionsStr.trim() ).booleanValue() ); else if (defaults != null) pcfg.setForceIgnoreUnresolvedTransactions( defaults.isForceIgnoreUnresolvedTransactions() ); else pcfg.setForceIgnoreUnresolvedTransactions( C3P0Defaults.forceIgnoreUnresolvedTransactions() ); // connectionTesterClassName if ( connectionTesterClassName != null ) pcfg.setConnectionTesterClassName( connectionTesterClassName.trim() ); else if (defaults != null) pcfg.setConnectionTesterClassName( defaults.getConnectionTesterClassName() ); else pcfg.setConnectionTesterClassName( C3P0Defaults.connectionTesterClassName() ); // automaticTestTable if ( automaticTestTable != null ) pcfg.setAutomaticTestTable( automaticTestTable.trim() ); else if (defaults != null) pcfg.setAutomaticTestTable( defaults.getAutomaticTestTable() ); else pcfg.setAutomaticTestTable( C3P0Defaults.automaticTestTable() ); // numHelperThreads if ( numHelperThreadsStr != null ) pcfg.setNumHelperThreads( Integer.parseInt( numHelperThreadsStr.trim() ) ); else if (defaults != null) pcfg.setNumHelperThreads( defaults.getNumHelperThreads() ); else pcfg.setNumHelperThreads( C3P0Defaults.numHelperThreads() ); // preferredTestQuery if ( preferredTestQuery != null ) pcfg.setPreferredTestQuery( preferredTestQuery.trim() ); else if (defaults != null) pcfg.setPreferredTestQuery( defaults.getPreferredTestQuery() ); else pcfg.setPreferredTestQuery( C3P0Defaults.preferredTestQuery() ); // factoryClassLocation if ( factoryClassLocation != null ) pcfg.setFactoryClassLocation( factoryClassLocation.trim() ); else if (defaults != null) pcfg.setFactoryClassLocation( defaults.getFactoryClassLocation() ); else pcfg.setFactoryClassLocation( C3P0Defaults.factoryClassLocation() ); } private static Properties findResourceProperties() { return MultiPropertiesConfig.readVmConfig().getPropertiesByResourcePath(DEFAULT_CONFIG_RSRC_PATH); } private static Properties origFindResourceProperties() { Properties props = new Properties(); InputStream is = null; try { is = PoolConfig.class.getResourceAsStream(DEFAULT_CONFIG_RSRC_PATH); if ( is != null ) props.load( is ); } catch (IOException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An IOException occurred while trying to read Pool properties!", e ); props = new Properties(); } finally { InputStreamUtils.attemptClose( is ); } return props; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/PooledDataSource.java0000644000175000017500000004044310624366527023251 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.SQLException; import javax.sql.DataSource; import java.util.Collection; /** *

Most clients need never use or know about this interface -- c3p0 pooled DataSources * can be treated like any other DataSource.

* *

The functionality in this interface will be only be of interest if 1) for administrative * reasons you like to keep close track of the number and status of all Connections your application * is using; 2) to work around problems encountered while managing a DataSource whose clients are * poorly coded applications that leak Connections, but which you are not permitted to fix; * or 3) to work around problems that may occur if an underlying jdbc driver / DBMS system is * unreliable. In the third case, most users will be better off not using the present interface * at all, and using the DataSources' maxIdleTime, idleConnectionTestPeriod, * or testConnectionOnCheckout parameters to help your DataSources "automatically" heal. * But for those who prefer a more direct, manual approach, this interface is for you. It is anticipated * that the methods of this interface will primarily be of use to administrators managing c3p0 * PooledDataSources via JMX MBeans.

* *

Method Names & Per-User Pools

* *

To understand this interface, you need to realize that a c3p0 PooledDataSource may represent * not just one pool of Connections, but many, if users call the method * Connection getConnection(String username, String password) rather than the * no-argument getConnection() method. If users make use of non-default username, password * combinations, there will be a separate pool for each set of authentification criteria supplied.

* *

Many methods in this interface have three variants:

*
    *
  1. <method-name>DefaultUser()
  2. *
  3. <method-name>(String username, String password)
  4. *
  5. <method-name>AllUsers()
  6. *
*

The first variant makes use of the pool maintained for the default user -- * Connections created by calls to the no argument getConnection(), * the second variant lets you keeps track of pools created by calling * getConnection( username, password ), and the third variant * provides aggregate information or performs operation on all pools.

* *

Under most circumstances, non-default authentication credentials will not * be used, and methods of the first variant are sufficient to manage the DataSource.

* *

Soft and Hard Resets

* *

A properly configured PooledDataSource whose applications are careful to close all checked-out Connections * would never need to use these methods. But, sometimes applications are untrustworthy * and leak Connections, or database administrators suspect that Connections may be corrupt or invalid, * and would like to force a pool to flush and acquire fresh Connections. This interface provides two * ways to do so.

* *
    *
  1. hardReset() immediately closes all Connections managed by the DataSource, including * those that are currently checked out, bringing the DataSource back to the state it was in before * the first client called getConnection(). This method is obviously disruptive, and should be with * great care. Administrators who need to work around client applications that leak Connections, can * periodically poll for pool exhaustion (using the methods of this class, or by attempting to retrieve * a Connection and timing out) and use this method clean-up all Connections and start over. But calling * this method risks breaking Connections in current use by valid applications.

  2. * *
  3. softResetDefaultUser(), softReset( username, password ) and * softResetAllUsers() asks the DataSource to flush its current pool of Connections and * reacquire without invalidating currently checked-out Connections. Currently checked out Connections * are logically removed from the pool, but their destruction is deferred until a client attempts to close() / check-in * the Connection. Administrators who suspect that some Connections in the pool may be invalid, but who do not * wish to rely upon c3p0's automatic testing and detection mechanisms to resolve the problem, may call these * methods to force a refresh without disrupting current clients. Administrators who suspect that clients may be * leaking Connections may minimize disruptive hardReset() calls by using softReset() until the number of unclosed * orphaned connections reaches an unacceptable level. (See above to understand * why there are three variants of this method.)
  4. *
* *

Understanding Connection Counts

* *

For each per-user pool, four different statistics are available:

* *
    *
  1. numConnections represents the total number of Connections in the pool.

  2. *
  3. numIdleConnections represents the number of Connections in the pool that are currently available for checkout.

  4. *
  5. numBusyConnections represents the number of Connections in the pool that are currently checked out. The * invariant numIdleConnections + numBusyConnections == numConnections should always hold.

  6. *
  7. numUnclosedOrphanedConnections will only be non-zero following a call to softReset(). It represents * the number of Connections that were checked out when a soft reset occurred and were therefore * silently excluded from the pool, and which remain unclosed by the client application.
  8. *
*/ public interface PooledDataSource extends DataSource { public String getIdentityToken(); public String getDataSourceName(); public void setDataSourceName(String dataSourceName); /** @deprecated use getNumConnectionsDefaultUser() */ public int getNumConnections() throws SQLException; /** @deprecated use getNumIdleConnectionsDefaultUser() */ public int getNumIdleConnections() throws SQLException; /** @deprecated use getNumBusyConnectionsDefaultUser() */ public int getNumBusyConnections() throws SQLException; /** @deprecated use getNumUnclosedOrphanedConnectionsDefaultUser() */ public int getNumUnclosedOrphanedConnections() throws SQLException; public int getNumConnectionsDefaultUser() throws SQLException; public int getNumIdleConnectionsDefaultUser() throws SQLException; public int getNumBusyConnectionsDefaultUser() throws SQLException; public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException; public int getStatementCacheNumStatementsDefaultUser() throws SQLException; public int getStatementCacheNumCheckedOutDefaultUser() throws SQLException; public int getStatementCacheNumConnectionsWithCachedStatementsDefaultUser() throws SQLException; public long getStartTimeMillisDefaultUser() throws SQLException; public long getUpTimeMillisDefaultUser() throws SQLException; public long getNumFailedCheckinsDefaultUser() throws SQLException; public long getNumFailedCheckoutsDefaultUser() throws SQLException; public long getNumFailedIdleTestsDefaultUser() throws SQLException; public float getEffectivePropertyCycleDefaultUser() throws SQLException; public int getNumThreadsAwaitingCheckoutDefaultUser() throws SQLException; /** * Discards all Connections managed by the PooledDataSource's default-authentication pool * and reacquires new Connections to populate. * Current checked out Connections will still * be valid, and should still be checked into the * PooledDataSource (so the PooledDataSource can destroy * them). */ public void softResetDefaultUser() throws SQLException; public int getNumConnections(String username, String password) throws SQLException; public int getNumIdleConnections(String username, String password) throws SQLException; public int getNumBusyConnections(String username, String password) throws SQLException; public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException; public int getStatementCacheNumStatements(String username, String password) throws SQLException; public int getStatementCacheNumCheckedOut(String username, String password) throws SQLException; public int getStatementCacheNumConnectionsWithCachedStatements(String username, String password) throws SQLException; public float getEffectivePropertyCycle(String username, String password) throws SQLException; public int getNumThreadsAwaitingCheckout(String username, String password) throws SQLException; /** * Discards all Connections managed by the PooledDataSource with the specified authentication credentials * and reacquires new Connections to populate. * Current checked out Connections will still * be valid, and should still be checked into the * PooledDataSource (so the PooledDataSource can destroy * them). */ public void softReset(String username, String password) throws SQLException; public int getNumBusyConnectionsAllUsers() throws SQLException; public int getNumIdleConnectionsAllUsers() throws SQLException; public int getNumConnectionsAllUsers() throws SQLException; public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException; public int getStatementCacheNumStatementsAllUsers() throws SQLException; public int getStatementCacheNumCheckedOutStatementsAllUsers() throws SQLException; public int getStatementCacheNumConnectionsWithCachedStatementsAllUsers() throws SQLException; public int getThreadPoolSize() throws SQLException; public int getThreadPoolNumActiveThreads() throws SQLException; public int getThreadPoolNumIdleThreads() throws SQLException; public int getThreadPoolNumTasksPending() throws SQLException; public String sampleThreadPoolStackTraces() throws SQLException; public String sampleThreadPoolStatus() throws SQLException; public String sampleStatementCacheStatusDefaultUser() throws SQLException; public String sampleStatementCacheStatus(String username, String password) throws SQLException; public Throwable getLastAcquisitionFailureDefaultUser() throws SQLException; public Throwable getLastCheckinFailureDefaultUser() throws SQLException; public Throwable getLastCheckoutFailureDefaultUser() throws SQLException; public Throwable getLastIdleTestFailureDefaultUser() throws SQLException; public Throwable getLastConnectionTestFailureDefaultUser() throws SQLException; public Throwable getLastAcquisitionFailure(String username, String password) throws SQLException; public Throwable getLastCheckinFailure(String username, String password) throws SQLException; public Throwable getLastCheckoutFailure(String username, String password) throws SQLException; public Throwable getLastIdleTestFailure(String username, String password) throws SQLException; public Throwable getLastConnectionTestFailure(String username, String password) throws SQLException; public String sampleLastAcquisitionFailureStackTraceDefaultUser() throws SQLException; public String sampleLastCheckinFailureStackTraceDefaultUser() throws SQLException; public String sampleLastCheckoutFailureStackTraceDefaultUser() throws SQLException; public String sampleLastIdleTestFailureStackTraceDefaultUser() throws SQLException; public String sampleLastConnectionTestFailureStackTraceDefaultUser() throws SQLException; public String sampleLastAcquisitionFailureStackTrace(String username, String password) throws SQLException; public String sampleLastCheckinFailureStackTrace(String username, String password) throws SQLException; public String sampleLastCheckoutFailureStackTrace(String username, String password) throws SQLException; public String sampleLastIdleTestFailureStackTrace(String username, String password) throws SQLException; public String sampleLastConnectionTestFailureStackTrace(String username, String password) throws SQLException; /** * Discards all Connections managed by the PooledDataSource * and reacquires new Connections to populate. * Current checked out Connections will still * be valid, and should still be checked into the * PooledDataSource (so the PooledDataSource can destroy * them). */ public void softResetAllUsers() throws SQLException; public int getNumUserPools() throws SQLException; public int getNumHelperThreads() throws SQLException; public Collection getAllUsers() throws SQLException; /** * Destroys all pooled and checked-out Connections associated with * this DataSource immediately. The PooledDataSource is * reset to its initial state prior to first Connection acquisition, * with no pools yet active, but ready for requests. */ public void hardReset() throws SQLException; /** *

C3P0 pooled DataSources use no resources before they are actually used in a VM, * and they close themselves in their finalize() method. When they are active and * pooling, they may have open database connections and their pool may spawn several threads * for its maintenance. You can use this method to clean these resource methods up quickly * when you will no longer be using this DataSource. The resources will actually be cleaned up only if * no other DataSources are sharing the same pool.

* *

You can equivalently use the static method destroy() in the DataSources class to clean-up * these resources.

* *

This is equivalent to calling close( false ).

* * @see DataSources#destroy */ public void close() throws SQLException; /** *

Should be used only with great caution. If force_destroy is set to true, * this immediately destroys any pool and cleans up all resources * this DataSource may be using, even if other DataSources are sharing that * pool! In general, it is difficult to know whether a pool is being shared by * multiple DataSources. It may depend upon whether or not a JNDI implementation returns * a single instance or multiple copies upon lookup (which is undefined by the JNDI spec).

* *

In general, this method should be used only when you wish to wind down all c3p0 pools * in a ClassLoader. For example, when shutting down and restarting a web application * that uses c3p0, you may wish to kill all threads making use of classes loaded by a * web-app specific ClassLoader, so that the ClassLoader can be cleanly garbage collected. * In this case, you may wish to use force destroy. Otherwise, it is much safer to use * the simple destroy() method, which will not shut down pools that may still be in use.

* *

To close a pool normally, use the no argument close method, or set force_destroy * to false.

* * @deprecated the force_destroy argument is now meaningless, as pools are no longer * potentially shared between multiple DataSources. * * @see #close() */ public void close(boolean force_destory) throws SQLException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/QueryConnectionTester.java0000644000175000017500000000205010624366530024352 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; public interface QueryConnectionTester extends ConnectionTester { public int activeCheckConnection(Connection c, String preferredTestQuery); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/SQLWarnings.java0000644000175000017500000000275110624366530022216 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLWarning; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; public final class SQLWarnings { final static MLogger logger = MLog.getLogger( SQLWarnings.class ); public static void logAndClearWarnings(Connection con) throws SQLException { if (logger.isLoggable(MLevel.INFO)) { for(SQLWarning w = con.getWarnings(); w != null; w = w.getNextWarning()) logger.log(MLevel.INFO, w.getMessage(), w); } con.clearWarnings(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/UnifiedConnectionTester.java0000644000175000017500000000646010624366530024641 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.sql.Connection; /** *

Having expanded the once-simple ConnectionTester interface to support both * user-specified queries and return of root cause Exceptions (via an out-param), * this interface has grown unnecessarily complex.

* *

If you wish to implement a custom Connection tester, here is the simple * way to do it

* *
    *
  1. Extend {@link com.mchange.v2.c3p0.AbstractConnectionTester}
  2. *
  3. Override only the two abstract methods
  4. *
      *
    • public int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
    • *
    • public int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
    • *
    *
  5. Take care to ensure that your methods are defined to allow preferredTestQuery and * rootCauseOutParamHolder to be null.
  6. *
* *

Parameter rootCauseOutParamHolder is an optional parameter, which if supplied, will be a Throwable array whose size * it at least one. If a Connection test fails because of some Exception, the Connection tester may set this Exception as the * zero-th element of the array to provide information about why and how the test failed.

*/ public interface UnifiedConnectionTester extends FullQueryConnectionTester { public final static int CONNECTION_IS_OKAY = ConnectionTester.CONNECTION_IS_OKAY; public final static int CONNECTION_IS_INVALID = ConnectionTester.CONNECTION_IS_INVALID; public final static int DATABASE_IS_INVALID = ConnectionTester.DATABASE_IS_INVALID; public int activeCheckConnection(Connection c); public int activeCheckConnection(Connection c, Throwable[] rootCauseOutParamHolder); public int activeCheckConnection(Connection c, String preferredTestQuery); public int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder); public int statusOnException(Connection c, Throwable t); public int statusOnException(Connection c, Throwable t, Throwable[] rootCauseOutParamHolder); public int statusOnException(Connection c, Throwable t, String preferredTestQuery); public int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder); public boolean equals(Object o); public int hashCode(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/c3p0/WrapperConnectionPoolDataSource.java0000644000175000017500000002254210624366530026313 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.c3p0; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.beans.VetoableChangeListener; import java.beans.PropertyChangeListener; import java.io.PrintWriter; import java.lang.reflect.Method; import java.util.Map; import java.sql.*; import javax.sql.*; import com.mchange.v2.c3p0.cfg.C3P0Config; import com.mchange.v2.c3p0.impl.*; import com.mchange.v2.log.*; // MT: Most methods are left unsynchronized, because getNestedDataSource() is synchronized, and for most methods, that's // the only critical part. Previous oversynchronization led to hangs, when getting the Connection for one Thread happened // to hang, blocking access to getPooledConnection() for all Threads. public final class WrapperConnectionPoolDataSource extends WrapperConnectionPoolDataSourceBase implements ConnectionPoolDataSource { final static MLogger logger = MLog.getLogger( WrapperConnectionPoolDataSource.class ); //MT: protected by this' lock ConnectionTester connectionTester = C3P0ImplUtils.defaultConnectionTester(); Map userOverrides; public WrapperConnectionPoolDataSource(boolean autoregister) { super( autoregister ); setUpPropertyListeners(); //set up initial value of userOverrides try { this.userOverrides = C3P0ImplUtils.parseUserOverridesAsString( this.getUserOverridesAsString() ); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to parse stringified userOverrides. " + this.getUserOverridesAsString(), e ); } } public WrapperConnectionPoolDataSource() { this( true ); } private void setUpPropertyListeners() { VetoableChangeListener setConnectionTesterListener = new VetoableChangeListener() { // always called within synchronized mutators of the parent class... needn't explicitly sync here public void vetoableChange( PropertyChangeEvent evt ) throws PropertyVetoException { String propName = evt.getPropertyName(); Object val = evt.getNewValue(); if ( "connectionTesterClassName".equals( propName ) ) { try { recreateConnectionTester( (String) val ); } catch ( Exception e ) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to create ConnectionTester of class " + val, e ); throw new PropertyVetoException("Could not instantiate connection tester class with name '" + val + "'.", evt); } } else if ("userOverridesAsString".equals( propName )) { try { WrapperConnectionPoolDataSource.this.userOverrides = C3P0ImplUtils.parseUserOverridesAsString( (String) val ); } catch (Exception e) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to parse stringified userOverrides. " + val, e ); throw new PropertyVetoException("Failed to parse stringified userOverrides. " + val, evt); } } } }; this.addVetoableChangeListener( setConnectionTesterListener ); } public WrapperConnectionPoolDataSource( String configName ) { this(); try { if (configName != null) C3P0Config.bindNamedConfigToBean( this, configName ); } catch (Exception e) { if (logger.isLoggable( MLevel.WARNING )) logger.log( MLevel.WARNING, "Error binding WrapperConnectionPoolDataSource to named-config '" + configName + "'. Some default-config values may be used.", e); } } // implementation of javax.sql.ConnectionPoolDataSource public PooledConnection getPooledConnection() throws SQLException { return this.getPooledConnection( (ConnectionCustomizer) null, null ); } // getNestedDataSource() is sync'ed, which is enough. Unsync'ed this method, // because when sync'ed a hang in retrieving one connection blocks all // protected PooledConnection getPooledConnection( ConnectionCustomizer cc, String pdsIdt ) throws SQLException { DataSource nds = getNestedDataSource(); if (nds == null) throw new SQLException( "No standard DataSource has been set beneath this wrapper! [ nestedDataSource == null ]"); Connection conn = nds.getConnection(); if (conn == null) throw new SQLException("An (unpooled) DataSource returned null from its getConnection() method! " + "DataSource: " + getNestedDataSource()); if ( this.isUsesTraditionalReflectiveProxies() ) { //return new C3P0PooledConnection( new com.mchange.v2.c3p0.test.CloseReportingConnection( conn ), return new C3P0PooledConnection( conn, connectionTester, this.isAutoCommitOnClose(), this.isForceIgnoreUnresolvedTransactions(), cc, pdsIdt); } else { return new NewPooledConnection( conn, connectionTester, this.isAutoCommitOnClose(), this.isForceIgnoreUnresolvedTransactions(), this.getPreferredTestQuery(), cc, pdsIdt); } } public PooledConnection getPooledConnection(String user, String password) throws SQLException { return this.getPooledConnection( user, password, null, null ); } // getNestedDataSource() is sync'ed, which is enough. Unsync'ed this method, // because when sync'ed a hang in retrieving one connection blocks all // protected PooledConnection getPooledConnection(String user, String password, ConnectionCustomizer cc, String pdsIdt) throws SQLException { DataSource nds = getNestedDataSource(); if (nds == null) throw new SQLException( "No standard DataSource has been set beneath this wrapper! [ nestedDataSource == null ]"); Connection conn = nds.getConnection(user, password); if (conn == null) throw new SQLException("An (unpooled) DataSource returned null from its getConnection() method! " + "DataSource: " + getNestedDataSource()); if ( this.isUsesTraditionalReflectiveProxies() ) { //return new C3P0PooledConnection( new com.mchange.v2.c3p0.test.CloseReportingConnection( conn ), return new C3P0PooledConnection( conn, connectionTester, this.isAutoCommitOnClose(), this.isForceIgnoreUnresolvedTransactions(), cc, pdsIdt); } else { return new NewPooledConnection( conn, connectionTester, this.isAutoCommitOnClose(), this.isForceIgnoreUnresolvedTransactions(), this.getPreferredTestQuery(), cc, pdsIdt); } } public PrintWriter getLogWriter() throws SQLException { return getNestedDataSource().getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { getNestedDataSource().setLogWriter( out ); } public void setLoginTimeout(int seconds) throws SQLException { getNestedDataSource().setLoginTimeout( seconds ); } public int getLoginTimeout() throws SQLException { return getNestedDataSource().getLoginTimeout(); } //"virtual properties" public String getUser() { try { return C3P0ImplUtils.findAuth( this.getNestedDataSource() ).getUser(); } catch (SQLException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while trying to find the 'user' property from our nested DataSource." + " Defaulting to no specified username.", e ); return null; } } public String getPassword() { try { return C3P0ImplUtils.findAuth( this.getNestedDataSource() ).getPassword(); } catch (SQLException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while trying to find the 'password' property from our nested DataSource." + " Defaulting to no specified password.", e ); return null; } } public Map getUserOverrides() { return userOverrides; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append( super.toString() ); // if (userOverrides != null) // sb.append("; userOverrides: " + userOverrides.toString()); return sb.toString(); } protected String extraToStringInfo() { if (userOverrides != null) return "; userOverrides: " + userOverrides.toString(); else return null; } //other code private synchronized void recreateConnectionTester(String className) throws Exception { if (className != null) { ConnectionTester ct = (ConnectionTester) Class.forName( className ).newInstance(); this.connectionTester = ct; } else this.connectionTester = C3P0ImplUtils.defaultConnectionTester(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/cfg/0000755000175000017500000000000010673162231017164 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/cfg/junit/0000755000175000017500000000000010673162231020315 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/cfg/junit/BasicMultiPropertiesConfigJUnitTestCase.java0000644000175000017500000000376310624366527031050 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cfg.junit; import junit.framework.*; import com.mchange.v2.cfg.*; public final class BasicMultiPropertiesConfigJUnitTestCase extends TestCase { final static String RP_A = "/com/mchange/v2/cfg/junit/a.properties"; final static String RP_B = "/com/mchange/v2/cfg/junit/b.properties"; public void testNoSystemConfig() { MultiPropertiesConfig mpc = new BasicMultiPropertiesConfig(new String[] {RP_A, RP_B}); //System.err.println(mpc.getProperty( "user.home" )); assertTrue( "/b/home".equals( mpc.getProperty( "user.home" ) ) ); } public void testSystemShadows() { MultiPropertiesConfig mpc = new BasicMultiPropertiesConfig(new String[] {RP_A, RP_B, "/"}); //System.err.println(mpc.getProperty( "user.home" )); assertTrue( (! "/b/home".equals( mpc.getProperty( "user.home" ) ) ) && (! "/a/home".equals( mpc.getProperty( "user.home" ) ) ) ); } public void testSystemShadowed() { MultiPropertiesConfig mpc = new BasicMultiPropertiesConfig(new String[] {RP_A, "/", RP_B}); //System.err.println(mpc.getProperty( "user.home" )); assertTrue( "/b/home".equals( mpc.getProperty( "user.home" ) ) ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/cfg/BasicMultiPropertiesConfig.java0000644000175000017500000002132710624366530025277 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cfg; import java.util.*; import java.io.*; import com.mchange.v2.log.*; public class BasicMultiPropertiesConfig extends MultiPropertiesConfig { String[] rps; Map propsByResourcePaths = new HashMap(); Map propsByPrefixes; Properties propsByKey; public BasicMultiPropertiesConfig(String[] resourcePaths) { this( resourcePaths, null ); } public BasicMultiPropertiesConfig(String[] resourcePaths, MLogger logger) { List goodPaths = new ArrayList(); for( int i = 0, len = resourcePaths.length; i < len; ++i ) { String rp = resourcePaths[i]; if ("/".equals(rp)) { try { propsByResourcePaths.put( rp, System.getProperties() ); goodPaths.add( rp ); } catch (SecurityException e) { if (logger != null) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Read of system Properties blocked -- " + "ignoring any configuration via System properties, and using Empty Properties! " + "(But any configuration via a resource properties files is still okay!)", e ); } else { System.err.println("Read of system Properties blocked -- " + "ignoring any configuration via System properties, and using Empty Properties! " + "(But any configuration via a resource properties files is still okay!)"); e.printStackTrace(); } } } else { Properties p = new Properties(); InputStream pis = MultiPropertiesConfig.class.getResourceAsStream( rp ); if ( pis != null ) { try { p.load( pis ); propsByResourcePaths.put( rp, p ); goodPaths.add( rp ); } catch (IOException e) { if (logger != null) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An IOException occurred while loading configuration properties from resource path '" + rp + "'.", e ); } else e.printStackTrace(); } finally { try { if ( pis != null ) pis.close(); } catch (IOException e) { if (logger != null) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An IOException occurred while closing InputStream from resource path '" + rp + "'.", e ); } else e.printStackTrace(); } } } else { if (logger != null) { if ( logger.isLoggable( MLevel.FINE ) ) logger.fine( "Configuration properties not found at ResourcePath '" + rp + "'. [logger name: " + logger.getName() + ']' ); } // else if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) // System.err.println("Configuration properties not found at ResourcePath '" + rp + "'." ); } } } this.rps = (String[]) goodPaths.toArray( new String[ goodPaths.size() ] ); this.propsByPrefixes = Collections.unmodifiableMap( extractPrefixMapFromRsrcPathMap(rps, propsByResourcePaths) ); this.propsByResourcePaths = Collections.unmodifiableMap( propsByResourcePaths ); this.propsByKey = extractPropsByKey(rps, propsByResourcePaths); } private static String extractPrefix( String s ) { int lastdot = s.lastIndexOf('.'); if ( lastdot < 0 ) return null; else return s.substring(0, lastdot); } private static Properties findProps(String rp, Map pbrp) { //System.err.println("findProps( " + rp + ", ... )"); Properties p; // MOVED THIS LOGIC INTO CONSTRUCTOR ABOVE, TO TREAT SYSTEM PROPS UNIFORMLY // WITH THE REST, AND TO AVOID UNINTENTIONAL ATTEMPTS TO READ RESOURCE "/" // AS STREAM -- swaldman, 2006-01-19 // if ( "/".equals( rp ) ) // { // try { p = System.getProperties(); } // catch ( SecurityException e ) // { // System.err.println(BasicMultiPropertiesConfig.class.getName() + // " Read of system Properties blocked -- ignoring any configuration via System properties, and using Empty Properties! " + // "(But any configuration via a resource properties files is still okay!)"); // p = new Properties(); // } // } // else p = (Properties) pbrp.get( rp ); // System.err.println( p ); return p; } private static Properties extractPropsByKey( String[] resourcePaths, Map pbrp ) { Properties out = new Properties(); for (int i = 0, len = resourcePaths.length; i < len; ++i) { String rp = resourcePaths[i]; Properties p = findProps( rp, pbrp ); if (p == null) { System.err.println("Could not find loaded properties for resource path: " + rp); continue; } for (Iterator ii = p.keySet().iterator(); ii.hasNext(); ) { Object kObj = ii.next(); if (!(kObj instanceof String)) { // note that we can not use the MLog library here, because initialization // of that library depends on this function. System.err.println( BasicMultiPropertiesConfig.class.getName() + ": " + "Properties object found at resource path " + ("/".equals(rp) ? "[system properties]" : "'" + rp + "'") + "' contains a key that is not a String: " + kObj); System.err.println("Skipping..."); continue; } Object vObj = p.get( kObj ); if (vObj != null && !(vObj instanceof String)) { // note that we can not use the MLog library here, because initialization // of that library depends on this function. System.err.println( BasicMultiPropertiesConfig.class.getName() + ": " + "Properties object found at resource path " + ("/".equals(rp) ? "[system properties]" : "'" + rp + "'") + " contains a value that is not a String: " + vObj); System.err.println("Skipping..."); continue; } String key = (String) kObj; String val = (String) vObj; out.put( key, val ); } } return out; } private static Map extractPrefixMapFromRsrcPathMap(String[] resourcePaths, Map pbrp) { Map out = new HashMap(); //for( Iterator ii = pbrp.values().iterator(); ii.hasNext(); ) for (int i = 0, len = resourcePaths.length; i < len; ++i) { String rp = resourcePaths[i]; Properties p = findProps( rp, pbrp ); if (p == null) { System.err.println(BasicMultiPropertiesConfig.class.getName() + " -- Could not find loaded properties for resource path: " + rp); continue; } for (Iterator jj = p.keySet().iterator(); jj.hasNext(); ) { Object kObj = jj.next(); if (! (kObj instanceof String)) { // note that we can not use the MLog library here, because initialization // of that library depends on this function. System.err.println( BasicMultiPropertiesConfig.class.getName() + ": " + "Properties object found at resource path " + ("/".equals(rp) ? "[system properties]" : "'" + rp + "'") + "' contains a key that is not a String: " + kObj); System.err.println("Skipping..."); continue; } String key = (String) kObj; String prefix = extractPrefix( key ); while (prefix != null) { Properties byPfx = (Properties) out.get( prefix ); if (byPfx == null) { byPfx = new Properties(); out.put( prefix, byPfx ); } byPfx.put( key, p.get( key ) ); prefix=extractPrefix( prefix ); } } } return out; } public String[] getPropertiesResourcePaths() { return (String[]) rps.clone(); } public Properties getPropertiesByResourcePath(String path) { Properties out = ((Properties) propsByResourcePaths.get( path )); return (out == null ? new Properties() : out); } public Properties getPropertiesByPrefix(String pfx) { Properties out = ((Properties) propsByPrefixes.get( pfx )); return (out == null ? new Properties() : out); } public String getProperty( String key ) { return propsByKey.getProperty( key ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/cfg/CombinedMultiPropertiesConfig.java0000644000175000017500000000540510624366530025775 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cfg; import java.util.*; class CombinedMultiPropertiesConfig extends MultiPropertiesConfig { MultiPropertiesConfig[] configs; String[] resourcePaths; CombinedMultiPropertiesConfig( MultiPropertiesConfig[] configs ) { this.configs = configs; List allPaths = new LinkedList(); for (int i = configs.length - 1; i >= 0; --i) { String[] rps = configs[i].getPropertiesResourcePaths(); for (int j = rps.length - 1; j >= 0; --j) { String rp = rps[j]; if (! allPaths.contains( rp ) ) allPaths.add(0, rp); } } this.resourcePaths = (String[]) allPaths.toArray( new String[ allPaths.size() ] ); } public String[] getPropertiesResourcePaths() { return (String[]) resourcePaths.clone(); } public Properties getPropertiesByResourcePath(String path) { for (int i = configs.length - 1; i >= 0; --i) { MultiPropertiesConfig config = configs[i]; Properties check = config.getPropertiesByResourcePath(path); if (check != null) return check; } return null; } public Properties getPropertiesByPrefix(String pfx) { List entries = new LinkedList(); for (int i = configs.length - 1; i >= 0; --i) { MultiPropertiesConfig config = configs[i]; Properties check = config.getPropertiesByPrefix(pfx); if (check != null) entries.addAll( 0, check.entrySet() ); } if (entries.size() == 0) return null; else { Properties out = new Properties(); for (Iterator ii = entries.iterator(); ii.hasNext(); ) { Map.Entry entry = (Map.Entry) ii.next(); out.put( entry.getKey(), entry.getValue() ); } return out; } } public String getProperty( String key ) { for (int i = configs.length - 1; i >= 0; --i) { MultiPropertiesConfig config = configs[i]; String check = config.getProperty(key); if (check != null) return check; } return null; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/cfg/MultiPropertiesConfig.java0000644000175000017500000001136110624366527024340 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.cfg; import java.util.*; import java.io.*; import com.mchange.v2.log.*; /** * MultiPropertiesConfig allows applications to accept configuration data * from a more than one property file (each of which is to be loaded from * a unique path using this class' ClassLoader's resource-loading mechanism), * and permits access to property data via the resource path from which the * properties were loaded, via the prefix of the property (where hierarchical * property names are presumed to be '.'-separated), and simply by key. * In the by-key and by-prefix indices, when two definitions conflict, the * key value pairing specified in the MOST RECENT properties file shadows * earlier definitions, and files are loaded in the order of the list of * resource paths provided a constructor. * * The rescource path "/" is a special case that always refers to System * properties. No actual resource will be loaded. * The class manages a special instance called "vmConfig" which is accessable * via a static method. It's resource path is list specified by a text-file, * itself a ClassLoader managed resource, which must be located at * /com/mchange/v2/cfg/vmConfigResourcePaths.txt. This file should * be one resource path per line, with blank lines ignored and lines beginning * with '#' treated as comments. */ public abstract class MultiPropertiesConfig { final static MultiPropertiesConfig EMPTY = new BasicMultiPropertiesConfig( new String[0] ); final static String VM_CONFIG_RSRC_PATHS = "/com/mchange/v2/cfg/vmConfigResourcePaths.txt"; static MultiPropertiesConfig vmConfig = null; public static MultiPropertiesConfig read(String[] resourcePath, MLogger logger) { return new BasicMultiPropertiesConfig( resourcePath, logger ); } public static MultiPropertiesConfig read(String[] resourcePath) { return new BasicMultiPropertiesConfig( resourcePath ); } public static MultiPropertiesConfig combine( MultiPropertiesConfig[] configs ) { return new CombinedMultiPropertiesConfig( configs ); } public static MultiPropertiesConfig readVmConfig(String[] defaultResources, String[] preemptingResources) { List l = new LinkedList(); if (defaultResources != null) l.add( read( defaultResources ) ); l.add( readVmConfig() ); if (preemptingResources != null) l.add( read( preemptingResources ) ); return combine( (MultiPropertiesConfig[]) l.toArray( new MultiPropertiesConfig[ l.size() ] ) ); } public static MultiPropertiesConfig readVmConfig() { if ( vmConfig == null ) { List rps = new ArrayList(); BufferedReader br = null; try { InputStream is = MultiPropertiesConfig.class.getResourceAsStream( VM_CONFIG_RSRC_PATHS ); if ( is != null ) { br = new BufferedReader( new InputStreamReader( is, "8859_1" ) ); String rp; while ((rp = br.readLine()) != null) { rp = rp.trim(); if ("".equals( rp ) || rp.startsWith("#")) continue; rps.add( rp ); } vmConfig = new BasicMultiPropertiesConfig( (String[]) rps.toArray( new String[ rps.size() ] ) ); } else { System.err.println("com.mchange.v2.cfg.MultiPropertiesConfig: Resource path list could not be found at resource path: " + VM_CONFIG_RSRC_PATHS); System.err.println("com.mchange.v2.cfg.MultiPropertiesConfig: Using empty vmconfig."); vmConfig = EMPTY; } } catch (IOException e) { e.printStackTrace(); } finally { try { if ( br != null ) br.close(); } catch (IOException e) { e.printStackTrace(); } } } return vmConfig; } public boolean foundVmConfig() { return vmConfig != EMPTY; } public abstract String[] getPropertiesResourcePaths(); public abstract Properties getPropertiesByResourcePath(String path); public abstract Properties getPropertiesByPrefix(String pfx); public abstract String getProperty( String key ); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/0000755000175000017500000000000010673162231020203 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/AbstractStrongCoalescer.java0000644000175000017500000000260210624366527025641 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; class AbstractStrongCoalescer implements Coalescer { Map coalesced; AbstractStrongCoalescer( Map coalesced ) { this.coalesced = coalesced; } public Object coalesce( Object o ) { Object out = coalesced.get( o ); if ( out == null ) { coalesced.put( o , o ); out = o; } return out; } public int countCoalesced() { return coalesced.size(); } public Iterator iterator() { return new CoalescerIterator( coalesced.keySet().iterator() ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/AbstractWeakCoalescer.java0000644000175000017500000000326010624366527025255 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; import java.lang.ref.WeakReference; class AbstractWeakCoalescer implements Coalescer { Map wcoalesced; AbstractWeakCoalescer( Map wcoalesced ) { this.wcoalesced = wcoalesced; } public Object coalesce( Object o ) { //System.err.println("AbstractWeakCoalescer.coalesce( " + o + " )"); Object out = null; WeakReference wr = (WeakReference) wcoalesced.get( o ); if ( wr != null ) out = wr.get(); //there is a conceivable race that would //permit wr be cleared if ( out == null ) { wcoalesced.put( o , new WeakReference(o) ); out = o; } return out; } public int countCoalesced() { return wcoalesced.size(); } public Iterator iterator() { return new CoalescerIterator( wcoalesced.keySet().iterator() ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/CoalesceChecker.java0000644000175000017500000000252010624366527024062 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; public interface CoalesceChecker { /** * @return true iff a and b should be considered equivalent, * so that a Coalescer should simply return whichever * Object it considers canonical. */ public boolean checkCoalesce( Object a, Object b ); /** * Any two objects for which checkCoalese() would return true must * coalesce hash to the same value!!! */ public int coalesceHash( Object a ); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/CoalesceIdenticator.java0000644000175000017500000000232310624366527024764 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import com.mchange.v1.identicator.*; class CoalesceIdenticator implements Identicator { CoalesceChecker cc; CoalesceIdenticator( CoalesceChecker cc ) { this.cc = cc; } public boolean identical(Object a, Object b) { return cc.checkCoalesce( a , b ); } public int hash(Object o) { return cc.coalesceHash( o ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/Coalescer.java0000644000175000017500000000203710624366530022754 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.Iterator; public interface Coalescer { public Object coalesce( Object o ); public int countCoalesced(); public Iterator iterator(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/CoalescerFactory.java0000644000175000017500000001000010624366527024277 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; public final class CoalescerFactory { /** *

Creates a "Coalescer" that coalesces Objects according to their * equals() method. Given a set of n Objects among whom equals() would * return true, calling coalescer.coalesce() in any order on any sequence * of these Objects will always return a single "canonical" instance.

* *

This method creates a weak, synchronized coalesecer, safe for use * by multiple Threads.

*/ public static Coalescer createCoalescer() { return createCoalescer( true, true ); } /** *

Creates a "Coalescer" that coalesces Objects according to their * equals() method. Given a set of n Objects among whom equals() would * return true, calling coalescer.coalesce() in any order on any sequence * of these Objects will always return a single "canonical" instance.

* * @param weak if true, the Coalescer will use WeakReferences to hold * its canonical instances, allowing them to be garbage * collected if they are nowhere in use. * * @param synced if true, access to the Coalescer will be automatically * synchronized. if set to false, then users must manually * synchronize access. */ public static Coalescer createCoalescer( boolean weak, boolean synced ) { return createCoalescer( null, weak, synced ); } /** *

Creates a "Coalescer" that coalesces Objects according to the * checkCoalesce() method of a "CoalesceChecker". Given a set of * n Objects among whom calling cc.checkCoalesce() on any pair would * return true, calling coalescer.coalesce() in any order on any sequence * of these Objects will always return a single "canonical" instance. * This allows one to define immutable value Objects whose equals() * method is a mere identity test -- one can use a Coalescer in a * factory method to ensure that no two instances with the same values * are made available to clients.

* * @param cc CoalesceChecker that will be used to determine whether two * objects are equivalent and can be coalesced. [If cc is null, then two * objects will be coalesced iff o1.equals( o2 ).] * * @param weak if true, the Coalescer will use WeakReferences to hold * its canonical instances, allowing them to be garbage * collected if they are nowhere in use. * * @param synced if true, access to the Coalescer will be automatically * synchronized. if set to false, then users must manually * synchronize access. */ public static Coalescer createCoalescer( CoalesceChecker cc, boolean weak, boolean synced ) { Coalescer out; if ( cc == null ) { out = ( weak ? (Coalescer) new WeakEqualsCoalescer() : (Coalescer) new StrongEqualsCoalescer() ); } else { out = ( weak ? (Coalescer) new WeakCcCoalescer( cc ) : (Coalescer) new StrongCcCoalescer( cc ) ); } return ( synced ? new SyncedCoalescer( out ) : out ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/CoalescerIterator.java0000644000175000017500000000241610624366527024475 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; class CoalescerIterator implements Iterator { Iterator inner; CoalescerIterator(Iterator inner) { this.inner = inner; } public boolean hasNext() { return inner.hasNext(); } public Object next() { return inner.next(); } public void remove() { throw new UnsupportedOperationException("Objects cannot be removed from a coalescer!"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/StrongCcCoalescer.java0000644000175000017500000000221010624366527024416 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; import com.mchange.v1.identicator.IdHashMap; final class StrongCcCoalescer extends AbstractStrongCoalescer implements Coalescer { StrongCcCoalescer( CoalesceChecker cc ) { super( new IdHashMap( new CoalesceIdenticator( cc ) ) ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/StrongEqualsCoalescer.java0000644000175000017500000000212310624366527025326 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; import java.lang.ref.WeakReference; final class StrongEqualsCoalescer extends AbstractStrongCoalescer implements Coalescer { StrongEqualsCoalescer() { super( new HashMap() ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/SyncedCoalescer.java0000644000175000017500000000245610624366527024135 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.Iterator; class SyncedCoalescer implements Coalescer { Coalescer inner; public SyncedCoalescer( Coalescer inner ) { this.inner = inner; } public synchronized Object coalesce( Object o ) { return inner.coalesce( o ); } public synchronized int countCoalesced() { return inner.countCoalesced(); } public synchronized Iterator iterator() { return inner.iterator(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/WeakCcCoalescer.java0000644000175000017500000000225010624366527024035 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; import java.lang.ref.WeakReference; import com.mchange.v1.identicator.IdWeakHashMap; final class WeakCcCoalescer extends AbstractWeakCoalescer implements Coalescer { WeakCcCoalescer(CoalesceChecker cc) { super( new IdWeakHashMap( new CoalesceIdenticator( cc ) ) ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/coalesce/WeakEqualsCoalescer.java0000644000175000017500000000206110624366527024742 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.coalesce; import java.util.*; import java.lang.ref.WeakReference; class WeakEqualsCoalescer extends AbstractWeakCoalescer { WeakEqualsCoalescer() { super( new WeakHashMap() ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/0000755000175000017500000000000010673162231020031 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/0000755000175000017500000000000010673162231020736 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/BeanExtractingGeneratorExtension.java0000644000175000017500000000777210624366530030264 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class BeanExtractingGeneratorExtension implements GeneratorExtension { int ctor_modifiers = Modifier.PUBLIC; int method_modifiers = Modifier.PRIVATE; public void setConstructorModifiers( int ctor_modifiers ) { this.ctor_modifiers = ctor_modifiers; } public int getConstructorModifiers() { return ctor_modifiers; } public void setExtractMethodModifiers( int method_modifiers ) { this.method_modifiers = method_modifiers; } public int getExtractMethodModifiers() { return method_modifiers; } public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { Set set = new HashSet(); set.add("java.beans.BeanInfo"); set.add("java.beans.PropertyDescriptor"); set.add("java.beans.Introspector"); set.add("java.beans.IntrospectionException"); set.add("java.lang.reflect.InvocationTargetException"); return set; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.println("private static Class[] NOARGS = new Class[0];"); iw.println(); iw.print( CodegenUtils.getModifierString( method_modifiers ) ); iw.print(" void extractPropertiesFromBean( Object bean ) throws InvocationTargetException, IllegalAccessException, IntrospectionException"); iw.println("{"); iw.upIndent(); iw.println("BeanInfo bi = Introspector.getBeanInfo( bean.getClass() );"); iw.println("PropertyDescriptor[] pds = bi.getPropertyDescriptors();"); iw.println("for (int i = 0, len = pds.length; i < len; ++i)"); iw.println("{"); iw.upIndent(); for (int i = 0, len = props.length; i < len; ++i) { iw.println("if (\"" + props[i].getName() + "\".equals( pds[i].getName() ) )"); iw.upIndent(); iw.println("this." + props[i].getName() + " = " + extractorExpr( props[i], propTypes[i] ) + ';'); iw.downIndent(); } iw.println("}"); //for loop iw.downIndent(); iw.println("}"); //method iw.println(); iw.print( CodegenUtils.getModifierString( ctor_modifiers ) ); iw.println(' ' + info.getClassName() + "( Object bean ) throws InvocationTargetException, IllegalAccessException, IntrospectionException"); iw.println("{"); iw.upIndent(); iw.println("extractPropertiesFromBean( bean );"); iw.downIndent(); iw.println("}"); } private String extractorExpr( Property prop, Class propType ) { if ( propType.isPrimitive() ) { String castType = BeangenUtils.capitalize( prop.getSimpleTypeName() ); String valueMethod = prop.getSimpleTypeName() + "Value()"; if ( propType == char.class) castType = "Character"; else if ( propType == int.class) castType = "Integer"; return "((" + castType + ") pds[i].getReadMethod().invoke( bean, NOARGS ))." + valueMethod; } else return "(" + prop.getSimpleTypeName() + ") pds[i].getReadMethod().invoke( bean, NOARGS )"; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/BeangenUtils.java0000644000175000017500000002017310624366527024176 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.Comparator; import java.io.IOException; import java.lang.reflect.Modifier; import com.mchange.v1.lang.ClassUtils; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public final class BeangenUtils { public final static Comparator PROPERTY_COMPARATOR = new Comparator() { public int compare(Object a, Object b) { Property aa = (Property) a; Property bb = (Property) b; return String.CASE_INSENSITIVE_ORDER.compare(aa.getName(), bb.getName() ); } }; public static String capitalize( String propName ) { char c = propName.charAt( 0 ); return Character.toUpperCase(c) + propName.substring(1); } // public static Class[] attemptResolveTypes(ClassInfo info, Property[] props) // { // String[] gen = info.getGeneralImports(); // String[] spc = info.getSpecificImports(); // Class[] out = new Class[ props.length ]; // for ( int i = 0, len = props.length; i < len; ++i ) // { // String name = props[i].getSimpleTypeName(); // try // { out[i] = ClassUtils.forName( name , gen, spc ); } // catch ( Exception e ) // { // e.printStackTrace(); // System.err.println("WARNING: " + this.getClass().getName() + " could not resolve " + // "property type '" + name + "'."); // out[i] = null; // } // } // } public static void writeExplicitDefaultConstructor( int ctor_modifiers, ClassInfo info, IndentedWriter iw) throws IOException { iw.print( CodegenUtils.getModifierString( ctor_modifiers ) ); iw.println(' ' + info.getClassName() + "()"); iw.println("{}"); } public static void writeArgList(Property[] props, boolean declare_types, IndentedWriter iw ) throws IOException { for (int i = 0, len = props.length; i < len; ++i) { if (i != 0) iw.print(", "); if (declare_types) iw.print(props[i].getSimpleTypeName() + ' '); iw.print( props[i].getName() ); } } /** * @deprecated use writePropertyVariable */ public static void writePropertyMember( Property prop, IndentedWriter iw ) throws IOException { writePropertyVariable( prop, iw ); } public static void writePropertyVariable( Property prop, IndentedWriter iw ) throws IOException { writePropertyVariable( prop, prop.getDefaultValueExpression(), iw ); } /** * @deprecated use writePropertyVariable */ public static void writePropertyMember( Property prop, String defaultValueExpression, IndentedWriter iw ) throws IOException { writePropertyVariable( prop, defaultValueExpression, iw ); } public static void writePropertyVariable( Property prop, String defaultValueExpression, IndentedWriter iw ) throws IOException { iw.print( CodegenUtils.getModifierString( prop.getVariableModifiers() ) ); iw.print( ' ' + prop.getSimpleTypeName() + ' ' + prop.getName()); String dflt = defaultValueExpression; if (dflt != null) iw.print( " = " + dflt ); iw.println(';'); } public static void writePropertyGetter( Property prop, IndentedWriter iw ) throws IOException { writePropertyGetter( prop, prop.getDefensiveCopyExpression(), iw ); } public static void writePropertyGetter( Property prop, String defensiveCopyExpression, IndentedWriter iw ) throws IOException { String pfx = ("boolean".equals( prop.getSimpleTypeName() ) ? "is" : "get" ); iw.print( CodegenUtils.getModifierString( prop.getGetterModifiers() ) ); iw.println(' ' + prop.getSimpleTypeName() + ' ' + pfx + BeangenUtils.capitalize( prop.getName() ) + "()"); String retVal = defensiveCopyExpression; if (retVal == null) retVal = prop.getName(); iw.println("{ return " + retVal + "; }"); } public static void writePropertySetter( Property prop, IndentedWriter iw ) throws IOException { writePropertySetter( prop, prop.getDefensiveCopyExpression(), iw ); } public static void writePropertySetter( Property prop, String setterDefensiveCopyExpression, IndentedWriter iw ) throws IOException { String setVal = setterDefensiveCopyExpression; if (setVal == null) setVal = prop.getName(); String usualGetExpression = ("this." + prop.getName()); String usualSetStatement = ("this." + prop.getName() + " = " + setVal + ';'); writePropertySetterWithGetExpressionSetStatement(prop, usualGetExpression, usualSetStatement, iw); } public static void writePropertySetterWithGetExpressionSetStatement( Property prop, String getExpression, String setStatement, IndentedWriter iw ) throws IOException { iw.print( CodegenUtils.getModifierString( prop.getSetterModifiers() ) ); iw.print(" void set" + BeangenUtils.capitalize( prop.getName() ) + "( " + prop.getSimpleTypeName() + ' ' + prop.getName() + " )"); if ( prop.isConstrained() ) iw.println(" throws PropertyVetoException"); else iw.println(); iw.println('{'); iw.upIndent(); if ( changeMarked( prop ) ) { iw.println( prop.getSimpleTypeName() + " oldVal = " + getExpression + ';'); String oldValExpr = "oldVal"; String newValExpr = prop.getName(); String changeCheck; String simpleTypeName = prop.getSimpleTypeName(); if ( ClassUtils.isPrimitive( simpleTypeName ) ) { Class propType = ClassUtils.classForPrimitive( simpleTypeName ); // PropertyChangeSupport already has overloads // for boolean and int if (propType == byte.class) { oldValExpr = "new Byte( "+ oldValExpr +" )"; newValExpr = "new Byte( "+ newValExpr +" )"; } else if (propType == char.class) { oldValExpr = "new Character( "+ oldValExpr +" )"; newValExpr = "new Character( "+ newValExpr +" )"; } else if (propType == short.class) { oldValExpr = "new Short( "+ oldValExpr +" )"; newValExpr = "new Short( "+ newValExpr +" )"; } else if (propType == float.class) { oldValExpr = "new Float( "+ oldValExpr +" )"; newValExpr = "new Float( "+ newValExpr +" )"; } else if (propType == double.class) { oldValExpr = "new Double( "+ oldValExpr +" )"; newValExpr = "new Double( "+ newValExpr +" )"; } changeCheck = "oldVal != " + prop.getName(); } else changeCheck = "! eqOrBothNull( oldVal, " + prop.getName() + " )"; if ( prop.isConstrained() ) { iw.println("if ( " + changeCheck + " )"); iw.upIndent(); iw.println("vcs.fireVetoableChange( \"" + prop.getName() + "\", " + oldValExpr + ", " + newValExpr + " );"); iw.downIndent(); } iw.println( setStatement ); if ( prop.isBound() ) { iw.println("if ( " + changeCheck + " )"); iw.upIndent(); iw.println("pcs.firePropertyChange( \"" + prop.getName() + "\", " + oldValExpr + ", " + newValExpr + " );"); iw.downIndent(); } } else iw.println( setStatement ); iw.downIndent(); iw.println('}'); } public static boolean hasBoundProperties(Property[] props) { for (int i = 0, len = props.length; i < len; ++i) if (props[i].isBound()) return true; return false; } public static boolean hasConstrainedProperties(Property[] props) { for (int i = 0, len = props.length; i < len; ++i) if (props[i].isConstrained()) return true; return false; } private static boolean changeMarked( Property prop ) { return prop.isBound() || prop.isConstrained(); } private BeangenUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ClassInfo.java0000644000175000017500000000226110624366527023475 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; public interface ClassInfo { public String getPackageName(); public int getModifiers(); public String getClassName(); public String getSuperclassName(); public String[] getInterfaceNames(); public String[] getGeneralImports(); public String[] getSpecificImports(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/CloneableExtension.java0000644000175000017500000000707710624366530025401 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.io.IOException; import com.mchange.v2.codegen.IndentedWriter; public class CloneableExtension implements GeneratorExtension { boolean export_public; boolean exception_swallowing; String mLoggerName = null; public boolean isExportPublic() { return export_public; } public void setExportPublic(boolean export_public) { this.export_public = export_public; } public boolean isExceptionSwallowing() { return exception_swallowing; } public void setExceptionSwallowing(boolean exception_swallowing) { this.exception_swallowing = exception_swallowing; } public String getMLoggerName() { return mLoggerName; } public void setMLoggerName( String mLoggerName ) { this.mLoggerName = mLoggerName; } public CloneableExtension(boolean export_public, boolean exception_swallowing) { this.export_public = export_public; this.exception_swallowing = exception_swallowing; } public CloneableExtension() { this ( true, false ); } public Collection extraGeneralImports() { return (mLoggerName == null ? ((Collection) Collections.EMPTY_SET) : ((Collection) Arrays.asList( new String[] {"com.mchange.v2.log"} )) ); } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { Set set = new HashSet(); set.add( "Cloneable" ); return set; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { if (export_public) { iw.print("public Object clone()"); if ( !exception_swallowing ) iw.println(" throws CloneNotSupportedException"); else iw.println(); iw.println("{"); iw.upIndent(); if ( exception_swallowing ) { iw.println("try"); iw.println("{"); iw.upIndent(); } iw.println( "return super.clone();" ); if ( exception_swallowing ) { iw.downIndent(); iw.println("}"); iw.println("catch (CloneNotSupportedException e)"); iw.println("{"); iw.upIndent(); if (mLoggerName == null) iw.println("e.printStackTrace();"); else { iw.println("if ( " + mLoggerName + ".isLoggable( MLevel.FINE ) )" ); iw.upIndent(); iw.println( mLoggerName + ".log( MLevel.FINE, \"Inconsistent clone() definitions between subclass and superclass! \", e );"); iw.downIndent(); } iw.println("throw new RuntimeException(\"Inconsistent clone() definitions between subclass and superclass! \" + e);" ); iw.downIndent(); iw.println("}"); } iw.downIndent(); iw.println("}"); } //else, write nothing... just add Cloneable to interface definitions... } } ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/CompleteConstructorGeneratorExtension.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/CompleteConstructorGeneratorExtension.java0000644000175000017500000000405710624366530031375 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class CompleteConstructorGeneratorExtension implements GeneratorExtension { int ctor_modifiers = Modifier.PUBLIC; public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.print( CodegenUtils.getModifierString( ctor_modifiers ) ); iw.print( info.getClassName() + "( "); BeangenUtils.writeArgList(props, true, iw); iw.println(" )"); iw.println("{"); iw.upIndent(); for (int i = 0, len = props.length; i < len; ++i) { iw.print("this." + props[i].getName() + " = "); String setExp = props[i].getDefensiveCopyExpression(); if (setExp == null) setExp = props[i].getName(); iw.println(setExp + ';'); } iw.downIndent(); iw.println("}"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/CopyConstructorGeneratorExtension.java0000644000175000017500000000464410624366527030547 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class CopyConstructorGeneratorExtension implements GeneratorExtension { int ctor_modifiers = Modifier.PUBLIC; public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.print( CodegenUtils.getModifierString( ctor_modifiers ) ); iw.print(" " + info.getClassName() + "( "); iw.print( info.getClassName() + " copyMe" ); iw.println(" )"); iw.println("{"); iw.upIndent(); for (int i = 0, len = props.length; i < len; ++i) { String propGetterMethodCall; if (propTypes[i] == boolean.class) propGetterMethodCall = "is" + BeangenUtils.capitalize( props[i].getName() ) + "()"; else propGetterMethodCall = "get" + BeangenUtils.capitalize( props[i].getName() ) + "()"; iw.println(props[i].getSimpleTypeName() + ' ' + props[i].getName() + " = copyMe." + propGetterMethodCall + ';'); iw.print("this." + props[i].getName() + " = "); String setExp = props[i].getDefensiveCopyExpression(); if (setExp == null) setExp = props[i].getName(); iw.println(setExp + ';'); } iw.downIndent(); iw.println("}"); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ExplicitDefaultConstructorGeneratorExtension.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ExplicitDefaultConstructorGeneratorExtensi0000644000175000017500000000321310624366527031435 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class ExplicitDefaultConstructorGeneratorExtension implements GeneratorExtension { int ctor_modifiers = Modifier.PUBLIC; public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { BeangenUtils.writeExplicitDefaultConstructor( ctor_modifiers, info, iw); } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ExplicitPropsConstructorGeneratorExtension.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ExplicitPropsConstructorGeneratorExtension0000644000175000017500000000761110624366527031517 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import com.mchange.v2.log.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; /** * Writes a constructor that takes an explicitly listed subset of a bean's properties * for its arguments, and sets these properties initial values appropriately. * Skips any specified names for properties that are not found in a bean being generated. * Writes nothing if there are none of the property names are properties of the bean. */ public class ExplicitPropsConstructorGeneratorExtension implements GeneratorExtension { final static MLogger logger = MLog.getLogger( ExplicitPropsConstructorGeneratorExtension.class ); String[] propNames; boolean skips_silently = false; public ExplicitPropsConstructorGeneratorExtension() {} public ExplicitPropsConstructorGeneratorExtension(String[] propNames) { this.propNames = propNames; } public String[] getPropNames() { return (String[]) propNames.clone(); } public void setPropNames(String[] propNames) { this.propNames = (String[]) propNames.clone(); } public boolean isSkipsSilently() { return skips_silently; } public void setsSkipsSilently( boolean skips_silently ) { this.skips_silently = skips_silently; } int ctor_modifiers = Modifier.PUBLIC; public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { Map propNamesToProps = new HashMap(); for (int i = 0, len = props.length; i < len; ++i) propNamesToProps.put( props[i].getName(), props[i] ); List subPropsList = new ArrayList( propNames.length ); for (int i = 0, len = propNames.length; i < len; ++i) { Property p = (Property) propNamesToProps.get( propNames[i] ); if ( p == null ) logger.warning("Could not include property '" + propNames[i] +"' in explicit-props-constructor generated for bean class '" + info.getClassName() +"' because the property is not defined for the bean. Skipping."); else subPropsList.add(p); } if (subPropsList.size() > 0) { Property[] subProps = (Property[]) subPropsList.toArray( new Property[ subPropsList.size() ] ); iw.print( CodegenUtils.getModifierString( ctor_modifiers ) ); iw.print( info.getClassName() + "( "); BeangenUtils.writeArgList(subProps, true, iw); iw.println(" )"); iw.println("{"); iw.upIndent(); for (int i = 0, len = subProps.length; i < len; ++i) { iw.print("this." + subProps[i].getName() + " = "); String setExp = subProps[i].getDefensiveCopyExpression(); if (setExp == null) setExp = subProps[i].getName(); iw.println(setExp + ';'); } iw.downIndent(); iw.println("}"); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/GeneratorExtension.java0000644000175000017500000000271010624366527025436 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.io.IOException; import com.mchange.v2.codegen.IndentedWriter; /** * By the time generate(...) is called, all extra interfaces and imports from all * GeneratorExtensions should be incorporated into the passed-in ClassInfo object. */ public interface GeneratorExtension { public Collection extraGeneralImports(); public Collection extraSpecificImports(); public Collection extraInterfaceNames(); public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/IndirectingSerializableExtension.java0000644000175000017500000001275010624366530030275 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.io.Serializable; import java.io.IOException; import com.mchange.v2.codegen.IndentedWriter; import com.mchange.v2.ser.IndirectPolicy; public class IndirectingSerializableExtension extends SerializableExtension { protected String findIndirectorExpr; protected String indirectorClassName; /** * We expect this indirector to be a public class with a public no_arg ctor; * If you need the indirector initialized somehow, you'll have to extend * the class. * * @see #writeInitializeIndirector * @see #writeExtraDeclarations */ public IndirectingSerializableExtension( String indirectorClassName ) { this.indirectorClassName = indirectorClassName; this.findIndirectorExpr = "new " + indirectorClassName + "()"; } protected IndirectingSerializableExtension() {} public Collection extraSpecificImports() { Collection col = super.extraSpecificImports(); col.add( indirectorClassName ); col.add( "com.mchange.v2.ser.IndirectlySerialized" ); col.add( "com.mchange.v2.ser.Indirector" ); col.add( "com.mchange.v2.ser.SerializableUtils" ); col.add( "java.io.NotSerializableException" ); return col; } protected IndirectPolicy indirectingPolicy( Property prop, Class propType ) { if (Serializable.class.isAssignableFrom( propType )) return IndirectPolicy.DEFINITELY_DIRECT; else return IndirectPolicy.INDIRECT_ON_EXCEPTION; } /** * hook method... does nothing by default... override at will. * The indirector will be called, uh, "indirector". * You are in the middle of a method when you define this. */ protected void writeInitializeIndirector( Property prop, Class propType, IndentedWriter iw ) throws IOException {} protected void writeExtraDeclarations(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException {} public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { super.generate( info, superclassType, props, propTypes, iw); writeExtraDeclarations( info, superclassType, props, propTypes, iw); } protected void writeStoreObject( Property prop, Class propType, IndentedWriter iw ) throws IOException { IndirectPolicy policy = indirectingPolicy( prop, propType ); if (policy == IndirectPolicy.DEFINITELY_INDIRECT) writeIndirectStoreObject( prop, propType, iw ); else if (policy == IndirectPolicy.INDIRECT_ON_EXCEPTION) { iw.println("try"); iw.println("{"); iw.upIndent(); iw.println("//test serialize"); iw.println("SerializableUtils.toByteArray(" + prop.getName() + ");"); super.writeStoreObject( prop, propType, iw ); iw.downIndent(); iw.println("}"); iw.println("catch (NotSerializableException nse)"); iw.println("{"); iw.upIndent(); writeIndirectStoreObject( prop, propType, iw ); iw.downIndent(); iw.println("}"); } else if (policy == IndirectPolicy.DEFINITELY_DIRECT) super.writeStoreObject( prop, propType, iw ); else throw new InternalError("indirectingPolicy() overridden to return unknown policy: " + policy); } protected void writeIndirectStoreObject( Property prop, Class propType, IndentedWriter iw ) throws IOException { iw.println("try"); iw.println("{"); iw.upIndent(); iw.println("Indirector indirector = " + findIndirectorExpr + ';'); writeInitializeIndirector( prop, propType, iw ); iw.println("oos.writeObject( indirector.indirectForm( " + prop.getName() + " ) );"); iw.downIndent(); iw.println("}"); iw.println("catch (IOException indirectionIOException)"); iw.println("{ throw indirectionIOException; }"); iw.println("catch (Exception indirectionOtherException)"); iw.println("{ throw new IOException(\"Problem indirectly serializing " + prop.getName() + ": \" + indirectionOtherException.toString() ); }"); } protected void writeUnstoreObject( Property prop, Class propType, IndentedWriter iw ) throws IOException { IndirectPolicy policy = indirectingPolicy( prop, propType ); if (policy == IndirectPolicy.DEFINITELY_INDIRECT || policy == IndirectPolicy.INDIRECT_ON_EXCEPTION) { iw.println("Object o = ois.readObject();"); iw.println("if (o instanceof IndirectlySerialized) o = ((IndirectlySerialized) o).getObject();"); iw.println("this." + prop.getName() + " = (" + prop.getSimpleTypeName() + ") o;"); } else if (policy == IndirectPolicy.DEFINITELY_DIRECT) super.writeUnstoreObject( prop, propType, iw ); else throw new InternalError("indirectingPolicy() overridden to return unknown policy: " + policy); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/InnerBeanPropertyBeanGenerator.java0000644000175000017500000001604510624366527027664 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.*; public class InnerBeanPropertyBeanGenerator extends SimplePropertyBeanGenerator { String innerBeanClassName; int inner_bean_member_modifiers = Modifier.PROTECTED; int inner_bean_accessor_modifiers = Modifier.PROTECTED; int inner_bean_replacer_modifiers = Modifier.PROTECTED; String innerBeanInitializationExpression = null; //if you want it to stay null, set to String "null" public void setInnerBeanClassName(String innerBeanClassName) { this.innerBeanClassName = innerBeanClassName; } public String getInnerBeanClassName() { return innerBeanClassName; } private String defaultInnerBeanInitializationExpression() { return "new " + innerBeanClassName + "()"; } private String findInnerBeanClassName() { return (innerBeanClassName == null ? "InnerBean" : innerBeanClassName); } private String findInnerBeanInitializationExpression() { return (innerBeanInitializationExpression == null ? defaultInnerBeanInitializationExpression() : innerBeanInitializationExpression); } private int findInnerClassModifiers() { int out = Modifier.STATIC; if (Modifier.isPublic( inner_bean_accessor_modifiers ) || Modifier.isPublic( inner_bean_replacer_modifiers )) out |= Modifier.PUBLIC; else if (Modifier.isProtected( inner_bean_accessor_modifiers ) || Modifier.isProtected( inner_bean_replacer_modifiers )) out |= Modifier.PROTECTED; else if (Modifier.isPrivate( inner_bean_accessor_modifiers ) && Modifier.isPrivate( inner_bean_replacer_modifiers )) out |= Modifier.PRIVATE; //else leave as package accessible return out; } //TODO: add a hook for subclassses to custom define maskedProps private void writeSyntheticInnerBeanClass() throws IOException { int num_props = props.length; Property[] maskedProps = new Property[ num_props ]; for (int i = 0; i < num_props; ++i) { maskedProps[i] = new SimplePropertyMask( props[i] ) { public int getVariableModifiers() { return Modifier.PRIVATE | Modifier.TRANSIENT; } }; } ClassInfo ci = new WrapperClassInfo( info ) { public String getClassName() { return "InnerBean"; } public int getModifiers() { return findInnerClassModifiers(); } }; createInnerGenerator().generate( ci, maskedProps, iw ); } protected PropertyBeanGenerator createInnerGenerator() { SimplePropertyBeanGenerator innerGenerator = new SimplePropertyBeanGenerator(); innerGenerator.setInner( true ); innerGenerator.addExtension( new SerializableExtension() ); CloneableExtension ce = new CloneableExtension(); ce.setExceptionSwallowing( true ); innerGenerator.addExtension( ce ); return innerGenerator; } protected void writeOtherVariables() throws IOException { iw.println( CodegenUtils.getModifierString( inner_bean_member_modifiers ) + ' ' + findInnerBeanClassName() + " innerBean = " + findInnerBeanInitializationExpression() + ';'); iw.println(); iw.println( CodegenUtils.getModifierString( inner_bean_accessor_modifiers ) + ' ' + findInnerBeanClassName() + " accessInnerBean()"); iw.println("{ return innerBean; }"); } protected void writeOtherFunctions() throws IOException { iw.print( CodegenUtils.getModifierString( inner_bean_replacer_modifiers ) + ' ' + findInnerBeanClassName() + " replaceInnerBean( " + findInnerBeanClassName() + " innerBean )"); if (constrainedProperties()) iw.println(" throws PropertyVetoException"); else iw.println(); iw.println("{"); iw.upIndent(); iw.println("beforeReplaceInnerBean();"); iw.println("this.innerBean = innerBean;"); iw.println("afterReplaceInnerBean();"); iw.downIndent(); iw.println("}"); iw.println(); boolean is_abstract = Modifier.isAbstract( info.getModifiers() ); iw.print("protected "); if (is_abstract) iw.print("abstract "); iw.print("void beforeReplaceInnerBean()"); if (constrainedProperties()) iw.print(" throws PropertyVetoException"); if (is_abstract) iw.println(';'); else iw.println(" {} //hook method for subclasses"); iw.println(); iw.print("protected "); if (is_abstract) iw.print("abstract "); iw.print("void afterReplaceInnerBean()"); if (is_abstract) iw.println(';'); else iw.println(" {} //hook method for subclasses"); iw.println(); BeangenUtils.writeExplicitDefaultConstructor( Modifier.PUBLIC, info, iw ); iw.println(); iw.println("public " + info.getClassName() + "(" + findInnerBeanClassName() + " innerBean)"); iw.println("{ this.innerBean = innerBean; }"); } protected void writeOtherClasses() throws IOException { if (innerBeanClassName == null) writeSyntheticInnerBeanClass(); } protected void writePropertyVariable( Property prop ) throws IOException { /* do nothing... we have no members, only the inner bean */ } protected void writePropertyGetter( Property prop, Class propType ) throws IOException { String stn = prop.getSimpleTypeName(); String pfx = ("boolean".equals( stn ) ? "is" : "get" ); String methodName = pfx + BeangenUtils.capitalize( prop.getName() ); iw.print( CodegenUtils.getModifierString( prop.getGetterModifiers() ) ); iw.println(' ' + prop.getSimpleTypeName() + ' ' + methodName + "()"); iw.println('{'); iw.upIndent(); iw.println( stn + ' ' + prop.getName() + " = innerBean." + methodName + "();"); String retVal = this.getGetterDefensiveCopyExpression( prop, propType ); if (retVal == null) retVal = prop.getName(); iw.println("return " + retVal + ';'); iw.downIndent(); iw.println('}'); } protected void writePropertySetter( Property prop, Class propType ) throws IOException { String stn = prop.getSimpleTypeName(); String pfx = ("boolean".equals( stn ) ? "is" : "get" ); String setVal = this.getSetterDefensiveCopyExpression( prop, propType ); if (setVal == null) setVal = prop.getName(); String getExpression = ("innerBean." + pfx + BeangenUtils.capitalize( prop.getName() ) + "()"); String setStatement = ("innerBean.set" + BeangenUtils.capitalize( prop.getName() ) + "( " + setVal + " );"); BeangenUtils.writePropertySetterWithGetExpressionSetStatement(prop, getExpression, setStatement, iw); } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ParsedPropertyBeanDocument.java0000644000175000017500000001515410624366527027071 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import org.w3c.dom.*; import java.lang.reflect.Modifier; import com.mchange.v1.xml.DomParseUtils; public class ParsedPropertyBeanDocument { final static String[] EMPTY_SA = new String[0]; String packageName; int class_modifiers; String className; String superclassName; String[] interfaceNames = EMPTY_SA; String[] generalImports = EMPTY_SA; String[] specificImports = EMPTY_SA; Property[] properties; public ParsedPropertyBeanDocument(Document doc) { Element rootElem = doc.getDocumentElement(); this.packageName = DomParseUtils.allTextFromUniqueChild( rootElem, "package" ); Element modifiersElem = DomParseUtils.uniqueImmediateChild( rootElem, "modifiers" ); if (modifiersElem != null) class_modifiers = parseModifiers( modifiersElem ); else class_modifiers = Modifier.PUBLIC; Element importsElem = DomParseUtils.uniqueChild( rootElem, "imports" ); if (importsElem != null) { this.generalImports = DomParseUtils.allTextFromImmediateChildElements( importsElem, "general" ); this.specificImports = DomParseUtils.allTextFromImmediateChildElements( importsElem, "specific" ); } this.className = DomParseUtils.allTextFromUniqueChild( rootElem, "output-class" ); this.superclassName = DomParseUtils.allTextFromUniqueChild( rootElem, "extends" ); Element implementsElem = DomParseUtils.uniqueChild( rootElem, "implements" ); if (implementsElem != null) this.interfaceNames = DomParseUtils.allTextFromImmediateChildElements( implementsElem, "interface" ); Element propertiesElem = DomParseUtils.uniqueChild( rootElem, "properties" ); this.properties = findProperties( propertiesElem ); } public ClassInfo getClassInfo() { return new ClassInfo() { public String getPackageName() { return packageName; } public int getModifiers() { return class_modifiers; } public String getClassName() { return className; } public String getSuperclassName() { return superclassName; } public String[] getInterfaceNames() { return interfaceNames; } public String[] getGeneralImports() { return generalImports; } public String[] getSpecificImports() { return specificImports; } }; } public Property[] getProperties() { return (Property[]) properties.clone(); } private Property[] findProperties( Element propertiesElem ) { NodeList nl = DomParseUtils.immediateChildElementsByTagName( propertiesElem, "property" ); int len = nl.getLength(); Property[] out = new Property[ len ]; for( int i = 0; i < len; ++i) { Element propertyElem = (Element) nl.item( i ); int variable_modifiers; String name; String simpleTypeName; String defensiveCopyExpression; String defaultValueExpression; int getter_modifiers; int setter_modifiers; boolean is_read_only; boolean is_bound; boolean is_constrained; variable_modifiers = modifiersThroughParentElem( propertyElem, "variable", Modifier.PRIVATE ); name = DomParseUtils.allTextFromUniqueChild( propertyElem, "name", true ); simpleTypeName = DomParseUtils.allTextFromUniqueChild( propertyElem, "type", true ); defensiveCopyExpression = DomParseUtils.allTextFromUniqueChild( propertyElem, "defensive-copy", true ); defaultValueExpression = DomParseUtils.allTextFromUniqueChild( propertyElem, "default-value", true ); getter_modifiers = modifiersThroughParentElem( propertyElem, "getter", Modifier.PUBLIC ); setter_modifiers = modifiersThroughParentElem( propertyElem, "setter", Modifier.PUBLIC ); Element readOnlyElem = DomParseUtils.uniqueChild( propertyElem, "read-only" ); is_read_only = (readOnlyElem != null); Element isBoundElem = DomParseUtils.uniqueChild( propertyElem, "bound" ); is_bound = (isBoundElem != null); Element isConstrainedElem = DomParseUtils.uniqueChild( propertyElem, "constrained" ); is_constrained = (isConstrainedElem != null); out[i] = new SimpleProperty( variable_modifiers, name, simpleTypeName, defensiveCopyExpression, defaultValueExpression, getter_modifiers, setter_modifiers, is_read_only, is_bound, is_constrained ); } return out; } private static int modifiersThroughParentElem( Element grandparentElem, String parentElemName, int default_mods ) { Element parentElem = DomParseUtils.uniqueChild( grandparentElem, parentElemName ); if (parentElem != null ) { Element modifiersElem = DomParseUtils.uniqueChild( parentElem, "modifiers" ); if (modifiersElem != null) return parseModifiers( modifiersElem ); else return default_mods; } else return default_mods; } private static int parseModifiers( Element modifiersElem ) { int out = 0; String[] all_modifiers = DomParseUtils.allTextFromImmediateChildElements( modifiersElem, "modifier", true ); for ( int i = 0, len = all_modifiers.length; i < len; ++i) { String modifier = all_modifiers[i]; if ("public".equals( modifier )) out |= Modifier.PUBLIC; else if ("protected".equals( modifier )) out |= Modifier.PROTECTED; else if ("private".equals( modifier )) out |= Modifier.PRIVATE; else if ("final".equals( modifier )) out |= Modifier.FINAL; else if ("abstract".equals( modifier )) out |= Modifier.ABSTRACT; else if ("static".equals( modifier )) out |= Modifier.STATIC; else if ("synchronized".equals( modifier )) out |= Modifier.SYNCHRONIZED; else if ("volatile".equals( modifier )) out |= Modifier.VOLATILE; else if ("transient".equals( modifier )) out |= Modifier.TRANSIENT; else if ("strictfp".equals( modifier )) out |= Modifier.STRICT; else if ("native".equals( modifier )) out |= Modifier.NATIVE; else if ("interface".equals( modifier )) out |= Modifier.INTERFACE; // ???? else throw new IllegalArgumentException("Bad modifier: " + modifier); } return out; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/Property.java0000644000175000017500000000255610624366530023441 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; public interface Property { public int getVariableModifiers(); public String getName(); public String getSimpleTypeName(); public String getDefensiveCopyExpression(); public String getDefaultValueExpression(); public int getGetterModifiers(); public int getSetterModifiers(); public boolean isReadOnly(); public boolean isBound(); public boolean isConstrained(); //indexed properties not supported... use array or List valued props } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/PropertyBeanGenerator.java0000644000175000017500000000203010624366527026067 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.io.*; public interface PropertyBeanGenerator { public void generate( ClassInfo info, Property[] props, Writer w ) throws IOException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/PropertyComparator.java0000644000175000017500000000207610624366527025474 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; class PropertyComparator { public int compare(Object a, Object b) { Property aa = (Property) a; Property bb = (Property) b; return (aa.getName().compareTo(bb.getName())); } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/PropertyMapConstructorGeneratorExtension.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/PropertyMapConstructorGeneratorExtension.j0000644000175000017500000000564410624366527031430 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class PropertyMapConstructorGeneratorExtension implements GeneratorExtension { int ctor_modifiers = Modifier.PUBLIC; public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { Set set = new HashSet(); set.add("java.util.Map"); return set; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.print( CodegenUtils.getModifierString( ctor_modifiers ) ); iw.print(' ' + info.getClassName() + "( Map map )"); iw.println("{"); iw.upIndent(); iw.println( "Object raw;" ); for (int i = 0, len = props.length; i < len; ++i) { Property prop = props[i]; String propName = prop.getName(); Class propType = propTypes[i]; iw.println("raw = map.get( \"" + propName + "\" );"); iw.println("if (raw != null)"); iw.println("{"); iw.upIndent(); iw.print("this." + propName + " = "); if ( propType == boolean.class ) iw.println( "((Boolean) raw ).booleanValue();" ); else if ( propType == byte.class ) iw.println( "((Byte) raw ).byteValue();" ); else if ( propType == char.class ) iw.println( "((Character) raw ).charValue();" ); else if ( propType == short.class ) iw.println( "((Short) raw ).shortValue();" ); else if ( propType == int.class ) iw.println( "((Integer) raw ).intValue();" ); else if ( propType == long.class ) iw.println( "((Long) raw ).longValue();" ); else if ( propType == float.class ) iw.println( "((Float) raw ).floatValue();" ); else if ( propType == double.class ) iw.println( "((Double) raw ).doubleValue();" ); iw.println("raw = null;"); iw.downIndent(); iw.println("}"); } iw.downIndent(); iw.println("}"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/PropertyReferenceableExtension.java0000644000175000017500000000705110624366527030002 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import com.mchange.v2.codegen.IndentedWriter; import com.mchange.v2.naming.JavaBeanObjectFactory; import com.mchange.v2.naming.JavaBeanReferenceMaker; import java.io.IOException; public class PropertyReferenceableExtension implements GeneratorExtension { boolean explicit_reference_properties = false; String factoryClassName = JavaBeanObjectFactory.class.getName(); String javaBeanReferenceMakerClassName = JavaBeanReferenceMaker.class.getName(); public void setUseExplicitReferenceProperties( boolean explicit_reference_properties ) { this.explicit_reference_properties = explicit_reference_properties; } public boolean getUseExplicitReferenceProperties() { return explicit_reference_properties; } public void setFactoryClassName( String factoryClassName ) { this.factoryClassName = factoryClassName; } public String getFactoryClassName() { return factoryClassName; } // public void setJavaBeanReferenceMakerClassName( String javaBeanReferenceMakerClassName ) // { this.javaBeanReferenceMakerClassName = javaBeanReferenceMakerClassName; } // public String getJavaBeanReferenceMakerClassName() // { return javaBeanReferenceMakerClassName; } public Collection extraGeneralImports() { Set set = new HashSet(); return set; } public Collection extraSpecificImports() { Set set = new HashSet(); set.add( "javax.naming.Reference" ); set.add( "javax.naming.Referenceable" ); set.add( "javax.naming.NamingException" ); set.add( "com.mchange.v2.naming.JavaBeanObjectFactory" ); set.add( "com.mchange.v2.naming.JavaBeanReferenceMaker" ); set.add( "com.mchange.v2.naming.ReferenceMaker" ); return set; } public Collection extraInterfaceNames() { Set set = new HashSet(); set.add( "Referenceable" ); return set; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.println("final static JavaBeanReferenceMaker referenceMaker = new " + javaBeanReferenceMakerClassName + "();"); iw.println(); iw.println("static"); iw.println("{"); iw.upIndent(); iw.println("referenceMaker.setFactoryClassName( \"" + factoryClassName + "\" );"); if ( explicit_reference_properties ) { for( int i = 0, len = props.length; i < len; ++i) iw.println("referenceMaker.addReferenceProperty(\"" + props[i].getName() + "\");"); } iw.downIndent(); iw.println("}"); iw.println(); iw.println("public Reference getReference() throws NamingException"); iw.println("{"); iw.upIndent(); iw.println("return referenceMaker.createReference( this );"); iw.downIndent(); iw.println("}"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/PropsToStringGeneratorExtension.java0000644000175000017500000000523010624366530030146 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.io.IOException; import com.mchange.v2.codegen.IndentedWriter; public class PropsToStringGeneratorExtension implements GeneratorExtension { private Collection excludePropNames = null; public void setExcludePropertyNames( Collection excludePropNames ) { this.excludePropNames = excludePropNames; } public Collection getExcludePropertyNames() { return excludePropNames; } public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.println("public String toString()"); iw.println("{"); iw.upIndent(); iw.println("StringBuffer sb = new StringBuffer();"); iw.println("sb.append( super.toString() );"); iw.println("sb.append(\" [ \");"); for (int i = 0, len = props.length; i < len; ++i) { Property prop = props[i]; if ( excludePropNames != null && excludePropNames.contains( prop.getName() ) ) continue; iw.println("sb.append( \"" + prop.getName() + " -> \"" + " + " + prop.getName() + " );"); if ( i != len - 1 ) iw.println("sb.append( \", \");"); } iw.println(); iw.println("String extraToStringInfo = this.extraToStringInfo();"); iw.println("if (extraToStringInfo != null)"); iw.upIndent(); iw.println("sb.append( extraToStringInfo );"); iw.downIndent(); iw.println("sb.append(\" ]\");"); iw.println("return sb.toString();"); iw.downIndent(); iw.println("}"); iw.println(); iw.println("protected String extraToStringInfo()"); iw.println("{ return null; }"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ResolvedClassInfo.java0000644000175000017500000000200010624366530025162 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; public interface ResolvedClassInfo extends ClassInfo { public Class[] getInterfaces(); public Class[] getSuperclass(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/ResolvedProperty.java0000644000175000017500000000172210624366527025145 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; public interface ResolvedProperty extends Property { public Class getType(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SerializableExtension.java0000644000175000017500000001623210624366530026114 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.io.IOException; import com.mchange.v2.codegen.IndentedWriter; /** * Note: this class pays no attention to whether users have marked any property variables as transient. * In fact, it will work most efficiently if users mark ALL variables as transient... to define transient * properties for this class, use the constructor which allows a user-specified set of transients. */ public class SerializableExtension implements GeneratorExtension { Set transientProperties; Map transientPropertyInitializers; /** * @param transientProperties a set of Strings, the names of all properties that should be considered transient and not serialized * @param transientPropertyInitializers an optional Map of a subset of the transient property names to non-default initialization * expressions, which should be unterminated expressions, and which will be used verbatim in * the generated code. */ public SerializableExtension(Set transientProperties, Map transientPropertyInitializers) { this.transientProperties = transientProperties; this.transientPropertyInitializers = transientPropertyInitializers; } public SerializableExtension() { this ( Collections.EMPTY_SET, null ); } public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { Set set = new HashSet(); set.add( "java.io.IOException" ); set.add( "java.io.Serializable" ); set.add( "java.io.ObjectOutputStream" ); set.add( "java.io.ObjectInputStream" ); return set; } public Collection extraInterfaceNames() { Set set = new HashSet(); set.add( "Serializable" ); return set; } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { iw.println("private static final long serialVersionUID = 1;"); iw.println("private static final short VERSION = 0x0001;"); iw.println(); iw.println("private void writeObject( ObjectOutputStream oos ) throws IOException"); iw.println("{"); iw.upIndent(); iw.println( "oos.writeShort( VERSION );" ); for( int i = 0, len = props.length; i < len; ++i ) { Property prop = props[i]; if (! transientProperties.contains( prop.getName() ) ) { Class propType = propTypes[i]; if (propType != null && propType.isPrimitive()) //primitives should always resolve, object types may not, and be null { if (propType == byte.class) iw.println("oos.writeByte(" + prop.getName() + ");"); else if (propType == char.class) iw.println("oos.writeChar(" + prop.getName() + ");"); else if (propType == short.class) iw.println("oos.writeShort(" + prop.getName() + ");"); else if (propType == int.class) iw.println("oos.writeInt(" + prop.getName() + ");"); else if (propType == boolean.class) iw.println("oos.writeBoolean(" + prop.getName() + ");"); else if (propType == long.class) iw.println("oos.writeLong(" + prop.getName() + ");"); else if (propType == float.class) iw.println("oos.writeFloat(" + prop.getName() + ");"); else if (propType == double.class) iw.println("oos.writeDouble(" + prop.getName() + ");"); } else writeStoreObject( prop, propType, iw ); } } generateExtraSerWriteStatements( info, superclassType, props, propTypes, iw); iw.downIndent(); iw.println("}"); iw.println(); iw.println("private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException"); iw.println("{"); iw.upIndent(); iw.println("short version = ois.readShort();"); iw.println("switch (version)"); iw.println("{"); iw.upIndent(); iw.println("case VERSION:"); iw.upIndent(); for( int i = 0, len = props.length; i < len; ++i ) { Property prop = props[i]; if (! transientProperties.contains( prop.getName() ) ) { Class propType = propTypes[i]; if (propType != null && propType.isPrimitive()) //if a propType is unresolvable, it ain't a primitive { if (propType == byte.class) iw.println("this." + prop.getName() + " = ois.readByte();"); else if (propType == char.class) iw.println("this." + prop.getName() + " = ois.readChar();"); else if (propType == short.class) iw.println("this." + prop.getName() + " = ois.readShort();"); else if (propType == int.class) iw.println("this." + prop.getName() + " = ois.readInt();"); else if (propType == boolean.class) iw.println("this." + prop.getName() + " = ois.readBoolean();"); else if (propType == long.class) iw.println("this." + prop.getName() + " = ois.readLong();"); else if (propType == float.class) iw.println("this." + prop.getName() + " = ois.readFloat();"); else if (propType == double.class) iw.println("this." + prop.getName() + " = ois.readDouble();"); } else writeUnstoreObject( prop, propType, iw ); } else { String initializer = (String) transientPropertyInitializers.get( prop.getName() ); if (initializer != null) iw.println("this." + prop.getName() + " = " + initializer +';'); } } generateExtraSerInitializers( info, superclassType, props, propTypes, iw); iw.println("break;"); iw.downIndent(); iw.println("default:"); iw.upIndent(); iw.println("throw new IOException(\"Unsupported Serialized Version: \" + version);"); iw.downIndent(); iw.downIndent(); iw.println("}"); iw.downIndent(); iw.println("}"); } protected void writeStoreObject( Property prop, Class propType, IndentedWriter iw ) throws IOException { iw.println("oos.writeObject( " + prop.getName() + " );"); } protected void writeUnstoreObject( Property prop, Class propType, IndentedWriter iw ) throws IOException { iw.println("this." + prop.getName() + " = (" + prop.getSimpleTypeName() + ") ois.readObject();"); } protected void generateExtraSerWriteStatements(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException {} protected void generateExtraSerInitializers(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SimpleClassInfo.java0000644000175000017500000000417410624366527024654 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.lang.reflect.Modifier; public class SimpleClassInfo implements ClassInfo { String packageName; int modifiers; String className; String superclassName; String[] interfaceNames; String[] generalImports; String[] specificImports; public String getPackageName() { return packageName; } public int getModifiers() { return modifiers; } public String getClassName() { return className; } public String getSuperclassName() { return superclassName; } public String[] getInterfaceNames() { return interfaceNames; } public String[] getGeneralImports() { return generalImports; } public String[] getSpecificImports() { return specificImports; } public SimpleClassInfo( String packageName, int modifiers, String className, String superclassName, String[] interfaceNames, String[] generalImports, String[] specificImports ) { this.packageName = packageName; this.modifiers = modifiers; this.className = className; this.superclassName = superclassName; this.interfaceNames = interfaceNames; this.generalImports = generalImports; this.specificImports = specificImports; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SimpleProperty.java0000644000175000017500000000627710624366527024625 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.lang.reflect.Modifier; public class SimpleProperty implements Property { int variable_modifiers; String name; String simpleTypeName; String defensiveCopyExpression; String defaultValueExpression; int getter_modifiers; int setter_modifiers; boolean is_read_only; boolean is_bound; boolean is_constrained; public int getVariableModifiers() { return variable_modifiers; } public String getName() { return name; } public String getSimpleTypeName() { return simpleTypeName; } public String getDefensiveCopyExpression() { return defensiveCopyExpression; } public String getDefaultValueExpression() { return defaultValueExpression; } public int getGetterModifiers() { return getter_modifiers; } public int getSetterModifiers() { return setter_modifiers; } public boolean isReadOnly() { return is_read_only; } public boolean isBound() { return is_bound; } public boolean isConstrained() { return is_constrained; } public SimpleProperty( int variable_modifiers, String name, String simpleTypeName, String defensiveCopyExpression, String defaultValueExpression, int getter_modifiers, int setter_modifiers, boolean is_read_only, boolean is_bound, boolean is_constrained ) { this.variable_modifiers = variable_modifiers; this.name = name; this.simpleTypeName = simpleTypeName; this.defensiveCopyExpression = defensiveCopyExpression; this.defaultValueExpression = defaultValueExpression; this.getter_modifiers = getter_modifiers; this.setter_modifiers = setter_modifiers; this.is_read_only = is_read_only; this.is_bound = is_bound; this.is_constrained = is_constrained; } public SimpleProperty( String name, String simpleTypeName, String defensiveCopyExpression, String defaultValueExpression, boolean is_read_only, boolean is_bound, boolean is_constrained ) { this ( Modifier.PRIVATE, name, simpleTypeName, defensiveCopyExpression, defaultValueExpression, Modifier.PUBLIC, Modifier.PUBLIC, is_read_only, is_bound, is_constrained ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SimplePropertyBeanGenerator.java0000644000175000017500000004557410624366530027257 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.io.*; import java.util.*; import com.mchange.v2.log.*; import java.lang.reflect.Modifier; import com.mchange.v1.lang.ClassUtils; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class SimplePropertyBeanGenerator implements PropertyBeanGenerator { private final static MLogger logger = MLog.getLogger( SimplePropertyBeanGenerator.class ); private boolean inner = false; private int java_version = 130; //1.3.0 private boolean force_unmodifiable = false; private String generatorName = this.getClass().getName(); // helper vars for generate method protected ClassInfo info; protected Property[] props; protected IndentedWriter iw; protected Set generalImports; protected Set specificImports; protected Set interfaceNames; protected Class superclassType; protected List interfaceTypes; protected Class[] propertyTypes; protected List generatorExtensions = new ArrayList(); public synchronized void setInner( boolean inner ) { this.inner = inner; } public synchronized boolean isInner() { return inner; } /** * @param version a three digit number -- for example Java 1.3.1 is 131 */ public synchronized void setJavaVersion(int java_version) { this.java_version = java_version; } public synchronized int getJavaVersion() { return java_version; } public synchronized void setGeneratorName(String generatorName) { this.generatorName = generatorName; } public synchronized String getGeneratorName() { return generatorName; } public synchronized void setForceUnmodifiable(boolean force_unmodifiable) { this.force_unmodifiable = force_unmodifiable; } public synchronized boolean isForceUnmodifiable() { return force_unmodifiable; } public synchronized void addExtension( GeneratorExtension ext ) { generatorExtensions.add( ext ); } public synchronized void removeExtension( GeneratorExtension ext ) { generatorExtensions.remove( ext ); } public synchronized void generate( ClassInfo info, Property[] props, Writer w) throws IOException { this.info = info; this.props = props; Arrays.sort( props, BeangenUtils.PROPERTY_COMPARATOR ); this.iw = ( w instanceof IndentedWriter ? (IndentedWriter) w : new IndentedWriter(w)); this.generalImports = new TreeSet(); if ( info.getGeneralImports() != null ) generalImports.addAll( Arrays.asList( info.getGeneralImports() ) ); this.specificImports = new TreeSet(); if ( info.getSpecificImports() != null ) specificImports.addAll( Arrays.asList( info.getSpecificImports() ) ); this.interfaceNames = new TreeSet(); if ( info.getInterfaceNames() != null ) interfaceNames.addAll( Arrays.asList( info.getInterfaceNames() ) ); addInternalImports(); addInternalInterfaces(); resolveTypes(); if (! inner ) { writeHeader(); iw.println(); } writeClassDeclaration(); iw.println('{'); iw.upIndent(); writeCoreBody(); iw.downIndent(); iw.println('}'); } protected void resolveTypes() { String[] gen = (String[]) generalImports.toArray( new String[ generalImports.size() ] ); String[] spc = (String[]) specificImports.toArray( new String[ specificImports.size() ] ); if ( info.getSuperclassName() != null ) { try { superclassType = ClassUtils.forName( info.getSuperclassName(), gen, spc ); } catch ( Exception e ) { // System.err.println("WARNING: " + this.getClass().getName() + " could not resolve " + // "superclass '" + info.getSuperclassName() + "'."); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning(this.getClass().getName() + " could not resolve superclass '" + info.getSuperclassName() + "'."); superclassType = null; } } interfaceTypes = new ArrayList( interfaceNames.size() ); for ( Iterator ii = interfaceNames.iterator(); ii.hasNext(); ) { String name = (String) ii.next(); try { interfaceTypes.add( ClassUtils.forName( name , gen, spc ) ); } catch ( Exception e ) { // System.err.println("WARNING: " + this.getClass().getName() + " could not resolve " + // "interface '" + name + "'."); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning(this.getClass().getName() + " could not resolve interface '" + name + "'."); interfaceTypes.add( null ); } } propertyTypes = new Class[ props.length ]; for ( int i = 0, len = props.length; i < len; ++i ) { String name = props[i].getSimpleTypeName(); try { propertyTypes[i] = ClassUtils.forName( name , gen, spc ); } catch ( Exception e ) { // e.printStackTrace(); // System.err.println("WARNING: " + this.getClass().getName() + " could not resolve " + // "property type '" + name + "'."); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, this.getClass().getName() + " could not resolve property type '" + name + "'.", e); propertyTypes[i] = null; } } } protected void addInternalImports() { if (boundProperties()) { specificImports.add("java.beans.PropertyChangeEvent"); specificImports.add("java.beans.PropertyChangeSupport"); specificImports.add("java.beans.PropertyChangeListener"); } if (constrainedProperties()) { specificImports.add("java.beans.PropertyChangeEvent"); specificImports.add("java.beans.PropertyVetoException"); specificImports.add("java.beans.VetoableChangeSupport"); specificImports.add("java.beans.VetoableChangeListener"); } for (Iterator ii = generatorExtensions.iterator(); ii.hasNext(); ) { GeneratorExtension ge = (GeneratorExtension) ii.next(); specificImports.addAll( ge.extraSpecificImports() ); generalImports.addAll( ge.extraGeneralImports() ); } } protected void addInternalInterfaces() { for (Iterator ii = generatorExtensions.iterator(); ii.hasNext(); ) { GeneratorExtension ge = (GeneratorExtension) ii.next(); interfaceNames.addAll( ge.extraInterfaceNames() ); } } protected void writeCoreBody() throws IOException { writeJavaBeansChangeSupport(); writePropertyVariables(); writeOtherVariables(); iw.println(); writeGetterSetterPairs(); if ( boundProperties() ) { iw.println(); writeBoundPropertyEventSourceMethods(); } if ( constrainedProperties() ) { iw.println(); writeConstrainedPropertyEventSourceMethods(); } writeInternalUtilityFunctions(); writeOtherFunctions(); writeOtherClasses(); String[] completed_intfc_names = (String[]) interfaceNames.toArray( new String[ interfaceNames.size() ] ); String[] completed_gen_imports = (String[]) generalImports.toArray( new String[ generalImports.size() ] ); String[] completed_spc_imports = (String[]) specificImports.toArray( new String[ specificImports.size() ] ); ClassInfo completedClassInfo = new SimpleClassInfo( info.getPackageName(), info.getModifiers(), info.getClassName(), info.getSuperclassName(), completed_intfc_names, completed_gen_imports, completed_spc_imports ); for (Iterator ii = generatorExtensions.iterator(); ii.hasNext(); ) { GeneratorExtension ext = (GeneratorExtension) ii.next(); iw.println(); ext.generate( completedClassInfo, superclassType, props, propertyTypes, iw ); } } protected void writeInternalUtilityFunctions() throws IOException { iw.println("private boolean eqOrBothNull( Object a, Object b )"); iw.println("{"); iw.upIndent(); iw.println("return"); iw.upIndent(); iw.println("a == b ||"); iw.println("(a != null && a.equals(b));"); iw.downIndent(); iw.downIndent(); iw.println("}"); } protected void writeConstrainedPropertyEventSourceMethods() throws IOException { iw.println("public void addVetoableChangeListener( VetoableChangeListener vcl )"); iw.println("{ vcs.addVetoableChangeListener( vcl ); }"); iw.println(); iw.println("public void removeVetoableChangeListener( VetoableChangeListener vcl )"); iw.println("{ vcs.removeVetoableChangeListener( vcl ); }"); iw.println(); if (java_version >= 140) { iw.println("public VetoableChangeListener[] getVetoableChangeListeners()"); iw.println("{ return vcs.getPropertyChangeListeners(); }"); } } protected void writeBoundPropertyEventSourceMethods() throws IOException { iw.println("public void addPropertyChangeListener( PropertyChangeListener pcl )"); iw.println("{ pcs.addPropertyChangeListener( pcl ); }"); iw.println(); iw.println("public void addPropertyChangeListener( String propName, PropertyChangeListener pcl )"); iw.println("{ pcs.addPropertyChangeListener( propName, pcl ); }"); iw.println(); iw.println("public void removePropertyChangeListener( PropertyChangeListener pcl )"); iw.println("{ pcs.removePropertyChangeListener( pcl ); }"); iw.println(); iw.println("public void removePropertyChangeListener( String propName, PropertyChangeListener pcl )"); iw.println("{ pcs.removePropertyChangeListener( propName, pcl ); }"); iw.println(); if (java_version >= 140) { iw.println("public PropertyChangeListener[] getPropertyChangeListeners()"); iw.println("{ return pcs.getPropertyChangeListeners(); }"); } } protected void writeJavaBeansChangeSupport() throws IOException { if ( boundProperties() ) { iw.println("protected PropertyChangeSupport pcs = new PropertyChangeSupport( this );"); iw.println(); iw.println("protected PropertyChangeSupport getPropertyChangeSupport()"); iw.println("{ return pcs; }"); } if ( constrainedProperties() ) { iw.println("protected VetoableChangeSupport vcs = new VetoableChangeSupport( this );"); iw.println(); iw.println("protected VetoableChangeSupport getVetoableChangeSupport()"); iw.println("{ return vcs; }"); } } protected void writeOtherVariables() throws IOException //hook method for subclasses {} protected void writeOtherFunctions() throws IOException //hook method for subclasses {} protected void writeOtherClasses() throws IOException //hook method for subclasses {} protected void writePropertyVariables() throws IOException { for (int i = 0, len = props.length; i < len; ++i) writePropertyVariable( props[i] ); } protected void writePropertyVariable( Property prop ) throws IOException { BeangenUtils.writePropertyVariable( prop, iw ); // iw.print( CodegenUtils.getModifierString( prop.getVariableModifiers() ) ); // iw.print( ' ' + prop.getSimpleTypeName() + ' ' + prop.getName()); // String dflt = prop.getDefaultValueExpression(); // if (dflt != null) // iw.print( " = " + dflt ); // iw.println(';'); } /** * @deprecated */ protected void writePropertyMembers() throws IOException { throw new InternalError("writePropertyMembers() deprecated and removed. please us writePropertyVariables()."); } /** * @deprecated */ protected void writePropertyMember( Property prop ) throws IOException { throw new InternalError("writePropertyMember() deprecated and removed. please us writePropertyVariable()."); } protected void writeGetterSetterPairs() throws IOException { for (int i = 0, len = props.length; i < len; ++i) { writeGetterSetterPair( props[i], propertyTypes[i] ); if ( i != len - 1) iw.println(); } } protected void writeGetterSetterPair( Property prop, Class propType ) throws IOException { writePropertyGetter( prop, propType ); if (! prop.isReadOnly() && ! force_unmodifiable) { iw.println(); writePropertySetter( prop, propType ); } } protected void writePropertyGetter( Property prop, Class propType ) throws IOException { BeangenUtils.writePropertyGetter( prop, this.getGetterDefensiveCopyExpression( prop, propType ), iw ); // String pfx = ("boolean".equals( prop.getSimpleTypeName() ) ? "is" : "get" ); // iw.print( CodegenUtils.getModifierString( prop.getGetterModifiers() ) ); // iw.println(' ' + prop.getSimpleTypeName() + ' ' + pfx + BeangenUtils.capitalize( prop.getName() ) + "()"); // String retVal = getGetterDefensiveCopyExpression( prop, propType ); // if (retVal == null) retVal = prop.getName(); // iw.println("{ return " + retVal + "; }"); } // boolean changeMarked( Property prop ) // { return prop.isBound() || prop.isConstrained(); } protected void writePropertySetter( Property prop, Class propType ) throws IOException { BeangenUtils.writePropertySetter( prop, this.getSetterDefensiveCopyExpression( prop, propType ), iw ); // iw.print( CodegenUtils.getModifierString( prop.getSetterModifiers() ) ); // iw.print(" void set" + BeangenUtils.capitalize( prop.getName() ) + "( " + prop.getSimpleTypeName() + ' ' + prop.getName() + " )"); // if ( prop.isConstrained() ) // iw.println(" throws PropertyVetoException"); // else // iw.println(); // String setVal = getSetterDefensiveCopyExpression( prop, propType ); // if (setVal == null) setVal = prop.getName(); // iw.println('{'); // iw.upIndent(); // if ( changeMarked( prop ) ) // { // iw.println( prop.getSimpleTypeName() + " oldVal = this." + prop.getName() + ';'); // String oldValExpr = "oldVal"; // String newValExpr = prop.getName(); // String changeCheck; // if ( propType != null && propType.isPrimitive() ) //sometimes the type can't be resolved. if so, it ain't primitive. // { // // PropertyChange support already has overrides // // for boolean and int // if (propType == byte.class) // { // oldValExpr = "new Byte( "+ oldValExpr +" )"; // newValExpr = "new Byte( "+ newValExpr +" )"; // } // else if (propType == char.class) // { // oldValExpr = "new Character( "+ oldValExpr +" )"; // newValExpr = "new Character( "+ newValExpr +" )"; // } // else if (propType == short.class) // { // oldValExpr = "new Short( "+ oldValExpr +" )"; // newValExpr = "new Short( "+ newValExpr +" )"; // } // else if (propType == float.class) // { // oldValExpr = "new Float( "+ oldValExpr +" )"; // newValExpr = "new Float( "+ newValExpr +" )"; // } // else if (propType == double.class) // { // oldValExpr = "new Double( "+ oldValExpr +" )"; // newValExpr = "new Double( "+ newValExpr +" )"; // } // changeCheck = "oldVal != " + prop.getName(); // } // else // changeCheck = "! eqOrBothNull( oldVal, " + prop.getName() + " )"; // if ( prop.isConstrained() ) // { // iw.println("if ( " + changeCheck + " )"); // iw.upIndent(); // iw.println("vcs.fireVetoableChange( \"" + prop.getName() + "\", " + oldValExpr + ", " + newValExpr + " );"); // iw.downIndent(); // } // iw.println("this." + prop.getName() + " = " + setVal + ';'); // if ( prop.isBound() ) // { // iw.println("if ( " + changeCheck + " )"); // iw.upIndent(); // iw.println("pcs.firePropertyChange( \"" + prop.getName() + "\", " + oldValExpr + ", " + newValExpr + " );"); // iw.downIndent(); // } // } // else // iw.println("this." + prop.getName() + " = " + setVal + ';'); // iw.downIndent(); // iw.println('}'); } protected String getGetterDefensiveCopyExpression( Property prop, Class propType ) { return prop.getDefensiveCopyExpression(); } protected String getSetterDefensiveCopyExpression( Property prop, Class propType ) { return prop.getDefensiveCopyExpression(); } protected String getConstructorDefensiveCopyExpression( Property prop, Class propType ) { return prop.getDefensiveCopyExpression(); } protected void writeHeader() throws IOException { writeBannerComments(); iw.println(); iw.println("package " + info.getPackageName() + ';'); iw.println(); writeImports(); } protected void writeBannerComments() throws IOException { iw.println("/*"); iw.println(" * This class autogenerated by " + generatorName + '.'); iw.println(" * DO NOT HAND EDIT!"); iw.println(" */"); } protected void writeImports() throws IOException { for ( Iterator ii = generalImports.iterator(); ii.hasNext(); ) iw.println("import " + ii.next() + ".*;"); for ( Iterator ii = specificImports.iterator(); ii.hasNext(); ) iw.println("import " + ii.next() + ";"); } protected void writeClassDeclaration() throws IOException { iw.print( CodegenUtils.getModifierString( info.getModifiers() ) + " class " + info.getClassName() ); String superclassName = info.getSuperclassName(); if (superclassName != null) iw.print( " extends " + superclassName ); if (interfaceNames.size() > 0) { iw.print(" implements "); boolean first = true; for (Iterator ii = interfaceNames.iterator(); ii.hasNext(); ) { if (first) first = false; else iw.print(", "); iw.print( (String) ii.next() ); } } iw.println(); } boolean boundProperties() { return BeangenUtils.hasBoundProperties( props ); } boolean constrainedProperties() { return BeangenUtils.hasConstrainedProperties( props ); } public static void main( String[] argv ) { try { ClassInfo info = new SimpleClassInfo("test", Modifier.PUBLIC, argv[0], null, null, new String[] {"java.awt"}, null); Property[] props = { new SimpleProperty( "number", "int", null, "7", false, true, false ), new SimpleProperty( "fpNumber", "float", null, null, true, true, false ), new SimpleProperty( "location", "Point", "new Point( location.x, location.y )", "new Point( 0, 0 )", false, true, true ) }; FileWriter fw = new FileWriter( argv[0] + ".java" ); SimplePropertyBeanGenerator g = new SimplePropertyBeanGenerator(); g.addExtension( new SerializableExtension() ); g.generate(info, props, fw ); fw.flush(); fw.close(); } catch ( Exception e ) { e.printStackTrace(); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SimplePropertyMask.java0000644000175000017500000000327510624366527025434 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.lang.reflect.Modifier; class SimplePropertyMask implements Property { Property p; SimplePropertyMask(Property p) { this.p = p; } public int getVariableModifiers() { return Modifier.PRIVATE; } public String getName() { return p.getName(); } public String getSimpleTypeName() { return p.getSimpleTypeName(); } public String getDefensiveCopyExpression() { return null; } public String getDefaultValueExpression() { return p.getDefaultValueExpression(); } public int getGetterModifiers() { return Modifier.PUBLIC; } public int getSetterModifiers() { return Modifier.PUBLIC; } public boolean isReadOnly() { return false; } public boolean isBound() { return false; } public boolean isConstrained() { return false; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SimpleStateBeanImportExportGeneratorExtension.javac3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/SimpleStateBeanImportExportGeneratorExtens0000644000175000017500000000557510624366530031354 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.util.*; import java.lang.reflect.Modifier; import java.io.IOException; import com.mchange.v2.codegen.CodegenUtils; import com.mchange.v2.codegen.IndentedWriter; public class SimpleStateBeanImportExportGeneratorExtension implements GeneratorExtension { int ctor_modifiers = Modifier.PUBLIC; public Collection extraGeneralImports() { return Collections.EMPTY_SET; } public Collection extraSpecificImports() { return Collections.EMPTY_SET; } public Collection extraInterfaceNames() { return Collections.EMPTY_SET; } static class SimplePropertyMask implements Property { Property p; SimplePropertyMask(Property p) { this.p = p; } public int getVariableModifiers() { return Modifier.PRIVATE; } public String getName() { return p.getName(); } public String getSimpleTypeName() { return p.getSimpleTypeName(); } public String getDefensiveCopyExpression() { return null; } public String getDefaultValueExpression() { return null; } public int getGetterModifiers() { return Modifier.PUBLIC; } public int getSetterModifiers() { return Modifier.PUBLIC; } public boolean isReadOnly() { return false; } public boolean isBound() { return false; } public boolean isConstrained() { return false; } } public void generate(ClassInfo info, Class superclassType, Property[] props, Class[] propTypes, IndentedWriter iw) throws IOException { int num_props = props.length; Property[] masked = new Property[ num_props ]; for (int i = 0; i < num_props; ++i) masked[i] = new SimplePropertyMask( props[i] ); iw.println("protected static class SimpleStateBean implements ExportedState"); iw.println("{"); iw.upIndent(); for (int i = 0; i < num_props; ++i) { masked[i] = new SimplePropertyMask( props[i] ); BeangenUtils.writePropertyMember( masked[i], iw ); iw.println(); BeangenUtils.writePropertyGetter( masked[i], iw ); iw.println(); BeangenUtils.writePropertySetter( masked[i], iw ); } iw.downIndent(); iw.println("}"); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/WrapperClassInfo.java0000644000175000017500000000304710624366530025033 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; public abstract class WrapperClassInfo implements ClassInfo { ClassInfo inner; public WrapperClassInfo(ClassInfo info) { this.inner = info; } public String getPackageName() { return inner.getPackageName(); } public int getModifiers() { return inner.getModifiers(); } public String getClassName() { return inner.getClassName(); } public String getSuperclassName() { return inner.getSuperclassName(); } public String[] getInterfaceNames() { return inner.getInterfaceNames(); } public String[] getGeneralImports() { return inner.getGeneralImports(); } public String[] getSpecificImports() { return inner.getSpecificImports(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/bean/WrapperProperty.java0000644000175000017500000000351610624366527025005 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.bean; import java.lang.reflect.Modifier; public abstract class WrapperProperty implements Property { Property p; public WrapperProperty(Property p) { this.p = p; } protected Property getInner() { return p; } public int getVariableModifiers() { return p.getVariableModifiers(); } public String getName() { return p.getName(); } public String getSimpleTypeName() { return p.getSimpleTypeName(); } public String getDefensiveCopyExpression() { return p.getDefensiveCopyExpression(); } public String getDefaultValueExpression() { return p.getDefaultValueExpression(); } public int getGetterModifiers() { return p.getGetterModifiers(); } public int getSetterModifiers() { return p.getSetterModifiers(); } public boolean isReadOnly() { return p.isReadOnly(); } public boolean isBound() { return p.isBound(); } public boolean isConstrained() { return p.isConstrained(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/intfc/0000755000175000017500000000000010673162231021134 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/intfc/DelegatorGenerator.java0000644000175000017500000002062410624366530025564 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen.intfc; import java.io.*; import java.util.*; import java.lang.reflect.*; import com.mchange.v2.codegen.*; import com.mchange.v1.lang.ClassUtils; public class DelegatorGenerator { int class_modifiers = Modifier.PUBLIC | Modifier.ABSTRACT; int method_modifiers = Modifier.PUBLIC; int wrapping_ctor_modifiers = Modifier.PUBLIC; int default_ctor_modifiers = Modifier.PUBLIC; boolean wrapping_constructor = true; boolean default_constructor = true; boolean inner_getter = true; boolean inner_setter = true; Class superclass = null; Class[] extraInterfaces = null; final static Comparator classComp = new Comparator() { public int compare(Object a, Object b) { return ((Class) a).getName().compareTo(((Class) b).getName()); } }; public void setGenerateInnerSetter( boolean b ) { this.inner_setter = b; } public boolean isGenerateInnerSetter() { return inner_setter; } public void setGenerateInnerGetter( boolean b ) { this.inner_getter = b; } public boolean isGenerateInnerGetter() { return inner_getter; } public void setGenerateNoArgConstructor( boolean b ) { this.default_constructor = b; } public boolean isGenerateNoArgConstructor() { return default_constructor; } public void setGenerateWrappingConstructor( boolean b ) { this.wrapping_constructor = b; } public boolean isGenerateWrappingConstructor() { return wrapping_constructor; } public void setWrappingConstructorModifiers( int modifiers ) { this.wrapping_ctor_modifiers = modifiers; } public int getWrappingConstructorModifiers() { return wrapping_ctor_modifiers; } public void setNoArgConstructorModifiers( int modifiers ) { this.default_ctor_modifiers = modifiers; } public int getNoArgConstructorModifiers() { return default_ctor_modifiers; } public void setMethodModifiers( int modifiers ) { this.method_modifiers = modifiers; } public int getMethodModifiers() { return method_modifiers; } public void setClassModifiers( int modifiers ) { this.class_modifiers = modifiers; } public int getClassModifiers() { return class_modifiers; } public void setSuperclass( Class superclass ) { this.superclass = superclass; } public Class getSuperclass() { return superclass; } public void setExtraInterfaces( Class[] extraInterfaces ) { this.extraInterfaces = extraInterfaces; } public Class[] getExtraInterfaces() { return extraInterfaces; } public void writeDelegator(Class intfcl, String genclass, Writer w) throws IOException { IndentedWriter iw = CodegenUtils.toIndentedWriter(w); String pkg = genclass.substring(0, genclass.lastIndexOf('.')); String sgc = CodegenUtils.fqcnLastElement( genclass ); String scn = (superclass != null ? ClassUtils.simpleClassName( superclass ) : null); String sin = ClassUtils.simpleClassName( intfcl ); String[] eins = null; if (extraInterfaces != null) { eins = new String[ extraInterfaces.length ]; for (int i = 0, len = extraInterfaces.length; i < len; ++i) eins[i] = ClassUtils.simpleClassName( extraInterfaces[i] ); } Set imports = new TreeSet( classComp ); Method[] methods = intfcl.getMethods(); //TODO: don't add array classes! //build import set if (! CodegenUtils.inSamePackage( intfcl.getName(), genclass ) ) imports.add( intfcl ); if (superclass != null && ! CodegenUtils.inSamePackage( superclass.getName(), genclass ) ) imports.add( superclass ); if (extraInterfaces != null) { for (int i = 0, len = extraInterfaces.length; i < len; ++i) { Class checkMe = extraInterfaces[i]; if (! CodegenUtils.inSamePackage( checkMe.getName(), genclass ) ) imports.add( checkMe ); } } for (int i = 0, len = methods.length; i < len; ++i) { Class[] args = methods[i].getParameterTypes(); for (int j = 0, jlen = args.length; j < jlen; ++j) { if (! CodegenUtils.inSamePackage( args[j].getName(), genclass ) ) imports.add( CodegenUtils.unarrayClass( args[j] ) ); } Class[] excClasses = methods[i].getExceptionTypes(); for (int j = 0, jlen = excClasses.length; j < jlen; ++j) { if (! CodegenUtils.inSamePackage( excClasses[j].getName(), genclass ) ) { //System.err.println("Adding exception type: " + excClasses[j]); imports.add( CodegenUtils.unarrayClass( excClasses[j] ) ); } } if (! CodegenUtils.inSamePackage( methods[i].getReturnType().getName(), genclass ) ) imports.add( CodegenUtils.unarrayClass( methods[i].getReturnType() ) ); } generateBannerComment( iw ); iw.println("package " + pkg + ';'); iw.println(); for (Iterator ii = imports.iterator(); ii.hasNext(); ) iw.println("import "+ ((Class) ii.next()).getName() + ';'); generateExtraImports( iw ); iw.println(); iw.print(CodegenUtils.getModifierString( class_modifiers ) + " class " + sgc); if (superclass != null) iw.print(" extends " + scn); iw.print(" implements " + sin); if (eins != null) for (int i = 0, len = eins.length; i < len; ++i) iw.print(", " + eins[i]); iw.println(); iw.println("{"); iw.upIndent(); iw.println("protected " + sin + " inner;"); iw.println(); if ( wrapping_constructor ) { iw.println("public" + ' ' + sgc + '(' + sin + " inner)"); iw.println("{ this.inner = inner; }"); } if (default_constructor) { iw.println(); iw.println("public" + ' ' + sgc + "()"); iw.println("{}"); } if (inner_setter) { iw.println(); iw.println( CodegenUtils.getModifierString( method_modifiers ) + " void setInner( " + sin + " inner )"); iw.println( "{ this.inner = inner; }" ); } if (inner_getter) { iw.println(); iw.println( CodegenUtils.getModifierString( method_modifiers ) + ' ' + sin + " getInner()"); iw.println( "{ return inner; }" ); } iw.println(); for (int i = 0, len = methods.length; i < len; ++i) { Method method = methods[i]; Class retType = method.getReturnType(); if (i != 0) iw.println(); iw.println( CodegenUtils.methodSignature( method_modifiers, method, null ) ); iw.println("{"); iw.upIndent(); generatePreDelegateCode( intfcl, genclass, method, iw ); generateDelegateCode( intfcl, genclass, method, iw ); generatePostDelegateCode( intfcl, genclass, method, iw ); iw.downIndent(); iw.println("}"); } iw.println(); generateExtraDeclarations( intfcl, genclass, iw ); iw.downIndent(); iw.println("}"); } protected void generateDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException { Class retType = method.getReturnType(); iw.println( (retType == void.class ? "" : "return " ) + "inner." + CodegenUtils.methodCall( method ) + ";" ); } protected void generateBannerComment( IndentedWriter iw ) throws IOException { iw.println("/*"); iw.println(" * This class generated by " + this.getClass().getName()); iw.println(" * " + new Date()); iw.println(" * DO NOT HAND EDIT!!!!"); iw.println(" */"); } protected void generateExtraImports( IndentedWriter iw ) throws IOException {} protected void generatePreDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException {} protected void generatePostDelegateCode( Class intfcl, String genclass, Method method, IndentedWriter iw ) throws IOException {} protected void generateExtraDeclarations( Class intfcl, String genclass, IndentedWriter iw ) throws IOException {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/CodegenUtils.java0000644000175000017500000001256210624366530023273 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen; import java.lang.reflect.*; import java.io.File; import java.io.Writer; import com.mchange.v1.lang.ClassUtils; public final class CodegenUtils { public static String getModifierString( int modifiers ) { StringBuffer sb = new StringBuffer(32); if ( Modifier.isPublic( modifiers ) ) sb.append("public "); if ( Modifier.isProtected( modifiers ) ) sb.append("protected "); if ( Modifier.isPrivate( modifiers ) ) sb.append("private "); if ( Modifier.isAbstract( modifiers ) ) sb.append("abstract "); if ( Modifier.isStatic( modifiers ) ) sb.append("static "); if ( Modifier.isFinal( modifiers ) ) sb.append("final "); if ( Modifier.isSynchronized( modifiers ) ) sb.append("synchronized "); if ( Modifier.isTransient( modifiers ) ) sb.append("transient "); if ( Modifier.isVolatile( modifiers ) ) sb.append("volatile "); if ( Modifier.isStrict( modifiers ) ) sb.append("strictfp "); if ( Modifier.isNative( modifiers ) ) sb.append("native "); if ( Modifier.isInterface( modifiers ) ) //???? sb.append("interface "); return sb.toString().trim(); } public static Class unarrayClass( Class cl ) { Class out = cl; while ( out.isArray() ) out = out.getComponentType(); return out; } public static boolean inSamePackage(String cn1, String cn2) { int pkgdot = cn1.lastIndexOf('.'); int pkgdot2 = cn2.lastIndexOf('.'); //always return true of one class is a primitive or unpackages if (pkgdot < 0 || pkgdot2 < 0) return true; if ( cn1.substring(0, pkgdot).equals(cn1.substring(0, pkgdot)) ) { if (cn2.indexOf('.') >= 0) return false; else return true; } else return false; } /** * @return fully qualified class name last element */ public static String fqcnLastElement(String fqcn) { return ClassUtils.fqcnLastElement( fqcn ); } public static String methodSignature( Method m ) { return methodSignature( m, null ); } public static String methodSignature( Method m, String[] argNames ) { return methodSignature( Modifier.PUBLIC, m, argNames ); } public static String methodSignature( int modifiers, Method m, String[] argNames ) { StringBuffer sb = new StringBuffer(256); sb.append(getModifierString(modifiers)); sb.append(' '); sb.append( ClassUtils.simpleClassName( m.getReturnType() ) ); sb.append(' '); sb.append( m.getName() ); sb.append('('); Class[] cls = m.getParameterTypes(); for(int i = 0, len = cls.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( ClassUtils.simpleClassName( cls[i] ) ); sb.append(' '); sb.append( argNames == null ? String.valueOf((char) ('a' + i)) : argNames[i] ); } sb.append(')'); Class[] excClasses = m.getExceptionTypes(); if (excClasses.length > 0) { sb.append(" throws "); for (int i = 0, len = excClasses.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( ClassUtils.simpleClassName( excClasses[i] ) ); } } return sb.toString(); } public static String methodCall( Method m ) { return methodCall( m, null ); } public static String methodCall( Method m, String[] argNames ) { StringBuffer sb = new StringBuffer(256); sb.append( m.getName() ); sb.append('('); Class[] cls = m.getParameterTypes(); for(int i = 0, len = cls.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( argNames == null ? generatedArgumentName( i ) : argNames[i] ); } sb.append(')'); return sb.toString(); } public static String generatedArgumentName( int index ) { return String.valueOf((char) ('a' + index)); } public static String simpleClassName( Class cl ) { return ClassUtils.simpleClassName( cl ); } public static IndentedWriter toIndentedWriter( Writer w ) { return (w instanceof IndentedWriter ? (IndentedWriter) w : new IndentedWriter(w)); } public static String packageNameToFileSystemDirPath(String packageName) { StringBuffer sb = new StringBuffer( packageName ); for (int i = 0, len = sb.length(); i < len; ++i) if ( sb.charAt(i) == '.' ) sb.setCharAt(i, File.separatorChar); sb.append( File.separatorChar ); return sb.toString(); } private CodegenUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/codegen/IndentedWriter.java0000644000175000017500000000213310624366527023634 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.codegen; import java.io.*; /** * @deprecated -- please user com.mchange.v2.io.IndentedWriter */ public class IndentedWriter extends com.mchange.v2.io.IndentedWriter { public IndentedWriter( Writer out ) { super( out ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/debug/0000755000175000017500000000000010673162231017513 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/debug/DebugConstants.java0000644000175000017500000000204110624366527023310 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.debug; public interface DebugConstants { public final static int TRACE_NONE = 0; public final static int TRACE_MED = 5; public final static int TRACE_MAX = 10; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/debug/ThreadNameStackTraceRecorder.java0000644000175000017500000000661010624366527026036 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.debug; import java.text.*; import java.util.*; import com.mchange.lang.ThrowableUtils; public class ThreadNameStackTraceRecorder { final static String NL = System.getProperty("line.separator", "\r\n"); Set set = new HashSet(); String dumpHeader; String stackTraceHeader; public ThreadNameStackTraceRecorder( String dumpHeader ) { this( dumpHeader, "Debug Stack Trace." ); } public ThreadNameStackTraceRecorder( String dumpHeader, String stackTraceHeader ) { this.dumpHeader = dumpHeader; this.stackTraceHeader = stackTraceHeader; } public synchronized Object record() { Record r = new Record( stackTraceHeader ); set.add( r ); return r; } public synchronized void remove( Object rec ) { set.remove( rec ); } public synchronized int size() { return set.size(); } public synchronized String getDump() { return getDump(null); } public synchronized String getDump(String locationSpecificNote) { DateFormat df = new SimpleDateFormat("dd-MMMM-yyyy HH:mm:ss.SSSS"); StringBuffer sb = new StringBuffer(2047); sb.append(NL); sb.append("----------------------------------------------------"); sb.append(NL); sb.append( dumpHeader ); sb.append(NL); if (locationSpecificNote != null) { sb.append( locationSpecificNote ); sb.append( NL ); } boolean first = true; for (Iterator ii = set.iterator(); ii.hasNext(); ) { if (first) first = false; else { sb.append("---"); sb.append( NL ); } Record r = (Record) ii.next(); sb.append(df.format( new Date( r.time ) )); sb.append(" --> Thread Name: "); sb.append(r.threadName); sb.append(NL); sb.append("Stack Trace: "); sb.append( ThrowableUtils.extractStackTrace( r.stackTrace ) ); } sb.append("----------------------------------------------------"); sb.append(NL); return sb.toString(); } private final static class Record implements Comparable { long time; String threadName; Throwable stackTrace; Record(String sth) { this.time = System.currentTimeMillis(); this.threadName = Thread.currentThread().getName(); this.stackTrace = new Exception( sth ); } public int compareTo( Object o ) { Record oo = (Record) o; if ( this.time > oo.time ) return 1; else if (this.time < oo.time ) return -1; else { int mine = System.identityHashCode( this ); int yours = System.identityHashCode( oo ); if (mine > yours) return 1; else if (mine < yours) return -1; return 0; } } } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/encounter/0000755000175000017500000000000010673162231020427 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/encounter/AbstractEncounterCounter.java0000644000175000017500000000265510624366527026302 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.encounter; import java.util.Map; class AbstractEncounterCounter implements EncounterCounter { final static Long ONE = new Long(1); Map m; AbstractEncounterCounter(Map m) { this.m = m; } /** * @return how many times have I seen this object before? */ public long encounter(Object o) { Long oldLong = (Long) m.get(o); Long newLong; long out; if (oldLong == null) { out = 0; newLong = ONE; } else { out = oldLong.longValue(); newLong = new Long(out + 1); } m.put( o, newLong ); return out; } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/encounter/EncounterCounter.java0000644000175000017500000000202510624366530024577 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.encounter; public interface EncounterCounter { /** * @return how many times have I seen this object before? */ public long encounter(Object o); }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/encounter/EqualityEncounterCounter.java0000644000175000017500000000210510624366527026322 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.encounter; import java.util.Map; import java.util.WeakHashMap; public class EqualityEncounterCounter extends AbstractEncounterCounter { public EqualityEncounterCounter() { super( new WeakHashMap() ); } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/holders/0000755000175000017500000000000010673162231020065 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/holders/ChangeNotifyingSynchronizedIntHolder.java0000644000175000017500000000467110624366527030237 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.holders; import java.io.*; import com.mchange.v2.ser.UnsupportedVersionException; public final class ChangeNotifyingSynchronizedIntHolder implements ThreadSafeIntHolder, Serializable { transient int value; transient boolean notify_all; public ChangeNotifyingSynchronizedIntHolder( int value, boolean notify_all ) { this.value = value; this.notify_all = notify_all; } public ChangeNotifyingSynchronizedIntHolder() { this(0, true); } public synchronized int getValue() { return value; } public synchronized void setValue(int value) { if (value != this.value) { this.value = value; doNotify(); } } public synchronized void increment() { ++value; doNotify(); } public synchronized void decrement() { --value; doNotify(); } //must be called from a sync'ed block... private void doNotify() { if (notify_all) this.notifyAll(); else this.notify(); } //Serialization static final long serialVersionUID = 1; //override to take control of versioning private final static short VERSION = 0x0001; private void writeObject(ObjectOutputStream out) throws IOException { out.writeShort(VERSION); out.writeInt(value); out.writeBoolean(notify_all); } private void readObject(ObjectInputStream in) throws IOException { short version = in.readShort(); switch (version) { case 0x0001: this.value = in.readInt(); this.notify_all = in.readBoolean(); break; default: throw new UnsupportedVersionException(this, version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/holders/SynchronizedIntHolder.java0000644000175000017500000000375410624366527025243 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.holders; import java.io.*; import com.mchange.v2.ser.UnsupportedVersionException; public class SynchronizedIntHolder implements ThreadSafeIntHolder, Serializable { transient int value; public SynchronizedIntHolder( int value ) { this.value = value; } public SynchronizedIntHolder() { this(0); } public synchronized int getValue() { return value; } public synchronized void setValue(int value) { this.value = value; } public synchronized void increment() { ++value; } public synchronized void decrement() { --value; } //Serialization static final long serialVersionUID = 1; //override to take control of versioning private final static short VERSION = 0x0001; private void writeObject(ObjectOutputStream out) throws IOException { out.writeShort(VERSION); out.writeInt(value); } private void readObject(ObjectInputStream in) throws IOException { short version = in.readShort(); switch (version) { case 0x0001: this.value = in.readInt(); break; default: throw new UnsupportedVersionException(this, version); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/holders/ThreadSafeIntHolder.java0000644000175000017500000000174010624366530024555 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.holders; public interface ThreadSafeIntHolder { public int getValue(); public void setValue(int i); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/io/0000755000175000017500000000000010673162231017034 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/io/IndentedWriter.java0000644000175000017500000000776610624366527022660 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.io; import java.io.*; public class IndentedWriter extends FilterWriter { final static String EOL; static { String eol = System.getProperty( "line.separator" ); EOL = ( eol != null ? eol : "\r\n" ); } int indent_level = 0; boolean at_line_start = true; public IndentedWriter( Writer out ) { super( out ); } private boolean isEol( char c ) { return ( c == '\r' || c == '\n' ); } public void upIndent() { ++indent_level; } public void downIndent() { --indent_level; } public void write( int c ) throws IOException { out.write( c ); at_line_start = isEol( (char) c ); } public void write( char[] chars, int off, int len ) throws IOException { out.write( chars, off, len ); at_line_start = isEol( chars[ off + len - 1] ); } public void write( String s, int off, int len ) throws IOException { if (len > 0) { out.write( s, off, len ); at_line_start = isEol( s.charAt( off + len - 1) ); } } private void printIndent() throws IOException { for (int i = 0; i < indent_level; ++i) out.write( '\t' ); } public void print( String s ) throws IOException { if ( at_line_start ) printIndent(); out.write(s); char last = s.charAt( s.length() - 1 ); at_line_start = isEol( last ); } public void println( String s ) throws IOException { if ( at_line_start ) printIndent(); out.write(s); out.write( EOL ); at_line_start = true; } public void print( boolean x ) throws IOException { print( String.valueOf(x) ); } public void print( byte x ) throws IOException { print( String.valueOf(x) ); } public void print( char x ) throws IOException { print( String.valueOf(x) ); } public void print( short x ) throws IOException { print( String.valueOf(x) ); } public void print( int x ) throws IOException { print( String.valueOf(x) ); } public void print( long x ) throws IOException { print( String.valueOf(x) ); } public void print( float x ) throws IOException { print( String.valueOf(x) ); } public void print( double x ) throws IOException { print( String.valueOf(x) ); } public void print( Object x ) throws IOException { print( String.valueOf(x) ); } public void println( boolean x ) throws IOException { println( String.valueOf(x) ); } public void println( byte x ) throws IOException { println( String.valueOf(x) ); } public void println( char x ) throws IOException { println( String.valueOf(x) ); } public void println( short x ) throws IOException { println( String.valueOf(x) ); } public void println( int x ) throws IOException { println( String.valueOf(x) ); } public void println( long x ) throws IOException { println( String.valueOf(x) ); } public void println( float x ) throws IOException { println( String.valueOf(x) ); } public void println( double x ) throws IOException { println( String.valueOf(x) ); } public void println( Object x ) throws IOException { println( String.valueOf(x) ); } public void println() throws IOException { println( "" ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/lang/0000755000175000017500000000000010673162231017346 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/lang/Coerce.java0000644000175000017500000000717610624366530021430 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.lang; import java.util.*; public final class Coerce { final static Set CAN_COERCE; static { Class[] classes = { byte.class, boolean.class, char.class, short.class, int.class, long.class, float.class, double.class, String.class, Byte.class, Boolean.class, Character.class, Short.class, Integer.class, Long.class, Float.class, Double.class }; Set tmp = new HashSet(); tmp.addAll( Arrays.asList( classes ) ); CAN_COERCE = Collections.unmodifiableSet( tmp ); } public static boolean canCoerce( Class cl ) { return CAN_COERCE.contains( cl ); } public static boolean canCoerce( Object o ) { return canCoerce( o.getClass() ); } public static int toInt( String s ) { try { return Integer.parseInt( s ); } catch ( NumberFormatException e ) { return (int) Double.parseDouble( s ); } } public static long toLong( String s ) { try { return Long.parseLong( s ); } catch ( NumberFormatException e ) { return (long) Double.parseDouble( s ); } } public static float toFloat( String s ) { return Float.parseFloat( s ); } public static double toDouble( String s ) { return Double.parseDouble( s ); } public static byte toByte( String s ) { return (byte) toInt(s); } public static short toShort( String s ) { return (short) toInt(s); } public static boolean toBoolean( String s ) { return Boolean.valueOf( s ).booleanValue(); } public static char toChar( String s ) { s = s.trim(); if (s.length() == 1) return s.charAt( 0 ); else return (char) toInt(s); } public static Object toObject( String s, Class type ) { if ( type == byte.class) type = Byte.class; else if ( type == boolean.class) type = Boolean.class; else if ( type == char.class) type = Character.class; else if ( type == short.class) type = Short.class; else if ( type == int.class) type = Integer.class; else if ( type == long.class) type = Long.class; else if ( type == float.class) type = Float.class; else if ( type == double.class) type = Double.class; if ( type == String.class ) return s; else if ( type == Byte.class ) return new Byte( toByte( s ) ); else if ( type == Boolean.class ) return Boolean.valueOf( s ); else if ( type == Character.class ) return new Character( toChar( s ) ); else if ( type == Short.class ) return new Short( toShort( s ) ); else if ( type == Integer.class ) return new Integer( s ); else if ( type == Long.class ) return new Long( s ); else if ( type == Float.class ) return new Float( s ); else if ( type == Double.class ) return new Double( s ); else throw new IllegalArgumentException("Cannot coerce to type: " + type.getName()); } private Coerce() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/lang/ObjectUtils.java0000644000175000017500000000263310624366530022450 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.lang; public final class ObjectUtils { public static boolean eqOrBothNull(Object a, Object b) { if (a == b) return true; else if (a == null) return false; else return a.equals(b); } /** * Note -- if you are using Arrays.equals( ... ) or similar * and want a compatible hash method, see methods in * {@link com.mchange.v1.util.ArrayUtils#hashOrZeroArray ArrayUtils}. */ public static int hashOrZero(Object o) { return (o == null ? 0 : o.hashCode()); } private ObjectUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/lang/ThreadGroupUtils.java0000644000175000017500000000226410624366530023466 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.lang; public final class ThreadGroupUtils { public static ThreadGroup rootThreadGroup() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); ThreadGroup ptg = tg.getParent(); while (ptg != null) { tg = ptg; ptg = tg.getParent(); } return tg; } private ThreadGroupUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/lang/ThreadUtils.java0000644000175000017500000000370610624366527022461 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.lang; import com.mchange.v2.log.*; import java.lang.reflect.Method; public final class ThreadUtils { private final static MLogger logger = MLog.getLogger( ThreadUtils.class ); final static Method holdsLock; static { Method _holdsLock; try { _holdsLock = Thread.class.getMethod("holdsLock", new Class[] { Object.class }); } catch (NoSuchMethodException e) { _holdsLock = null; } holdsLock = _holdsLock; } public static void enumerateAll( Thread[] threads ) { ThreadGroupUtils.rootThreadGroup().enumerate( threads ); } /** * @returns null if cannot be determined, otherwise true or false */ public static Boolean reflectiveHoldsLock( Object o ) { try { if (holdsLock == null) return null; else return (Boolean) holdsLock.invoke( null, new Object[] { o } ); } catch (Exception e) { if ( logger.isLoggable( MLevel.FINER ) ) logger.log( MLevel.FINER, "An Exception occurred while trying to call Thread.holdsLock( ... ) reflectively.", e); return null; } } private ThreadUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/lang/VersionUtils.java0000644000175000017500000001170110624366530022663 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.lang; import com.mchange.v2.log.*; import com.mchange.v1.util.StringTokenizerUtils; public final class VersionUtils { private final static MLogger logger = MLog.getLogger( VersionUtils.class ); private final static int[] DFLT_VERSION_ARRAY = {1,1}; private final static int[] JDK_VERSION_ARRAY; private final static int JDK_VERSION; //two digit int... 10 for 1.0, 11 for 1.1, etc. private final static Integer NUM_BITS; static { String vstr = System.getProperty( "java.version" ); int[] v; if (vstr == null) { if (logger.isLoggable( MLevel.WARNING )) logger.warning("Could not find java.version System property. Defaulting to JDK 1.1"); v = DFLT_VERSION_ARRAY; } else { try { v = extractVersionNumberArray( vstr, "._" ); } catch ( NumberFormatException e ) { if (logger.isLoggable( MLevel.WARNING )) logger.warning("java.version ''" + vstr + "'' could not be parsed. Defaulting to JDK 1.1."); v = DFLT_VERSION_ARRAY; } } int jdkv = 0; if (v.length > 0) jdkv += (v[0] * 10); if (v.length > 1) jdkv += (v[1]); JDK_VERSION_ARRAY = v; JDK_VERSION = jdkv; //System.err.println( JDK_VERSION ); Integer tmpNumBits; try { String numBitsStr = System.getProperty("sun.arch.data.model"); if (numBitsStr == null) tmpNumBits = null; else tmpNumBits = new Integer( numBitsStr ); } catch (Exception e) { tmpNumBits = null; } if (tmpNumBits == null || tmpNumBits.intValue() == 32 || tmpNumBits.intValue() == 64) NUM_BITS = tmpNumBits; else { if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning("Determined a surprising jvmNumerOfBits: " + tmpNumBits + ". Setting jvmNumberOfBits to unknown (null)."); NUM_BITS = null; } } /** * @return null if unknown, * an Integer (as of 2006 always 32 or 64) * otherwise */ public static Integer jvmNumberOfBits() { return NUM_BITS; } public static boolean isJavaVersion10() { return (JDK_VERSION == 10); } public static boolean isJavaVersion11() { return (JDK_VERSION == 11); } public static boolean isJavaVersion12() { return (JDK_VERSION == 12); } public static boolean isJavaVersion13() { return (JDK_VERSION == 13); } public static boolean isJavaVersion14() { return (JDK_VERSION == 14); } public static boolean isJavaVersion15() { return (JDK_VERSION == 15); } public static boolean isAtLeastJavaVersion10() { return (JDK_VERSION >= 10); } public static boolean isAtLeastJavaVersion11() { return (JDK_VERSION >= 11); } public static boolean isAtLeastJavaVersion12() { return (JDK_VERSION >= 12); } public static boolean isAtLeastJavaVersion13() { return (JDK_VERSION >= 13); } public static boolean isAtLeastJavaVersion14() { return (JDK_VERSION >= 14); } public static boolean isAtLeastJavaVersion15() { return (JDK_VERSION >= 15); } public static int[] extractVersionNumberArray(String versionString, String delims) throws NumberFormatException { String[] intStrs = StringTokenizerUtils.tokenizeToArray( versionString, delims, false ); int len = intStrs.length; int[] out = new int[ len ]; for (int i = 0; i < len; ++i) out[i] = Integer.parseInt( intStrs[i] ); return out; } public boolean prefixMatches( int[] pfx, int[] fullVersion ) { if (pfx.length > fullVersion.length) return false; else { for (int i = 0, len = pfx.length; i < len; ++i) if (pfx[i] != fullVersion[i]) return false; return true; } } public static int lexicalCompareVersionNumberArrays(int[] a, int[] b) { int alen = a.length; int blen = b.length; for (int i = 0; i < alen; ++i) { if (i == blen) return 1; //a is larger if they are the same to a point, but a has an extra version number else if (a[i] > b[i]) return 1; else if (a[i] < b[i]) return -1; } if (blen > alen) return -1; //a is smaller if they are the same to a point, but b has an extra version number else return 0; } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/0000755000175000017500000000000010673162231017206 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/jdk14logging/0000755000175000017500000000000010673162231021472 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/jdk14logging/Jdk14MLog.java0000644000175000017500000003104210624366530023775 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log.jdk14logging; import java.util.*; import java.util.logging.*; import com.mchange.v2.log.*; import com.mchange.v2.util.DoubleWeakHashMap; public final class Jdk14MLog extends MLog { private static String[] UNKNOWN_ARRAY = new String[] {"UNKNOWN_CLASS", "UNKNOWN_METHOD"}; private final static String CHECK_CLASS = "java.util.logging.Logger"; private final Map namedLoggerMap = new DoubleWeakHashMap(); MLogger global = null; public Jdk14MLog() throws ClassNotFoundException { Class.forName( CHECK_CLASS ); } public synchronized MLogger getMLogger(String name) { name = name.intern(); MLogger out = (MLogger) namedLoggerMap.get( name ); if (out == null) { Logger lg = Logger.getLogger(name); out = new Jdk14MLogger( lg ); namedLoggerMap.put( name, out ); } return out; } public synchronized MLogger getMLogger(Class cl) { return getLogger( cl.getName() ); } public synchronized MLogger getMLogger() { if (global == null) global = new Jdk14MLogger( LogManager.getLogManager().getLogger("global") ); return global; } /* * We have to do this ourselves when class and method aren't provided, * because the automatic extraction of this information will find the * (not very informative) calls in this class. */ private static String[] findCallingClassAndMethod() { StackTraceElement[] ste = new Throwable().getStackTrace(); for (int i = 0, len = ste.length; i < len; ++i) { StackTraceElement check = ste[i]; String cn = check.getClassName(); if (cn != null && ! cn.startsWith("com.mchange.v2.log.jdk14logging")) return new String[] { check.getClassName(), check.getMethodName() }; } return UNKNOWN_ARRAY; } private final static class Jdk14MLogger implements MLogger { volatile Logger logger; Jdk14MLogger( Logger logger ) { this.logger = logger; //System.err.println("LOGGER: " + this.logger); } private static Level level(MLevel lvl) { return (Level) lvl.asJdk14Level(); } public ResourceBundle getResourceBundle() { return logger.getResourceBundle(); } public String getResourceBundleName() { return logger.getResourceBundleName(); } public void setFilter(Object java14Filter) throws SecurityException { if (! (java14Filter instanceof Filter)) throw new IllegalArgumentException("MLogger.setFilter( ... ) requires a java.util.logging.Filter. " + "This is not enforced by the compiler only to permit building under jdk 1.3"); logger.setFilter( (Filter) java14Filter ); } public Object getFilter() { return logger.getFilter(); } public void log(MLevel l, String msg) { if (! logger.isLoggable( level(l) )) return; String[] sa = findCallingClassAndMethod(); logger.logp( level(l), sa[0], sa[1], msg ); } public void log(MLevel l, String msg, Object param) { if (! logger.isLoggable( level(l) )) return; String[] sa = findCallingClassAndMethod(); logger.logp( level(l), sa[0], sa[1], msg, param ); } public void log(MLevel l,String msg, Object[] params) { if (! logger.isLoggable( level(l) )) return; String[] sa = findCallingClassAndMethod(); logger.logp( level(l), sa[0], sa[1], msg, params ); } public void log(MLevel l, String msg, Throwable t) { if (! logger.isLoggable( level(l) )) return; String[] sa = findCallingClassAndMethod(); logger.logp( level(l), sa[0], sa[1], msg, t ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logp( level(l), srcClass, srcMeth, msg ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object param) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logp( level(l), srcClass, srcMeth, msg, param ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object[] params) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logp( level(l), srcClass, srcMeth, msg, params ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Throwable t) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logp( level(l), srcClass, srcMeth, msg, t ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logrb( level(l), srcClass, srcMeth, rb, msg ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object param) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logrb( level(l), srcClass, srcMeth, rb, msg, param ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object[] params) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logrb( level(l), srcClass, srcMeth, rb, msg, params ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Throwable t) { if (! logger.isLoggable( level(l) )) return; if (srcClass == null && srcMeth == null) { String[] sa = findCallingClassAndMethod(); srcClass = sa[0]; srcMeth = sa[1]; } logger.logrb( level(l), srcClass, srcMeth, rb, msg, t ); } public void entering(String srcClass, String srcMeth) { if (! logger.isLoggable( Level.FINER )) return; logger.entering( srcClass, srcMeth ); } public void entering(String srcClass, String srcMeth, Object param) { if (! logger.isLoggable( Level.FINER )) return; logger.entering( srcClass, srcMeth, param ); } public void entering(String srcClass, String srcMeth, Object params[]) { if (! logger.isLoggable( Level.FINER )) return; logger.entering( srcClass, srcMeth, params ); } public void exiting(String srcClass, String srcMeth) { if (! logger.isLoggable( Level.FINER )) return; logger.exiting( srcClass, srcMeth ); } public void exiting(String srcClass, String srcMeth, Object result) { if (! logger.isLoggable( Level.FINER )) return; logger.exiting( srcClass, srcMeth, result ); } public void throwing(String srcClass, String srcMeth, Throwable t) { if (! logger.isLoggable( Level.FINER )) return; logger.throwing( srcClass, srcMeth, t ); } public void severe(String msg) { if (! logger.isLoggable( Level.SEVERE )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.SEVERE, sa[0], sa[1], msg ); } public void warning(String msg) { if (! logger.isLoggable( Level.WARNING )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.WARNING, sa[0], sa[1], msg ); } public void info(String msg) { if (! logger.isLoggable( Level.INFO )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.INFO, sa[0], sa[1], msg ); } public void config(String msg) { if (! logger.isLoggable( Level.CONFIG )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.CONFIG, sa[0], sa[1], msg ); } public void fine(String msg) { if (! logger.isLoggable( Level.FINE )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.FINE, sa[0], sa[1], msg ); } public void finer(String msg) { if (! logger.isLoggable( Level.FINER )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.FINER, sa[0], sa[1], msg ); } public void finest(String msg) { if (! logger.isLoggable( Level.FINEST )) return; String[] sa = findCallingClassAndMethod(); logger.logp( Level.FINEST, sa[0], sa[1], msg ); } public void setLevel(MLevel l) throws SecurityException { logger.setLevel( level(l) ); } public MLevel getLevel() { return MLevel.fromIntValue( logger.getLevel().intValue() ); } public boolean isLoggable(MLevel l) { return logger.isLoggable( level(l) ); } public String getName() { return logger.getName(); } public void addHandler(Object h) throws SecurityException { if (! (h instanceof Handler)) throw new IllegalArgumentException("MLogger.addHandler( ... ) requires a java.util.logging.Handler. " + "This is not enforced by the compiler only to permit building under jdk 1.3"); logger.addHandler( (Handler) h ); } public void removeHandler(Object h) throws SecurityException { if (! (h instanceof Handler)) throw new IllegalArgumentException("MLogger.removeHandler( ... ) requires a java.util.logging.Handler. " + "This is not enforced by the compiler only to permit building under jdk 1.3"); logger.removeHandler( (Handler) h ); } public Object[] getHandlers() { return logger.getHandlers(); } public void setUseParentHandlers(boolean uph) { logger.setUseParentHandlers( uph ); } public boolean getUseParentHandlers() { return logger.getUseParentHandlers(); } } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/log4j/0000755000175000017500000000000010673162231020225 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/log4j/Log4jMLog.java0000644000175000017500000002621310624366530022636 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log.log4j; import java.text.*; import java.util.*; import com.mchange.v2.log.*; import com.mchange.v2.util.DoubleWeakHashMap; import org.apache.log4j.*; public final class Log4jMLog extends MLog { final static String CHECK_CLASS = "org.apache.log4j.Logger"; MLogger global = null; public Log4jMLog() throws ClassNotFoundException { Class.forName( CHECK_CLASS ); } public MLogger getMLogger(String name) { Logger lg = Logger.getLogger(name); return new Log4jMLogger( lg ); } public MLogger getMLogger(Class cl) { Logger lg = Logger.getLogger(cl); return new Log4jMLogger( lg ); } public MLogger getMLogger() { Logger lg = Logger.getRootLogger(); return new Log4jMLogger( lg ); } private final static class Log4jMLogger implements MLogger { final static String FQCN = Log4jMLogger.class.getName(); // protected by this' lock MLevel myLevel = null; volatile Logger logger; Log4jMLogger( Logger logger ) { this.logger = logger; } private static MLevel guessMLevel(Level lvl) { if (lvl == null) return null; else if (lvl == Level.ALL) return MLevel.ALL; else if (lvl == Level.DEBUG) return MLevel.FINEST; else if (lvl == Level.ERROR) return MLevel.SEVERE; else if (lvl == Level.FATAL) return MLevel.SEVERE; else if (lvl == Level.INFO) return MLevel.INFO; else if (lvl == Level.OFF) return MLevel.OFF; else if (lvl == Level.WARN) return MLevel.WARNING; else throw new IllegalArgumentException("Unknown level: " + lvl); } private static Level level(MLevel lvl) { if (lvl == null) return null; else if (lvl == MLevel.ALL) return Level.ALL; else if (lvl == MLevel.CONFIG) return Level.DEBUG; else if (lvl == MLevel.FINE) return Level.DEBUG; else if (lvl == MLevel.FINER) return Level.DEBUG; else if (lvl == MLevel.FINEST) return Level.DEBUG; else if (lvl == MLevel.INFO) return Level.INFO; else if (lvl == MLevel.INFO) return Level.OFF; else if (lvl == MLevel.SEVERE) return Level.ERROR; else if (lvl == MLevel.WARNING) return Level.WARN; else throw new IllegalArgumentException("Unknown MLevel: " + lvl); } private static String createMessage(String srcClass, String srcMeth, String msg) { StringBuffer sb = new StringBuffer(511); sb.append("[class: "); sb.append( srcClass ); sb.append("; method: "); sb.append( srcMeth ); if (! srcMeth.endsWith(")")) sb.append("()"); sb.append("] "); sb.append( msg ); return sb.toString(); } private static String createMessage(String srcMeth, String msg) { StringBuffer sb = new StringBuffer(511); sb.append("[method: "); sb.append( srcMeth ); if (! srcMeth.endsWith(")")) sb.append("()"); sb.append("] "); sb.append( msg ); return sb.toString(); } public ResourceBundle getResourceBundle() { return null; } public String getResourceBundleName() { return null; } public void setFilter(Object java14Filter) throws SecurityException { warning("setFilter() not supported by MLogger " + this.getClass().getName()); } public Object getFilter() { return null; } private void log(Level lvl, Object msg, Throwable t) { logger.log( FQCN, lvl, msg, t ); } public void log(MLevel l, String msg) { log( level(l), msg, null); } public void log(MLevel l, String msg, Object param) { log( level(l), (msg!=null ? MessageFormat.format(msg, new Object[] { param }) : null), null); } public void log(MLevel l,String msg, Object[] params) { log( level(l), (msg!=null ? MessageFormat.format(msg, params) : null), null); } public void log(MLevel l, String msg, Throwable t) { log( level(l), msg, t); } public void logp(MLevel l, String srcClass, String srcMeth, String msg) { log( level(l), createMessage( srcClass, srcMeth, msg), null); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object param) { log( level(l), createMessage( srcClass, srcMeth, (msg!=null ? MessageFormat.format(msg, new Object[] {param}) : null) ), null); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object[] params) { log( level(l), createMessage( srcClass, srcMeth, (msg!=null ? MessageFormat.format(msg, params) : null) ), null); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Throwable t) { log( level(l), createMessage( srcClass, srcMeth, msg ), t); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg) { log( level(l), createMessage( srcClass, srcMeth, formatMessage(rb, msg, null) ), null); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object param) { log( level(l), createMessage( srcClass, srcMeth, formatMessage(rb, msg, new Object[] { param } ) ), null); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object[] params) { log( level(l), createMessage( srcClass, srcMeth, formatMessage(rb, msg, params) ), null); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Throwable t) { log( level(l), createMessage( srcClass, srcMeth, formatMessage(rb, msg, null) ), t); } public void entering(String srcClass, String srcMeth) { log( Level.DEBUG, createMessage( srcClass, srcMeth, "entering method." ), null); } public void entering(String srcClass, String srcMeth, Object param) { log( Level.DEBUG, createMessage( srcClass, srcMeth, "entering method... param: " + param.toString() ), null); } public void entering(String srcClass, String srcMeth, Object params[]) { log( Level.DEBUG, createMessage( srcClass, srcMeth, "entering method... " + LogUtils.createParamsList( params ) ), null); } public void exiting(String srcClass, String srcMeth) { log( Level.DEBUG, createMessage( srcClass, srcMeth, "exiting method." ), null); } public void exiting(String srcClass, String srcMeth, Object result) { log( Level.DEBUG, createMessage( srcClass, srcMeth, "exiting method... result: " + result.toString() ), null); } public void throwing(String srcClass, String srcMeth, Throwable t) { log( Level.DEBUG, createMessage( srcClass, srcMeth, "throwing exception... " ), t); } public void severe(String msg) { log( Level.ERROR, msg, null); } public void warning(String msg) { log( Level.WARN, msg, null); } public void info(String msg) { log( Level.INFO, msg, null); } public void config(String msg) { log( Level.DEBUG, msg, null); } public void fine(String msg) { log( Level.DEBUG, msg, null); } public void finer(String msg) { log( Level.DEBUG, msg, null); } public void finest(String msg) { log( Level.DEBUG, msg, null); } public synchronized void setLevel(MLevel l) throws SecurityException { logger.setLevel( level( l ) ); myLevel = l; } public synchronized MLevel getLevel() { //System.err.println( logger.getLevel() ); if (myLevel == null) myLevel = guessMLevel( logger.getLevel() ); return myLevel; } public boolean isLoggable(MLevel l) { //System.err.println( "MLevel: " + l + "; isEnabledFor(): " + logger.isEnabledFor( level(l) ) + "; getLevel(): " + getLevel() + //"; MLog.getLogger().getLevel(): " + MLog.getLogger().getLevel()); //new Exception("WHADDAFUC").printStackTrace(); return logger.isEnabledFor( level(l) ); } public String getName() { return logger.getName(); } public void addHandler(Object h) throws SecurityException { if (! (h instanceof Appender)) throw new IllegalArgumentException("The 'handler' " + h + " is not compatible with MLogger " + this); logger.addAppender( (Appender) h ); } public void removeHandler(Object h) throws SecurityException { if (! (h instanceof Appender)) throw new IllegalArgumentException("The 'handler' " + h + " is not compatible with MLogger " + this); logger.removeAppender( (Appender) h ); } public Object[] getHandlers() { List tmp = new LinkedList(); for (Enumeration e = logger.getAllAppenders(); e.hasMoreElements(); ) tmp.add( e.nextElement() ); return tmp.toArray(); } public void setUseParentHandlers(boolean uph) { logger.setAdditivity( uph ); } public boolean getUseParentHandlers() { return logger.getAdditivity(); } } private static String formatMessage( String rbname, String msg, Object[] params ) { if ( msg == null ) { if (params == null) return ""; else return LogUtils.createParamsList( params ); } else { ResourceBundle rb = ResourceBundle.getBundle( rbname ); if (rb != null) { String check = rb.getString( msg ); if (check != null) msg = check; } return (params == null ? msg : MessageFormat.format( msg, params )); } } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/FallbackMLog.java0000644000175000017500000002232510624366530022337 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; import java.text.*; import java.util.*; import java.util.logging.*; import com.mchange.lang.ThrowableUtils; public final class FallbackMLog extends MLog { final static MLevel DEFAULT_CUTOFF_LEVEL; static { MLevel dflt = null; String dfltName = MLog.CONFIG.getProperty( "com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL" ); if (dfltName != null) dflt = MLevel.fromSeverity( dfltName ); if (dflt == null) dflt = MLevel.INFO; DEFAULT_CUTOFF_LEVEL = dflt; } MLogger logger = new FallbackMLogger(); public synchronized MLogger getMLogger(String name) { return logger; } public MLogger getMLogger(Class cl) { return getLogger( cl.getName() ); } public MLogger getMLogger() { return logger; } private final static class FallbackMLogger implements MLogger { MLevel cutoffLevel = DEFAULT_CUTOFF_LEVEL; private void formatrb(MLevel l, String srcClass, String srcMeth, String rbname, String msg, Object[] params, Throwable t) { ResourceBundle rb = ResourceBundle.getBundle( rbname ); if (msg != null && rb != null) { String check = rb.getString( msg ); if (check != null) msg = check; } format( l, srcClass, srcMeth, msg, params, t); } private void format(MLevel l, String srcClass, String srcMeth, String msg, Object[] params, Throwable t) { System.err.println( formatString( l, srcClass, srcMeth, msg, params, t ) ); } private String formatString(MLevel l, String srcClass, String srcMeth, String msg, Object[] params, Throwable t) { boolean add_parens = (srcMeth != null && ! srcMeth.endsWith(")")); StringBuffer sb = new StringBuffer(256); sb.append(l.getLineHeader()); sb.append(' '); if (srcClass != null && srcMeth != null) { sb.append('['); sb.append( srcClass ); sb.append( '.' ); sb.append( srcMeth ); if (add_parens) sb.append("()"); sb.append( ']' ); } else if (srcClass != null) { sb.append('['); sb.append( srcClass ); sb.append( ']' ); } else if (srcMeth != null) { sb.append('['); sb.append( srcMeth ); if (add_parens) sb.append("()"); sb.append( ']' ); } if (msg == null) { if (params != null) { sb.append("params: "); for (int i = 0, len = params.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( params[i] ); } } } else { if (params == null) sb.append( msg ); else { MessageFormat mfmt = new MessageFormat( msg ); sb.append( mfmt.format( params ) ); } } if (t != null) sb.append( ThrowableUtils.extractStackTrace( t ) ); return sb.toString(); } public ResourceBundle getResourceBundle() { //warn("Using logger " + this.getClass().getName() + ", which does not support ResourceBundles."); return null; } public String getResourceBundleName() { return null; } public void setFilter(Object java14Filter) throws SecurityException { warning("Using FallbackMLog -- Filters not supported!"); } public Object getFilter() { return null; } public void log(MLevel l, String msg) { if ( isLoggable( l ) ) format( l, null, null, msg, null, null ); } public void log(MLevel l, String msg, Object param) { if ( isLoggable( l ) ) format( l, null, null, msg, new Object[] { param }, null ); } public void log(MLevel l,String msg, Object[] params) { if ( isLoggable( l ) ) format( l, null, null, msg, params, null ); } public void log(MLevel l, String msg, Throwable t) { if ( isLoggable( l ) ) format( l, null, null, msg, null, t ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg) { if ( isLoggable( l ) ) format( l, srcClass, srcMeth, msg, null, null ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object param) { if ( isLoggable( l ) ) format( l, srcClass, srcMeth, msg, new Object[] { param }, null ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object[] params) { if ( isLoggable( l ) ) format( l, srcClass, srcMeth, msg, params, null ); } public void logp(MLevel l, String srcClass, String srcMeth, String msg, Throwable t) { if ( isLoggable( l ) ) format( l, srcClass, srcMeth, msg, null, t ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg) { if ( isLoggable( l ) ) formatrb( l, srcClass, srcMeth, rb, msg, null, null ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object param) { if ( isLoggable( l ) ) formatrb( l, srcClass, srcMeth, rb, msg, new Object[] { param }, null ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object[] params) { if ( isLoggable( l ) ) formatrb( l, srcClass, srcMeth, rb, msg, params, null ); } public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Throwable t) { if ( isLoggable( l ) ) formatrb( l, srcClass, srcMeth, rb, msg, null, t ); } public void entering(String srcClass, String srcMeth) { if ( isLoggable( MLevel.FINER ) ) format(MLevel.FINER, srcClass, srcMeth, "Entering method.", null, null); } public void entering(String srcClass, String srcMeth, Object param) { if ( isLoggable( MLevel.FINER ) ) format(MLevel.FINER, srcClass, srcMeth, "Entering method with argument " + param, null, null); } public void entering(String srcClass, String srcMeth, Object[] params) { if ( isLoggable( MLevel.FINER ) ) { if (params == null) entering( srcClass, srcMeth ); else { StringBuffer sb = new StringBuffer(128); sb.append("( "); for (int i = 0, len = params.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( params[i] ); } sb.append(" )"); format(MLevel.FINER, srcClass, srcMeth, "Entering method with arguments " + sb.toString(), null, null); } } } public void exiting(String srcClass, String srcMeth) { if ( isLoggable( MLevel.FINER ) ) format(MLevel.FINER, srcClass, srcMeth, "Exiting method.", null, null); } public void exiting(String srcClass, String srcMeth, Object result) { if ( isLoggable( MLevel.FINER ) ) format(MLevel.FINER, srcClass, srcMeth, "Exiting method with result " + result, null, null); } public void throwing(String srcClass, String srcMeth, Throwable t) { if ( isLoggable( MLevel.FINE ) ) format(MLevel.FINE, srcClass, srcMeth, "Throwing exception." , null, t); } public void severe(String msg) { if ( isLoggable( MLevel.SEVERE ) ) format(MLevel.SEVERE, null, null, msg, null, null); } public void warning(String msg) { if ( isLoggable( MLevel.WARNING ) ) format(MLevel.WARNING, null, null, msg, null, null); } public void info(String msg) { if ( isLoggable( MLevel.INFO ) ) format(MLevel.INFO, null, null, msg, null, null); } public void config(String msg) { if ( isLoggable( MLevel.CONFIG ) ) format(MLevel.CONFIG, null, null, msg, null, null); } public void fine(String msg) { if ( isLoggable( MLevel.FINE ) ) format(MLevel.FINE, null, null, msg, null, null); } public void finer(String msg) { if ( isLoggable( MLevel.FINER ) ) format(MLevel.FINER, null, null, msg, null, null); } public void finest(String msg) { if ( isLoggable( MLevel.FINEST ) ) format(MLevel.FINEST, null, null, msg, null, null); } public void setLevel(MLevel l) throws SecurityException { this.cutoffLevel = l; } public synchronized MLevel getLevel() { return cutoffLevel; } public synchronized boolean isLoggable(MLevel l) { return (l.intValue() >= cutoffLevel.intValue()); } public String getName() { return "global"; } public void addHandler(Object h) throws SecurityException { warning("Using FallbackMLog -- Handlers not supported."); } public void removeHandler(Object h) throws SecurityException { warning("Using FallbackMLog -- Handlers not supported."); } public Object[] getHandlers() { warning("Using FallbackMLog -- Handlers not supported."); return new Object[0]; } public void setUseParentHandlers(boolean uph) { warning("Using FallbackMLog -- Handlers not supported."); } public boolean getUseParentHandlers() { return false; } } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/LogUtils.java0000644000175000017500000000254610624366530021626 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; public final class LogUtils { public static String createParamsList(Object[] params) { StringBuffer sb = new StringBuffer(511); LogUtils.appendParamsList( sb, params ); return sb.toString(); } public static void appendParamsList(StringBuffer sb, Object[] params) { sb.append("[params: "); for (int i = 0, len = params.length; i < len; ++i) { if (i != 0) sb.append(", "); sb.append( params[i] ); } sb.append(']'); } private LogUtils() {} }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/MLevel.java0000644000175000017500000001134510624366527021253 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; import java.util.*; public final class MLevel { public final static MLevel ALL; public final static MLevel CONFIG; public final static MLevel FINE; public final static MLevel FINER; public final static MLevel FINEST; public final static MLevel INFO; public final static MLevel OFF; public final static MLevel SEVERE; public final static MLevel WARNING; private final static Map integersToMLevels; private final static Map namesToMLevels; public static MLevel fromIntValue(int intval) { return (MLevel) integersToMLevels.get( new Integer( intval ) ); } public static MLevel fromSeverity(String name) { return (MLevel) namesToMLevels.get( name ); } static { Class lvlClass; boolean jdk14api; //not just jdk14 -- it is possible for the api to be present with older vms try { lvlClass = Class.forName( "java.util.logging.Level" ); jdk14api = true; } catch (ClassNotFoundException e ) { lvlClass = null; jdk14api = false; } MLevel all; MLevel config; MLevel fine; MLevel finer; MLevel finest; MLevel info; MLevel off; MLevel severe; MLevel warning; try { // numeric values match the intvalues from java.util.logging.Level all = new MLevel( (jdk14api ? lvlClass.getField("ALL").get(null) : null), Integer.MIN_VALUE, "ALL" ); config = new MLevel( (jdk14api ? lvlClass.getField("CONFIG").get(null) : null), 700, "CONFIG" ); fine = new MLevel( (jdk14api ? lvlClass.getField("FINE").get(null) : null), 500, "FINE" ); finer = new MLevel( (jdk14api ? lvlClass.getField("FINER").get(null) : null), 400, "FINER" ); finest = new MLevel( (jdk14api ? lvlClass.getField("FINEST").get(null) : null), 300, "FINEST" ); info = new MLevel( (jdk14api ? lvlClass.getField("INFO").get(null) : null), 800, "INFO" ); off = new MLevel( (jdk14api ? lvlClass.getField("OFF").get(null) : null), Integer.MAX_VALUE, "OFF" ); severe = new MLevel( (jdk14api ? lvlClass.getField("SEVERE").get(null) : null), 900, "SEVERE" ); warning = new MLevel( (jdk14api ? lvlClass.getField("WARNING").get(null) : null), 1000, "WARNING" ); } catch ( Exception e ) { e.printStackTrace(); throw new InternalError("Huh? java.util.logging.Level is here, but not its expected public fields?"); } ALL = all; CONFIG = config; FINE = fine; FINER = finer; FINEST = finest; INFO = info; OFF = off; SEVERE = severe; WARNING = warning; Map tmp = new HashMap(); tmp.put( new Integer(all.intValue()), all); tmp.put( new Integer(config.intValue()), config); tmp.put( new Integer(fine.intValue()), fine); tmp.put( new Integer(finer.intValue()), finer); tmp.put( new Integer(finest.intValue()), finest); tmp.put( new Integer(info.intValue()), info); tmp.put( new Integer(off.intValue()), off); tmp.put( new Integer(severe.intValue()), severe); tmp.put( new Integer(warning.intValue()), warning); integersToMLevels = Collections.unmodifiableMap( tmp ); tmp = new HashMap(); tmp.put( all.getSeverity(), all); tmp.put( config.getSeverity(), config); tmp.put( fine.getSeverity(), fine); tmp.put( finer.getSeverity(), finer); tmp.put( finest.getSeverity(), finest); tmp.put( info.getSeverity(), info); tmp.put( off.getSeverity(), off); tmp.put( severe.getSeverity(), severe); tmp.put( warning.getSeverity(), warning); namesToMLevels = Collections.unmodifiableMap( tmp ); } Object level; int intval; String lvlstring; public int intValue() { return intval; } public Object asJdk14Level() { return level; } public String getSeverity() { return lvlstring; } public String toString() { return this.getClass().getName() + this.getLineHeader(); } public String getLineHeader() { return "[" + lvlstring + ']';} private MLevel(Object level, int intval, String lvlstring) { this.level = level; this.intval = intval; this.lvlstring = lvlstring; } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/MLog.java0000644000175000017500000002022210624366530020711 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; import java.util.List; import java.util.ArrayList; import com.mchange.v1.util.StringTokenizerUtils; import com.mchange.v2.cfg.MultiPropertiesConfig; public abstract class MLog { final static NameTransformer transformer; final static MLog mlog; final static MultiPropertiesConfig CONFIG; final static MLogger logger; static { String[] defaults = new String[] { "/com/mchange/v2/log/default-mchange-log.properties", "/mchange-log.properties", "/" }; CONFIG = MultiPropertiesConfig.readVmConfig( defaults, null ); String classnamesStr = CONFIG.getProperty("com.mchange.v2.log.MLog"); String[] classnames = null; if (classnamesStr == null) classnamesStr = CONFIG.getProperty("com.mchange.v2.log.mlog"); if (classnamesStr != null) classnames = StringTokenizerUtils.tokenizeToArray( classnamesStr, ", \t\r\n" ); boolean warn = false; MLog tmpml = null; if (classnames != null) tmpml = findByClassnames( classnames ); if (tmpml == null) tmpml = findByClassnames( MLogClasses.CLASSNAMES ); if (tmpml == null) { warn = true; tmpml = new FallbackMLog(); } mlog = tmpml; if (warn) info("Using " + mlog.getClass().getName() + " -- Named logger's not supported, everything goes to System.err."); logger = mlog.getLogger( MLog.class ); String loggerDesc = mlog.getClass().getName(); if ("com.mchange.v2.log.jdk14logging.Jdk14MLog".equals( loggerDesc )) loggerDesc = "java 1.4+ standard"; else if ("com.mchange.v2.log.log4j.Log4jMLog".equals( loggerDesc )) loggerDesc = "log4j"; if (logger.isLoggable( MLevel.INFO )) logger.log( MLevel.INFO, "MLog clients using " + loggerDesc + " logging."); NameTransformer tmpt = null; String tClassName = CONFIG.getProperty("com.mchange.v2.log.NameTransformer"); if (tClassName == null) tClassName = CONFIG.getProperty("com.mchange.v2.log.nametransformer"); try { if (tClassName != null) tmpt = (NameTransformer) Class.forName( tClassName ).newInstance(); } catch ( Exception e ) { System.err.println("Failed to instantiate com.mchange.v2.log.NameTransformer '" + tClassName + "'!"); e.printStackTrace(); } transformer = tmpt; //System.err.println(mlog); } public static MLog findByClassnames( String[] classnames ) { List attempts = null; for (int i = 0, len = classnames.length; i < len; ++i) { try { return (MLog) Class.forName( classnames[i] ).newInstance(); } catch (Exception e) { if (attempts == null) attempts = new ArrayList(); attempts.add( classnames[i] ); // System.err.println("com.mchange.v2.log.MLog '" + classnames[i] + "' could not be loaded!"); // e.printStackTrace(); } } System.err.println("Tried without success to load the following MLog classes:"); for (int i = 0, len = attempts.size(); i < len; ++i) System.err.println("\t" + attempts.get(i)); return null; } public static MLog instance() { return mlog; } public static MLogger getLogger(String name) { MLogger out; if ( transformer == null ) out = instance().getMLogger( name ); else { String xname = transformer.transformName( name ); if (xname != null) out = instance().getMLogger( xname ); else out = instance().getMLogger( name ); } return out; } public static MLogger getLogger(Class cl) { MLogger out; if ( transformer == null ) out = instance().getMLogger( cl ); else { String xname = transformer.transformName( cl ); if (xname != null) out = instance().getMLogger( xname ); else out = instance().getMLogger( cl ); } return out; } public static MLogger getLogger() { MLogger out; if ( transformer == null ) out = instance().getMLogger(); else { String xname = transformer.transformName(); if (xname != null) out = instance().getMLogger( xname ); else out = instance().getMLogger(); } return out; } public static void log(MLevel l, String msg) { instance().getLogger().log( l, msg ); } public static void log(MLevel l, String msg, Object param) { instance().getLogger().log( l, msg, param ); } public static void log(MLevel l,String msg, Object[] params) { instance().getLogger().log( l, msg, params ); } public static void log(MLevel l, String msg,Throwable t) { instance().getLogger().log( l, msg, t ); } public static void logp(MLevel l, String srcClass, String srcMeth, String msg) { instance().getLogger().logp( l, srcClass, srcMeth, msg ); } public static void logp(MLevel l, String srcClass, String srcMeth, String msg, Object param) { instance().getLogger().logp( l, srcClass, srcMeth, msg, param ); } public static void logp(MLevel l, String srcClass, String srcMeth, String msg, Object[] params) { instance().getLogger().logp( l, srcClass, srcMeth, msg, params ); } public static void logp(MLevel l, String srcClass, String srcMeth, String msg, Throwable t) { instance().getLogger().logp( l, srcClass, srcMeth, msg, t ); } public static void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg) { instance().getLogger().logp( l, srcClass, srcMeth, rb, msg ); } public static void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object param) { instance().getLogger().logrb( l, srcClass, srcMeth, rb, msg, param ); } public static void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object[] params) { instance().getLogger().logrb( l, srcClass, srcMeth, rb, msg, params ); } public static void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Throwable t) { instance().getLogger().logrb( l, srcClass, srcMeth, rb, msg, t ); } public static void entering(String srcClass, String srcMeth) { instance().getLogger().entering( srcClass, srcMeth ); } public static void entering(String srcClass, String srcMeth, Object param) { instance().getLogger().entering( srcClass, srcMeth, param ); } public static void entering(String srcClass, String srcMeth, Object params[]) { instance().getLogger().entering( srcClass, srcMeth, params ); } public static void exiting(String srcClass, String srcMeth) { instance().getLogger().exiting( srcClass, srcMeth ); } public static void exiting(String srcClass, String srcMeth, Object result) { instance().getLogger().exiting( srcClass, srcMeth, result ); } public static void throwing(String srcClass, String srcMeth, Throwable t) { instance().getLogger().throwing( srcClass, srcMeth, t); } public static void severe(String msg) { instance().getLogger().severe( msg ); } public static void warning(String msg) { instance().getLogger().warning( msg ); } public static void info(String msg) { instance().getLogger().info( msg ); } public static void config(String msg) { instance().getLogger().config( msg ); } public static void fine(String msg) { instance().getLogger().fine( msg ); } public static void finer(String msg) { instance().getLogger().finer( msg ); } public static void finest(String msg) { instance().getLogger().finest( msg ); } public abstract MLogger getMLogger(String name); public abstract MLogger getMLogger(Class cl); public abstract MLogger getMLogger(); }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/MLogClasses.java0000644000175000017500000000211010624366527022231 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; public final class MLogClasses { public final static String[] CLASSNAMES = { "com.mchange.v2.log.jdk14logging.Jdk14MLog", "com.mchange.v2.log.FallbackMLog" }; private MLogClasses() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/MLogger.java0000644000175000017500000000701010624366530021407 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; import java.util.*; /** * This is an interface designed to wrap around the JDK1.4 logging API, without * having any compilation dependencies on that API, so that applications that use * MLogger in a non JDK1.4 environment, or where some other logging library is * prefrerred, may do so. * * Calls to handler and filter related methods may be ignored if some logging * system besides jdk1.4 logging is the underlying library. */ public interface MLogger { public ResourceBundle getResourceBundle(); public String getResourceBundleName(); public void setFilter(Object java14Filter) throws SecurityException; public Object getFilter(); public void log(MLevel l, String msg); public void log(MLevel l, String msg, Object param); public void log(MLevel l,String msg, Object[] params); public void log(MLevel l, String msg,Throwable t); public void logp(MLevel l, String srcClass, String srcMeth, String msg); public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object param); public void logp(MLevel l, String srcClass, String srcMeth, String msg, Object[] params); public void logp(MLevel l, String srcClass, String srcMeth, String msg, Throwable t); public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg); public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object param); public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Object[] params); public void logrb(MLevel l, String srcClass, String srcMeth, String rb, String msg, Throwable t); public void entering(String srcClass, String srcMeth); public void entering(String srcClass, String srcMeth, Object param); public void entering(String srcClass, String srcMeth, Object params[]); public void exiting(String srcClass, String srcMeth); public void exiting(String srcClass, String srcMeth, Object result); public void throwing(String srcClass, String srcMeth, Throwable t); public void severe(String msg); public void warning(String msg); public void info(String msg); public void config(String msg); public void fine(String msg); public void finer(String msg); public void finest(String msg); public void setLevel(MLevel l) throws SecurityException; public MLevel getLevel(); public boolean isLoggable(MLevel l); public String getName(); public void addHandler(Object h) throws SecurityException; public void removeHandler(Object h) throws SecurityException; public Object[] getHandlers(); public void setUseParentHandlers(boolean uph); public boolean getUseParentHandlers(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/NameTransformer.java0000644000175000017500000000272610624366530023167 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; /** *

When the methods return a name, the log requested from MLog.getLogger( XXX ) * the logger actually acquired will be based on the String returned.

* *

When the methods return null, no transformation will occur, and the logger * that would have been returned without a transformer will be returned.

* *

Implementing classes must have public, no-arg constructors, through which * they will be instantiated.

*/ public interface NameTransformer { public String transformName( String name ); public String transformName( Class cl ); public String transformName(); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/log/PackageNames.java0000644000175000017500000000234510624366527022406 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.log; public class PackageNames implements NameTransformer { public String transformName( String name ) { return null; } public String transformName( Class cl ) { String fqcn = cl.getName(); int i = fqcn.lastIndexOf('.'); if (i <= 0) return ""; else return fqcn.substring(0,i); } public String transformName() { return null; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/management/0000755000175000017500000000000010673162231020541 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/management/ManagementUtils.java0000644000175000017500000000642410624366527024521 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.management; import javax.management.*; import java.util.Comparator; public class ManagementUtils { public final static Comparator PARAM_INFO_COMPARATOR = new Comparator() { public int compare(Object a, Object b) { MBeanParameterInfo aa = (MBeanParameterInfo) a; MBeanParameterInfo bb = (MBeanParameterInfo) b; int out = aa.getType().compareTo(bb.getType()); if (out == 0) { out = aa.getName().compareTo(bb.getName()); if (out == 0) { String aDesc = aa.getDescription(); String bDesc = bb.getDescription(); if (aDesc == null && bDesc == null) out = 0; else if (aDesc == null) out = -1; else if (bDesc == null) out = 1; else out = aDesc.compareTo(bDesc); } } return out; } }; public final static Comparator OP_INFO_COMPARATOR = new Comparator() { public int compare(Object a, Object b) { MBeanOperationInfo aa = (MBeanOperationInfo) a; MBeanOperationInfo bb = (MBeanOperationInfo) b; String aName = aa.getName(); String bName = bb.getName(); int out = String.CASE_INSENSITIVE_ORDER.compare(aName, bName); if (out == 0) { if (aName.equals(bName)) { MBeanParameterInfo[] aParams = aa.getSignature(); MBeanParameterInfo[] bParams = bb.getSignature(); if (aParams.length < bParams.length) out = -1; else if (aParams.length > bParams.length) out = 1; else { for (int i = 0, len = aParams.length; i < len; ++i) { out = PARAM_INFO_COMPARATOR.compare(aParams[i], bParams[i]); if (out != 0) break; } } } else { out = aName.compareTo(bName); } } return out; } }; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/naming/0000755000175000017500000000000010673162231017676 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/naming/JavaBeanObjectFactory.java0000644000175000017500000001266710624366530024707 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.naming; import java.beans.*; import java.util.*; import javax.naming.*; import com.mchange.v2.log.*; import java.lang.reflect.Method; import javax.naming.spi.ObjectFactory; import com.mchange.v2.beans.BeansUtils; import com.mchange.v2.lang.Coerce; import com.mchange.v2.ser.SerializableUtils; public class JavaBeanObjectFactory implements ObjectFactory { private final static MLogger logger = MLog.getLogger( JavaBeanObjectFactory.class ); final static Object NULL_TOKEN = new Object(); public Object getObjectInstance(Object refObj, Name name, Context nameCtx, Hashtable env) throws Exception { if (refObj instanceof Reference) { Reference ref = (Reference) refObj; Map refAddrsMap = new HashMap(); for (Enumeration e = ref.getAll(); e.hasMoreElements(); ) { RefAddr addr = (RefAddr) e.nextElement(); refAddrsMap.put( addr.getType(), addr ); } Class beanClass = Class.forName( ref.getClassName() ); Set refProps = null; RefAddr refPropsRefAddr = (BinaryRefAddr) refAddrsMap.remove( JavaBeanReferenceMaker.REF_PROPS_KEY ); if ( refPropsRefAddr != null ) refProps = (Set) SerializableUtils.fromByteArray( (byte[]) refPropsRefAddr.getContent() ); Map propMap = createPropertyMap( beanClass, refAddrsMap ); return findBean( beanClass, propMap, refProps ); } else return null; } private Map createPropertyMap( Class beanClass, Map refAddrsMap ) throws Exception { BeanInfo bi = Introspector.getBeanInfo( beanClass ); PropertyDescriptor[] pds = bi.getPropertyDescriptors(); Map out = new HashMap(); for (int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; String propertyName = pd.getName(); Class propertyType = pd.getPropertyType(); Object addr = refAddrsMap.remove( propertyName ); if (addr != null) { if ( addr instanceof StringRefAddr ) { String content = (String) ((StringRefAddr) addr).getContent(); if ( Coerce.canCoerce( propertyType ) ) out.put( propertyName, Coerce.toObject( content, propertyType ) ); else { PropertyEditor pe = BeansUtils.findPropertyEditor( pd ); pe.setAsText( content ); out.put( propertyName, pe.getValue() ); } } else if ( addr instanceof BinaryRefAddr ) { byte[] content = (byte[]) ((BinaryRefAddr) addr).getContent(); if ( content.length == 0 ) out.put( propertyName, NULL_TOKEN ); //we use an empty array to mean null else out.put( propertyName, SerializableUtils.fromByteArray( content ) ); //this will handle "indirectly serialized" objects. } else { if (logger.isLoggable( MLevel.WARNING )) logger.warning(this.getClass().getName() + " -- unknown RefAddr subclass: " + addr.getClass().getName()); } } } for ( Iterator ii = refAddrsMap.keySet().iterator(); ii.hasNext(); ) { String type = (String) ii.next(); if (logger.isLoggable( MLevel.WARNING )) logger.warning(this.getClass().getName() + " -- RefAddr for unknown property: " + type); } return out; } protected Object createBlankInstance(Class beanClass) throws Exception { return beanClass.newInstance(); } protected Object findBean(Class beanClass, Map propertyMap, Set refProps ) throws Exception { Object bean = createBlankInstance( beanClass ); BeanInfo bi = Introspector.getBeanInfo( bean.getClass() ); PropertyDescriptor[] pds = bi.getPropertyDescriptors(); for (int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; String propertyName = pd.getName(); Object value = propertyMap.get( propertyName ); Method setter = pd.getWriteMethod(); if (value != null) { if (setter != null) setter.invoke( bean, new Object[] { (value == NULL_TOKEN ? null : value) } ); else { //System.err.println(this.getClass().getName() + ": Could not restore read-only property '" + propertyName + "'."); if (logger.isLoggable( MLevel.WARNING )) logger.warning(this.getClass().getName() + ": Could not restore read-only property '" + propertyName + "'."); } } else { if (setter != null) { if (refProps == null || refProps.contains( propertyName )) { //System.err.println(this.getClass().getName() + //": WARNING -- Expected writable property '" + propertyName + "' left at default value"); if (logger.isLoggable( MLevel.WARNING )) logger.warning(this.getClass().getName() + " -- Expected writable property ''" + propertyName + "'' left at default value"); } } } } return bean; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/naming/JavaBeanReferenceMaker.java0000644000175000017500000001407410624366527025027 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.naming; import java.beans.*; import java.io.*; import java.util.*; import javax.naming.*; import com.mchange.v2.log.*; import java.lang.reflect.Method; import com.mchange.v2.lang.Coerce; import com.mchange.v2.beans.BeansUtils; import com.mchange.v2.ser.SerializableUtils; import com.mchange.v2.ser.IndirectPolicy; public class JavaBeanReferenceMaker implements ReferenceMaker { private final static MLogger logger = MLog.getLogger( JavaBeanReferenceMaker.class ); final static String REF_PROPS_KEY = "com.mchange.v2.naming.JavaBeanReferenceMaker.REF_PROPS_KEY"; final static Object[] EMPTY_ARGS = new Object[0]; final static byte[] NULL_TOKEN_BYTES = new byte[0]; String factoryClassName = "com.mchange.v2.naming.JavaBeanObjectFactory"; String defaultFactoryClassLocation = null; Set referenceProperties = new HashSet(); ReferenceIndirector indirector = new ReferenceIndirector(); public Hashtable getEnvironmentProperties() { return indirector.getEnvironmentProperties(); } public void setEnvironmentProperties( Hashtable environmentProperties ) { indirector.setEnvironmentProperties( environmentProperties ); } public void setFactoryClassName(String factoryClassName) { this.factoryClassName = factoryClassName; } public String getFactoryClassName() { return factoryClassName; } public String getDefaultFactoryClassLocation() { return defaultFactoryClassLocation; } public void setDefaultFactoryClassLocation( String defaultFactoryClassLocation ) { this.defaultFactoryClassLocation = defaultFactoryClassLocation; } public void addReferenceProperty( String propName ) { referenceProperties.add( propName ); } public void removeReferenceProperty( String propName ) { referenceProperties.remove( propName ); } public Reference createReference( Object bean ) throws NamingException { try { BeanInfo bi = Introspector.getBeanInfo( bean.getClass() ); PropertyDescriptor[] pds = bi.getPropertyDescriptors(); List refAddrs = new ArrayList(); String factoryClassLocation = defaultFactoryClassLocation; boolean using_ref_props = referenceProperties.size() > 0; // we only include this so that on dereference we are not surprised to find some properties missing if (using_ref_props) refAddrs.add( new BinaryRefAddr( REF_PROPS_KEY, SerializableUtils.toByteArray( referenceProperties ) ) ); for (int i = 0, len = pds.length; i < len; ++i) { PropertyDescriptor pd = pds[i]; String propertyName = pd.getName(); //System.err.println("Making Reference: " + propertyName); if (using_ref_props && ! referenceProperties.contains( propertyName )) { //System.err.println("Not a ref_prop -- continuing."); continue; } Class propertyType = pd.getPropertyType(); Method getter = pd.getReadMethod(); Method setter = pd.getWriteMethod(); if (getter != null && setter != null) //only use properties that are both readable and writable { Object val = getter.invoke( bean, EMPTY_ARGS ); //System.err.println( "val: " + val ); if (propertyName.equals("factoryClassLocation")) { if (String.class != propertyType) throw new NamingException(this.getClass().getName() + " requires a factoryClassLocation property to be a string, " + propertyType.getName() + " is not valid."); factoryClassLocation = (String) val; } if (val == null) { RefAddr addMe = new BinaryRefAddr( propertyName, NULL_TOKEN_BYTES ); refAddrs.add( addMe ); } else if ( Coerce.canCoerce( propertyType ) ) { RefAddr addMe = new StringRefAddr( propertyName, String.valueOf( val ) ); refAddrs.add( addMe ); } else //other Object properties { RefAddr addMe = null; PropertyEditor pe = BeansUtils.findPropertyEditor( pd ); if (pe != null) { pe.setValue( val ); String textValue = pe.getAsText(); if (textValue != null) addMe = new StringRefAddr( propertyName, textValue ); } if (addMe == null) //property editor approach failed addMe = new BinaryRefAddr( propertyName, SerializableUtils.toByteArray( val, indirector, IndirectPolicy.INDIRECT_ON_EXCEPTION ) ); refAddrs.add( addMe ); } } else { // System.err.println(this.getClass().getName() + // ": Skipping " + propertyName + " because it is " + (setter == null ? "read-only." : "write-only.")); if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning(this.getClass().getName() + ": Skipping " + propertyName + " because it is " + (setter == null ? "read-only." : "write-only.")); } } Reference out = new Reference( bean.getClass().getName(), factoryClassName, factoryClassLocation ); for (Iterator ii = refAddrs.iterator(); ii.hasNext(); ) out.add( (RefAddr) ii.next() ); return out; } catch ( Exception e ) { //e.printStackTrace(); if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Exception trying to create Reference.", e); throw new NamingException("Could not create reference from bean: " + e.toString() ); } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/naming/ReferenceIndirector.java0000644000175000017500000000674410624366527024507 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.naming; import java.io.InvalidObjectException; import java.io.IOException; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Name; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import com.mchange.v2.ser.Indirector; import com.mchange.v2.ser.IndirectlySerialized; public class ReferenceIndirector implements Indirector { final static MLogger logger = MLog.getLogger( ReferenceIndirector.class ); Name name; Name contextName; Hashtable environmentProperties; public Name getName() { return name; } public void setName( Name name ) { this.name = name; } public Name getNameContextName() { return contextName; } public void setNameContextName( Name contextName ) { this.contextName = contextName; } public Hashtable getEnvironmentProperties() { return environmentProperties; } public void setEnvironmentProperties( Hashtable environmentProperties ) { this.environmentProperties = environmentProperties; } public IndirectlySerialized indirectForm( Object orig ) throws Exception { Reference ref = ((Referenceable) orig).getReference(); return new ReferenceSerialized( ref, name, contextName, environmentProperties ); } private static class ReferenceSerialized implements IndirectlySerialized { Reference reference; Name name; Name contextName; Hashtable env; ReferenceSerialized( Reference reference, Name name, Name contextName, Hashtable env ) { this.reference = reference; this.name = name; this.contextName = contextName; this.env = env; } public Object getObject() throws ClassNotFoundException, IOException { try { Context initialContext; if ( env == null ) initialContext = new InitialContext(); else initialContext = new InitialContext( env ); Context nameContext = null; if ( contextName != null ) nameContext = (Context) initialContext.lookup( contextName ); return ReferenceableUtils.referenceToObject( reference, name, nameContext, env ); } catch (NamingException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to acquire the Context necessary to lookup an Object.", e ); throw new InvalidObjectException( "Failed to acquire the Context necessary to lookup an Object: " + e.toString() ); } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/naming/ReferenceMaker.java0000644000175000017500000000205410624366527023432 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.naming; import javax.naming.Reference; import javax.naming.NamingException; public interface ReferenceMaker { public Reference createReference( Object o ) throws NamingException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/naming/ReferenceableUtils.java0000644000175000017500000001326510624366527024325 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.naming; import java.net.*; import javax.naming.*; import com.mchange.v2.log.MLevel; import com.mchange.v2.log.MLog; import com.mchange.v2.log.MLogger; import javax.naming.spi.ObjectFactory; import java.util.Hashtable; public final class ReferenceableUtils { final static MLogger logger = MLog.getLogger( ReferenceableUtils.class ); /* don't worry -- References can have duplicate RefAddrs (I think!) */ final static String REFADDR_VERSION = "version"; final static String REFADDR_CLASSNAME = "classname"; final static String REFADDR_FACTORY = "factory"; final static String REFADDR_FACTORY_CLASS_LOCATION = "factoryClassLocation"; final static String REFADDR_SIZE = "size"; final static int CURRENT_REF_VERSION = 1; /** * A null string value in a Reference sometimes goes to the literal * "null". Sigh. We convert this string to a Java null. */ public static String literalNullToNull( String s ) { if (s == null || "null".equals( s )) return null; else return s; } public static Object referenceToObject( Reference ref, Name name, Context nameCtx, Hashtable env) throws NamingException { try { String fClassName = ref.getFactoryClassName(); String fClassLocation = ref.getFactoryClassLocation(); ClassLoader cl; if ( fClassLocation == null ) cl = ClassLoader.getSystemClassLoader(); else { URL u = new URL( fClassLocation ); cl = new URLClassLoader( new URL[] { u }, ClassLoader.getSystemClassLoader() ); } Class fClass = Class.forName( fClassName, true, cl ); ObjectFactory of = (ObjectFactory) fClass.newInstance(); return of.getObjectInstance( ref, name, nameCtx, env ); } catch ( Exception e ) { if (Debug.DEBUG) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Could not resolve Reference to Object!", e); } NamingException ne = new NamingException("Could not resolve Reference to Object!"); ne.setRootCause( e ); throw ne; } } /** * @deprecated nesting references seemed useful until I realized that * references are Serializable and can be stored in a BinaryRefAddr. * Oops. */ public static void appendToReference(Reference appendTo, Reference orig) throws NamingException { int len = orig.size(); appendTo.add( new StringRefAddr( REFADDR_VERSION, String.valueOf( CURRENT_REF_VERSION ) ) ); appendTo.add( new StringRefAddr( REFADDR_CLASSNAME, orig.getClassName() ) ); appendTo.add( new StringRefAddr( REFADDR_FACTORY, orig.getFactoryClassName() ) ); appendTo.add( new StringRefAddr( REFADDR_FACTORY_CLASS_LOCATION, orig.getFactoryClassLocation() ) ); appendTo.add( new StringRefAddr( REFADDR_SIZE, String.valueOf(len) ) ); for (int i = 0; i < len; ++i) appendTo.add( orig.get(i) ); } /** * @deprecated nesting references seemed useful until I realized that * references are Serializable and can be stored in a BinaryRefAddr. * Oops. */ public static ExtractRec extractNestedReference(Reference extractFrom, int index) throws NamingException { try { int version = Integer.parseInt((String) extractFrom.get(index++).getContent()); if (version == 1) { String className = (String) extractFrom.get(index++).getContent(); String factoryClassName = (String) extractFrom.get(index++).getContent(); String factoryClassLocation = (String) extractFrom.get(index++).getContent(); Reference outRef = new Reference( className, factoryClassName, factoryClassLocation ); int size = Integer.parseInt((String) extractFrom.get(index++).getContent()); for (int i = 0; i < size; ++i) outRef.add( extractFrom.get( index++ ) ); return new ExtractRec( outRef, index ); } else throw new NamingException("Bad version of nested reference!!!"); } catch (NumberFormatException e) { if (Debug.DEBUG) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Version or size nested reference was not a number!!!", e); } throw new NamingException("Version or size nested reference was not a number!!!"); } } /** * @deprecated nesting references seemed useful until I realized that * references are Serializable and can be stored in a BinaryRefAddr. * Oops. */ public static class ExtractRec { public Reference ref; /** * return the first RefAddr index that the function HAS NOT read to * extract the reference. */ public int index; private ExtractRec(Reference ref, int index) { this.ref = ref; this.index = index; } } private ReferenceableUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/0000755000175000017500000000000010673162231021146 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/BasicResourcePool.java0000644000175000017500000023122010624366530025400 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import java.util.*; import com.mchange.v2.async.*; import com.mchange.v2.log.*; import com.mchange.v2.lang.ThreadUtils; import com.mchange.v2.util.ResourceClosedException; class BasicResourcePool implements ResourcePool { private final static MLogger logger = MLog.getLogger( BasicResourcePool.class ); final static int AUTO_CULL_FREQUENCY_DIVISOR = 4; final static int AUTO_MAX_CULL_FREQUENCY = (15 * 60 * 1000); //15 mins final static int AUTO_MIN_CULL_FREQUENCY = (1 * 1000); //15 mins //XXX: temporary -- for selecting between AcquireTask types // remove soon, and use only ScatteredAcquireTask, // presuming no problems appear final static String USE_SCATTERED_ACQUIRE_TASK_KEY = "com.mchange.v2.resourcepool.experimental.useScatteredAcquireTask"; final static boolean USE_SCATTERED_ACQUIRE_TASK; static { String checkScattered = com.mchange.v2.cfg.MultiPropertiesConfig.readVmConfig().getProperty(USE_SCATTERED_ACQUIRE_TASK_KEY); if (checkScattered != null && checkScattered.trim().toLowerCase().equals("true")) { USE_SCATTERED_ACQUIRE_TASK = true; if ( logger.isLoggable( MLevel.INFO ) ) logger.info(BasicResourcePool.class.getName() + " using experimental ScatteredAcquireTask."); } else USE_SCATTERED_ACQUIRE_TASK = false; } // end temporary switch between acquire task types //MT: unchanged post c'tor final Manager mgr; final int start; final int min; final int max; final int inc; final int num_acq_attempts; final int acq_attempt_delay; final long check_idle_resources_delay; //milliseconds final long max_resource_age; //milliseconds final long max_idle_time; //milliseconds final long excess_max_idle_time; //milliseconds final long destroy_unreturned_resc_time; //milliseconds final long expiration_enforcement_delay; //milliseconds final boolean break_on_acquisition_failure; final boolean debug_store_checkout_exceptions; final long pool_start_time = System.currentTimeMillis(); //MT: not-reassigned, thread-safe, and independent final BasicResourcePoolFactory factory; final AsynchronousRunner taskRunner; final RunnableQueue asyncEventQueue; final ResourcePoolEventSupport rpes; //MT: protected by this' lock Timer cullAndIdleRefurbishTimer; TimerTask cullTask; TimerTask idleRefurbishTask; HashSet acquireWaiters = new HashSet(); HashSet otherWaiters = new HashSet(); int pending_acquires; int pending_removes; int target_pool_size; /* keys are all valid, managed resources, value is a PunchCard */ HashMap managed = new HashMap(); /* all valid, managed resources currently available for checkout */ LinkedList unused = new LinkedList(); /* resources which have been invalidated somehow, but which are */ /* still checked out and in use. */ HashSet excluded = new HashSet(); Map formerResources = new WeakHashMap(); Set idleCheckResources = new HashSet(); boolean force_kill_acquires = false; boolean broken = false; // long total_acquired = 0; long failed_checkins = 0; long failed_checkouts = 0; long failed_idle_tests = 0; Throwable lastCheckinFailure = null; Throwable lastCheckoutFailure = null; Throwable lastIdleTestFailure = null; Throwable lastResourceTestFailure = null; Throwable lastAcquisitionFailiure = null; //DEBUG only! Object exampleResource; public long getStartTime() { return pool_start_time; } public long getUpTime() { return System.currentTimeMillis() - pool_start_time; } public synchronized long getNumFailedCheckins() { return failed_checkins; } public synchronized long getNumFailedCheckouts() { return failed_checkouts; } public synchronized long getNumFailedIdleTests() { return failed_idle_tests; } public synchronized Throwable getLastCheckinFailure() { return lastCheckinFailure; } //must be called from a pre-existing sync'ed block private void setLastCheckinFailure(Throwable t) { assert ( Thread.holdsLock(this)); this.lastCheckinFailure = t; this.lastResourceTestFailure = t; } public synchronized Throwable getLastCheckoutFailure() { return lastCheckoutFailure; } //must be called from a pre-existing sync'ed block private void setLastCheckoutFailure(Throwable t) { assert ( Thread.holdsLock(this)); this.lastCheckoutFailure = t; this.lastResourceTestFailure = t; } public synchronized Throwable getLastIdleCheckFailure() { return lastIdleTestFailure; } //must be called from a pre-existing sync'ed block private void setLastIdleCheckFailure(Throwable t) { assert ( Thread.holdsLock(this)); this.lastIdleTestFailure = t; this.lastResourceTestFailure = t; } public synchronized Throwable getLastResourceTestFailure() { return lastResourceTestFailure; } public synchronized Throwable getLastAcquisitionFailure() { return lastAcquisitionFailiure; } // ought not be called while holding this' lock private synchronized void setLastAcquisitionFailure( Throwable t ) { this.lastAcquisitionFailiure = t; } public synchronized int getNumCheckoutWaiters() { return acquireWaiters.size(); } private void addToFormerResources( Object resc ) { formerResources.put( resc, null ); } private boolean isFormerResource( Object resc ) { return formerResources.keySet().contains( resc ); } /** * @param factory may be null */ public BasicResourcePool(Manager mgr, int start, int min, int max, int inc, int num_acq_attempts, int acq_attempt_delay, long check_idle_resources_delay, long max_resource_age, long max_idle_time, long excess_max_idle_time, long destroy_unreturned_resc_time, long expiration_enforcement_delay, boolean break_on_acquisition_failure, boolean debug_store_checkout_exceptions, AsynchronousRunner taskRunner, RunnableQueue asyncEventQueue, Timer cullAndIdleRefurbishTimer, BasicResourcePoolFactory factory) throws ResourcePoolException { try { this.mgr = mgr; this.start = start; this.min = min; this.max = max; this.inc = inc; this.num_acq_attempts = num_acq_attempts; this.acq_attempt_delay = acq_attempt_delay; this.check_idle_resources_delay = check_idle_resources_delay; this.max_resource_age = max_resource_age; this.max_idle_time = max_idle_time; this.excess_max_idle_time = excess_max_idle_time; this.destroy_unreturned_resc_time = destroy_unreturned_resc_time; //this.expiration_enforcement_delay = expiration_enforcement_delay; -- set up below this.break_on_acquisition_failure = break_on_acquisition_failure; this.debug_store_checkout_exceptions = (debug_store_checkout_exceptions && destroy_unreturned_resc_time > 0); this.taskRunner = taskRunner; this.asyncEventQueue = asyncEventQueue; this.cullAndIdleRefurbishTimer = cullAndIdleRefurbishTimer; this.factory = factory; this.pending_acquires = 0; this.pending_removes = 0; this.target_pool_size = Math.max(start, min); if (asyncEventQueue != null) this.rpes = new ResourcePoolEventSupport(this); else this.rpes = null; //start acquiring our initial resources ensureStartResources(); if (mustEnforceExpiration()) { if (expiration_enforcement_delay <= 0) this.expiration_enforcement_delay = automaticExpirationEnforcementDelay(); else this.expiration_enforcement_delay = expiration_enforcement_delay; this.cullTask = new CullTask(); //System.err.println("minExpirationTime(): " + minExpirationTime()); //System.err.println("this.expiration_enforcement_delay: " + this.expiration_enforcement_delay); cullAndIdleRefurbishTimer.schedule( cullTask, minExpirationTime(), this.expiration_enforcement_delay ); } else this.expiration_enforcement_delay = expiration_enforcement_delay; //System.err.println("this.check_idle_resources_delay: " + this.check_idle_resources_delay); if (check_idle_resources_delay > 0) { this.idleRefurbishTask = new CheckIdleResourcesTask(); cullAndIdleRefurbishTimer.schedule( idleRefurbishTask, check_idle_resources_delay, check_idle_resources_delay ); } if ( logger.isLoggable( MLevel.FINER ) ) logger.finer( this + " config: [start -> " + this.start + "; min -> " + this.min + "; max -> " + this.max + "; inc -> " + this.inc + "; num_acq_attempts -> " + this.num_acq_attempts + "; acq_attempt_delay -> " + this.acq_attempt_delay + "; check_idle_resources_delay -> " + this.check_idle_resources_delay + "; mox_resource_age -> " + this.max_resource_age + "; max_idle_time -> " + this.max_idle_time + "; excess_max_idle_time -> " + this.excess_max_idle_time + "; destroy_unreturned_resc_time -> " + this.destroy_unreturned_resc_time + "; expiration_enforcement_delay -> " + this.expiration_enforcement_delay + "; break_on_acquisition_failure -> " + this.break_on_acquisition_failure + "; debug_store_checkout_exceptions -> " + this.debug_store_checkout_exceptions + "]"); } catch (Exception e) { // if ( logger.isLoggable( MLevel.WARNING) ) // logger.log( MLevel.WARNING, "Could not create resource pool due to Exception!", e ); throw ResourcePoolUtils.convertThrowable( e ); } } // private boolean timerRequired() // { return mustEnforceExpiration() || mustTestIdleResources(); } // no need to sync private boolean mustTestIdleResources() { return check_idle_resources_delay > 0; } // no need to sync private boolean mustEnforceExpiration() { return max_resource_age > 0 || max_idle_time > 0 || excess_max_idle_time > 0 || destroy_unreturned_resc_time > 0; } // no need to sync private long minExpirationTime() { long out = Long.MAX_VALUE; if (max_resource_age > 0) out = Math.min( out, max_resource_age ); if (max_idle_time > 0) out = Math.min( out, max_idle_time ); if (excess_max_idle_time > 0) out = Math.min( out, excess_max_idle_time ); if (destroy_unreturned_resc_time > 0) out = Math.min( out, destroy_unreturned_resc_time ); return out; } private long automaticExpirationEnforcementDelay() { long out = minExpirationTime(); out /= AUTO_CULL_FREQUENCY_DIVISOR; out = Math.min( out, AUTO_MAX_CULL_FREQUENCY ); out = Math.max( out, AUTO_MIN_CULL_FREQUENCY ); return out; } public long getEffectiveExpirationEnforcementDelay() { return expiration_enforcement_delay; } private synchronized boolean isBroken() { return broken; } // no need to sync private boolean supportsEvents() { return asyncEventQueue != null; } public Object checkoutResource() throws ResourcePoolException, InterruptedException { try { return checkoutResource( 0 ); } catch (TimeoutException e) { //this should never happen //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Huh??? TimeoutException with no timeout set!!!", e); throw new ResourcePoolException("Huh??? TimeoutException with no timeout set!!!", e); } } // must be called from synchronized method, idempotent private void _recheckResizePool() { assert Thread.holdsLock(this); if (! broken) { int msz = managed.size(); //int expected_size = msz + pending_acquires - pending_removes; // System.err.print("target: " + target_pool_size); // System.err.println(" (msz: " + msz + "; pending_acquires: " + pending_acquires + "; pending_removes: " + pending_removes + ')'); //new Exception( "_recheckResizePool() STACK TRACE" ).printStackTrace(); int shrink_count; int expand_count; if ((shrink_count = msz - pending_removes - target_pool_size) > 0) shrinkPool( shrink_count ); else if ((expand_count = target_pool_size - (msz + pending_acquires)) > 0) expandPool( expand_count ); } } private synchronized void incrementPendingAcquires() { ++pending_acquires; if (logger.isLoggable(MLevel.FINEST)) logger.finest("incremented pending_acquires: " + pending_acquires); //new Exception("ACQUIRE SOURCE STACK TRACE").printStackTrace(); } private synchronized void incrementPendingRemoves() { ++pending_removes; if (logger.isLoggable(MLevel.FINEST)) logger.finest("incremented pending_removes: " + pending_removes); //new Exception("REMOVE SOURCE STACK TRACE").printStackTrace(); } private synchronized void decrementPendingAcquires() { --pending_acquires; if (logger.isLoggable(MLevel.FINEST)) logger.finest("decremented pending_acquires: " + pending_acquires); //new Exception("ACQUIRE SOURCE STACK TRACE").printStackTrace(); } private synchronized void decrementPendingRemoves() { --pending_removes; if (logger.isLoggable(MLevel.FINEST)) logger.finest("decremented pending_removes: " + pending_removes); //new Exception("ACQUIRE SOURCE STACK TRACE").printStackTrace(); } // idempotent private synchronized void recheckResizePool() { _recheckResizePool(); } // must be called from synchronized method private void expandPool(int count) { assert Thread.holdsLock(this); // XXX: temporary switch -- assuming no problems appear, we'll get rid of AcquireTask // in favor of ScatteredAcquireTask if ( USE_SCATTERED_ACQUIRE_TASK ) { for (int i = 0; i < count; ++i) taskRunner.postRunnable( new ScatteredAcquireTask() ); } else { for (int i = 0; i < count; ++i) taskRunner.postRunnable( new AcquireTask() ); } } // must be called from synchronized method private void shrinkPool(int count) { assert Thread.holdsLock(this); for (int i = 0; i < count; ++i) taskRunner.postRunnable( new RemoveTask() ); } /* * This function recursively calls itself... under nonpathological * situations, it shouldn't be a problem, but if resources can never * successfully check out for some reason, we might blow the stack... * * by the semantics of wait(), a timeout of zero means forever. */ public Object checkoutResource( long timeout ) throws TimeoutException, ResourcePoolException, InterruptedException { Object resc = prelimCheckoutResource( timeout ); boolean refurb = attemptRefurbishResourceOnCheckout( resc ); synchronized( this ) { if (!refurb) { removeResource( resc ); ensureMinResources(); resc = null; } else { asyncFireResourceCheckedOut( resc, managed.size(), unused.size(), excluded.size() ); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) trace(); PunchCard card = (PunchCard) managed.get( resc ); if (card == null) //the resource has been removed! { if (logger.isLoggable( MLevel.FINE )) logger.fine("Resource " + resc + " was removed from the pool while it was being checked out " + " or refurbished for checkout."); resc = null; } else { card.checkout_time = System.currentTimeMillis(); if (debug_store_checkout_exceptions) card.checkoutStackTraceException = new Exception("DEBUG ONLY: Overdue resource check-out stack trace."); } } } // best to do the recheckout while we don't hold this' // lock, so we don't refurbish-on-checkout while holding. if (resc == null) return checkoutResource( timeout ); else return resc; } private synchronized Object prelimCheckoutResource( long timeout ) throws TimeoutException, ResourcePoolException, InterruptedException { try { ensureNotBroken(); int available = unused.size(); if (available == 0) { int msz = managed.size(); if (msz < max) { // to cover all the load, we need the current size, plus those waiting already for acquisition, // plus the current client int desired_target = msz + acquireWaiters.size() + 1; if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "acquire test -- pool size: " + msz + "; target_pool_size: " + target_pool_size + "; desired target? " + desired_target); if (desired_target >= target_pool_size) { //make sure we don't grab less than inc Connections at a time, if we can help it. desired_target = Math.max(desired_target, target_pool_size + inc); //make sure our target is within its bounds target_pool_size = Math.max( Math.min( max, desired_target ), min ); _recheckResizePool(); } } else { if (logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "acquire test -- pool is already maxed out. [managed: " + msz + "; max: " + max + "]"); } awaitAvailable(timeout); //throws timeout exception } Object resc = unused.get(0); // this is a hack -- but "doing it right" adds a lot of complexity, and collisions between // an idle check and a checkout should be relatively rare. anyway, it should work just fine. if ( idleCheckResources.contains( resc ) ) { if (Debug.DEBUG && logger.isLoggable( MLevel.FINER)) logger.log( MLevel.FINER, "Resource we want to check out is in idleCheck! (waiting until idle-check completes.) [" + this + "]"); // we'll move remove() to after the if, so we don't have to add back // unused.add(0, resc ); // we'll wait for "something to happen" -- probably an idle check to // complete -- then we'll try again and hope for the best. Thread t = Thread.currentThread(); try { otherWaiters.add ( t ); this.wait( timeout ); ensureNotBroken(); } finally { otherWaiters.remove( t ); } return prelimCheckoutResource( timeout ); } else if ( shouldExpire( resc ) ) { removeResource( resc ); ensureMinResources(); return prelimCheckoutResource( timeout ); } else { unused.remove(0); return resc; } } catch ( ResourceClosedException e ) // one of our async threads died { //System.err.println(this + " -- the pool was found to be closed or broken during an attempt to check out a resource."); //e.printStackTrace(); if (logger.isLoggable( MLevel.SEVERE )) logger.log( MLevel.SEVERE, this + " -- the pool was found to be closed or broken during an attempt to check out a resource.", e ); this.unexpectedBreak(); throw e; } catch ( InterruptedException e ) { // System.err.println(this + " -- an attempt to checkout a resource was interrupted: some other thread " + // "must have either interrupted the Thread attempting checkout, or close() was called on the pool."); // e.printStackTrace(); if (broken) { if (logger.isLoggable( MLevel.FINER )) logger.log(MLevel.FINER, this + " -- an attempt to checkout a resource was interrupted, because the pool is now closed. " + "[Thread: " + Thread.currentThread().getName() + ']', e ); else if (logger.isLoggable( MLevel.INFO )) logger.log(MLevel.INFO, this + " -- an attempt to checkout a resource was interrupted, because the pool is now closed. " + "[Thread: " + Thread.currentThread().getName() + ']'); } else { if (logger.isLoggable( MLevel.WARNING )) { logger.log(MLevel.WARNING, this + " -- an attempt to checkout a resource was interrupted, and the pool is still live: some other thread " + "must have either interrupted the Thread attempting checkout!", e ); } } throw e; } } public synchronized void checkinResource( Object resc ) throws ResourcePoolException { try { //we permit straggling resources to be checked in //without exception even if we are broken if (managed.keySet().contains(resc)) doCheckinManaged( resc ); else if (excluded.contains(resc)) doCheckinExcluded( resc ); else if ( isFormerResource(resc) ) { if ( logger.isLoggable( MLevel.FINER ) ) logger.finer("Resource " + resc + " checked-in after having been checked-in already, or checked-in after " + " having being destroyed for being checked-out too long."); } else throw new ResourcePoolException("ResourcePool" + (broken ? " [BROKEN!]" : "") + ": Tried to check-in a foreign resource!"); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) trace(); } catch ( ResourceClosedException e ) // one of our async threads died { // System.err.println(this + // " - checkinResource( ... ) -- even broken pools should allow checkins without exception. probable resource pool bug."); // e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, this + " - checkinResource( ... ) -- even broken pools should allow checkins without exception. probable resource pool bug.", e); this.unexpectedBreak(); throw e; } } public synchronized void checkinAll() throws ResourcePoolException { try { Set checkedOutNotExcluded = new HashSet( managed.keySet() ); checkedOutNotExcluded.removeAll( unused ); for (Iterator ii = checkedOutNotExcluded.iterator(); ii.hasNext(); ) doCheckinManaged( ii.next() ); for (Iterator ii = excluded.iterator(); ii.hasNext(); ) doCheckinExcluded( ii.next() ); } catch ( ResourceClosedException e ) // one of our async threads died { // System.err.println(this + // " - checkinAll() -- even broken pools should allow checkins without exception. probable resource pool bug."); // e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, this + " - checkinAll() -- even broken pools should allow checkins without exception. probable resource pool bug.", e ); this.unexpectedBreak(); throw e; } } public synchronized int statusInPool( Object resc ) throws ResourcePoolException { try { if ( unused.contains( resc ) ) return KNOWN_AND_AVAILABLE; else if ( managed.keySet().contains( resc ) || excluded.contains( resc ) ) return KNOWN_AND_CHECKED_OUT; else return UNKNOWN_OR_PURGED; } catch ( ResourceClosedException e ) // one of our async threads died { // e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, "Apparent pool break.", e ); this.unexpectedBreak(); throw e; } } public synchronized void markBroken(Object resc) { try { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Resource " + resc + " marked broken by pool (" + this + ")."); _markBroken( resc ); ensureMinResources(); } catch ( ResourceClosedException e ) // one of our async threads died { //e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, "Apparent pool break.", e ); this.unexpectedBreak(); } } //min is immutable, no need to synchronize public int getMinPoolSize() { return min; } //max is immutable, no need to synchronize public int getMaxPoolSize() { return max; } public synchronized int getPoolSize() throws ResourcePoolException { return managed.size(); } // //i don't think i like the async, no-guarantees approach // public synchronized void requestResize( int req_sz ) // { // if (req_sz > max) // req_sz = max; // else if (req_sz < min) // req_sz = min; // int sz = managed.size(); // if (req_sz > sz) // postAcquireUntil( req_sz ); // else if (req_sz < sz) // postRemoveTowards( req_sz ); // } public synchronized int getAvailableCount() { return unused.size(); } public synchronized int getExcludedCount() { return excluded.size(); } public synchronized int getAwaitingCheckinCount() { return managed.size() - unused.size() + excluded.size(); } public synchronized void resetPool() { try { for (Iterator ii = cloneOfManaged().keySet().iterator(); ii.hasNext();) markBrokenNoEnsureMinResources(ii.next()); ensureMinResources(); } catch ( ResourceClosedException e ) // one of our async threads died { //e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, "Apparent pool break.", e ); this.unexpectedBreak(); } } public synchronized void close() throws ResourcePoolException { //we permit closes when we are already broken, so //that resources that were checked out when the break //occured can still be cleaned up close( true ); } public void finalize() throws Throwable { //obviously, clients mustn't rely on finalize, //but must close pools ASAP after use. //System.err.println("finalizing..." + this); if (! broken ) this.close(); } //no need to sync public void addResourcePoolListener(ResourcePoolListener rpl) { if ( ! supportsEvents() ) throw new RuntimeException(this + " does not support ResourcePoolEvents. " + "Probably it was constructed by a BasicResourceFactory configured not to support such events."); else rpes.addResourcePoolListener(rpl); } //no need to sync public void removeResourcePoolListener(ResourcePoolListener rpl) { if ( ! supportsEvents() ) throw new RuntimeException(this + " does not support ResourcePoolEvents. " + "Probably it was constructed by a BasicResourceFactory configured not to support such events."); else rpes.removeResourcePoolListener(rpl); } private synchronized boolean isForceKillAcquiresPending() { return force_kill_acquires; } // this is designed as a response to a determination that our resource source is down. // rather than declaring ourselves broken in this case (as we did previously), we // kill all pending acquisition attempts, but retry on new acqusition requests. private synchronized void forceKillAcquires() throws InterruptedException { Thread t = Thread.currentThread(); try { force_kill_acquires = true; this.notifyAll(); //wake up any threads waiting on an acquire, and force them all to die. while (acquireWaiters.size() > 0) //we want to let all the waiting acquires die before we unset force_kill_acquires { otherWaiters.add( t ); this.wait(); } force_kill_acquires = false; } finally { otherWaiters.remove( t ); } } //same as close(), but we do not destroy checked out //resources private synchronized void unexpectedBreak() { if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, this + " -- Unexpectedly broken!!!", new ResourcePoolException("Unexpected Break Stack Trace!") ); close( false ); } // no need to sync private boolean canFireEvents() { return ( asyncEventQueue != null && !isBroken() ); } // no need to sync private void asyncFireResourceAcquired( final Object resc, final int pool_size, final int available_size, final int removed_but_unreturned_size ) { if ( canFireEvents() ) { Runnable r = new Runnable() { public void run() {rpes.fireResourceAcquired(resc, pool_size, available_size, removed_but_unreturned_size);} }; asyncEventQueue.postRunnable(r); } } // no need to sync private void asyncFireResourceCheckedIn( final Object resc, final int pool_size, final int available_size, final int removed_but_unreturned_size ) { if ( canFireEvents() ) { Runnable r = new Runnable() { public void run() {rpes.fireResourceCheckedIn(resc, pool_size, available_size, removed_but_unreturned_size);} }; asyncEventQueue.postRunnable(r); } } // no need to sync private void asyncFireResourceCheckedOut( final Object resc, final int pool_size, final int available_size, final int removed_but_unreturned_size ) { if ( canFireEvents() ) { Runnable r = new Runnable() { public void run() {rpes.fireResourceCheckedOut(resc,pool_size,available_size,removed_but_unreturned_size);} }; asyncEventQueue.postRunnable(r); } } // no need to sync private void asyncFireResourceRemoved( final Object resc, final boolean checked_out_resource, final int pool_size, final int available_size, final int removed_but_unreturned_size ) { if ( canFireEvents() ) { //System.err.println("ASYNC RSRC REMOVED"); //new Exception().printStackTrace(); Runnable r = new Runnable() { public void run() { rpes.fireResourceRemoved(resc, checked_out_resource, pool_size,available_size,removed_but_unreturned_size); } }; asyncEventQueue.postRunnable(r); } } // needn't be called from a sync'ed method private void destroyResource(final Object resc) { destroyResource( resc, false ); } // needn't be called from a sync'ed method private void destroyResource(final Object resc, boolean synchronous) { class DestroyResourceTask implements Runnable { public void run() { try { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log(MLevel.FINER, "Preparing to destroy resource: " + resc); mgr.destroyResource(resc); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) logger.log(MLevel.FINER, "Successfully destroyed resource: " + resc); } catch ( Exception e ) { if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to destroy resource: " + resc, e ); // System.err.println("Failed to destroy resource: " + resc); // e.printStackTrace(); } } } Runnable r = new DestroyResourceTask(); if ( synchronous || broken ) //if we're broken, our taskRunner may be dead, so we destroy synchronously { if ( logger.isLoggable(MLevel.FINEST) && !broken && Boolean.TRUE.equals( ThreadUtils.reflectiveHoldsLock( this ) ) ) logger.log( MLevel.FINEST, this + ": Destroyiong a resource on an active pool, synchronousy while holding pool's lock! " + "(not a bug, but a potential bottleneck... is there a good reason for this?)", new Exception("DEBUG STACK TRACE") ); r.run(); } else { try { taskRunner.postRunnable( r ); } catch (Exception e) { if (logger.isLoggable(MLevel.FINER)) logger.log( MLevel.FINER, "AsynchronousRunner refused to accept task to destroy resource. " + "It is probably shared, and has probably been closed underneath us. " + "Reverting to synchronous destruction. This is not usually a problem.", e ); destroyResource( resc, true ); } } } //this method SHOULD NOT be invoked from a synchronized //block!!!! private void doAcquire() throws Exception { assert !Thread.holdsLock( this ); Object resc = mgr.acquireResource(); //note we acquire the resource while we DO NOT hold the pool's lock! boolean destroy = false; int msz; synchronized(this) //assimilate resc if we do need it { // ++total_acquired; // if (logger.isLoggable( MLevel.FINER)) // logger.log(MLevel.FINER, "acquired new resource, total_acquired: " + total_acquired); msz = managed.size(); if (msz < target_pool_size) assimilateResource(resc); else destroy = true; } if (destroy) { mgr.destroyResource( resc ); //destroy resc if superfluous, without holding the pool's lock if (logger.isLoggable( MLevel.FINER)) logger.log(MLevel.FINER, "destroying overacquired resource: " + resc); } } public synchronized void setPoolSize( int sz ) throws ResourcePoolException { try { setTargetPoolSize( sz ); while ( managed.size() != sz ) this.wait(); } catch (Exception e) { String msg = "An exception occurred while trying to set the pool size!"; if ( logger.isLoggable( MLevel.FINER ) ) logger.log( MLevel.FINER, msg, e ); throw ResourcePoolUtils.convertThrowable( msg, e ); } } public synchronized void setTargetPoolSize(int sz) { if (sz > max) { throw new IllegalArgumentException("Requested size [" + sz + "] is greater than max [" + max + "]."); } else if (sz < min) { throw new IllegalArgumentException("Requested size [" + sz + "] is less than min [" + min + "]."); } this.target_pool_size = sz; _recheckResizePool(); } // private void acquireUntil(int num) throws Exception // { // int msz = managed.size(); // for (int i = msz; i < num; ++i) // assimilateResource(); // } //the following methods should only be invoked from //sync'ed methods / blocks... // private Object useUnusedButNotInIdleCheck() // { // for (Iterator ii = unused.iterator(); ii.hasNext(); ) // { // Object maybeOut = ii.next(); // if (! idleCheckResources.contains( maybeOut )) // { // ii.remove(); // return maybeOut; // } // } // throw new RuntimeException("Internal Error -- the pool determined that it did have a resource available for checkout, but was unable to find one."); // } // private int actuallyAvailable() // { return unused.size() - idleCheckResources.size(); } // must own this' lock private void markBrokenNoEnsureMinResources(Object resc) { assert Thread.holdsLock( this ); try { _markBroken( resc ); } catch ( ResourceClosedException e ) // one of our async threads died { //e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, "Apparent pool break.", e ); this.unexpectedBreak(); } } // must own this' lock private void _markBroken( Object resc ) { assert Thread.holdsLock( this ); if ( unused.contains( resc ) ) removeResource( resc ); else excludeResource( resc ); } //DEBUG //Exception firstClose = null; public synchronized void close( boolean close_checked_out_resources ) { if (! broken ) //ignore repeated calls to close { //DEBUG //firstClose = new Exception("First close() -- debug stack trace [CRAIG]"); //firstClose.printStackTrace(); this.broken = true; final Collection cleanupResources = ( close_checked_out_resources ? (Collection) cloneOfManaged().keySet() : (Collection) cloneOfUnused() ); if ( cullTask != null ) cullTask.cancel(); if (idleRefurbishTask != null) idleRefurbishTask.cancel(); // we destroy resources asynchronously, but with a dedicated one-off Thread, rather than // our asynchronous runner, because our asynchrous runner may be shutting down. The // destruction is asynchrounous because destroying a resource might require the resource's // lock, and we already have the pool's lock. But client threads may well have the resource's // lock while they try to check-in to the pool. The async destruction of resources avoids // the possibility of deadlock. managed.keySet().removeAll( cleanupResources ); unused.removeAll( cleanupResources ); Thread resourceDestroyer = new Thread("Resource Destroyer in BasicResourcePool.close()") { public void run() { for (Iterator ii = cleanupResources.iterator(); ii.hasNext();) { try { Object resc = ii.next(); //System.err.println("Destroying resource... " + resc); destroyResource( resc, true ); } catch (Exception e) { if (Debug.DEBUG) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "BasicResourcePool -- A resource couldn't be cleaned up on close()", e ); } } } } }; resourceDestroyer.start(); for (Iterator ii = acquireWaiters.iterator(); ii.hasNext(); ) ((Thread) ii.next()).interrupt(); for (Iterator ii = otherWaiters.iterator(); ii.hasNext(); ) ((Thread) ii.next()).interrupt(); if (factory != null) factory.markBroken( this ); // System.err.println(this + " closed."); } else { if ( logger.isLoggable( MLevel.WARNING ) ) logger.warning(this + " -- close() called multiple times."); //System.err.println(this + " -- close() called multiple times."); //DEBUG //firstClose.printStackTrace(); //new Exception("Repeat close() [CRAIG]").printStackTrace(); } } private void doCheckinManaged( final Object resc ) throws ResourcePoolException { assert Thread.holdsLock( this ); if (unused.contains(resc)) { if ( Debug.DEBUG ) throw new ResourcePoolException("Tried to check-in an already checked-in resource: " + resc); } else if (broken) removeResource( resc, true ); //synchronous... if we're broken, async tasks might not work else { class RefurbishCheckinResourceTask implements Runnable { public void run() { boolean resc_okay = attemptRefurbishResourceOnCheckin( resc ); synchronized( BasicResourcePool.this ) { PunchCard card = (PunchCard) managed.get( resc ); if ( resc_okay && card != null) //we have to check that the resource is still in the pool { unused.add(0, resc ); card.last_checkin_time = System.currentTimeMillis(); card.checkout_time = -1; } else { if (card != null) card.checkout_time = -1; //so we don't see this as still checked out and log an overdue cxn in removeResource() removeResource( resc ); ensureMinResources(); if (card == null && logger.isLoggable( MLevel.FINE )) logger.fine("Resource " + resc + " was removed from the pool during its refurbishment for checkin."); } asyncFireResourceCheckedIn( resc, managed.size(), unused.size(), excluded.size() ); BasicResourcePool.this.notifyAll(); } } } Runnable doMe = new RefurbishCheckinResourceTask(); taskRunner.postRunnable( doMe ); } } private void doCheckinExcluded( Object resc ) { assert Thread.holdsLock( this ); excluded.remove(resc); destroyResource(resc); } /* * by the semantics of wait(), a timeout of zero means forever. */ private void awaitAvailable(long timeout) throws InterruptedException, TimeoutException, ResourcePoolException { assert Thread.holdsLock( this ); if (force_kill_acquires) throw new ResourcePoolException("A ResourcePool cannot acquire a new resource -- the factory or source appears to be down."); Thread t = Thread.currentThread(); try { acquireWaiters.add( t ); int avail; long start = ( timeout > 0 ? System.currentTimeMillis() : -1); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) { if ( logger.isLoggable( MLevel.FINE ) ) logger.fine("awaitAvailable(): " + (exampleResource != null ? exampleResource : "[unknown]") ); trace(); } while ((avail = unused.size()) == 0) { // the if case below can only occur when 1) a user attempts a // checkout which would provoke an acquire; 2) this // increments the pending acquires, so we go to the // wait below without provoking postAcquireMore(); 3) // the resources are acquired; 4) external management // of the pool (via for instance unpoolResource() // depletes the newly acquired resources before we // regain this' monitor; 5) we fall into wait() with // no acquires being scheduled, and perhaps a managed.size() // of zero, leading to deadlock. This could only occur in // fairly pathological situations where the pool is being // externally forced to a very low (even zero) size, but // since I've seen it, I've fixed it. if (pending_acquires == 0 && managed.size() < max) _recheckResizePool(); this.wait(timeout); if (timeout > 0 && System.currentTimeMillis() - start > timeout) throw new TimeoutException("A client timed out while waiting to acquire a resource from " + this + " -- timeout at awaitAvailable()"); if (force_kill_acquires) throw new CannotAcquireResourceException("A ResourcePool could not acquire a resource from its primary factory or source."); ensureNotBroken(); } } finally { acquireWaiters.remove( t ); if (acquireWaiters.size() == 0) this.notifyAll(); } } private void assimilateResource( Object resc ) throws Exception { assert Thread.holdsLock( this ); managed.put(resc, new PunchCard()); unused.add(0, resc); //System.err.println("assimilate resource... unused: " + unused.size()); asyncFireResourceAcquired( resc, managed.size(), unused.size(), excluded.size() ); this.notifyAll(); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) trace(); if (Debug.DEBUG && exampleResource == null) exampleResource = resc; } // should NOT be called from synchronized method private void synchronousRemoveArbitraryResource() { assert !Thread.holdsLock( this ); Object removeMe = null; synchronized ( this ) { if (unused.size() > 0) { removeMe = unused.get(0); managed.remove(removeMe); unused.remove(removeMe); } else { Set checkedOut = cloneOfManaged().keySet(); if ( checkedOut.isEmpty() ) { unexpectedBreak(); logger.severe("A pool from which a resource is requested to be removed appears to have no managed resources?!"); } else excludeResource( checkedOut.iterator().next() ); } } if (removeMe != null) destroyResource( removeMe, true ); } private void removeResource(Object resc) { removeResource( resc, false ); } private void removeResource(Object resc, boolean synchronous) { assert Thread.holdsLock( this ); PunchCard pc = (PunchCard) managed.remove(resc); if (pc != null) { if ( pc.checkout_time > 0 && !broken) //this is a checked-out resource in an active pool, must be overdue if we are removing it { if (logger.isLoggable( MLevel.INFO ) ) { logger.info("A checked-out resource is overdue, and will be destroyed: " + resc); if (pc.checkoutStackTraceException != null) { logger.log( MLevel.INFO, "Logging the stack trace by which the overdue resource was checked-out.", pc.checkoutStackTraceException ); } } } } else if ( logger.isLoggable( MLevel.FINE ) ) logger.fine("Resource " + resc + " was removed twice. (Lotsa reasons a resource can be removed, sometimes simultaneously. It's okay)"); unused.remove(resc); destroyResource(resc, synchronous); addToFormerResources( resc ); asyncFireResourceRemoved( resc, false, managed.size(), unused.size(), excluded.size() ); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) trace(); //System.err.println("RESOURCE REMOVED!"); } //when we want to conceptually remove a checked //out resource from the pool private void excludeResource(Object resc) { assert Thread.holdsLock( this ); managed.remove(resc); excluded.add(resc); if (Debug.DEBUG && unused.contains(resc) ) throw new InternalError( "We should only \"exclude\" checked-out resources!" ); asyncFireResourceRemoved( resc, true, managed.size(), unused.size(), excluded.size() ); } private void removeTowards( int new_sz ) { assert Thread.holdsLock( this ); int num_to_remove = managed.size() - new_sz; int count = 0; for (Iterator ii = cloneOfUnused().iterator(); ii.hasNext() && count < num_to_remove; ++count) { Object resc = ii.next(); removeResource( resc ); } } private void cullExpired() { assert Thread.holdsLock( this ); if ( logger.isLoggable( MLevel.FINER ) ) logger.log( MLevel.FINER, "BEGIN check for expired resources. [" + this + "]"); // if we do not time-out checkedout resources, we only need to test unused resources Collection checkMe = ( destroy_unreturned_resc_time > 0 ? (Collection) cloneOfManaged().keySet() : cloneOfUnused() ); for ( Iterator ii = checkMe.iterator(); ii.hasNext(); ) { Object resc = ii.next(); if ( shouldExpire( resc ) ) { if ( logger.isLoggable( MLevel.FINER ) ) logger.log( MLevel.FINER, "Removing expired resource: " + resc + " [" + this + "]"); target_pool_size = Math.max( min, target_pool_size - 1 ); //expiring a resource resources the target size to match removeResource( resc ); if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) trace(); } } if ( logger.isLoggable( MLevel.FINER ) ) logger.log( MLevel.FINER, "FINISHED check for expired resources. [" + this + "]"); ensureMinResources(); } private void checkIdleResources() { assert Thread.holdsLock( this ); List u = cloneOfUnused(); for ( Iterator ii = u.iterator(); ii.hasNext(); ) { Object resc = ii.next(); if ( idleCheckResources.add( resc ) ) taskRunner.postRunnable( new AsyncTestIdleResourceTask( resc ) ); } if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX) trace(); } private boolean shouldExpire( Object resc ) { assert Thread.holdsLock( this ); boolean expired = false; PunchCard pc = (PunchCard) managed.get( resc ); // the resource has already been removed // we return true, because removing twice does no harm // (false should work as well, but true seems safer. // we certainly don't want to do anything else with // this resource.) if (pc == null) { if ( logger.isLoggable( MLevel.FINE ) ) logger.fine( "Resource " + resc + " was being tested for expiration, but has already been removed from the pool."); return true; } long now = System.currentTimeMillis(); if (pc.checkout_time < 0) //resource is not checked out { long idle_age = now - pc.last_checkin_time; if (excess_max_idle_time > 0) { int msz = managed.size(); expired = (msz > min && idle_age > excess_max_idle_time); if ( expired && logger.isLoggable( MLevel.FINER ) ) logger.log(MLevel.FINER, "EXPIRED excess idle resource: " + resc + " ---> idle_time: " + idle_age + "; excess_max_idle_time: " + excess_max_idle_time + "; pool_size: " + msz + "; min_pool_size: " + min + " [" + this + "]"); } if (!expired && max_idle_time > 0) { expired = idle_age > max_idle_time; if ( expired && logger.isLoggable( MLevel.FINER ) ) logger.log(MLevel.FINER, "EXPIRED idle resource: " + resc + " ---> idle_time: " + idle_age + "; max_idle_time: " + max_idle_time + " [" + this + "]"); } if (!expired && max_resource_age > 0) { long abs_age = now - pc.acquisition_time; expired = ( abs_age > max_resource_age ); if ( expired && logger.isLoggable( MLevel.FINER ) ) logger.log(MLevel.FINER, "EXPIRED old resource: " + resc + " ---> absolute_age: " + abs_age + "; max_absolute_age: " + max_resource_age + " [" + this + "]"); } } else //resource is checked out { long checkout_age = now - pc.checkout_time; expired = checkout_age > destroy_unreturned_resc_time; } return expired; } // private boolean resourcesInIdleCheck() // { return idleCheckresources.size() > 0; } // private int countAvailable() // { return unused.size() - idleCheckResources.size(); } // we needn't hold this' lock private void ensureStartResources() { recheckResizePool(); } // we needn't hold this' lock private void ensureMinResources() { recheckResizePool(); } private boolean attemptRefurbishResourceOnCheckout( Object resc ) { assert !Thread.holdsLock( this ); try { mgr.refurbishResourceOnCheckout(resc); return true; } catch (Exception e) { //uh oh... bad resource... if (Debug.DEBUG) { //e.printStackTrace(); if (logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "A resource could not be refurbished for checkout. [" + resc + ']', e ); } synchronized (this) { ++failed_checkouts; setLastCheckoutFailure(e); } return false; } } private boolean attemptRefurbishResourceOnCheckin( Object resc ) { assert !Thread.holdsLock( this ); try { mgr.refurbishResourceOnCheckin(resc); return true; } catch (Exception e) { //uh oh... bad resource... if (Debug.DEBUG) { //e.printStackTrace(); if (logger.isLoggable( MLevel.FINE )) logger.log( MLevel.FINE, "A resource could not be refurbished on checkin. [" + resc + ']', e ); } synchronized (this) { ++failed_checkins; setLastCheckinFailure(e); } return false; } } private void ensureNotBroken() throws ResourcePoolException { assert Thread.holdsLock( this ); if (broken) throw new ResourcePoolException("Attempted to use a closed or broken resource pool"); } private void trace() { assert Thread.holdsLock( this ); if ( logger.isLoggable( MLevel.FINEST ) ) { String exampleResStr = ( exampleResource == null ? "" : " (e.g. " + exampleResource +")"); logger.finest("trace " + this + " [managed: " + managed.size() + ", " + "unused: " + unused.size() + ", excluded: " + excluded.size() + ']' + exampleResStr ); } } private final HashMap cloneOfManaged() { assert Thread.holdsLock( this ); return (HashMap) managed.clone(); } private final LinkedList cloneOfUnused() { assert Thread.holdsLock( this ); return (LinkedList) unused.clone(); } private final HashSet cloneOfExcluded() { assert Thread.holdsLock( this ); return (HashSet) excluded.clone(); } class ScatteredAcquireTask implements Runnable { int attempts_remaining; ScatteredAcquireTask() { this ( (num_acq_attempts >= 0 ? num_acq_attempts : -1) , true ); } private ScatteredAcquireTask(int attempts_remaining, boolean first_attempt) { this.attempts_remaining = attempts_remaining; if (first_attempt) { incrementPendingAcquires(); if (logger.isLoggable(MLevel.FINEST)) logger.finest("Starting acquisition series. Incremented pending_acquires [" + pending_acquires + "], " + " attempts_remaining: " + attempts_remaining); } else { if (logger.isLoggable(MLevel.FINEST)) logger.finest("Continuing acquisition series. pending_acquires [" + pending_acquires + "], " + " attempts_remaining: " + attempts_remaining); } } public void run() { try { boolean fkap = isForceKillAcquiresPending(); if (! fkap) { //we don't want this call to be sync'd //on the pool, so that resource acquisition //does not interfere with other pool clients. BasicResourcePool.this.doAcquire(); } decrementPendingAcquires(); if (logger.isLoggable(MLevel.FINEST)) logger.finest("Acquisition series terminated " + (fkap ? "because force-kill-acquires is pending" : "successfully") + ". Decremented pending_acquires [" + pending_acquires + "], " + " attempts_remaining: " + attempts_remaining); } catch (Exception e) { BasicResourcePool.this.setLastAcquisitionFailure(e); if (attempts_remaining == 0) //last try in a round... { decrementPendingAcquires(); if ( logger.isLoggable( MLevel.WARNING ) ) { logger.log( MLevel.WARNING, this + " -- Acquisition Attempt Failed!!! Clearing pending acquires. " + "While trying to acquire a needed new resource, we failed " + "to succeed more than the maximum number of allowed " + "acquisition attempts (" + num_acq_attempts + "). " + "Last acquisition attempt exception: ", e); } if (break_on_acquisition_failure) { //System.err.println("\tTHE RESOURCE POOL IS PERMANENTLY BROKEN!"); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.severe("A RESOURCE POOL IS PERMANENTLY BROKEN! [" + this + "] " + "(because a series of " + num_acq_attempts + " acquisition attempts " + "failed.)"); unexpectedBreak(); } else { try { forceKillAcquires(); } catch (InterruptedException ie) { if ( logger.isLoggable(MLevel.WARNING) ) logger.log(MLevel.WARNING, "Failed to force-kill pending acquisition attempts after acquisition failue, " + " due to an InterruptedException!", ie ); // we might still have clients waiting, so we should try // to ensure there are sufficient connections to serve recheckResizePool(); } } if (logger.isLoggable(MLevel.FINEST)) logger.finest("Acquisition series terminated unsuccessfully. Decremented pending_acquires [" + pending_acquires + "], " + " attempts_remaining: " + attempts_remaining); } else { // if attempts_remaining < 0, we try to acquire forever, so the end-of-batch // log message below will never be triggered if there is a persistent problem // so in this case, it's better flag a higher-than-debug-level message for // each failed attempt. (Thanks to Eric Crahen for calling attention to this // issue.) MLevel logLevel = (attempts_remaining > 0 ? MLevel.FINE : MLevel.INFO); if (logger.isLoggable( logLevel )) logger.log( logLevel, "An exception occurred while acquiring a poolable resource. Will retry.", e ); TimerTask doNextAcquire = new TimerTask() { public void run() { taskRunner.postRunnable( new ScatteredAcquireTask( attempts_remaining - 1, false ) ); } }; cullAndIdleRefurbishTimer.schedule( doNextAcquire, acq_attempt_delay ); } } } } /* * task we post to separate thread to acquire * pooled resources */ class AcquireTask implements Runnable { boolean success = false; public AcquireTask() { incrementPendingAcquires(); } public void run() { try { Exception lastException = null; for (int i = 0; shouldTry( i ); ++i) { try { if (i > 0) Thread.sleep(acq_attempt_delay); //we don't want this call to be sync'd //on the pool, so that resource acquisition //does not interfere with other pool clients. BasicResourcePool.this.doAcquire(); success = true; } catch (InterruptedException e) { // end the whole task on interrupt, regardless of success // or failure throw e; } catch (Exception e) { //e.printStackTrace(); // if num_acq_attempts <= 0, we try to acquire forever, so the end-of-batch // log message below will never be triggered if there is a persistent problem // so in this case, it's better flag a higher-than-debug-level message for // each failed attempt. (Thanks to Eric Crahen for calling attention to this // issue.) MLevel logLevel = (num_acq_attempts > 0 ? MLevel.FINE : MLevel.INFO); if (logger.isLoggable( logLevel )) logger.log( logLevel, "An exception occurred while acquiring a poolable resource. Will retry.", e ); lastException = e; setLastAcquisitionFailure(e); } } if (!success) { if ( logger.isLoggable( MLevel.WARNING ) ) { logger.log( MLevel.WARNING, this + " -- Acquisition Attempt Failed!!! Clearing pending acquires. " + "While trying to acquire a needed new resource, we failed " + "to succeed more than the maximum number of allowed " + "acquisition attempts (" + num_acq_attempts + "). " + (lastException == null ? "" : "Last acquisition attempt exception: "), lastException); } if (break_on_acquisition_failure) { //System.err.println("\tTHE RESOURCE POOL IS PERMANENTLY BROKEN!"); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.severe("A RESOURCE POOL IS PERMANENTLY BROKEN! [" + this + "]"); unexpectedBreak(); } else forceKillAcquires(); } else recheckResizePool(); } catch ( ResourceClosedException e ) // one of our async threads died { //e.printStackTrace(); if ( Debug.DEBUG ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "a resource pool async thread died.", e ); } unexpectedBreak(); } catch (InterruptedException e) //from force kill acquires, or by the thread pool during the long task... { if ( logger.isLoggable( MLevel.WARNING ) ) { logger.log( MLevel.WARNING, BasicResourcePool.this + " -- Thread unexpectedly interrupted while performing an acquisition attempt.", e ); } // System.err.println(BasicResourcePool.this + " -- Thread unexpectedly interrupted while waiting for stale acquisition attempts to die."); // e.printStackTrace(); recheckResizePool(); } finally { decrementPendingAcquires(); } } private boolean shouldTry(int attempt_num) { //try if we haven't already succeeded //and someone hasn't signalled that our resource source is down //and not max attempts is set, //or we are less than the set limit return !success && !isForceKillAcquiresPending() && (num_acq_attempts <= 0 || attempt_num < num_acq_attempts); } } /* * task we post to separate thread to remove * unspecified pooled resources * * TODO: do removal and destruction synchronously * but carefully not synchronized during the * destruction of the resource. */ class RemoveTask implements Runnable { public RemoveTask() { incrementPendingRemoves(); } public void run() { try { synchronousRemoveArbitraryResource(); recheckResizePool(); } finally { decrementPendingRemoves(); } } } class CullTask extends TimerTask { public void run() { try { if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable( MLevel.FINER )) logger.log( MLevel.FINER, "Checking for expired resources - " + new Date() + " [" + BasicResourcePool.this + "]"); synchronized ( BasicResourcePool.this ) { cullExpired(); } } catch ( ResourceClosedException e ) // one of our async threads died { if ( Debug.DEBUG ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "a resource pool async thread died.", e ); } unexpectedBreak(); } } } // this is run by a single-threaded timer, so we don't have // to worry about multiple threads executing the task at the same // time class CheckIdleResourcesTask extends TimerTask { public void run() { try { //System.err.println("c3p0-JENNIFER: refurbishing idle resources - " + new Date() + " [" + BasicResourcePool.this + "]"); if (Debug.DEBUG && Debug.TRACE >= Debug.TRACE_MED && logger.isLoggable(MLevel.FINER)) logger.log(MLevel.FINER, "Refurbishing idle resources - " + new Date() + " [" + BasicResourcePool.this + "]"); synchronized ( BasicResourcePool.this ) { checkIdleResources(); } } catch ( ResourceClosedException e ) // one of our async threads died { //e.printStackTrace(); if ( Debug.DEBUG ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "a resource pool async thread died.", e ); } unexpectedBreak(); } } } class AsyncTestIdleResourceTask implements Runnable { // unchanging after ctor Object resc; // protected by this' lock boolean pending = true; boolean failed; AsyncTestIdleResourceTask( Object resc ) { this.resc = resc; } public void run() { assert !Thread.holdsLock( BasicResourcePool.this ); try { try { mgr.refurbishIdleResource( resc ); } catch ( Exception e ) { if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "BasicResourcePool: An idle resource is broken and will be purged. [" + resc + ']', e); synchronized (BasicResourcePool.this) { if ( managed.keySet().contains( resc ) ) //resc might have been culled as expired while we tested { removeResource( resc ); ensureMinResources(); } ++failed_idle_tests; setLastIdleCheckFailure(e); } } } finally { synchronized (BasicResourcePool.this) { idleCheckResources.remove( resc ); BasicResourcePool.this.notifyAll(); } } } } final static class PunchCard { long acquisition_time; long last_checkin_time; long checkout_time; Exception checkoutStackTraceException; PunchCard() { this.acquisition_time = System.currentTimeMillis(); this.last_checkin_time = acquisition_time; this.checkout_time = -1; this.checkoutStackTraceException = null; } } // static class CheckInProgressResourceHolder // { // Object checkResource; // public synchronized void setCheckResource( Object resc ) // { // this.checkResource = resc; // this.notifyAll(); // } // public void unsetCheckResource() // { setCheckResource( null ); } // /** // * @return true if we actually had to wait // */ // public synchronized boolean awaitNotInCheck( Object resc ) // { // boolean had_to_wait = false; // boolean set_interrupt = false; // while ( checkResource == resc ) // { // try // { // had_to_wait = true; // this.wait(); // } // catch ( InterruptedException e ) // { // e.printStackTrace(); // set_interrupt = true; // } // } // if ( set_interrupt ) // Thread.currentThread().interrupt(); // return had_to_wait; // } // } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/BasicResourcePoolFactory.java0000644000175000017500000002547610624366530026746 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import java.util.*; import com.mchange.v2.async.*; public class BasicResourcePoolFactory extends ResourcePoolFactory { public static BasicResourcePoolFactory createNoEventSupportInstance( int num_task_threads ) { return createNoEventSupportInstance( null, null, num_task_threads ); } public static BasicResourcePoolFactory createNoEventSupportInstance( AsynchronousRunner taskRunner, Timer timer ) { return createNoEventSupportInstance( taskRunner, timer, ResourcePoolFactory.DEFAULT_NUM_TASK_THREADS ); } private static BasicResourcePoolFactory createNoEventSupportInstance( AsynchronousRunner taskRunner, Timer timer, int default_num_task_threads ) { return new BasicResourcePoolFactory( taskRunner, timer, default_num_task_threads, true ); } int start = -1; //default to min int min = 1; int max = 12; int inc = 3; int retry_attempts = -1; //by default, retry acquisitions forever int retry_delay = 1000; //1 second long idle_resource_test_period = -1; //milliseconds, by default we don't test idle resources long max_age = -1; //milliseconds, by default resources never expire long max_idle_time = -1; //milliseconds, by default resources never expire long excess_max_idle_time = -1; //milliseconds, by default resources never expire long destroy_overdue_resc_time = -1; //milliseconds long expiration_enforcement_delay = -1; //automatic, we come up with a reasonable default based on time params boolean break_on_acquisition_failure = true; boolean debug_store_checkout_stacktrace = false; AsynchronousRunner taskRunner; boolean taskRunner_is_external; RunnableQueue asyncEventQueue; boolean asyncEventQueue_is_external; Timer timer; boolean timer_is_external; int default_num_task_threads; Set liveChildren; //OLD // Set rqUsers = null; // SimpleRunnableQueue rq = null; // Set timerUsers = null; // Timer timer = null; //END OLD BasicResourcePoolFactory() { this( null, null, null ); } BasicResourcePoolFactory( AsynchronousRunner taskRunner, RunnableQueue asyncEventQueue, Timer timer ) { this ( taskRunner, asyncEventQueue, timer, DEFAULT_NUM_TASK_THREADS ); } BasicResourcePoolFactory( int num_task_threads ) { this ( null, null, null, num_task_threads ); } BasicResourcePoolFactory( AsynchronousRunner taskRunner, Timer timer, int default_num_task_threads, boolean no_event_support) { this( taskRunner, null, timer, default_num_task_threads ); if (no_event_support) asyncEventQueue_is_external = true; //if it's null, and external, it simply won't exist... } BasicResourcePoolFactory( AsynchronousRunner taskRunner, RunnableQueue asyncEventQueue, Timer timer, int default_num_task_threads) { this.taskRunner = taskRunner; this.taskRunner_is_external = ( taskRunner != null ); this.asyncEventQueue = asyncEventQueue; this.asyncEventQueue_is_external = ( asyncEventQueue != null ); this.timer = timer; this.timer_is_external = ( timer != null ); this.default_num_task_threads = default_num_task_threads; } private void createThreadResources() { if (! taskRunner_is_external ) { //taskRunner = new RoundRobinAsynchronousRunner( default_num_task_threads, true ); taskRunner = new ThreadPoolAsynchronousRunner( default_num_task_threads, true ); if (! asyncEventQueue_is_external) asyncEventQueue = ((Queuable) taskRunner).asRunnableQueue(); } if (! asyncEventQueue_is_external) asyncEventQueue = new CarefulRunnableQueue( true, false ); if (! timer_is_external ) timer = new Timer( true ); this.liveChildren = new HashSet(); } private void destroyThreadResources() { if (! taskRunner_is_external ) { taskRunner.close(); taskRunner = null; } if (! asyncEventQueue_is_external ) { asyncEventQueue.close(); asyncEventQueue = null; } if (! timer_is_external ) { timer.cancel(); timer = null; } this.liveChildren = null; } // synchronized RunnableQueue getSharedRunnableQueue( BasicResourcePool pool ) // { // if (rqUsers == null) // { // rqUsers = new HashSet(); // rq = new SimpleRunnableQueue(true); // } // rqUsers.add( pool ); // return rq; // } // synchronized Timer getTimer( BasicResourcePool pool ) // { // if (timerUsers == null) // { // timerUsers = new HashSet(); // timer = new Timer( true ); // } // timerUsers.add( pool ); // return timer; // } synchronized void markBroken( BasicResourcePool pool ) { //System.err.println("markBroken -- liveChildren: " + liveChildren); if (liveChildren != null) //keep this method idempotent! { liveChildren.remove( pool ); if (liveChildren.isEmpty()) destroyThreadResources(); } // rqUsers.remove( pool ); // if (rqUsers.size() == 0) // { // rqUsers = null; // rq.close(); // rq = null; // } // timerUsers.remove( pool ); // if (timerUsers.size() == 0) // { // timerUsers = null; // timer.cancel(); // timer = null; // } } /** * If start is less than min, it will * be ignored, and the pool will start * with min. */ public synchronized void setStart( int start ) throws ResourcePoolException { this.start = start; } public synchronized int getStart() throws ResourcePoolException { return start; } public synchronized void setMin( int min ) throws ResourcePoolException { this.min = min; } public synchronized int getMin() throws ResourcePoolException { return min; } public synchronized void setMax( int max ) throws ResourcePoolException { this.max = max; } public synchronized int getMax() throws ResourcePoolException { return max; } public synchronized void setIncrement( int inc ) throws ResourcePoolException { this.inc = inc; } public synchronized int getIncrement() throws ResourcePoolException { return inc; } public synchronized void setAcquisitionRetryAttempts( int retry_attempts ) throws ResourcePoolException { this.retry_attempts = retry_attempts; } public synchronized int getAcquisitionRetryAttempts() throws ResourcePoolException { return retry_attempts; } public synchronized void setAcquisitionRetryDelay( int retry_delay ) throws ResourcePoolException { this.retry_delay = retry_delay; } public synchronized int getAcquisitionRetryDelay() throws ResourcePoolException { return retry_delay; } public synchronized void setIdleResourceTestPeriod( long test_period ) { this.idle_resource_test_period = test_period; } public synchronized long getIdleResourceTestPeriod() { return idle_resource_test_period; } public synchronized void setResourceMaxAge( long max_age ) throws ResourcePoolException { this.max_age = max_age; } public synchronized long getResourceMaxAge() throws ResourcePoolException { return max_age; } public synchronized void setResourceMaxIdleTime( long millis ) throws ResourcePoolException { this.max_idle_time = millis; } public synchronized long getResourceMaxIdleTime() throws ResourcePoolException { return max_idle_time; } public synchronized void setExcessResourceMaxIdleTime( long millis ) throws ResourcePoolException { this.excess_max_idle_time = millis; } public synchronized long getExcessResourceMaxIdleTime() throws ResourcePoolException { return excess_max_idle_time; } public synchronized long getDestroyOverdueResourceTime() throws ResourcePoolException { return destroy_overdue_resc_time; } public synchronized void setDestroyOverdueResourceTime( long millis ) throws ResourcePoolException { this.destroy_overdue_resc_time = millis; } public synchronized void setExpirationEnforcementDelay( long expiration_enforcement_delay ) throws ResourcePoolException { this.expiration_enforcement_delay = expiration_enforcement_delay; } public synchronized long getExpirationEnforcementDelay() throws ResourcePoolException { return expiration_enforcement_delay; } public synchronized void setBreakOnAcquisitionFailure( boolean break_on_acquisition_failure ) throws ResourcePoolException { this.break_on_acquisition_failure = break_on_acquisition_failure; } public synchronized boolean getBreakOnAcquisitionFailure() throws ResourcePoolException { return break_on_acquisition_failure; } public synchronized void setDebugStoreCheckoutStackTrace( boolean debug_store_checkout_stacktrace ) throws ResourcePoolException { this.debug_store_checkout_stacktrace = debug_store_checkout_stacktrace; } public synchronized boolean getDebugStoreCheckoutStackTrace() throws ResourcePoolException { return debug_store_checkout_stacktrace; } public synchronized ResourcePool createPool(ResourcePool.Manager mgr) throws ResourcePoolException { if (liveChildren == null) createThreadResources(); //System.err.println("Created liveChildren: " + liveChildren); ResourcePool child = new BasicResourcePool( mgr, start, min, max, inc, retry_attempts, retry_delay, idle_resource_test_period, max_age, max_idle_time, excess_max_idle_time, destroy_overdue_resc_time, expiration_enforcement_delay, break_on_acquisition_failure, debug_store_checkout_stacktrace, taskRunner, asyncEventQueue, timer, this ); liveChildren.add( child ); return child; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/CannotAcquireResourceException.java0000644000175000017500000000236210624366530030143 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; public class CannotAcquireResourceException extends ResourcePoolException { public CannotAcquireResourceException(String msg, Throwable t) {super(msg, t);} public CannotAcquireResourceException(Throwable t) {super(t);} public CannotAcquireResourceException(String msg) {super(msg);} public CannotAcquireResourceException() {super();} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePool.java0000644000175000017500000001004510624366527024444 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import com.mchange.v1.util.ClosableResource; public interface ResourcePool extends ClosableResource { // status in pool return values final static int KNOWN_AND_AVAILABLE = 0; final static int KNOWN_AND_CHECKED_OUT = 1; final static int UNKNOWN_OR_PURGED = -1; public Object checkoutResource() throws ResourcePoolException, InterruptedException; public Object checkoutResource( long timeout ) throws TimeoutException, ResourcePoolException, InterruptedException; public void checkinResource( Object resc ) throws ResourcePoolException; public void checkinAll() throws ResourcePoolException; public int statusInPool( Object resc ) throws ResourcePoolException; /** * Marks a resource as broken. If the resource is checked in, * it will be destroyed immediately. Otherwise, it will be * destroyed on checkin. */ public void markBroken( Object resc ) throws ResourcePoolException; public int getMinPoolSize() throws ResourcePoolException; public int getMaxPoolSize() throws ResourcePoolException; public int getPoolSize() throws ResourcePoolException; public void setPoolSize(int size) throws ResourcePoolException; public int getAvailableCount() throws ResourcePoolException; public int getExcludedCount() throws ResourcePoolException; public int getAwaitingCheckinCount() throws ResourcePoolException; public long getEffectiveExpirationEnforcementDelay() throws ResourcePoolException; public long getStartTime() throws ResourcePoolException; public long getUpTime() throws ResourcePoolException; public long getNumFailedCheckins() throws ResourcePoolException; public long getNumFailedCheckouts() throws ResourcePoolException; public long getNumFailedIdleTests() throws ResourcePoolException; public int getNumCheckoutWaiters() throws ResourcePoolException; public Throwable getLastAcquisitionFailure() throws ResourcePoolException; public Throwable getLastCheckinFailure() throws ResourcePoolException; public Throwable getLastCheckoutFailure() throws ResourcePoolException; public Throwable getLastIdleCheckFailure() throws ResourcePoolException; public Throwable getLastResourceTestFailure() throws ResourcePoolException; /** * Discards all resources managed by the pool * and reacquires new resources to populate the * pool. Current checked out resources will still * be valid, and should still be checked into the * pool (so the pool can destroy them). */ public void resetPool() throws ResourcePoolException; public void close() throws ResourcePoolException; public void close( boolean close_checked_out_resources ) throws ResourcePoolException; public interface Manager { public Object acquireResource() throws Exception; public void refurbishIdleResource(Object resc) throws Exception; public void refurbishResourceOnCheckout(Object resc) throws Exception; public void refurbishResourceOnCheckin(Object resc) throws Exception; public void destroyResource(Object resc) throws Exception; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePoolEvent.java0000644000175000017500000000364310624366527025454 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import java.util.EventObject; public class ResourcePoolEvent extends EventObject { Object resc; boolean checked_out_resource; int pool_size; int available_size; int removed_but_unreturned_size; public ResourcePoolEvent( ResourcePool pool, Object resc, boolean checked_out_resource, int pool_size, int available_size, int removed_but_unreturned_size ) { super(pool); this.resc = resc; this.checked_out_resource = checked_out_resource; this.pool_size = pool_size; this.available_size = available_size; this.removed_but_unreturned_size = removed_but_unreturned_size; } public Object getResource() { return resc; } public boolean isCheckedOutResource() { return checked_out_resource; } public int getPoolSize() { return pool_size; } public int getAvailableSize() { return available_size; } public int getRemovedButUnreturnedSize() { return removed_but_unreturned_size; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePoolEventSupport.java0000644000175000017500000000742610624366530027046 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import java.util.*; public class ResourcePoolEventSupport { ResourcePool source; Set mlisteners = new HashSet(); public ResourcePoolEventSupport(ResourcePool source) { this.source = source; } public synchronized void addResourcePoolListener(ResourcePoolListener mlistener) {mlisteners.add(mlistener);} public synchronized void removeResourcePoolListener(ResourcePoolListener mlistener) {mlisteners.remove(mlistener);} public synchronized void fireResourceAcquired( Object resc, int pool_size, int available_size, int removed_but_unreturned_size ) { if (! mlisteners.isEmpty() ) { ResourcePoolEvent evt = new ResourcePoolEvent(source, resc, false, pool_size, available_size, removed_but_unreturned_size ); for (Iterator i = mlisteners.iterator(); i.hasNext();) { ResourcePoolListener rpl = (ResourcePoolListener) i.next(); rpl.resourceAcquired(evt); } } } public synchronized void fireResourceCheckedIn( Object resc, int pool_size, int available_size, int removed_but_unreturned_size ) { if (! mlisteners.isEmpty() ) { ResourcePoolEvent evt = new ResourcePoolEvent(source, resc, false, pool_size, available_size, removed_but_unreturned_size ); for (Iterator i = mlisteners.iterator(); i.hasNext();) { ResourcePoolListener rpl = (ResourcePoolListener) i.next(); rpl.resourceCheckedIn(evt); } } } public synchronized void fireResourceCheckedOut( Object resc, int pool_size, int available_size, int removed_but_unreturned_size ) { if (! mlisteners.isEmpty() ) { ResourcePoolEvent evt = new ResourcePoolEvent(source, resc, true, pool_size, available_size, removed_but_unreturned_size ); for (Iterator i = mlisteners.iterator(); i.hasNext();) { ResourcePoolListener rpl = (ResourcePoolListener) i.next(); rpl.resourceCheckedOut(evt); } } } public synchronized void fireResourceRemoved( Object resc, boolean checked_out_resource, int pool_size, int available_size, int removed_but_unreturned_size ) { if (! mlisteners.isEmpty() ) { ResourcePoolEvent evt = new ResourcePoolEvent(source, resc, checked_out_resource, pool_size, available_size, removed_but_unreturned_size ); for (Iterator i = mlisteners.iterator(); i.hasNext();) { ResourcePoolListener rpl = (ResourcePoolListener) i.next(); rpl.resourceRemoved(evt); } } } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePoolException.java0000644000175000017500000000240510624366530026316 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import com.mchange.lang.PotentiallySecondaryException; public class ResourcePoolException extends PotentiallySecondaryException { public ResourcePoolException(String msg, Throwable t) {super(msg, t);} public ResourcePoolException(Throwable t) {super(t);} public ResourcePoolException(String msg) {super(msg);} public ResourcePoolException() {super();} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePoolFactory.java0000644000175000017500000001421310624366530025767 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import java.util.Timer; import com.mchange.v2.async.*; /** *

A Factory for ResourcePools. ResourcePoolFactories may manage * resources (usually threads that perform maintenance tasks) that * are shared by all pools that they create. Clients who require * a large number of pools may wish to create their own factory * instances rather than using the shared instance to control * the degree of resource (Thread) sharing among pools.

* *

Factories should (and the default implementation does) be careful * to ensure that factories keep resources open only while there * are active ResourcePools that they have created.

* *

Subclasses must mark all methods synchronized so that clients * may reliably use shared factories to do stuff like...

* *
 *     synchronized (factory)
 *     {
 *         factory.setMin(8);
 *         factory.setMax(24);
 *         ResourcePool rp = factory.createPool();
 *     }
 *  
*/ public abstract class ResourcePoolFactory { // okay, 'cuz we don't actually create any threads / resourced // until the factory is used. final static ResourcePoolFactory SHARED_INSTANCE = new BasicResourcePoolFactory(); final static int DEFAULT_NUM_TASK_THREADS = 3; public static ResourcePoolFactory getSharedInstance() throws ResourcePoolException { return SHARED_INSTANCE; } public static ResourcePoolFactory createInstance() { return new BasicResourcePoolFactory(); } public static ResourcePoolFactory createInstance( int num_task_threads ) { return new BasicResourcePoolFactory( num_task_threads ); } /** * Any or all of these arguments can be null -- any unspecified resources * will be created and cleaned up internally. */ public static ResourcePoolFactory createInstance( AsynchronousRunner taskRunner, RunnableQueue asyncEventQueue, Timer cullTimer ) { return new BasicResourcePoolFactory( taskRunner, asyncEventQueue, cullTimer ); } public static ResourcePoolFactory createInstance( Queuable taskRunnerEventQueue, Timer cullTimer ) { return createInstance( taskRunnerEventQueue, taskRunnerEventQueue == null ? null : taskRunnerEventQueue.asRunnableQueue(), cullTimer ); } public abstract void setMin( int min ) throws ResourcePoolException; public abstract int getMin() throws ResourcePoolException; public abstract void setMax( int max ) throws ResourcePoolException; public abstract int getStart() throws ResourcePoolException; public abstract void setStart( int start ) throws ResourcePoolException; public abstract int getMax() throws ResourcePoolException; public abstract void setIncrement( int max ) throws ResourcePoolException; public abstract int getIncrement() throws ResourcePoolException; public abstract void setAcquisitionRetryAttempts( int retry_attempts ) throws ResourcePoolException; public abstract int getAcquisitionRetryAttempts() throws ResourcePoolException; public abstract void setAcquisitionRetryDelay( int retry_delay ) throws ResourcePoolException; public abstract int getAcquisitionRetryDelay() throws ResourcePoolException; public abstract void setIdleResourceTestPeriod( long test_period ) throws ResourcePoolException; public abstract long getIdleResourceTestPeriod() throws ResourcePoolException; public abstract void setResourceMaxAge( long millis ) throws ResourcePoolException; public abstract long getResourceMaxAge() throws ResourcePoolException; public abstract void setResourceMaxIdleTime( long millis ) throws ResourcePoolException; public abstract long getResourceMaxIdleTime() throws ResourcePoolException; public abstract void setExcessResourceMaxIdleTime( long millis ) throws ResourcePoolException; public abstract long getExcessResourceMaxIdleTime() throws ResourcePoolException; public abstract long getDestroyOverdueResourceTime() throws ResourcePoolException; public abstract void setDestroyOverdueResourceTime( long millis ) throws ResourcePoolException; public abstract void setExpirationEnforcementDelay( long millis ) throws ResourcePoolException; public abstract long getExpirationEnforcementDelay() throws ResourcePoolException; public abstract void setBreakOnAcquisitionFailure( boolean b ) throws ResourcePoolException; public abstract boolean getBreakOnAcquisitionFailure() throws ResourcePoolException; public abstract void setDebugStoreCheckoutStackTrace( boolean debug_store_checkout_stacktrace ) throws ResourcePoolException; public abstract boolean getDebugStoreCheckoutStackTrace() throws ResourcePoolException; // /** // * Sets whether or not maxAge should be interpreted // * as the maximum age since the resource was first acquired // * (age_is_absolute == true) or since the resource was last // * checked in (age_is_absolute == false). // */ // public abstract void setAgeIsAbsolute( boolean age_is_absolute ) // throws ResourcePoolException; // public abstract boolean getAgeIsAbsolute() // throws ResourcePoolException; public abstract ResourcePool createPool(ResourcePool.Manager mgr) throws ResourcePoolException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePoolListener.java0000644000175000017500000000231510624366527026153 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import java.util.EventListener; public interface ResourcePoolListener extends EventListener { public void resourceAcquired(ResourcePoolEvent evt); public void resourceCheckedIn(ResourcePoolEvent evt); public void resourceCheckedOut(ResourcePoolEvent evt); public void resourceRemoved(ResourcePoolEvent evt); } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/ResourcePoolUtils.java0000644000175000017500000000306610624366527025472 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; import com.mchange.v2.log.*; final class ResourcePoolUtils { final static MLogger logger = MLog.getLogger( ResourcePoolUtils.class ); final static ResourcePoolException convertThrowable( String msg, Throwable t ) { if (Debug.DEBUG) { //t.printStackTrace(); if (logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE , "Converting throwable to ResourcePoolException..." , t ); } if ( t instanceof ResourcePoolException) return (ResourcePoolException) t; else return new ResourcePoolException( msg, t ); } final static ResourcePoolException convertThrowable( Throwable t ) { return convertThrowable("Ouch! " + t.toString(), t ); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/resourcepool/TimeoutException.java0000644000175000017500000000225510624366527025334 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.resourcepool; public class TimeoutException extends ResourcePoolException { public TimeoutException(String msg, Throwable t) {super(msg, t);} public TimeoutException(Throwable t) {super(t);} public TimeoutException(String msg) {super(msg);} public TimeoutException() {super();} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/ser/0000755000175000017500000000000010673162231017216 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/ser/IndirectPolicy.java0000644000175000017500000000260210624366527023014 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.ser; public final class IndirectPolicy { public final static IndirectPolicy DEFINITELY_INDIRECT = new IndirectPolicy("DEFINITELY_INDIRECT"); public final static IndirectPolicy INDIRECT_ON_EXCEPTION = new IndirectPolicy("INDIRECT_ON_EXCEPTION"); public final static IndirectPolicy DEFINITELY_DIRECT = new IndirectPolicy("DEFINITELY_DIRECT"); String name; private IndirectPolicy(String name) { this.name = name; } public String toString() { return "[IndirectPolicy: " + name + ']'; } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/ser/IndirectlySerialized.java0000644000175000017500000000207210624366527024216 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.ser; import java.io.IOException; import java.io.Serializable; public interface IndirectlySerialized extends Serializable { public Object getObject() throws ClassNotFoundException, IOException; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/ser/Indirector.java0000644000175000017500000000174410624366527022203 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.ser; public interface Indirector { public IndirectlySerialized indirectForm( Object orig ) throws Exception; } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/ser/SerializableUtils.java0000644000175000017500000001235410624366530023521 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.ser; import java.io.*; import com.mchange.v1.io.*; import com.mchange.v2.log.*; public final class SerializableUtils { final static MLogger logger = MLog.getLogger( SerializableUtils.class ); private SerializableUtils() {} public static byte[] toByteArray(Object obj) throws NotSerializableException { return serializeToByteArray( obj ); } public static byte[] toByteArray(Object obj, Indirector indirector, IndirectPolicy policy) throws NotSerializableException { try { if (policy == IndirectPolicy.DEFINITELY_INDIRECT) { if (indirector == null) throw new IllegalArgumentException("null indirector is not consistent with " + policy); IndirectlySerialized indirect = indirector.indirectForm( obj ); return toByteArray( indirect ); } else if ( policy == IndirectPolicy.INDIRECT_ON_EXCEPTION ) { if (indirector == null) throw new IllegalArgumentException("null indirector is not consistent with " + policy); try { return toByteArray( obj ); } catch ( NotSerializableException e ) { return toByteArray( obj, indirector, IndirectPolicy.DEFINITELY_INDIRECT ); } } else if (policy == IndirectPolicy.DEFINITELY_DIRECT) return toByteArray( obj ); else throw new InternalError("unknown indirecting policy: " + policy); } catch ( NotSerializableException e ) { throw e; } catch ( Exception e ) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "An Exception occurred while serializing an Object to a byte[] with an Indirector.", e ); throw new NotSerializableException( e.toString() ); } } /** * @deprecated use SerialializableUtils.toByteArray() [shorter name is better!] */ public static byte[] serializeToByteArray(Object obj) throws NotSerializableException { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(obj); return baos.toByteArray(); } catch (NotSerializableException e) { //this is the only IOException that //shouldn't signal a bizarre error... e.fillInStackTrace(); throw e; } catch (IOException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.SEVERE ) ) logger.log( MLevel.SEVERE, "An IOException occurred while writing into a ByteArrayOutputStream?!?", e ); throw new Error("IOException writing to a byte array!"); } } /** * By default, unwraps IndirectlySerialized objects, returning the original */ public static Object fromByteArray(byte[] bytes) throws IOException, ClassNotFoundException { Object out = deserializeFromByteArray( bytes ); if (out instanceof IndirectlySerialized) return ((IndirectlySerialized) out).getObject(); else return out; } public static Object fromByteArray(byte[] bytes, boolean ignore_indirects) throws IOException, ClassNotFoundException { if (ignore_indirects) return deserializeFromByteArray( bytes ); else return fromByteArray( bytes ); } /** * @deprecated use SerialializableUtils.fromByteArray() [shorter name is better!] */ public static Object deserializeFromByteArray(byte[] bytes) throws IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); return in.readObject(); } public static Object testSerializeDeserialize( Object o ) throws IOException, ClassNotFoundException { return deepCopy( o ); } public static Object deepCopy( Object o ) throws IOException, ClassNotFoundException { byte[] bytes = serializeToByteArray( o ); return deserializeFromByteArray( bytes ); } public final static Object unmarshallObjectFromFile(File file) throws IOException, ClassNotFoundException { ObjectInputStream in = null; try { in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))); return in.readObject(); } finally {InputStreamUtils.attemptClose(in);} } public final static void marshallObjectToFile(Object o, File file) throws IOException { ObjectOutputStream out = null; try { out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file))); out.writeObject(o); } finally {OutputStreamUtils.attemptClose(out);} } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/ser/UnsupportedVersionException.java0000644000175000017500000000225010624366527025647 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.ser; import java.io.*; public class UnsupportedVersionException extends InvalidClassException { public UnsupportedVersionException(String message) {super(message);} public UnsupportedVersionException(Object obj, int version) {this(obj.getClass().getName() + " -- unsupported version: " + version);} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/0000755000175000017500000000000010673162231017224 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/0000755000175000017500000000000010673162231020511 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/FilterCallableStatement.java0000644000175000017500000003716610624366527026135 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.InputStream; import java.io.Reader; import java.lang.Object; import java.lang.String; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Connection; import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Map; public abstract class FilterCallableStatement implements CallableStatement { protected CallableStatement inner; public FilterCallableStatement(CallableStatement inner) { this.inner = inner; } public FilterCallableStatement() {} public void setInner( CallableStatement inner ) { this.inner = inner; } public CallableStatement getInner() { return inner; } public boolean wasNull() throws SQLException { return inner.wasNull(); } public BigDecimal getBigDecimal(int a, int b) throws SQLException { return inner.getBigDecimal(a, b); } public BigDecimal getBigDecimal(int a) throws SQLException { return inner.getBigDecimal(a); } public BigDecimal getBigDecimal(String a) throws SQLException { return inner.getBigDecimal(a); } public Timestamp getTimestamp(String a) throws SQLException { return inner.getTimestamp(a); } public Timestamp getTimestamp(String a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public Timestamp getTimestamp(int a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public Timestamp getTimestamp(int a) throws SQLException { return inner.getTimestamp(a); } public Blob getBlob(String a) throws SQLException { return inner.getBlob(a); } public Blob getBlob(int a) throws SQLException { return inner.getBlob(a); } public Clob getClob(String a) throws SQLException { return inner.getClob(a); } public Clob getClob(int a) throws SQLException { return inner.getClob(a); } public void setNull(String a, int b, String c) throws SQLException { inner.setNull(a, b, c); } public void setNull(String a, int b) throws SQLException { inner.setNull(a, b); } public void setBigDecimal(String a, BigDecimal b) throws SQLException { inner.setBigDecimal(a, b); } public void setBytes(String a, byte[] b) throws SQLException { inner.setBytes(a, b); } public void setTimestamp(String a, Timestamp b, Calendar c) throws SQLException { inner.setTimestamp(a, b, c); } public void setTimestamp(String a, Timestamp b) throws SQLException { inner.setTimestamp(a, b); } public void setAsciiStream(String a, InputStream b, int c) throws SQLException { inner.setAsciiStream(a, b, c); } public void setBinaryStream(String a, InputStream b, int c) throws SQLException { inner.setBinaryStream(a, b, c); } public void setObject(String a, Object b) throws SQLException { inner.setObject(a, b); } public void setObject(String a, Object b, int c, int d) throws SQLException { inner.setObject(a, b, c, d); } public void setObject(String a, Object b, int c) throws SQLException { inner.setObject(a, b, c); } public void setCharacterStream(String a, Reader b, int c) throws SQLException { inner.setCharacterStream(a, b, c); } public void registerOutParameter(String a, int b) throws SQLException { inner.registerOutParameter(a, b); } public void registerOutParameter(int a, int b) throws SQLException { inner.registerOutParameter(a, b); } public void registerOutParameter(int a, int b, int c) throws SQLException { inner.registerOutParameter(a, b, c); } public void registerOutParameter(int a, int b, String c) throws SQLException { inner.registerOutParameter(a, b, c); } public void registerOutParameter(String a, int b, int c) throws SQLException { inner.registerOutParameter(a, b, c); } public void registerOutParameter(String a, int b, String c) throws SQLException { inner.registerOutParameter(a, b, c); } public Object getObject(String a, Map b) throws SQLException { return inner.getObject(a, b); } public Object getObject(int a, Map b) throws SQLException { return inner.getObject(a, b); } public Object getObject(int a) throws SQLException { return inner.getObject(a); } public Object getObject(String a) throws SQLException { return inner.getObject(a); } public boolean getBoolean(int a) throws SQLException { return inner.getBoolean(a); } public boolean getBoolean(String a) throws SQLException { return inner.getBoolean(a); } public byte getByte(String a) throws SQLException { return inner.getByte(a); } public byte getByte(int a) throws SQLException { return inner.getByte(a); } public short getShort(int a) throws SQLException { return inner.getShort(a); } public short getShort(String a) throws SQLException { return inner.getShort(a); } public int getInt(String a) throws SQLException { return inner.getInt(a); } public int getInt(int a) throws SQLException { return inner.getInt(a); } public long getLong(int a) throws SQLException { return inner.getLong(a); } public long getLong(String a) throws SQLException { return inner.getLong(a); } public float getFloat(String a) throws SQLException { return inner.getFloat(a); } public float getFloat(int a) throws SQLException { return inner.getFloat(a); } public double getDouble(String a) throws SQLException { return inner.getDouble(a); } public double getDouble(int a) throws SQLException { return inner.getDouble(a); } public byte[] getBytes(int a) throws SQLException { return inner.getBytes(a); } public byte[] getBytes(String a) throws SQLException { return inner.getBytes(a); } public URL getURL(String a) throws SQLException { return inner.getURL(a); } public URL getURL(int a) throws SQLException { return inner.getURL(a); } public void setBoolean(String a, boolean b) throws SQLException { inner.setBoolean(a, b); } public void setByte(String a, byte b) throws SQLException { inner.setByte(a, b); } public void setShort(String a, short b) throws SQLException { inner.setShort(a, b); } public void setInt(String a, int b) throws SQLException { inner.setInt(a, b); } public void setLong(String a, long b) throws SQLException { inner.setLong(a, b); } public void setFloat(String a, float b) throws SQLException { inner.setFloat(a, b); } public void setDouble(String a, double b) throws SQLException { inner.setDouble(a, b); } public String getString(String a) throws SQLException { return inner.getString(a); } public String getString(int a) throws SQLException { return inner.getString(a); } public Ref getRef(int a) throws SQLException { return inner.getRef(a); } public Ref getRef(String a) throws SQLException { return inner.getRef(a); } public void setURL(String a, URL b) throws SQLException { inner.setURL(a, b); } public void setTime(String a, Time b) throws SQLException { inner.setTime(a, b); } public void setTime(String a, Time b, Calendar c) throws SQLException { inner.setTime(a, b, c); } public Time getTime(int a, Calendar b) throws SQLException { return inner.getTime(a, b); } public Time getTime(String a) throws SQLException { return inner.getTime(a); } public Time getTime(int a) throws SQLException { return inner.getTime(a); } public Time getTime(String a, Calendar b) throws SQLException { return inner.getTime(a, b); } public Date getDate(int a, Calendar b) throws SQLException { return inner.getDate(a, b); } public Date getDate(String a) throws SQLException { return inner.getDate(a); } public Date getDate(int a) throws SQLException { return inner.getDate(a); } public Date getDate(String a, Calendar b) throws SQLException { return inner.getDate(a, b); } public void setString(String a, String b) throws SQLException { inner.setString(a, b); } public Array getArray(int a) throws SQLException { return inner.getArray(a); } public Array getArray(String a) throws SQLException { return inner.getArray(a); } public void setDate(String a, Date b, Calendar c) throws SQLException { inner.setDate(a, b, c); } public void setDate(String a, Date b) throws SQLException { inner.setDate(a, b); } public ResultSetMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public ResultSet executeQuery() throws SQLException { return inner.executeQuery(); } public int executeUpdate() throws SQLException { return inner.executeUpdate(); } public void addBatch() throws SQLException { inner.addBatch(); } public void setNull(int a, int b, String c) throws SQLException { inner.setNull(a, b, c); } public void setNull(int a, int b) throws SQLException { inner.setNull(a, b); } public void setBigDecimal(int a, BigDecimal b) throws SQLException { inner.setBigDecimal(a, b); } public void setBytes(int a, byte[] b) throws SQLException { inner.setBytes(a, b); } public void setTimestamp(int a, Timestamp b, Calendar c) throws SQLException { inner.setTimestamp(a, b, c); } public void setTimestamp(int a, Timestamp b) throws SQLException { inner.setTimestamp(a, b); } public void setAsciiStream(int a, InputStream b, int c) throws SQLException { inner.setAsciiStream(a, b, c); } public void setUnicodeStream(int a, InputStream b, int c) throws SQLException { inner.setUnicodeStream(a, b, c); } public void setBinaryStream(int a, InputStream b, int c) throws SQLException { inner.setBinaryStream(a, b, c); } public void clearParameters() throws SQLException { inner.clearParameters(); } public void setObject(int a, Object b) throws SQLException { inner.setObject(a, b); } public void setObject(int a, Object b, int c, int d) throws SQLException { inner.setObject(a, b, c, d); } public void setObject(int a, Object b, int c) throws SQLException { inner.setObject(a, b, c); } public void setCharacterStream(int a, Reader b, int c) throws SQLException { inner.setCharacterStream(a, b, c); } public void setRef(int a, Ref b) throws SQLException { inner.setRef(a, b); } public void setBlob(int a, Blob b) throws SQLException { inner.setBlob(a, b); } public void setClob(int a, Clob b) throws SQLException { inner.setClob(a, b); } public void setArray(int a, Array b) throws SQLException { inner.setArray(a, b); } public ParameterMetaData getParameterMetaData() throws SQLException { return inner.getParameterMetaData(); } public void setBoolean(int a, boolean b) throws SQLException { inner.setBoolean(a, b); } public void setByte(int a, byte b) throws SQLException { inner.setByte(a, b); } public void setShort(int a, short b) throws SQLException { inner.setShort(a, b); } public void setInt(int a, int b) throws SQLException { inner.setInt(a, b); } public void setLong(int a, long b) throws SQLException { inner.setLong(a, b); } public void setFloat(int a, float b) throws SQLException { inner.setFloat(a, b); } public void setDouble(int a, double b) throws SQLException { inner.setDouble(a, b); } public void setURL(int a, URL b) throws SQLException { inner.setURL(a, b); } public void setTime(int a, Time b) throws SQLException { inner.setTime(a, b); } public void setTime(int a, Time b, Calendar c) throws SQLException { inner.setTime(a, b, c); } public boolean execute() throws SQLException { return inner.execute(); } public void setString(int a, String b) throws SQLException { inner.setString(a, b); } public void setDate(int a, Date b, Calendar c) throws SQLException { inner.setDate(a, b, c); } public void setDate(int a, Date b) throws SQLException { inner.setDate(a, b); } public SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public void clearWarnings() throws SQLException { inner.clearWarnings(); } public void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public int getFetchSize() throws SQLException { return inner.getFetchSize(); } public int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public ResultSet executeQuery(String a) throws SQLException { return inner.executeQuery(a); } public int executeUpdate(String a, int b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a, String[] b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a, int[] b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a) throws SQLException { return inner.executeUpdate(a); } public int getMaxFieldSize() throws SQLException { return inner.getMaxFieldSize(); } public void setMaxFieldSize(int a) throws SQLException { inner.setMaxFieldSize(a); } public int getMaxRows() throws SQLException { return inner.getMaxRows(); } public void setMaxRows(int a) throws SQLException { inner.setMaxRows(a); } public void setEscapeProcessing(boolean a) throws SQLException { inner.setEscapeProcessing(a); } public int getQueryTimeout() throws SQLException { return inner.getQueryTimeout(); } public void setQueryTimeout(int a) throws SQLException { inner.setQueryTimeout(a); } public void setCursorName(String a) throws SQLException { inner.setCursorName(a); } public ResultSet getResultSet() throws SQLException { return inner.getResultSet(); } public int getUpdateCount() throws SQLException { return inner.getUpdateCount(); } public boolean getMoreResults() throws SQLException { return inner.getMoreResults(); } public boolean getMoreResults(int a) throws SQLException { return inner.getMoreResults(a); } public int getResultSetConcurrency() throws SQLException { return inner.getResultSetConcurrency(); } public int getResultSetType() throws SQLException { return inner.getResultSetType(); } public void addBatch(String a) throws SQLException { inner.addBatch(a); } public void clearBatch() throws SQLException { inner.clearBatch(); } public int[] executeBatch() throws SQLException { return inner.executeBatch(); } public ResultSet getGeneratedKeys() throws SQLException { return inner.getGeneratedKeys(); } public void close() throws SQLException { inner.close(); } public boolean execute(String a, int b) throws SQLException { return inner.execute(a, b); } public boolean execute(String a) throws SQLException { return inner.execute(a); } public boolean execute(String a, int[] b) throws SQLException { return inner.execute(a, b); } public boolean execute(String a, String[] b) throws SQLException { return inner.execute(a, b); } public Connection getConnection() throws SQLException { return inner.getConnection(); } public void cancel() throws SQLException { inner.cancel(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/FilterConnection.java0000644000175000017500000001161510624366527024637 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.lang.String; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Savepoint; import java.sql.Statement; import java.util.Map; public abstract class FilterConnection implements Connection { protected Connection inner; public FilterConnection(Connection inner) { this.inner = inner; } public FilterConnection() {} public void setInner( Connection inner ) { this.inner = inner; } public Connection getInner() { return inner; } public Statement createStatement(int a, int b, int c) throws SQLException { return inner.createStatement(a, b, c); } public Statement createStatement(int a, int b) throws SQLException { return inner.createStatement(a, b); } public Statement createStatement() throws SQLException { return inner.createStatement(); } public PreparedStatement prepareStatement(String a, String[] b) throws SQLException { return inner.prepareStatement(a, b); } public PreparedStatement prepareStatement(String a) throws SQLException { return inner.prepareStatement(a); } public PreparedStatement prepareStatement(String a, int b, int c) throws SQLException { return inner.prepareStatement(a, b, c); } public PreparedStatement prepareStatement(String a, int b, int c, int d) throws SQLException { return inner.prepareStatement(a, b, c, d); } public PreparedStatement prepareStatement(String a, int b) throws SQLException { return inner.prepareStatement(a, b); } public PreparedStatement prepareStatement(String a, int[] b) throws SQLException { return inner.prepareStatement(a, b); } public CallableStatement prepareCall(String a, int b, int c, int d) throws SQLException { return inner.prepareCall(a, b, c, d); } public CallableStatement prepareCall(String a, int b, int c) throws SQLException { return inner.prepareCall(a, b, c); } public CallableStatement prepareCall(String a) throws SQLException { return inner.prepareCall(a); } public String nativeSQL(String a) throws SQLException { return inner.nativeSQL(a); } public void setAutoCommit(boolean a) throws SQLException { inner.setAutoCommit(a); } public boolean getAutoCommit() throws SQLException { return inner.getAutoCommit(); } public void commit() throws SQLException { inner.commit(); } public void rollback(Savepoint a) throws SQLException { inner.rollback(a); } public void rollback() throws SQLException { inner.rollback(); } public DatabaseMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public void setCatalog(String a) throws SQLException { inner.setCatalog(a); } public String getCatalog() throws SQLException { return inner.getCatalog(); } public void setTransactionIsolation(int a) throws SQLException { inner.setTransactionIsolation(a); } public int getTransactionIsolation() throws SQLException { return inner.getTransactionIsolation(); } public SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public void clearWarnings() throws SQLException { inner.clearWarnings(); } public Map getTypeMap() throws SQLException { return inner.getTypeMap(); } public void setTypeMap(Map a) throws SQLException { inner.setTypeMap(a); } public void setHoldability(int a) throws SQLException { inner.setHoldability(a); } public int getHoldability() throws SQLException { return inner.getHoldability(); } public Savepoint setSavepoint() throws SQLException { return inner.setSavepoint(); } public Savepoint setSavepoint(String a) throws SQLException { return inner.setSavepoint(a); } public void releaseSavepoint(Savepoint a) throws SQLException { inner.releaseSavepoint(a); } public void setReadOnly(boolean a) throws SQLException { inner.setReadOnly(a); } public boolean isReadOnly() throws SQLException { return inner.isReadOnly(); } public void close() throws SQLException { inner.close(); } public boolean isClosed() throws SQLException { return inner.isClosed(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/FilterDatabaseMetaData.java0000644000175000017500000004676210624366527025660 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.lang.String; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; public abstract class FilterDatabaseMetaData implements DatabaseMetaData { protected DatabaseMetaData inner; public FilterDatabaseMetaData(DatabaseMetaData inner) { this.inner = inner; } public FilterDatabaseMetaData() {} public void setInner( DatabaseMetaData inner ) { this.inner = inner; } public DatabaseMetaData getInner() { return inner; } public boolean allProceduresAreCallable() throws SQLException { return inner.allProceduresAreCallable(); } public boolean allTablesAreSelectable() throws SQLException { return inner.allTablesAreSelectable(); } public boolean nullsAreSortedHigh() throws SQLException { return inner.nullsAreSortedHigh(); } public boolean nullsAreSortedLow() throws SQLException { return inner.nullsAreSortedLow(); } public boolean nullsAreSortedAtStart() throws SQLException { return inner.nullsAreSortedAtStart(); } public boolean nullsAreSortedAtEnd() throws SQLException { return inner.nullsAreSortedAtEnd(); } public String getDatabaseProductName() throws SQLException { return inner.getDatabaseProductName(); } public String getDatabaseProductVersion() throws SQLException { return inner.getDatabaseProductVersion(); } public String getDriverName() throws SQLException { return inner.getDriverName(); } public String getDriverVersion() throws SQLException { return inner.getDriverVersion(); } public int getDriverMajorVersion() { return inner.getDriverMajorVersion(); } public int getDriverMinorVersion() { return inner.getDriverMinorVersion(); } public boolean usesLocalFiles() throws SQLException { return inner.usesLocalFiles(); } public boolean usesLocalFilePerTable() throws SQLException { return inner.usesLocalFilePerTable(); } public boolean supportsMixedCaseIdentifiers() throws SQLException { return inner.supportsMixedCaseIdentifiers(); } public boolean storesUpperCaseIdentifiers() throws SQLException { return inner.storesUpperCaseIdentifiers(); } public boolean storesLowerCaseIdentifiers() throws SQLException { return inner.storesLowerCaseIdentifiers(); } public boolean storesMixedCaseIdentifiers() throws SQLException { return inner.storesMixedCaseIdentifiers(); } public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { return inner.supportsMixedCaseQuotedIdentifiers(); } public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { return inner.storesUpperCaseQuotedIdentifiers(); } public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { return inner.storesLowerCaseQuotedIdentifiers(); } public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { return inner.storesMixedCaseQuotedIdentifiers(); } public String getIdentifierQuoteString() throws SQLException { return inner.getIdentifierQuoteString(); } public String getSQLKeywords() throws SQLException { return inner.getSQLKeywords(); } public String getNumericFunctions() throws SQLException { return inner.getNumericFunctions(); } public String getStringFunctions() throws SQLException { return inner.getStringFunctions(); } public String getSystemFunctions() throws SQLException { return inner.getSystemFunctions(); } public String getTimeDateFunctions() throws SQLException { return inner.getTimeDateFunctions(); } public String getSearchStringEscape() throws SQLException { return inner.getSearchStringEscape(); } public String getExtraNameCharacters() throws SQLException { return inner.getExtraNameCharacters(); } public boolean supportsAlterTableWithAddColumn() throws SQLException { return inner.supportsAlterTableWithAddColumn(); } public boolean supportsAlterTableWithDropColumn() throws SQLException { return inner.supportsAlterTableWithDropColumn(); } public boolean supportsColumnAliasing() throws SQLException { return inner.supportsColumnAliasing(); } public boolean nullPlusNonNullIsNull() throws SQLException { return inner.nullPlusNonNullIsNull(); } public boolean supportsConvert() throws SQLException { return inner.supportsConvert(); } public boolean supportsConvert(int a, int b) throws SQLException { return inner.supportsConvert(a, b); } public boolean supportsTableCorrelationNames() throws SQLException { return inner.supportsTableCorrelationNames(); } public boolean supportsDifferentTableCorrelationNames() throws SQLException { return inner.supportsDifferentTableCorrelationNames(); } public boolean supportsExpressionsInOrderBy() throws SQLException { return inner.supportsExpressionsInOrderBy(); } public boolean supportsOrderByUnrelated() throws SQLException { return inner.supportsOrderByUnrelated(); } public boolean supportsGroupBy() throws SQLException { return inner.supportsGroupBy(); } public boolean supportsGroupByUnrelated() throws SQLException { return inner.supportsGroupByUnrelated(); } public boolean supportsGroupByBeyondSelect() throws SQLException { return inner.supportsGroupByBeyondSelect(); } public boolean supportsLikeEscapeClause() throws SQLException { return inner.supportsLikeEscapeClause(); } public boolean supportsMultipleResultSets() throws SQLException { return inner.supportsMultipleResultSets(); } public boolean supportsMultipleTransactions() throws SQLException { return inner.supportsMultipleTransactions(); } public boolean supportsNonNullableColumns() throws SQLException { return inner.supportsNonNullableColumns(); } public boolean supportsMinimumSQLGrammar() throws SQLException { return inner.supportsMinimumSQLGrammar(); } public boolean supportsCoreSQLGrammar() throws SQLException { return inner.supportsCoreSQLGrammar(); } public boolean supportsExtendedSQLGrammar() throws SQLException { return inner.supportsExtendedSQLGrammar(); } public boolean supportsANSI92EntryLevelSQL() throws SQLException { return inner.supportsANSI92EntryLevelSQL(); } public boolean supportsANSI92IntermediateSQL() throws SQLException { return inner.supportsANSI92IntermediateSQL(); } public boolean supportsANSI92FullSQL() throws SQLException { return inner.supportsANSI92FullSQL(); } public boolean supportsIntegrityEnhancementFacility() throws SQLException { return inner.supportsIntegrityEnhancementFacility(); } public boolean supportsOuterJoins() throws SQLException { return inner.supportsOuterJoins(); } public boolean supportsFullOuterJoins() throws SQLException { return inner.supportsFullOuterJoins(); } public boolean supportsLimitedOuterJoins() throws SQLException { return inner.supportsLimitedOuterJoins(); } public String getSchemaTerm() throws SQLException { return inner.getSchemaTerm(); } public String getProcedureTerm() throws SQLException { return inner.getProcedureTerm(); } public String getCatalogTerm() throws SQLException { return inner.getCatalogTerm(); } public boolean isCatalogAtStart() throws SQLException { return inner.isCatalogAtStart(); } public String getCatalogSeparator() throws SQLException { return inner.getCatalogSeparator(); } public boolean supportsSchemasInDataManipulation() throws SQLException { return inner.supportsSchemasInDataManipulation(); } public boolean supportsSchemasInProcedureCalls() throws SQLException { return inner.supportsSchemasInProcedureCalls(); } public boolean supportsSchemasInTableDefinitions() throws SQLException { return inner.supportsSchemasInTableDefinitions(); } public boolean supportsSchemasInIndexDefinitions() throws SQLException { return inner.supportsSchemasInIndexDefinitions(); } public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { return inner.supportsSchemasInPrivilegeDefinitions(); } public boolean supportsCatalogsInDataManipulation() throws SQLException { return inner.supportsCatalogsInDataManipulation(); } public boolean supportsCatalogsInProcedureCalls() throws SQLException { return inner.supportsCatalogsInProcedureCalls(); } public boolean supportsCatalogsInTableDefinitions() throws SQLException { return inner.supportsCatalogsInTableDefinitions(); } public boolean supportsCatalogsInIndexDefinitions() throws SQLException { return inner.supportsCatalogsInIndexDefinitions(); } public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { return inner.supportsCatalogsInPrivilegeDefinitions(); } public boolean supportsPositionedDelete() throws SQLException { return inner.supportsPositionedDelete(); } public boolean supportsPositionedUpdate() throws SQLException { return inner.supportsPositionedUpdate(); } public boolean supportsSelectForUpdate() throws SQLException { return inner.supportsSelectForUpdate(); } public boolean supportsStoredProcedures() throws SQLException { return inner.supportsStoredProcedures(); } public boolean supportsSubqueriesInComparisons() throws SQLException { return inner.supportsSubqueriesInComparisons(); } public boolean supportsSubqueriesInExists() throws SQLException { return inner.supportsSubqueriesInExists(); } public boolean supportsSubqueriesInIns() throws SQLException { return inner.supportsSubqueriesInIns(); } public boolean supportsSubqueriesInQuantifieds() throws SQLException { return inner.supportsSubqueriesInQuantifieds(); } public boolean supportsCorrelatedSubqueries() throws SQLException { return inner.supportsCorrelatedSubqueries(); } public boolean supportsUnion() throws SQLException { return inner.supportsUnion(); } public boolean supportsUnionAll() throws SQLException { return inner.supportsUnionAll(); } public boolean supportsOpenCursorsAcrossCommit() throws SQLException { return inner.supportsOpenCursorsAcrossCommit(); } public boolean supportsOpenCursorsAcrossRollback() throws SQLException { return inner.supportsOpenCursorsAcrossRollback(); } public boolean supportsOpenStatementsAcrossCommit() throws SQLException { return inner.supportsOpenStatementsAcrossCommit(); } public boolean supportsOpenStatementsAcrossRollback() throws SQLException { return inner.supportsOpenStatementsAcrossRollback(); } public int getMaxBinaryLiteralLength() throws SQLException { return inner.getMaxBinaryLiteralLength(); } public int getMaxCharLiteralLength() throws SQLException { return inner.getMaxCharLiteralLength(); } public int getMaxColumnNameLength() throws SQLException { return inner.getMaxColumnNameLength(); } public int getMaxColumnsInGroupBy() throws SQLException { return inner.getMaxColumnsInGroupBy(); } public int getMaxColumnsInIndex() throws SQLException { return inner.getMaxColumnsInIndex(); } public int getMaxColumnsInOrderBy() throws SQLException { return inner.getMaxColumnsInOrderBy(); } public int getMaxColumnsInSelect() throws SQLException { return inner.getMaxColumnsInSelect(); } public int getMaxColumnsInTable() throws SQLException { return inner.getMaxColumnsInTable(); } public int getMaxConnections() throws SQLException { return inner.getMaxConnections(); } public int getMaxCursorNameLength() throws SQLException { return inner.getMaxCursorNameLength(); } public int getMaxIndexLength() throws SQLException { return inner.getMaxIndexLength(); } public int getMaxSchemaNameLength() throws SQLException { return inner.getMaxSchemaNameLength(); } public int getMaxProcedureNameLength() throws SQLException { return inner.getMaxProcedureNameLength(); } public int getMaxCatalogNameLength() throws SQLException { return inner.getMaxCatalogNameLength(); } public int getMaxRowSize() throws SQLException { return inner.getMaxRowSize(); } public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { return inner.doesMaxRowSizeIncludeBlobs(); } public int getMaxStatementLength() throws SQLException { return inner.getMaxStatementLength(); } public int getMaxStatements() throws SQLException { return inner.getMaxStatements(); } public int getMaxTableNameLength() throws SQLException { return inner.getMaxTableNameLength(); } public int getMaxTablesInSelect() throws SQLException { return inner.getMaxTablesInSelect(); } public int getMaxUserNameLength() throws SQLException { return inner.getMaxUserNameLength(); } public int getDefaultTransactionIsolation() throws SQLException { return inner.getDefaultTransactionIsolation(); } public boolean supportsTransactions() throws SQLException { return inner.supportsTransactions(); } public boolean supportsTransactionIsolationLevel(int a) throws SQLException { return inner.supportsTransactionIsolationLevel(a); } public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException { return inner.supportsDataDefinitionAndDataManipulationTransactions(); } public boolean supportsDataManipulationTransactionsOnly() throws SQLException { return inner.supportsDataManipulationTransactionsOnly(); } public boolean dataDefinitionCausesTransactionCommit() throws SQLException { return inner.dataDefinitionCausesTransactionCommit(); } public boolean dataDefinitionIgnoredInTransactions() throws SQLException { return inner.dataDefinitionIgnoredInTransactions(); } public ResultSet getProcedures(String a, String b, String c) throws SQLException { return inner.getProcedures(a, b, c); } public ResultSet getProcedureColumns(String a, String b, String c, String d) throws SQLException { return inner.getProcedureColumns(a, b, c, d); } public ResultSet getTables(String a, String b, String c, String[] d) throws SQLException { return inner.getTables(a, b, c, d); } public ResultSet getSchemas() throws SQLException { return inner.getSchemas(); } public ResultSet getCatalogs() throws SQLException { return inner.getCatalogs(); } public ResultSet getTableTypes() throws SQLException { return inner.getTableTypes(); } public ResultSet getColumnPrivileges(String a, String b, String c, String d) throws SQLException { return inner.getColumnPrivileges(a, b, c, d); } public ResultSet getTablePrivileges(String a, String b, String c) throws SQLException { return inner.getTablePrivileges(a, b, c); } public ResultSet getBestRowIdentifier(String a, String b, String c, int d, boolean e) throws SQLException { return inner.getBestRowIdentifier(a, b, c, d, e); } public ResultSet getVersionColumns(String a, String b, String c) throws SQLException { return inner.getVersionColumns(a, b, c); } public ResultSet getPrimaryKeys(String a, String b, String c) throws SQLException { return inner.getPrimaryKeys(a, b, c); } public ResultSet getImportedKeys(String a, String b, String c) throws SQLException { return inner.getImportedKeys(a, b, c); } public ResultSet getExportedKeys(String a, String b, String c) throws SQLException { return inner.getExportedKeys(a, b, c); } public ResultSet getCrossReference(String a, String b, String c, String d, String e, String f) throws SQLException { return inner.getCrossReference(a, b, c, d, e, f); } public ResultSet getTypeInfo() throws SQLException { return inner.getTypeInfo(); } public ResultSet getIndexInfo(String a, String b, String c, boolean d, boolean e) throws SQLException { return inner.getIndexInfo(a, b, c, d, e); } public boolean supportsResultSetType(int a) throws SQLException { return inner.supportsResultSetType(a); } public boolean supportsResultSetConcurrency(int a, int b) throws SQLException { return inner.supportsResultSetConcurrency(a, b); } public boolean ownUpdatesAreVisible(int a) throws SQLException { return inner.ownUpdatesAreVisible(a); } public boolean ownDeletesAreVisible(int a) throws SQLException { return inner.ownDeletesAreVisible(a); } public boolean ownInsertsAreVisible(int a) throws SQLException { return inner.ownInsertsAreVisible(a); } public boolean othersUpdatesAreVisible(int a) throws SQLException { return inner.othersUpdatesAreVisible(a); } public boolean othersDeletesAreVisible(int a) throws SQLException { return inner.othersDeletesAreVisible(a); } public boolean othersInsertsAreVisible(int a) throws SQLException { return inner.othersInsertsAreVisible(a); } public boolean updatesAreDetected(int a) throws SQLException { return inner.updatesAreDetected(a); } public boolean deletesAreDetected(int a) throws SQLException { return inner.deletesAreDetected(a); } public boolean insertsAreDetected(int a) throws SQLException { return inner.insertsAreDetected(a); } public boolean supportsBatchUpdates() throws SQLException { return inner.supportsBatchUpdates(); } public ResultSet getUDTs(String a, String b, String c, int[] d) throws SQLException { return inner.getUDTs(a, b, c, d); } public boolean supportsSavepoints() throws SQLException { return inner.supportsSavepoints(); } public boolean supportsNamedParameters() throws SQLException { return inner.supportsNamedParameters(); } public boolean supportsMultipleOpenResults() throws SQLException { return inner.supportsMultipleOpenResults(); } public boolean supportsGetGeneratedKeys() throws SQLException { return inner.supportsGetGeneratedKeys(); } public ResultSet getSuperTypes(String a, String b, String c) throws SQLException { return inner.getSuperTypes(a, b, c); } public ResultSet getSuperTables(String a, String b, String c) throws SQLException { return inner.getSuperTables(a, b, c); } public boolean supportsResultSetHoldability(int a) throws SQLException { return inner.supportsResultSetHoldability(a); } public int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public int getDatabaseMajorVersion() throws SQLException { return inner.getDatabaseMajorVersion(); } public int getDatabaseMinorVersion() throws SQLException { return inner.getDatabaseMinorVersion(); } public int getJDBCMajorVersion() throws SQLException { return inner.getJDBCMajorVersion(); } public int getJDBCMinorVersion() throws SQLException { return inner.getJDBCMinorVersion(); } public int getSQLStateType() throws SQLException { return inner.getSQLStateType(); } public boolean locatorsUpdateCopy() throws SQLException { return inner.locatorsUpdateCopy(); } public boolean supportsStatementPooling() throws SQLException { return inner.supportsStatementPooling(); } public String getURL() throws SQLException { return inner.getURL(); } public boolean isReadOnly() throws SQLException { return inner.isReadOnly(); } public ResultSet getAttributes(String a, String b, String c, String d) throws SQLException { return inner.getAttributes(a, b, c, d); } public Connection getConnection() throws SQLException { return inner.getConnection(); } public ResultSet getColumns(String a, String b, String c, String d) throws SQLException { return inner.getColumns(a, b, c, d); } public String getUserName() throws SQLException { return inner.getUserName(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/FilterPreparedStatement.java0000644000175000017500000002062310624366530026160 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.InputStream; import java.io.Reader; import java.lang.Object; import java.lang.String; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; public abstract class FilterPreparedStatement implements PreparedStatement { protected PreparedStatement inner; public FilterPreparedStatement(PreparedStatement inner) { this.inner = inner; } public FilterPreparedStatement() {} public void setInner( PreparedStatement inner ) { this.inner = inner; } public PreparedStatement getInner() { return inner; } public ResultSetMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public ResultSet executeQuery() throws SQLException { return inner.executeQuery(); } public int executeUpdate() throws SQLException { return inner.executeUpdate(); } public void addBatch() throws SQLException { inner.addBatch(); } public void setNull(int a, int b, String c) throws SQLException { inner.setNull(a, b, c); } public void setNull(int a, int b) throws SQLException { inner.setNull(a, b); } public void setBigDecimal(int a, BigDecimal b) throws SQLException { inner.setBigDecimal(a, b); } public void setBytes(int a, byte[] b) throws SQLException { inner.setBytes(a, b); } public void setTimestamp(int a, Timestamp b, Calendar c) throws SQLException { inner.setTimestamp(a, b, c); } public void setTimestamp(int a, Timestamp b) throws SQLException { inner.setTimestamp(a, b); } public void setAsciiStream(int a, InputStream b, int c) throws SQLException { inner.setAsciiStream(a, b, c); } public void setUnicodeStream(int a, InputStream b, int c) throws SQLException { inner.setUnicodeStream(a, b, c); } public void setBinaryStream(int a, InputStream b, int c) throws SQLException { inner.setBinaryStream(a, b, c); } public void clearParameters() throws SQLException { inner.clearParameters(); } public void setObject(int a, Object b) throws SQLException { inner.setObject(a, b); } public void setObject(int a, Object b, int c, int d) throws SQLException { inner.setObject(a, b, c, d); } public void setObject(int a, Object b, int c) throws SQLException { inner.setObject(a, b, c); } public void setCharacterStream(int a, Reader b, int c) throws SQLException { inner.setCharacterStream(a, b, c); } public void setRef(int a, Ref b) throws SQLException { inner.setRef(a, b); } public void setBlob(int a, Blob b) throws SQLException { inner.setBlob(a, b); } public void setClob(int a, Clob b) throws SQLException { inner.setClob(a, b); } public void setArray(int a, Array b) throws SQLException { inner.setArray(a, b); } public ParameterMetaData getParameterMetaData() throws SQLException { return inner.getParameterMetaData(); } public void setBoolean(int a, boolean b) throws SQLException { inner.setBoolean(a, b); } public void setByte(int a, byte b) throws SQLException { inner.setByte(a, b); } public void setShort(int a, short b) throws SQLException { inner.setShort(a, b); } public void setInt(int a, int b) throws SQLException { inner.setInt(a, b); } public void setLong(int a, long b) throws SQLException { inner.setLong(a, b); } public void setFloat(int a, float b) throws SQLException { inner.setFloat(a, b); } public void setDouble(int a, double b) throws SQLException { inner.setDouble(a, b); } public void setURL(int a, URL b) throws SQLException { inner.setURL(a, b); } public void setTime(int a, Time b) throws SQLException { inner.setTime(a, b); } public void setTime(int a, Time b, Calendar c) throws SQLException { inner.setTime(a, b, c); } public boolean execute() throws SQLException { return inner.execute(); } public void setString(int a, String b) throws SQLException { inner.setString(a, b); } public void setDate(int a, Date b, Calendar c) throws SQLException { inner.setDate(a, b, c); } public void setDate(int a, Date b) throws SQLException { inner.setDate(a, b); } public SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public void clearWarnings() throws SQLException { inner.clearWarnings(); } public void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public int getFetchSize() throws SQLException { return inner.getFetchSize(); } public int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public ResultSet executeQuery(String a) throws SQLException { return inner.executeQuery(a); } public int executeUpdate(String a, int b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a, String[] b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a, int[] b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a) throws SQLException { return inner.executeUpdate(a); } public int getMaxFieldSize() throws SQLException { return inner.getMaxFieldSize(); } public void setMaxFieldSize(int a) throws SQLException { inner.setMaxFieldSize(a); } public int getMaxRows() throws SQLException { return inner.getMaxRows(); } public void setMaxRows(int a) throws SQLException { inner.setMaxRows(a); } public void setEscapeProcessing(boolean a) throws SQLException { inner.setEscapeProcessing(a); } public int getQueryTimeout() throws SQLException { return inner.getQueryTimeout(); } public void setQueryTimeout(int a) throws SQLException { inner.setQueryTimeout(a); } public void setCursorName(String a) throws SQLException { inner.setCursorName(a); } public ResultSet getResultSet() throws SQLException { return inner.getResultSet(); } public int getUpdateCount() throws SQLException { return inner.getUpdateCount(); } public boolean getMoreResults() throws SQLException { return inner.getMoreResults(); } public boolean getMoreResults(int a) throws SQLException { return inner.getMoreResults(a); } public int getResultSetConcurrency() throws SQLException { return inner.getResultSetConcurrency(); } public int getResultSetType() throws SQLException { return inner.getResultSetType(); } public void addBatch(String a) throws SQLException { inner.addBatch(a); } public void clearBatch() throws SQLException { inner.clearBatch(); } public int[] executeBatch() throws SQLException { return inner.executeBatch(); } public ResultSet getGeneratedKeys() throws SQLException { return inner.getGeneratedKeys(); } public void close() throws SQLException { inner.close(); } public boolean execute(String a, int b) throws SQLException { return inner.execute(a, b); } public boolean execute(String a) throws SQLException { return inner.execute(a); } public boolean execute(String a, int[] b) throws SQLException { return inner.execute(a, b); } public boolean execute(String a, String[] b) throws SQLException { return inner.execute(a, b); } public Connection getConnection() throws SQLException { return inner.getConnection(); } public void cancel() throws SQLException { inner.cancel(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/FilterResultSet.java0000644000175000017500000003376010624366527024477 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.InputStream; import java.io.Reader; import java.lang.Object; import java.lang.String; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Map; public abstract class FilterResultSet implements ResultSet { protected ResultSet inner; public FilterResultSet(ResultSet inner) { this.inner = inner; } public FilterResultSet() {} public void setInner( ResultSet inner ) { this.inner = inner; } public ResultSet getInner() { return inner; } public ResultSetMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public void clearWarnings() throws SQLException { inner.clearWarnings(); } public boolean wasNull() throws SQLException { return inner.wasNull(); } public BigDecimal getBigDecimal(int a) throws SQLException { return inner.getBigDecimal(a); } public BigDecimal getBigDecimal(String a, int b) throws SQLException { return inner.getBigDecimal(a, b); } public BigDecimal getBigDecimal(int a, int b) throws SQLException { return inner.getBigDecimal(a, b); } public BigDecimal getBigDecimal(String a) throws SQLException { return inner.getBigDecimal(a); } public Timestamp getTimestamp(int a) throws SQLException { return inner.getTimestamp(a); } public Timestamp getTimestamp(String a) throws SQLException { return inner.getTimestamp(a); } public Timestamp getTimestamp(int a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public Timestamp getTimestamp(String a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public InputStream getAsciiStream(String a) throws SQLException { return inner.getAsciiStream(a); } public InputStream getAsciiStream(int a) throws SQLException { return inner.getAsciiStream(a); } public InputStream getUnicodeStream(String a) throws SQLException { return inner.getUnicodeStream(a); } public InputStream getUnicodeStream(int a) throws SQLException { return inner.getUnicodeStream(a); } public InputStream getBinaryStream(int a) throws SQLException { return inner.getBinaryStream(a); } public InputStream getBinaryStream(String a) throws SQLException { return inner.getBinaryStream(a); } public String getCursorName() throws SQLException { return inner.getCursorName(); } public Reader getCharacterStream(int a) throws SQLException { return inner.getCharacterStream(a); } public Reader getCharacterStream(String a) throws SQLException { return inner.getCharacterStream(a); } public boolean isBeforeFirst() throws SQLException { return inner.isBeforeFirst(); } public boolean isAfterLast() throws SQLException { return inner.isAfterLast(); } public boolean isFirst() throws SQLException { return inner.isFirst(); } public boolean isLast() throws SQLException { return inner.isLast(); } public void beforeFirst() throws SQLException { inner.beforeFirst(); } public void afterLast() throws SQLException { inner.afterLast(); } public boolean absolute(int a) throws SQLException { return inner.absolute(a); } public void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public int getFetchSize() throws SQLException { return inner.getFetchSize(); } public int getConcurrency() throws SQLException { return inner.getConcurrency(); } public boolean rowUpdated() throws SQLException { return inner.rowUpdated(); } public boolean rowInserted() throws SQLException { return inner.rowInserted(); } public boolean rowDeleted() throws SQLException { return inner.rowDeleted(); } public void updateNull(int a) throws SQLException { inner.updateNull(a); } public void updateNull(String a) throws SQLException { inner.updateNull(a); } public void updateBoolean(int a, boolean b) throws SQLException { inner.updateBoolean(a, b); } public void updateBoolean(String a, boolean b) throws SQLException { inner.updateBoolean(a, b); } public void updateByte(int a, byte b) throws SQLException { inner.updateByte(a, b); } public void updateByte(String a, byte b) throws SQLException { inner.updateByte(a, b); } public void updateShort(int a, short b) throws SQLException { inner.updateShort(a, b); } public void updateShort(String a, short b) throws SQLException { inner.updateShort(a, b); } public void updateInt(String a, int b) throws SQLException { inner.updateInt(a, b); } public void updateInt(int a, int b) throws SQLException { inner.updateInt(a, b); } public void updateLong(int a, long b) throws SQLException { inner.updateLong(a, b); } public void updateLong(String a, long b) throws SQLException { inner.updateLong(a, b); } public void updateFloat(String a, float b) throws SQLException { inner.updateFloat(a, b); } public void updateFloat(int a, float b) throws SQLException { inner.updateFloat(a, b); } public void updateDouble(String a, double b) throws SQLException { inner.updateDouble(a, b); } public void updateDouble(int a, double b) throws SQLException { inner.updateDouble(a, b); } public void updateBigDecimal(int a, BigDecimal b) throws SQLException { inner.updateBigDecimal(a, b); } public void updateBigDecimal(String a, BigDecimal b) throws SQLException { inner.updateBigDecimal(a, b); } public void updateString(String a, String b) throws SQLException { inner.updateString(a, b); } public void updateString(int a, String b) throws SQLException { inner.updateString(a, b); } public void updateBytes(int a, byte[] b) throws SQLException { inner.updateBytes(a, b); } public void updateBytes(String a, byte[] b) throws SQLException { inner.updateBytes(a, b); } public void updateDate(String a, Date b) throws SQLException { inner.updateDate(a, b); } public void updateDate(int a, Date b) throws SQLException { inner.updateDate(a, b); } public void updateTimestamp(int a, Timestamp b) throws SQLException { inner.updateTimestamp(a, b); } public void updateTimestamp(String a, Timestamp b) throws SQLException { inner.updateTimestamp(a, b); } public void updateAsciiStream(String a, InputStream b, int c) throws SQLException { inner.updateAsciiStream(a, b, c); } public void updateAsciiStream(int a, InputStream b, int c) throws SQLException { inner.updateAsciiStream(a, b, c); } public void updateBinaryStream(int a, InputStream b, int c) throws SQLException { inner.updateBinaryStream(a, b, c); } public void updateBinaryStream(String a, InputStream b, int c) throws SQLException { inner.updateBinaryStream(a, b, c); } public void updateCharacterStream(int a, Reader b, int c) throws SQLException { inner.updateCharacterStream(a, b, c); } public void updateCharacterStream(String a, Reader b, int c) throws SQLException { inner.updateCharacterStream(a, b, c); } public void updateObject(String a, Object b) throws SQLException { inner.updateObject(a, b); } public void updateObject(int a, Object b) throws SQLException { inner.updateObject(a, b); } public void updateObject(int a, Object b, int c) throws SQLException { inner.updateObject(a, b, c); } public void updateObject(String a, Object b, int c) throws SQLException { inner.updateObject(a, b, c); } public void insertRow() throws SQLException { inner.insertRow(); } public void updateRow() throws SQLException { inner.updateRow(); } public void deleteRow() throws SQLException { inner.deleteRow(); } public void refreshRow() throws SQLException { inner.refreshRow(); } public void cancelRowUpdates() throws SQLException { inner.cancelRowUpdates(); } public void moveToInsertRow() throws SQLException { inner.moveToInsertRow(); } public void moveToCurrentRow() throws SQLException { inner.moveToCurrentRow(); } public Statement getStatement() throws SQLException { return inner.getStatement(); } public Blob getBlob(String a) throws SQLException { return inner.getBlob(a); } public Blob getBlob(int a) throws SQLException { return inner.getBlob(a); } public Clob getClob(String a) throws SQLException { return inner.getClob(a); } public Clob getClob(int a) throws SQLException { return inner.getClob(a); } public void updateRef(String a, Ref b) throws SQLException { inner.updateRef(a, b); } public void updateRef(int a, Ref b) throws SQLException { inner.updateRef(a, b); } public void updateBlob(String a, Blob b) throws SQLException { inner.updateBlob(a, b); } public void updateBlob(int a, Blob b) throws SQLException { inner.updateBlob(a, b); } public void updateClob(int a, Clob b) throws SQLException { inner.updateClob(a, b); } public void updateClob(String a, Clob b) throws SQLException { inner.updateClob(a, b); } public void updateArray(String a, Array b) throws SQLException { inner.updateArray(a, b); } public void updateArray(int a, Array b) throws SQLException { inner.updateArray(a, b); } public Object getObject(int a) throws SQLException { return inner.getObject(a); } public Object getObject(String a, Map b) throws SQLException { return inner.getObject(a, b); } public Object getObject(String a) throws SQLException { return inner.getObject(a); } public Object getObject(int a, Map b) throws SQLException { return inner.getObject(a, b); } public boolean getBoolean(int a) throws SQLException { return inner.getBoolean(a); } public boolean getBoolean(String a) throws SQLException { return inner.getBoolean(a); } public byte getByte(String a) throws SQLException { return inner.getByte(a); } public byte getByte(int a) throws SQLException { return inner.getByte(a); } public short getShort(String a) throws SQLException { return inner.getShort(a); } public short getShort(int a) throws SQLException { return inner.getShort(a); } public int getInt(String a) throws SQLException { return inner.getInt(a); } public int getInt(int a) throws SQLException { return inner.getInt(a); } public long getLong(int a) throws SQLException { return inner.getLong(a); } public long getLong(String a) throws SQLException { return inner.getLong(a); } public float getFloat(String a) throws SQLException { return inner.getFloat(a); } public float getFloat(int a) throws SQLException { return inner.getFloat(a); } public double getDouble(int a) throws SQLException { return inner.getDouble(a); } public double getDouble(String a) throws SQLException { return inner.getDouble(a); } public byte[] getBytes(String a) throws SQLException { return inner.getBytes(a); } public byte[] getBytes(int a) throws SQLException { return inner.getBytes(a); } public boolean next() throws SQLException { return inner.next(); } public URL getURL(int a) throws SQLException { return inner.getURL(a); } public URL getURL(String a) throws SQLException { return inner.getURL(a); } public int getType() throws SQLException { return inner.getType(); } public boolean previous() throws SQLException { return inner.previous(); } public void close() throws SQLException { inner.close(); } public String getString(String a) throws SQLException { return inner.getString(a); } public String getString(int a) throws SQLException { return inner.getString(a); } public Ref getRef(String a) throws SQLException { return inner.getRef(a); } public Ref getRef(int a) throws SQLException { return inner.getRef(a); } public Time getTime(int a, Calendar b) throws SQLException { return inner.getTime(a, b); } public Time getTime(String a) throws SQLException { return inner.getTime(a); } public Time getTime(int a) throws SQLException { return inner.getTime(a); } public Time getTime(String a, Calendar b) throws SQLException { return inner.getTime(a, b); } public Date getDate(String a) throws SQLException { return inner.getDate(a); } public Date getDate(int a) throws SQLException { return inner.getDate(a); } public Date getDate(int a, Calendar b) throws SQLException { return inner.getDate(a, b); } public Date getDate(String a, Calendar b) throws SQLException { return inner.getDate(a, b); } public boolean first() throws SQLException { return inner.first(); } public boolean last() throws SQLException { return inner.last(); } public Array getArray(String a) throws SQLException { return inner.getArray(a); } public Array getArray(int a) throws SQLException { return inner.getArray(a); } public boolean relative(int a) throws SQLException { return inner.relative(a); } public void updateTime(String a, Time b) throws SQLException { inner.updateTime(a, b); } public void updateTime(int a, Time b) throws SQLException { inner.updateTime(a, b); } public int findColumn(String a) throws SQLException { return inner.findColumn(a); } public int getRow() throws SQLException { return inner.getRow(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/FilterStatement.java0000644000175000017500000001113410624366530024472 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.lang.String; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; public abstract class FilterStatement implements Statement { protected Statement inner; public FilterStatement(Statement inner) { this.inner = inner; } public FilterStatement() {} public void setInner( Statement inner ) { this.inner = inner; } public Statement getInner() { return inner; } public SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public void clearWarnings() throws SQLException { inner.clearWarnings(); } public void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public int getFetchSize() throws SQLException { return inner.getFetchSize(); } public int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public ResultSet executeQuery(String a) throws SQLException { return inner.executeQuery(a); } public int executeUpdate(String a, int b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a, String[] b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a, int[] b) throws SQLException { return inner.executeUpdate(a, b); } public int executeUpdate(String a) throws SQLException { return inner.executeUpdate(a); } public int getMaxFieldSize() throws SQLException { return inner.getMaxFieldSize(); } public void setMaxFieldSize(int a) throws SQLException { inner.setMaxFieldSize(a); } public int getMaxRows() throws SQLException { return inner.getMaxRows(); } public void setMaxRows(int a) throws SQLException { inner.setMaxRows(a); } public void setEscapeProcessing(boolean a) throws SQLException { inner.setEscapeProcessing(a); } public int getQueryTimeout() throws SQLException { return inner.getQueryTimeout(); } public void setQueryTimeout(int a) throws SQLException { inner.setQueryTimeout(a); } public void setCursorName(String a) throws SQLException { inner.setCursorName(a); } public ResultSet getResultSet() throws SQLException { return inner.getResultSet(); } public int getUpdateCount() throws SQLException { return inner.getUpdateCount(); } public boolean getMoreResults() throws SQLException { return inner.getMoreResults(); } public boolean getMoreResults(int a) throws SQLException { return inner.getMoreResults(a); } public int getResultSetConcurrency() throws SQLException { return inner.getResultSetConcurrency(); } public int getResultSetType() throws SQLException { return inner.getResultSetType(); } public void addBatch(String a) throws SQLException { inner.addBatch(a); } public void clearBatch() throws SQLException { inner.clearBatch(); } public int[] executeBatch() throws SQLException { return inner.executeBatch(); } public ResultSet getGeneratedKeys() throws SQLException { return inner.getGeneratedKeys(); } public void close() throws SQLException { inner.close(); } public boolean execute(String a, int b) throws SQLException { return inner.execute(a, b); } public boolean execute(String a) throws SQLException { return inner.execute(a); } public boolean execute(String a, int[] b) throws SQLException { return inner.execute(a, b); } public boolean execute(String a, String[] b) throws SQLException { return inner.execute(a, b); } public Connection getConnection() throws SQLException { return inner.getConnection(); } public void cancel() throws SQLException { inner.cancel(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/RecreatePackage.java0000644000175000017500000000522710624366530024374 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.*; import java.sql.*; import java.lang.reflect.*; import com.mchange.v2.codegen.intfc.*; import com.mchange.v1.lang.ClassUtils; import javax.sql.DataSource; public final class RecreatePackage { final static Class[] intfcs = new Class[] { Connection.class, ResultSet.class, DatabaseMetaData.class, Statement.class, PreparedStatement.class, CallableStatement.class, DataSource.class }; public static void main( String[] argv ) { try { DelegatorGenerator dg = new DelegatorGenerator(); String thisClassName = RecreatePackage.class.getName(); String pkg = thisClassName.substring(0, thisClassName.lastIndexOf('.')); for (int i = 0; i < intfcs.length; ++i) { Class intfcl = intfcs[i]; String sin = ClassUtils.simpleClassName( intfcl ); String sgenclass1 = "Filter" + sin; String sgenclass2 = "SynchronizedFilter" + sin; Writer w = null; try { w = new BufferedWriter( new FileWriter( sgenclass1 + ".java" ) ); dg.setMethodModifiers( Modifier.PUBLIC ); dg.writeDelegator( intfcl, pkg + '.' + sgenclass1, w ); System.err.println( sgenclass1 ); } finally { try { if (w != null) w.close(); } catch (Exception e) { e.printStackTrace(); } } try { w = new BufferedWriter( new FileWriter( sgenclass2 + ".java" ) ); dg.setMethodModifiers( Modifier.PUBLIC | Modifier.SYNCHRONIZED ); dg.writeDelegator( intfcl, pkg + '.' + sgenclass2, w ); System.err.println( sgenclass2 ); } finally { try { if (w != null) w.close(); } catch (Exception e) { e.printStackTrace(); } } } } catch ( Exception e ) { e.printStackTrace(); } } private RecreatePackage() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/SynchronizedFilterCallableStatement.java0000644000175000017500000004317110624366527030526 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.InputStream; import java.io.Reader; import java.lang.Object; import java.lang.String; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Connection; import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Map; public abstract class SynchronizedFilterCallableStatement implements CallableStatement { protected CallableStatement inner; public SynchronizedFilterCallableStatement(CallableStatement inner) { this.inner = inner; } public SynchronizedFilterCallableStatement() {} public synchronized void setInner( CallableStatement inner ) { this.inner = inner; } public synchronized CallableStatement getInner() { return inner; } public synchronized boolean wasNull() throws SQLException { return inner.wasNull(); } public synchronized BigDecimal getBigDecimal(int a, int b) throws SQLException { return inner.getBigDecimal(a, b); } public synchronized BigDecimal getBigDecimal(int a) throws SQLException { return inner.getBigDecimal(a); } public synchronized BigDecimal getBigDecimal(String a) throws SQLException { return inner.getBigDecimal(a); } public synchronized Timestamp getTimestamp(String a) throws SQLException { return inner.getTimestamp(a); } public synchronized Timestamp getTimestamp(String a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public synchronized Timestamp getTimestamp(int a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public synchronized Timestamp getTimestamp(int a) throws SQLException { return inner.getTimestamp(a); } public synchronized Blob getBlob(String a) throws SQLException { return inner.getBlob(a); } public synchronized Blob getBlob(int a) throws SQLException { return inner.getBlob(a); } public synchronized Clob getClob(String a) throws SQLException { return inner.getClob(a); } public synchronized Clob getClob(int a) throws SQLException { return inner.getClob(a); } public synchronized void setNull(String a, int b, String c) throws SQLException { inner.setNull(a, b, c); } public synchronized void setNull(String a, int b) throws SQLException { inner.setNull(a, b); } public synchronized void setBigDecimal(String a, BigDecimal b) throws SQLException { inner.setBigDecimal(a, b); } public synchronized void setBytes(String a, byte[] b) throws SQLException { inner.setBytes(a, b); } public synchronized void setTimestamp(String a, Timestamp b, Calendar c) throws SQLException { inner.setTimestamp(a, b, c); } public synchronized void setTimestamp(String a, Timestamp b) throws SQLException { inner.setTimestamp(a, b); } public synchronized void setAsciiStream(String a, InputStream b, int c) throws SQLException { inner.setAsciiStream(a, b, c); } public synchronized void setBinaryStream(String a, InputStream b, int c) throws SQLException { inner.setBinaryStream(a, b, c); } public synchronized void setObject(String a, Object b) throws SQLException { inner.setObject(a, b); } public synchronized void setObject(String a, Object b, int c, int d) throws SQLException { inner.setObject(a, b, c, d); } public synchronized void setObject(String a, Object b, int c) throws SQLException { inner.setObject(a, b, c); } public synchronized void setCharacterStream(String a, Reader b, int c) throws SQLException { inner.setCharacterStream(a, b, c); } public synchronized void registerOutParameter(String a, int b) throws SQLException { inner.registerOutParameter(a, b); } public synchronized void registerOutParameter(int a, int b) throws SQLException { inner.registerOutParameter(a, b); } public synchronized void registerOutParameter(int a, int b, int c) throws SQLException { inner.registerOutParameter(a, b, c); } public synchronized void registerOutParameter(int a, int b, String c) throws SQLException { inner.registerOutParameter(a, b, c); } public synchronized void registerOutParameter(String a, int b, int c) throws SQLException { inner.registerOutParameter(a, b, c); } public synchronized void registerOutParameter(String a, int b, String c) throws SQLException { inner.registerOutParameter(a, b, c); } public synchronized Object getObject(String a, Map b) throws SQLException { return inner.getObject(a, b); } public synchronized Object getObject(int a, Map b) throws SQLException { return inner.getObject(a, b); } public synchronized Object getObject(int a) throws SQLException { return inner.getObject(a); } public synchronized Object getObject(String a) throws SQLException { return inner.getObject(a); } public synchronized boolean getBoolean(int a) throws SQLException { return inner.getBoolean(a); } public synchronized boolean getBoolean(String a) throws SQLException { return inner.getBoolean(a); } public synchronized byte getByte(String a) throws SQLException { return inner.getByte(a); } public synchronized byte getByte(int a) throws SQLException { return inner.getByte(a); } public synchronized short getShort(int a) throws SQLException { return inner.getShort(a); } public synchronized short getShort(String a) throws SQLException { return inner.getShort(a); } public synchronized int getInt(String a) throws SQLException { return inner.getInt(a); } public synchronized int getInt(int a) throws SQLException { return inner.getInt(a); } public synchronized long getLong(int a) throws SQLException { return inner.getLong(a); } public synchronized long getLong(String a) throws SQLException { return inner.getLong(a); } public synchronized float getFloat(String a) throws SQLException { return inner.getFloat(a); } public synchronized float getFloat(int a) throws SQLException { return inner.getFloat(a); } public synchronized double getDouble(String a) throws SQLException { return inner.getDouble(a); } public synchronized double getDouble(int a) throws SQLException { return inner.getDouble(a); } public synchronized byte[] getBytes(int a) throws SQLException { return inner.getBytes(a); } public synchronized byte[] getBytes(String a) throws SQLException { return inner.getBytes(a); } public synchronized URL getURL(String a) throws SQLException { return inner.getURL(a); } public synchronized URL getURL(int a) throws SQLException { return inner.getURL(a); } public synchronized void setBoolean(String a, boolean b) throws SQLException { inner.setBoolean(a, b); } public synchronized void setByte(String a, byte b) throws SQLException { inner.setByte(a, b); } public synchronized void setShort(String a, short b) throws SQLException { inner.setShort(a, b); } public synchronized void setInt(String a, int b) throws SQLException { inner.setInt(a, b); } public synchronized void setLong(String a, long b) throws SQLException { inner.setLong(a, b); } public synchronized void setFloat(String a, float b) throws SQLException { inner.setFloat(a, b); } public synchronized void setDouble(String a, double b) throws SQLException { inner.setDouble(a, b); } public synchronized String getString(String a) throws SQLException { return inner.getString(a); } public synchronized String getString(int a) throws SQLException { return inner.getString(a); } public synchronized Ref getRef(int a) throws SQLException { return inner.getRef(a); } public synchronized Ref getRef(String a) throws SQLException { return inner.getRef(a); } public synchronized void setURL(String a, URL b) throws SQLException { inner.setURL(a, b); } public synchronized void setTime(String a, Time b) throws SQLException { inner.setTime(a, b); } public synchronized void setTime(String a, Time b, Calendar c) throws SQLException { inner.setTime(a, b, c); } public synchronized Time getTime(int a, Calendar b) throws SQLException { return inner.getTime(a, b); } public synchronized Time getTime(String a) throws SQLException { return inner.getTime(a); } public synchronized Time getTime(int a) throws SQLException { return inner.getTime(a); } public synchronized Time getTime(String a, Calendar b) throws SQLException { return inner.getTime(a, b); } public synchronized Date getDate(int a, Calendar b) throws SQLException { return inner.getDate(a, b); } public synchronized Date getDate(String a) throws SQLException { return inner.getDate(a); } public synchronized Date getDate(int a) throws SQLException { return inner.getDate(a); } public synchronized Date getDate(String a, Calendar b) throws SQLException { return inner.getDate(a, b); } public synchronized void setString(String a, String b) throws SQLException { inner.setString(a, b); } public synchronized Array getArray(int a) throws SQLException { return inner.getArray(a); } public synchronized Array getArray(String a) throws SQLException { return inner.getArray(a); } public synchronized void setDate(String a, Date b, Calendar c) throws SQLException { inner.setDate(a, b, c); } public synchronized void setDate(String a, Date b) throws SQLException { inner.setDate(a, b); } public synchronized ResultSetMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public synchronized ResultSet executeQuery() throws SQLException { return inner.executeQuery(); } public synchronized int executeUpdate() throws SQLException { return inner.executeUpdate(); } public synchronized void addBatch() throws SQLException { inner.addBatch(); } public synchronized void setNull(int a, int b, String c) throws SQLException { inner.setNull(a, b, c); } public synchronized void setNull(int a, int b) throws SQLException { inner.setNull(a, b); } public synchronized void setBigDecimal(int a, BigDecimal b) throws SQLException { inner.setBigDecimal(a, b); } public synchronized void setBytes(int a, byte[] b) throws SQLException { inner.setBytes(a, b); } public synchronized void setTimestamp(int a, Timestamp b, Calendar c) throws SQLException { inner.setTimestamp(a, b, c); } public synchronized void setTimestamp(int a, Timestamp b) throws SQLException { inner.setTimestamp(a, b); } public synchronized void setAsciiStream(int a, InputStream b, int c) throws SQLException { inner.setAsciiStream(a, b, c); } public synchronized void setUnicodeStream(int a, InputStream b, int c) throws SQLException { inner.setUnicodeStream(a, b, c); } public synchronized void setBinaryStream(int a, InputStream b, int c) throws SQLException { inner.setBinaryStream(a, b, c); } public synchronized void clearParameters() throws SQLException { inner.clearParameters(); } public synchronized void setObject(int a, Object b) throws SQLException { inner.setObject(a, b); } public synchronized void setObject(int a, Object b, int c, int d) throws SQLException { inner.setObject(a, b, c, d); } public synchronized void setObject(int a, Object b, int c) throws SQLException { inner.setObject(a, b, c); } public synchronized void setCharacterStream(int a, Reader b, int c) throws SQLException { inner.setCharacterStream(a, b, c); } public synchronized void setRef(int a, Ref b) throws SQLException { inner.setRef(a, b); } public synchronized void setBlob(int a, Blob b) throws SQLException { inner.setBlob(a, b); } public synchronized void setClob(int a, Clob b) throws SQLException { inner.setClob(a, b); } public synchronized void setArray(int a, Array b) throws SQLException { inner.setArray(a, b); } public synchronized ParameterMetaData getParameterMetaData() throws SQLException { return inner.getParameterMetaData(); } public synchronized void setBoolean(int a, boolean b) throws SQLException { inner.setBoolean(a, b); } public synchronized void setByte(int a, byte b) throws SQLException { inner.setByte(a, b); } public synchronized void setShort(int a, short b) throws SQLException { inner.setShort(a, b); } public synchronized void setInt(int a, int b) throws SQLException { inner.setInt(a, b); } public synchronized void setLong(int a, long b) throws SQLException { inner.setLong(a, b); } public synchronized void setFloat(int a, float b) throws SQLException { inner.setFloat(a, b); } public synchronized void setDouble(int a, double b) throws SQLException { inner.setDouble(a, b); } public synchronized void setURL(int a, URL b) throws SQLException { inner.setURL(a, b); } public synchronized void setTime(int a, Time b) throws SQLException { inner.setTime(a, b); } public synchronized void setTime(int a, Time b, Calendar c) throws SQLException { inner.setTime(a, b, c); } public synchronized boolean execute() throws SQLException { return inner.execute(); } public synchronized void setString(int a, String b) throws SQLException { inner.setString(a, b); } public synchronized void setDate(int a, Date b, Calendar c) throws SQLException { inner.setDate(a, b, c); } public synchronized void setDate(int a, Date b) throws SQLException { inner.setDate(a, b); } public synchronized SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public synchronized void clearWarnings() throws SQLException { inner.clearWarnings(); } public synchronized void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public synchronized int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public synchronized void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public synchronized int getFetchSize() throws SQLException { return inner.getFetchSize(); } public synchronized int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public synchronized ResultSet executeQuery(String a) throws SQLException { return inner.executeQuery(a); } public synchronized int executeUpdate(String a, int b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a, String[] b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a, int[] b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a) throws SQLException { return inner.executeUpdate(a); } public synchronized int getMaxFieldSize() throws SQLException { return inner.getMaxFieldSize(); } public synchronized void setMaxFieldSize(int a) throws SQLException { inner.setMaxFieldSize(a); } public synchronized int getMaxRows() throws SQLException { return inner.getMaxRows(); } public synchronized void setMaxRows(int a) throws SQLException { inner.setMaxRows(a); } public synchronized void setEscapeProcessing(boolean a) throws SQLException { inner.setEscapeProcessing(a); } public synchronized int getQueryTimeout() throws SQLException { return inner.getQueryTimeout(); } public synchronized void setQueryTimeout(int a) throws SQLException { inner.setQueryTimeout(a); } public synchronized void setCursorName(String a) throws SQLException { inner.setCursorName(a); } public synchronized ResultSet getResultSet() throws SQLException { return inner.getResultSet(); } public synchronized int getUpdateCount() throws SQLException { return inner.getUpdateCount(); } public synchronized boolean getMoreResults() throws SQLException { return inner.getMoreResults(); } public synchronized boolean getMoreResults(int a) throws SQLException { return inner.getMoreResults(a); } public synchronized int getResultSetConcurrency() throws SQLException { return inner.getResultSetConcurrency(); } public synchronized int getResultSetType() throws SQLException { return inner.getResultSetType(); } public synchronized void addBatch(String a) throws SQLException { inner.addBatch(a); } public synchronized void clearBatch() throws SQLException { inner.clearBatch(); } public synchronized int[] executeBatch() throws SQLException { return inner.executeBatch(); } public synchronized ResultSet getGeneratedKeys() throws SQLException { return inner.getGeneratedKeys(); } public synchronized void close() throws SQLException { inner.close(); } public synchronized boolean execute(String a, int b) throws SQLException { return inner.execute(a, b); } public synchronized boolean execute(String a) throws SQLException { return inner.execute(a); } public synchronized boolean execute(String a, int[] b) throws SQLException { return inner.execute(a, b); } public synchronized boolean execute(String a, String[] b) throws SQLException { return inner.execute(a, b); } public synchronized Connection getConnection() throws SQLException { return inner.getConnection(); } public synchronized void cancel() throws SQLException { inner.cancel(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/SynchronizedFilterConnection.java0000644000175000017500000001263710624366527027244 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.lang.String; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Savepoint; import java.sql.Statement; import java.util.Map; public abstract class SynchronizedFilterConnection implements Connection { protected Connection inner; public SynchronizedFilterConnection(Connection inner) { this.inner = inner; } public SynchronizedFilterConnection() {} public synchronized void setInner( Connection inner ) { this.inner = inner; } public synchronized Connection getInner() { return inner; } public synchronized Statement createStatement(int a, int b, int c) throws SQLException { return inner.createStatement(a, b, c); } public synchronized Statement createStatement(int a, int b) throws SQLException { return inner.createStatement(a, b); } public synchronized Statement createStatement() throws SQLException { return inner.createStatement(); } public synchronized PreparedStatement prepareStatement(String a, String[] b) throws SQLException { return inner.prepareStatement(a, b); } public synchronized PreparedStatement prepareStatement(String a) throws SQLException { return inner.prepareStatement(a); } public synchronized PreparedStatement prepareStatement(String a, int b, int c) throws SQLException { return inner.prepareStatement(a, b, c); } public synchronized PreparedStatement prepareStatement(String a, int b, int c, int d) throws SQLException { return inner.prepareStatement(a, b, c, d); } public synchronized PreparedStatement prepareStatement(String a, int b) throws SQLException { return inner.prepareStatement(a, b); } public synchronized PreparedStatement prepareStatement(String a, int[] b) throws SQLException { return inner.prepareStatement(a, b); } public synchronized CallableStatement prepareCall(String a, int b, int c, int d) throws SQLException { return inner.prepareCall(a, b, c, d); } public synchronized CallableStatement prepareCall(String a, int b, int c) throws SQLException { return inner.prepareCall(a, b, c); } public synchronized CallableStatement prepareCall(String a) throws SQLException { return inner.prepareCall(a); } public synchronized String nativeSQL(String a) throws SQLException { return inner.nativeSQL(a); } public synchronized void setAutoCommit(boolean a) throws SQLException { inner.setAutoCommit(a); } public synchronized boolean getAutoCommit() throws SQLException { return inner.getAutoCommit(); } public synchronized void commit() throws SQLException { inner.commit(); } public synchronized void rollback(Savepoint a) throws SQLException { inner.rollback(a); } public synchronized void rollback() throws SQLException { inner.rollback(); } public synchronized DatabaseMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public synchronized void setCatalog(String a) throws SQLException { inner.setCatalog(a); } public synchronized String getCatalog() throws SQLException { return inner.getCatalog(); } public synchronized void setTransactionIsolation(int a) throws SQLException { inner.setTransactionIsolation(a); } public synchronized int getTransactionIsolation() throws SQLException { return inner.getTransactionIsolation(); } public synchronized SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public synchronized void clearWarnings() throws SQLException { inner.clearWarnings(); } public synchronized Map getTypeMap() throws SQLException { return inner.getTypeMap(); } public synchronized void setTypeMap(Map a) throws SQLException { inner.setTypeMap(a); } public synchronized void setHoldability(int a) throws SQLException { inner.setHoldability(a); } public synchronized int getHoldability() throws SQLException { return inner.getHoldability(); } public synchronized Savepoint setSavepoint() throws SQLException { return inner.setSavepoint(); } public synchronized Savepoint setSavepoint(String a) throws SQLException { return inner.setSavepoint(a); } public synchronized void releaseSavepoint(Savepoint a) throws SQLException { inner.releaseSavepoint(a); } public synchronized void setReadOnly(boolean a) throws SQLException { inner.setReadOnly(a); } public synchronized boolean isReadOnly() throws SQLException { return inner.isReadOnly(); } public synchronized void close() throws SQLException { inner.close(); } public synchronized boolean isClosed() throws SQLException { return inner.isClosed(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/SynchronizedFilterDatabaseMetaData.java0000644000175000017500000005322110624366527030244 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.lang.String; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; public abstract class SynchronizedFilterDatabaseMetaData implements DatabaseMetaData { protected DatabaseMetaData inner; public SynchronizedFilterDatabaseMetaData(DatabaseMetaData inner) { this.inner = inner; } public SynchronizedFilterDatabaseMetaData() {} public synchronized void setInner( DatabaseMetaData inner ) { this.inner = inner; } public synchronized DatabaseMetaData getInner() { return inner; } public synchronized boolean allProceduresAreCallable() throws SQLException { return inner.allProceduresAreCallable(); } public synchronized boolean allTablesAreSelectable() throws SQLException { return inner.allTablesAreSelectable(); } public synchronized boolean nullsAreSortedHigh() throws SQLException { return inner.nullsAreSortedHigh(); } public synchronized boolean nullsAreSortedLow() throws SQLException { return inner.nullsAreSortedLow(); } public synchronized boolean nullsAreSortedAtStart() throws SQLException { return inner.nullsAreSortedAtStart(); } public synchronized boolean nullsAreSortedAtEnd() throws SQLException { return inner.nullsAreSortedAtEnd(); } public synchronized String getDatabaseProductName() throws SQLException { return inner.getDatabaseProductName(); } public synchronized String getDatabaseProductVersion() throws SQLException { return inner.getDatabaseProductVersion(); } public synchronized String getDriverName() throws SQLException { return inner.getDriverName(); } public synchronized String getDriverVersion() throws SQLException { return inner.getDriverVersion(); } public synchronized int getDriverMajorVersion() { return inner.getDriverMajorVersion(); } public synchronized int getDriverMinorVersion() { return inner.getDriverMinorVersion(); } public synchronized boolean usesLocalFiles() throws SQLException { return inner.usesLocalFiles(); } public synchronized boolean usesLocalFilePerTable() throws SQLException { return inner.usesLocalFilePerTable(); } public synchronized boolean supportsMixedCaseIdentifiers() throws SQLException { return inner.supportsMixedCaseIdentifiers(); } public synchronized boolean storesUpperCaseIdentifiers() throws SQLException { return inner.storesUpperCaseIdentifiers(); } public synchronized boolean storesLowerCaseIdentifiers() throws SQLException { return inner.storesLowerCaseIdentifiers(); } public synchronized boolean storesMixedCaseIdentifiers() throws SQLException { return inner.storesMixedCaseIdentifiers(); } public synchronized boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { return inner.supportsMixedCaseQuotedIdentifiers(); } public synchronized boolean storesUpperCaseQuotedIdentifiers() throws SQLException { return inner.storesUpperCaseQuotedIdentifiers(); } public synchronized boolean storesLowerCaseQuotedIdentifiers() throws SQLException { return inner.storesLowerCaseQuotedIdentifiers(); } public synchronized boolean storesMixedCaseQuotedIdentifiers() throws SQLException { return inner.storesMixedCaseQuotedIdentifiers(); } public synchronized String getIdentifierQuoteString() throws SQLException { return inner.getIdentifierQuoteString(); } public synchronized String getSQLKeywords() throws SQLException { return inner.getSQLKeywords(); } public synchronized String getNumericFunctions() throws SQLException { return inner.getNumericFunctions(); } public synchronized String getStringFunctions() throws SQLException { return inner.getStringFunctions(); } public synchronized String getSystemFunctions() throws SQLException { return inner.getSystemFunctions(); } public synchronized String getTimeDateFunctions() throws SQLException { return inner.getTimeDateFunctions(); } public synchronized String getSearchStringEscape() throws SQLException { return inner.getSearchStringEscape(); } public synchronized String getExtraNameCharacters() throws SQLException { return inner.getExtraNameCharacters(); } public synchronized boolean supportsAlterTableWithAddColumn() throws SQLException { return inner.supportsAlterTableWithAddColumn(); } public synchronized boolean supportsAlterTableWithDropColumn() throws SQLException { return inner.supportsAlterTableWithDropColumn(); } public synchronized boolean supportsColumnAliasing() throws SQLException { return inner.supportsColumnAliasing(); } public synchronized boolean nullPlusNonNullIsNull() throws SQLException { return inner.nullPlusNonNullIsNull(); } public synchronized boolean supportsConvert() throws SQLException { return inner.supportsConvert(); } public synchronized boolean supportsConvert(int a, int b) throws SQLException { return inner.supportsConvert(a, b); } public synchronized boolean supportsTableCorrelationNames() throws SQLException { return inner.supportsTableCorrelationNames(); } public synchronized boolean supportsDifferentTableCorrelationNames() throws SQLException { return inner.supportsDifferentTableCorrelationNames(); } public synchronized boolean supportsExpressionsInOrderBy() throws SQLException { return inner.supportsExpressionsInOrderBy(); } public synchronized boolean supportsOrderByUnrelated() throws SQLException { return inner.supportsOrderByUnrelated(); } public synchronized boolean supportsGroupBy() throws SQLException { return inner.supportsGroupBy(); } public synchronized boolean supportsGroupByUnrelated() throws SQLException { return inner.supportsGroupByUnrelated(); } public synchronized boolean supportsGroupByBeyondSelect() throws SQLException { return inner.supportsGroupByBeyondSelect(); } public synchronized boolean supportsLikeEscapeClause() throws SQLException { return inner.supportsLikeEscapeClause(); } public synchronized boolean supportsMultipleResultSets() throws SQLException { return inner.supportsMultipleResultSets(); } public synchronized boolean supportsMultipleTransactions() throws SQLException { return inner.supportsMultipleTransactions(); } public synchronized boolean supportsNonNullableColumns() throws SQLException { return inner.supportsNonNullableColumns(); } public synchronized boolean supportsMinimumSQLGrammar() throws SQLException { return inner.supportsMinimumSQLGrammar(); } public synchronized boolean supportsCoreSQLGrammar() throws SQLException { return inner.supportsCoreSQLGrammar(); } public synchronized boolean supportsExtendedSQLGrammar() throws SQLException { return inner.supportsExtendedSQLGrammar(); } public synchronized boolean supportsANSI92EntryLevelSQL() throws SQLException { return inner.supportsANSI92EntryLevelSQL(); } public synchronized boolean supportsANSI92IntermediateSQL() throws SQLException { return inner.supportsANSI92IntermediateSQL(); } public synchronized boolean supportsANSI92FullSQL() throws SQLException { return inner.supportsANSI92FullSQL(); } public synchronized boolean supportsIntegrityEnhancementFacility() throws SQLException { return inner.supportsIntegrityEnhancementFacility(); } public synchronized boolean supportsOuterJoins() throws SQLException { return inner.supportsOuterJoins(); } public synchronized boolean supportsFullOuterJoins() throws SQLException { return inner.supportsFullOuterJoins(); } public synchronized boolean supportsLimitedOuterJoins() throws SQLException { return inner.supportsLimitedOuterJoins(); } public synchronized String getSchemaTerm() throws SQLException { return inner.getSchemaTerm(); } public synchronized String getProcedureTerm() throws SQLException { return inner.getProcedureTerm(); } public synchronized String getCatalogTerm() throws SQLException { return inner.getCatalogTerm(); } public synchronized boolean isCatalogAtStart() throws SQLException { return inner.isCatalogAtStart(); } public synchronized String getCatalogSeparator() throws SQLException { return inner.getCatalogSeparator(); } public synchronized boolean supportsSchemasInDataManipulation() throws SQLException { return inner.supportsSchemasInDataManipulation(); } public synchronized boolean supportsSchemasInProcedureCalls() throws SQLException { return inner.supportsSchemasInProcedureCalls(); } public synchronized boolean supportsSchemasInTableDefinitions() throws SQLException { return inner.supportsSchemasInTableDefinitions(); } public synchronized boolean supportsSchemasInIndexDefinitions() throws SQLException { return inner.supportsSchemasInIndexDefinitions(); } public synchronized boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { return inner.supportsSchemasInPrivilegeDefinitions(); } public synchronized boolean supportsCatalogsInDataManipulation() throws SQLException { return inner.supportsCatalogsInDataManipulation(); } public synchronized boolean supportsCatalogsInProcedureCalls() throws SQLException { return inner.supportsCatalogsInProcedureCalls(); } public synchronized boolean supportsCatalogsInTableDefinitions() throws SQLException { return inner.supportsCatalogsInTableDefinitions(); } public synchronized boolean supportsCatalogsInIndexDefinitions() throws SQLException { return inner.supportsCatalogsInIndexDefinitions(); } public synchronized boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { return inner.supportsCatalogsInPrivilegeDefinitions(); } public synchronized boolean supportsPositionedDelete() throws SQLException { return inner.supportsPositionedDelete(); } public synchronized boolean supportsPositionedUpdate() throws SQLException { return inner.supportsPositionedUpdate(); } public synchronized boolean supportsSelectForUpdate() throws SQLException { return inner.supportsSelectForUpdate(); } public synchronized boolean supportsStoredProcedures() throws SQLException { return inner.supportsStoredProcedures(); } public synchronized boolean supportsSubqueriesInComparisons() throws SQLException { return inner.supportsSubqueriesInComparisons(); } public synchronized boolean supportsSubqueriesInExists() throws SQLException { return inner.supportsSubqueriesInExists(); } public synchronized boolean supportsSubqueriesInIns() throws SQLException { return inner.supportsSubqueriesInIns(); } public synchronized boolean supportsSubqueriesInQuantifieds() throws SQLException { return inner.supportsSubqueriesInQuantifieds(); } public synchronized boolean supportsCorrelatedSubqueries() throws SQLException { return inner.supportsCorrelatedSubqueries(); } public synchronized boolean supportsUnion() throws SQLException { return inner.supportsUnion(); } public synchronized boolean supportsUnionAll() throws SQLException { return inner.supportsUnionAll(); } public synchronized boolean supportsOpenCursorsAcrossCommit() throws SQLException { return inner.supportsOpenCursorsAcrossCommit(); } public synchronized boolean supportsOpenCursorsAcrossRollback() throws SQLException { return inner.supportsOpenCursorsAcrossRollback(); } public synchronized boolean supportsOpenStatementsAcrossCommit() throws SQLException { return inner.supportsOpenStatementsAcrossCommit(); } public synchronized boolean supportsOpenStatementsAcrossRollback() throws SQLException { return inner.supportsOpenStatementsAcrossRollback(); } public synchronized int getMaxBinaryLiteralLength() throws SQLException { return inner.getMaxBinaryLiteralLength(); } public synchronized int getMaxCharLiteralLength() throws SQLException { return inner.getMaxCharLiteralLength(); } public synchronized int getMaxColumnNameLength() throws SQLException { return inner.getMaxColumnNameLength(); } public synchronized int getMaxColumnsInGroupBy() throws SQLException { return inner.getMaxColumnsInGroupBy(); } public synchronized int getMaxColumnsInIndex() throws SQLException { return inner.getMaxColumnsInIndex(); } public synchronized int getMaxColumnsInOrderBy() throws SQLException { return inner.getMaxColumnsInOrderBy(); } public synchronized int getMaxColumnsInSelect() throws SQLException { return inner.getMaxColumnsInSelect(); } public synchronized int getMaxColumnsInTable() throws SQLException { return inner.getMaxColumnsInTable(); } public synchronized int getMaxConnections() throws SQLException { return inner.getMaxConnections(); } public synchronized int getMaxCursorNameLength() throws SQLException { return inner.getMaxCursorNameLength(); } public synchronized int getMaxIndexLength() throws SQLException { return inner.getMaxIndexLength(); } public synchronized int getMaxSchemaNameLength() throws SQLException { return inner.getMaxSchemaNameLength(); } public synchronized int getMaxProcedureNameLength() throws SQLException { return inner.getMaxProcedureNameLength(); } public synchronized int getMaxCatalogNameLength() throws SQLException { return inner.getMaxCatalogNameLength(); } public synchronized int getMaxRowSize() throws SQLException { return inner.getMaxRowSize(); } public synchronized boolean doesMaxRowSizeIncludeBlobs() throws SQLException { return inner.doesMaxRowSizeIncludeBlobs(); } public synchronized int getMaxStatementLength() throws SQLException { return inner.getMaxStatementLength(); } public synchronized int getMaxStatements() throws SQLException { return inner.getMaxStatements(); } public synchronized int getMaxTableNameLength() throws SQLException { return inner.getMaxTableNameLength(); } public synchronized int getMaxTablesInSelect() throws SQLException { return inner.getMaxTablesInSelect(); } public synchronized int getMaxUserNameLength() throws SQLException { return inner.getMaxUserNameLength(); } public synchronized int getDefaultTransactionIsolation() throws SQLException { return inner.getDefaultTransactionIsolation(); } public synchronized boolean supportsTransactions() throws SQLException { return inner.supportsTransactions(); } public synchronized boolean supportsTransactionIsolationLevel(int a) throws SQLException { return inner.supportsTransactionIsolationLevel(a); } public synchronized boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException { return inner.supportsDataDefinitionAndDataManipulationTransactions(); } public synchronized boolean supportsDataManipulationTransactionsOnly() throws SQLException { return inner.supportsDataManipulationTransactionsOnly(); } public synchronized boolean dataDefinitionCausesTransactionCommit() throws SQLException { return inner.dataDefinitionCausesTransactionCommit(); } public synchronized boolean dataDefinitionIgnoredInTransactions() throws SQLException { return inner.dataDefinitionIgnoredInTransactions(); } public synchronized ResultSet getProcedures(String a, String b, String c) throws SQLException { return inner.getProcedures(a, b, c); } public synchronized ResultSet getProcedureColumns(String a, String b, String c, String d) throws SQLException { return inner.getProcedureColumns(a, b, c, d); } public synchronized ResultSet getTables(String a, String b, String c, String[] d) throws SQLException { return inner.getTables(a, b, c, d); } public synchronized ResultSet getSchemas() throws SQLException { return inner.getSchemas(); } public synchronized ResultSet getCatalogs() throws SQLException { return inner.getCatalogs(); } public synchronized ResultSet getTableTypes() throws SQLException { return inner.getTableTypes(); } public synchronized ResultSet getColumnPrivileges(String a, String b, String c, String d) throws SQLException { return inner.getColumnPrivileges(a, b, c, d); } public synchronized ResultSet getTablePrivileges(String a, String b, String c) throws SQLException { return inner.getTablePrivileges(a, b, c); } public synchronized ResultSet getBestRowIdentifier(String a, String b, String c, int d, boolean e) throws SQLException { return inner.getBestRowIdentifier(a, b, c, d, e); } public synchronized ResultSet getVersionColumns(String a, String b, String c) throws SQLException { return inner.getVersionColumns(a, b, c); } public synchronized ResultSet getPrimaryKeys(String a, String b, String c) throws SQLException { return inner.getPrimaryKeys(a, b, c); } public synchronized ResultSet getImportedKeys(String a, String b, String c) throws SQLException { return inner.getImportedKeys(a, b, c); } public synchronized ResultSet getExportedKeys(String a, String b, String c) throws SQLException { return inner.getExportedKeys(a, b, c); } public synchronized ResultSet getCrossReference(String a, String b, String c, String d, String e, String f) throws SQLException { return inner.getCrossReference(a, b, c, d, e, f); } public synchronized ResultSet getTypeInfo() throws SQLException { return inner.getTypeInfo(); } public synchronized ResultSet getIndexInfo(String a, String b, String c, boolean d, boolean e) throws SQLException { return inner.getIndexInfo(a, b, c, d, e); } public synchronized boolean supportsResultSetType(int a) throws SQLException { return inner.supportsResultSetType(a); } public synchronized boolean supportsResultSetConcurrency(int a, int b) throws SQLException { return inner.supportsResultSetConcurrency(a, b); } public synchronized boolean ownUpdatesAreVisible(int a) throws SQLException { return inner.ownUpdatesAreVisible(a); } public synchronized boolean ownDeletesAreVisible(int a) throws SQLException { return inner.ownDeletesAreVisible(a); } public synchronized boolean ownInsertsAreVisible(int a) throws SQLException { return inner.ownInsertsAreVisible(a); } public synchronized boolean othersUpdatesAreVisible(int a) throws SQLException { return inner.othersUpdatesAreVisible(a); } public synchronized boolean othersDeletesAreVisible(int a) throws SQLException { return inner.othersDeletesAreVisible(a); } public synchronized boolean othersInsertsAreVisible(int a) throws SQLException { return inner.othersInsertsAreVisible(a); } public synchronized boolean updatesAreDetected(int a) throws SQLException { return inner.updatesAreDetected(a); } public synchronized boolean deletesAreDetected(int a) throws SQLException { return inner.deletesAreDetected(a); } public synchronized boolean insertsAreDetected(int a) throws SQLException { return inner.insertsAreDetected(a); } public synchronized boolean supportsBatchUpdates() throws SQLException { return inner.supportsBatchUpdates(); } public synchronized ResultSet getUDTs(String a, String b, String c, int[] d) throws SQLException { return inner.getUDTs(a, b, c, d); } public synchronized boolean supportsSavepoints() throws SQLException { return inner.supportsSavepoints(); } public synchronized boolean supportsNamedParameters() throws SQLException { return inner.supportsNamedParameters(); } public synchronized boolean supportsMultipleOpenResults() throws SQLException { return inner.supportsMultipleOpenResults(); } public synchronized boolean supportsGetGeneratedKeys() throws SQLException { return inner.supportsGetGeneratedKeys(); } public synchronized ResultSet getSuperTypes(String a, String b, String c) throws SQLException { return inner.getSuperTypes(a, b, c); } public synchronized ResultSet getSuperTables(String a, String b, String c) throws SQLException { return inner.getSuperTables(a, b, c); } public synchronized boolean supportsResultSetHoldability(int a) throws SQLException { return inner.supportsResultSetHoldability(a); } public synchronized int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public synchronized int getDatabaseMajorVersion() throws SQLException { return inner.getDatabaseMajorVersion(); } public synchronized int getDatabaseMinorVersion() throws SQLException { return inner.getDatabaseMinorVersion(); } public synchronized int getJDBCMajorVersion() throws SQLException { return inner.getJDBCMajorVersion(); } public synchronized int getJDBCMinorVersion() throws SQLException { return inner.getJDBCMinorVersion(); } public synchronized int getSQLStateType() throws SQLException { return inner.getSQLStateType(); } public synchronized boolean locatorsUpdateCopy() throws SQLException { return inner.locatorsUpdateCopy(); } public synchronized boolean supportsStatementPooling() throws SQLException { return inner.supportsStatementPooling(); } public synchronized String getURL() throws SQLException { return inner.getURL(); } public synchronized boolean isReadOnly() throws SQLException { return inner.isReadOnly(); } public synchronized ResultSet getAttributes(String a, String b, String c, String d) throws SQLException { return inner.getAttributes(a, b, c, d); } public synchronized Connection getConnection() throws SQLException { return inner.getConnection(); } public synchronized ResultSet getColumns(String a, String b, String c, String d) throws SQLException { return inner.getColumns(a, b, c, d); } public synchronized String getUserName() throws SQLException { return inner.getUserName(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/SynchronizedFilterPreparedStatement.java0000644000175000017500000002262310624366527030570 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.InputStream; import java.io.Reader; import java.lang.Object; import java.lang.String; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.Date; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; public abstract class SynchronizedFilterPreparedStatement implements PreparedStatement { protected PreparedStatement inner; public SynchronizedFilterPreparedStatement(PreparedStatement inner) { this.inner = inner; } public SynchronizedFilterPreparedStatement() {} public synchronized void setInner( PreparedStatement inner ) { this.inner = inner; } public synchronized PreparedStatement getInner() { return inner; } public synchronized ResultSetMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public synchronized ResultSet executeQuery() throws SQLException { return inner.executeQuery(); } public synchronized int executeUpdate() throws SQLException { return inner.executeUpdate(); } public synchronized void addBatch() throws SQLException { inner.addBatch(); } public synchronized void setNull(int a, int b, String c) throws SQLException { inner.setNull(a, b, c); } public synchronized void setNull(int a, int b) throws SQLException { inner.setNull(a, b); } public synchronized void setBigDecimal(int a, BigDecimal b) throws SQLException { inner.setBigDecimal(a, b); } public synchronized void setBytes(int a, byte[] b) throws SQLException { inner.setBytes(a, b); } public synchronized void setTimestamp(int a, Timestamp b, Calendar c) throws SQLException { inner.setTimestamp(a, b, c); } public synchronized void setTimestamp(int a, Timestamp b) throws SQLException { inner.setTimestamp(a, b); } public synchronized void setAsciiStream(int a, InputStream b, int c) throws SQLException { inner.setAsciiStream(a, b, c); } public synchronized void setUnicodeStream(int a, InputStream b, int c) throws SQLException { inner.setUnicodeStream(a, b, c); } public synchronized void setBinaryStream(int a, InputStream b, int c) throws SQLException { inner.setBinaryStream(a, b, c); } public synchronized void clearParameters() throws SQLException { inner.clearParameters(); } public synchronized void setObject(int a, Object b) throws SQLException { inner.setObject(a, b); } public synchronized void setObject(int a, Object b, int c, int d) throws SQLException { inner.setObject(a, b, c, d); } public synchronized void setObject(int a, Object b, int c) throws SQLException { inner.setObject(a, b, c); } public synchronized void setCharacterStream(int a, Reader b, int c) throws SQLException { inner.setCharacterStream(a, b, c); } public synchronized void setRef(int a, Ref b) throws SQLException { inner.setRef(a, b); } public synchronized void setBlob(int a, Blob b) throws SQLException { inner.setBlob(a, b); } public synchronized void setClob(int a, Clob b) throws SQLException { inner.setClob(a, b); } public synchronized void setArray(int a, Array b) throws SQLException { inner.setArray(a, b); } public synchronized ParameterMetaData getParameterMetaData() throws SQLException { return inner.getParameterMetaData(); } public synchronized void setBoolean(int a, boolean b) throws SQLException { inner.setBoolean(a, b); } public synchronized void setByte(int a, byte b) throws SQLException { inner.setByte(a, b); } public synchronized void setShort(int a, short b) throws SQLException { inner.setShort(a, b); } public synchronized void setInt(int a, int b) throws SQLException { inner.setInt(a, b); } public synchronized void setLong(int a, long b) throws SQLException { inner.setLong(a, b); } public synchronized void setFloat(int a, float b) throws SQLException { inner.setFloat(a, b); } public synchronized void setDouble(int a, double b) throws SQLException { inner.setDouble(a, b); } public synchronized void setURL(int a, URL b) throws SQLException { inner.setURL(a, b); } public synchronized void setTime(int a, Time b) throws SQLException { inner.setTime(a, b); } public synchronized void setTime(int a, Time b, Calendar c) throws SQLException { inner.setTime(a, b, c); } public synchronized boolean execute() throws SQLException { return inner.execute(); } public synchronized void setString(int a, String b) throws SQLException { inner.setString(a, b); } public synchronized void setDate(int a, Date b, Calendar c) throws SQLException { inner.setDate(a, b, c); } public synchronized void setDate(int a, Date b) throws SQLException { inner.setDate(a, b); } public synchronized SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public synchronized void clearWarnings() throws SQLException { inner.clearWarnings(); } public synchronized void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public synchronized int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public synchronized void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public synchronized int getFetchSize() throws SQLException { return inner.getFetchSize(); } public synchronized int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public synchronized ResultSet executeQuery(String a) throws SQLException { return inner.executeQuery(a); } public synchronized int executeUpdate(String a, int b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a, String[] b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a, int[] b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a) throws SQLException { return inner.executeUpdate(a); } public synchronized int getMaxFieldSize() throws SQLException { return inner.getMaxFieldSize(); } public synchronized void setMaxFieldSize(int a) throws SQLException { inner.setMaxFieldSize(a); } public synchronized int getMaxRows() throws SQLException { return inner.getMaxRows(); } public synchronized void setMaxRows(int a) throws SQLException { inner.setMaxRows(a); } public synchronized void setEscapeProcessing(boolean a) throws SQLException { inner.setEscapeProcessing(a); } public synchronized int getQueryTimeout() throws SQLException { return inner.getQueryTimeout(); } public synchronized void setQueryTimeout(int a) throws SQLException { inner.setQueryTimeout(a); } public synchronized void setCursorName(String a) throws SQLException { inner.setCursorName(a); } public synchronized ResultSet getResultSet() throws SQLException { return inner.getResultSet(); } public synchronized int getUpdateCount() throws SQLException { return inner.getUpdateCount(); } public synchronized boolean getMoreResults() throws SQLException { return inner.getMoreResults(); } public synchronized boolean getMoreResults(int a) throws SQLException { return inner.getMoreResults(a); } public synchronized int getResultSetConcurrency() throws SQLException { return inner.getResultSetConcurrency(); } public synchronized int getResultSetType() throws SQLException { return inner.getResultSetType(); } public synchronized void addBatch(String a) throws SQLException { inner.addBatch(a); } public synchronized void clearBatch() throws SQLException { inner.clearBatch(); } public synchronized int[] executeBatch() throws SQLException { return inner.executeBatch(); } public synchronized ResultSet getGeneratedKeys() throws SQLException { return inner.getGeneratedKeys(); } public synchronized void close() throws SQLException { inner.close(); } public synchronized boolean execute(String a, int b) throws SQLException { return inner.execute(a, b); } public synchronized boolean execute(String a) throws SQLException { return inner.execute(a); } public synchronized boolean execute(String a, int[] b) throws SQLException { return inner.execute(a, b); } public synchronized boolean execute(String a, String[] b) throws SQLException { return inner.execute(a, b); } public synchronized Connection getConnection() throws SQLException { return inner.getConnection(); } public synchronized void cancel() throws SQLException { inner.cancel(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/SynchronizedFilterResultSet.java0000644000175000017500000003747510624366527027106 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.io.InputStream; import java.io.Reader; import java.lang.Object; import java.lang.String; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Map; public abstract class SynchronizedFilterResultSet implements ResultSet { protected ResultSet inner; public SynchronizedFilterResultSet(ResultSet inner) { this.inner = inner; } public SynchronizedFilterResultSet() {} public synchronized void setInner( ResultSet inner ) { this.inner = inner; } public synchronized ResultSet getInner() { return inner; } public synchronized ResultSetMetaData getMetaData() throws SQLException { return inner.getMetaData(); } public synchronized SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public synchronized void clearWarnings() throws SQLException { inner.clearWarnings(); } public synchronized boolean wasNull() throws SQLException { return inner.wasNull(); } public synchronized BigDecimal getBigDecimal(int a) throws SQLException { return inner.getBigDecimal(a); } public synchronized BigDecimal getBigDecimal(String a, int b) throws SQLException { return inner.getBigDecimal(a, b); } public synchronized BigDecimal getBigDecimal(int a, int b) throws SQLException { return inner.getBigDecimal(a, b); } public synchronized BigDecimal getBigDecimal(String a) throws SQLException { return inner.getBigDecimal(a); } public synchronized Timestamp getTimestamp(int a) throws SQLException { return inner.getTimestamp(a); } public synchronized Timestamp getTimestamp(String a) throws SQLException { return inner.getTimestamp(a); } public synchronized Timestamp getTimestamp(int a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public synchronized Timestamp getTimestamp(String a, Calendar b) throws SQLException { return inner.getTimestamp(a, b); } public synchronized InputStream getAsciiStream(String a) throws SQLException { return inner.getAsciiStream(a); } public synchronized InputStream getAsciiStream(int a) throws SQLException { return inner.getAsciiStream(a); } public synchronized InputStream getUnicodeStream(String a) throws SQLException { return inner.getUnicodeStream(a); } public synchronized InputStream getUnicodeStream(int a) throws SQLException { return inner.getUnicodeStream(a); } public synchronized InputStream getBinaryStream(int a) throws SQLException { return inner.getBinaryStream(a); } public synchronized InputStream getBinaryStream(String a) throws SQLException { return inner.getBinaryStream(a); } public synchronized String getCursorName() throws SQLException { return inner.getCursorName(); } public synchronized Reader getCharacterStream(int a) throws SQLException { return inner.getCharacterStream(a); } public synchronized Reader getCharacterStream(String a) throws SQLException { return inner.getCharacterStream(a); } public synchronized boolean isBeforeFirst() throws SQLException { return inner.isBeforeFirst(); } public synchronized boolean isAfterLast() throws SQLException { return inner.isAfterLast(); } public synchronized boolean isFirst() throws SQLException { return inner.isFirst(); } public synchronized boolean isLast() throws SQLException { return inner.isLast(); } public synchronized void beforeFirst() throws SQLException { inner.beforeFirst(); } public synchronized void afterLast() throws SQLException { inner.afterLast(); } public synchronized boolean absolute(int a) throws SQLException { return inner.absolute(a); } public synchronized void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public synchronized int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public synchronized void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public synchronized int getFetchSize() throws SQLException { return inner.getFetchSize(); } public synchronized int getConcurrency() throws SQLException { return inner.getConcurrency(); } public synchronized boolean rowUpdated() throws SQLException { return inner.rowUpdated(); } public synchronized boolean rowInserted() throws SQLException { return inner.rowInserted(); } public synchronized boolean rowDeleted() throws SQLException { return inner.rowDeleted(); } public synchronized void updateNull(int a) throws SQLException { inner.updateNull(a); } public synchronized void updateNull(String a) throws SQLException { inner.updateNull(a); } public synchronized void updateBoolean(int a, boolean b) throws SQLException { inner.updateBoolean(a, b); } public synchronized void updateBoolean(String a, boolean b) throws SQLException { inner.updateBoolean(a, b); } public synchronized void updateByte(int a, byte b) throws SQLException { inner.updateByte(a, b); } public synchronized void updateByte(String a, byte b) throws SQLException { inner.updateByte(a, b); } public synchronized void updateShort(int a, short b) throws SQLException { inner.updateShort(a, b); } public synchronized void updateShort(String a, short b) throws SQLException { inner.updateShort(a, b); } public synchronized void updateInt(String a, int b) throws SQLException { inner.updateInt(a, b); } public synchronized void updateInt(int a, int b) throws SQLException { inner.updateInt(a, b); } public synchronized void updateLong(int a, long b) throws SQLException { inner.updateLong(a, b); } public synchronized void updateLong(String a, long b) throws SQLException { inner.updateLong(a, b); } public synchronized void updateFloat(String a, float b) throws SQLException { inner.updateFloat(a, b); } public synchronized void updateFloat(int a, float b) throws SQLException { inner.updateFloat(a, b); } public synchronized void updateDouble(String a, double b) throws SQLException { inner.updateDouble(a, b); } public synchronized void updateDouble(int a, double b) throws SQLException { inner.updateDouble(a, b); } public synchronized void updateBigDecimal(int a, BigDecimal b) throws SQLException { inner.updateBigDecimal(a, b); } public synchronized void updateBigDecimal(String a, BigDecimal b) throws SQLException { inner.updateBigDecimal(a, b); } public synchronized void updateString(String a, String b) throws SQLException { inner.updateString(a, b); } public synchronized void updateString(int a, String b) throws SQLException { inner.updateString(a, b); } public synchronized void updateBytes(int a, byte[] b) throws SQLException { inner.updateBytes(a, b); } public synchronized void updateBytes(String a, byte[] b) throws SQLException { inner.updateBytes(a, b); } public synchronized void updateDate(String a, Date b) throws SQLException { inner.updateDate(a, b); } public synchronized void updateDate(int a, Date b) throws SQLException { inner.updateDate(a, b); } public synchronized void updateTimestamp(int a, Timestamp b) throws SQLException { inner.updateTimestamp(a, b); } public synchronized void updateTimestamp(String a, Timestamp b) throws SQLException { inner.updateTimestamp(a, b); } public synchronized void updateAsciiStream(String a, InputStream b, int c) throws SQLException { inner.updateAsciiStream(a, b, c); } public synchronized void updateAsciiStream(int a, InputStream b, int c) throws SQLException { inner.updateAsciiStream(a, b, c); } public synchronized void updateBinaryStream(int a, InputStream b, int c) throws SQLException { inner.updateBinaryStream(a, b, c); } public synchronized void updateBinaryStream(String a, InputStream b, int c) throws SQLException { inner.updateBinaryStream(a, b, c); } public synchronized void updateCharacterStream(int a, Reader b, int c) throws SQLException { inner.updateCharacterStream(a, b, c); } public synchronized void updateCharacterStream(String a, Reader b, int c) throws SQLException { inner.updateCharacterStream(a, b, c); } public synchronized void updateObject(String a, Object b) throws SQLException { inner.updateObject(a, b); } public synchronized void updateObject(int a, Object b) throws SQLException { inner.updateObject(a, b); } public synchronized void updateObject(int a, Object b, int c) throws SQLException { inner.updateObject(a, b, c); } public synchronized void updateObject(String a, Object b, int c) throws SQLException { inner.updateObject(a, b, c); } public synchronized void insertRow() throws SQLException { inner.insertRow(); } public synchronized void updateRow() throws SQLException { inner.updateRow(); } public synchronized void deleteRow() throws SQLException { inner.deleteRow(); } public synchronized void refreshRow() throws SQLException { inner.refreshRow(); } public synchronized void cancelRowUpdates() throws SQLException { inner.cancelRowUpdates(); } public synchronized void moveToInsertRow() throws SQLException { inner.moveToInsertRow(); } public synchronized void moveToCurrentRow() throws SQLException { inner.moveToCurrentRow(); } public synchronized Statement getStatement() throws SQLException { return inner.getStatement(); } public synchronized Blob getBlob(String a) throws SQLException { return inner.getBlob(a); } public synchronized Blob getBlob(int a) throws SQLException { return inner.getBlob(a); } public synchronized Clob getClob(String a) throws SQLException { return inner.getClob(a); } public synchronized Clob getClob(int a) throws SQLException { return inner.getClob(a); } public synchronized void updateRef(String a, Ref b) throws SQLException { inner.updateRef(a, b); } public synchronized void updateRef(int a, Ref b) throws SQLException { inner.updateRef(a, b); } public synchronized void updateBlob(String a, Blob b) throws SQLException { inner.updateBlob(a, b); } public synchronized void updateBlob(int a, Blob b) throws SQLException { inner.updateBlob(a, b); } public synchronized void updateClob(int a, Clob b) throws SQLException { inner.updateClob(a, b); } public synchronized void updateClob(String a, Clob b) throws SQLException { inner.updateClob(a, b); } public synchronized void updateArray(String a, Array b) throws SQLException { inner.updateArray(a, b); } public synchronized void updateArray(int a, Array b) throws SQLException { inner.updateArray(a, b); } public synchronized Object getObject(int a) throws SQLException { return inner.getObject(a); } public synchronized Object getObject(String a, Map b) throws SQLException { return inner.getObject(a, b); } public synchronized Object getObject(String a) throws SQLException { return inner.getObject(a); } public synchronized Object getObject(int a, Map b) throws SQLException { return inner.getObject(a, b); } public synchronized boolean getBoolean(int a) throws SQLException { return inner.getBoolean(a); } public synchronized boolean getBoolean(String a) throws SQLException { return inner.getBoolean(a); } public synchronized byte getByte(String a) throws SQLException { return inner.getByte(a); } public synchronized byte getByte(int a) throws SQLException { return inner.getByte(a); } public synchronized short getShort(String a) throws SQLException { return inner.getShort(a); } public synchronized short getShort(int a) throws SQLException { return inner.getShort(a); } public synchronized int getInt(String a) throws SQLException { return inner.getInt(a); } public synchronized int getInt(int a) throws SQLException { return inner.getInt(a); } public synchronized long getLong(int a) throws SQLException { return inner.getLong(a); } public synchronized long getLong(String a) throws SQLException { return inner.getLong(a); } public synchronized float getFloat(String a) throws SQLException { return inner.getFloat(a); } public synchronized float getFloat(int a) throws SQLException { return inner.getFloat(a); } public synchronized double getDouble(int a) throws SQLException { return inner.getDouble(a); } public synchronized double getDouble(String a) throws SQLException { return inner.getDouble(a); } public synchronized byte[] getBytes(String a) throws SQLException { return inner.getBytes(a); } public synchronized byte[] getBytes(int a) throws SQLException { return inner.getBytes(a); } public synchronized boolean next() throws SQLException { return inner.next(); } public synchronized URL getURL(int a) throws SQLException { return inner.getURL(a); } public synchronized URL getURL(String a) throws SQLException { return inner.getURL(a); } public synchronized int getType() throws SQLException { return inner.getType(); } public synchronized boolean previous() throws SQLException { return inner.previous(); } public synchronized void close() throws SQLException { inner.close(); } public synchronized String getString(String a) throws SQLException { return inner.getString(a); } public synchronized String getString(int a) throws SQLException { return inner.getString(a); } public synchronized Ref getRef(String a) throws SQLException { return inner.getRef(a); } public synchronized Ref getRef(int a) throws SQLException { return inner.getRef(a); } public synchronized Time getTime(int a, Calendar b) throws SQLException { return inner.getTime(a, b); } public synchronized Time getTime(String a) throws SQLException { return inner.getTime(a); } public synchronized Time getTime(int a) throws SQLException { return inner.getTime(a); } public synchronized Time getTime(String a, Calendar b) throws SQLException { return inner.getTime(a, b); } public synchronized Date getDate(String a) throws SQLException { return inner.getDate(a); } public synchronized Date getDate(int a) throws SQLException { return inner.getDate(a); } public synchronized Date getDate(int a, Calendar b) throws SQLException { return inner.getDate(a, b); } public synchronized Date getDate(String a, Calendar b) throws SQLException { return inner.getDate(a, b); } public synchronized boolean first() throws SQLException { return inner.first(); } public synchronized boolean last() throws SQLException { return inner.last(); } public synchronized Array getArray(String a) throws SQLException { return inner.getArray(a); } public synchronized Array getArray(int a) throws SQLException { return inner.getArray(a); } public synchronized boolean relative(int a) throws SQLException { return inner.relative(a); } public synchronized void updateTime(String a, Time b) throws SQLException { inner.updateTime(a, b); } public synchronized void updateTime(int a, Time b) throws SQLException { inner.updateTime(a, b); } public synchronized int findColumn(String a) throws SQLException { return inner.findColumn(a); } public synchronized int getRow() throws SQLException { return inner.getRow(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/filter/SynchronizedFilterStatement.java0000644000175000017500000001217310624366527027104 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.filter; import java.lang.String; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; public abstract class SynchronizedFilterStatement implements Statement { protected Statement inner; public SynchronizedFilterStatement(Statement inner) { this.inner = inner; } public SynchronizedFilterStatement() {} public synchronized void setInner( Statement inner ) { this.inner = inner; } public synchronized Statement getInner() { return inner; } public synchronized SQLWarning getWarnings() throws SQLException { return inner.getWarnings(); } public synchronized void clearWarnings() throws SQLException { inner.clearWarnings(); } public synchronized void setFetchDirection(int a) throws SQLException { inner.setFetchDirection(a); } public synchronized int getFetchDirection() throws SQLException { return inner.getFetchDirection(); } public synchronized void setFetchSize(int a) throws SQLException { inner.setFetchSize(a); } public synchronized int getFetchSize() throws SQLException { return inner.getFetchSize(); } public synchronized int getResultSetHoldability() throws SQLException { return inner.getResultSetHoldability(); } public synchronized ResultSet executeQuery(String a) throws SQLException { return inner.executeQuery(a); } public synchronized int executeUpdate(String a, int b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a, String[] b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a, int[] b) throws SQLException { return inner.executeUpdate(a, b); } public synchronized int executeUpdate(String a) throws SQLException { return inner.executeUpdate(a); } public synchronized int getMaxFieldSize() throws SQLException { return inner.getMaxFieldSize(); } public synchronized void setMaxFieldSize(int a) throws SQLException { inner.setMaxFieldSize(a); } public synchronized int getMaxRows() throws SQLException { return inner.getMaxRows(); } public synchronized void setMaxRows(int a) throws SQLException { inner.setMaxRows(a); } public synchronized void setEscapeProcessing(boolean a) throws SQLException { inner.setEscapeProcessing(a); } public synchronized int getQueryTimeout() throws SQLException { return inner.getQueryTimeout(); } public synchronized void setQueryTimeout(int a) throws SQLException { inner.setQueryTimeout(a); } public synchronized void setCursorName(String a) throws SQLException { inner.setCursorName(a); } public synchronized ResultSet getResultSet() throws SQLException { return inner.getResultSet(); } public synchronized int getUpdateCount() throws SQLException { return inner.getUpdateCount(); } public synchronized boolean getMoreResults() throws SQLException { return inner.getMoreResults(); } public synchronized boolean getMoreResults(int a) throws SQLException { return inner.getMoreResults(a); } public synchronized int getResultSetConcurrency() throws SQLException { return inner.getResultSetConcurrency(); } public synchronized int getResultSetType() throws SQLException { return inner.getResultSetType(); } public synchronized void addBatch(String a) throws SQLException { inner.addBatch(a); } public synchronized void clearBatch() throws SQLException { inner.clearBatch(); } public synchronized int[] executeBatch() throws SQLException { return inner.executeBatch(); } public synchronized ResultSet getGeneratedKeys() throws SQLException { return inner.getGeneratedKeys(); } public synchronized void close() throws SQLException { inner.close(); } public synchronized boolean execute(String a, int b) throws SQLException { return inner.execute(a, b); } public synchronized boolean execute(String a) throws SQLException { return inner.execute(a); } public synchronized boolean execute(String a, int[] b) throws SQLException { return inner.execute(a, b); } public synchronized boolean execute(String a, String[] b) throws SQLException { return inner.execute(a, b); } public synchronized Connection getConnection() throws SQLException { return inner.getConnection(); } public synchronized void cancel() throws SQLException { inner.cancel(); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/junit/0000755000175000017500000000000010673162231020355 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/junit/SqlUtilsJUnitTestCase.java0000644000175000017500000000324010624366527025417 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql.junit; import java.sql.*; import junit.framework.*; import com.mchange.v2.sql.SqlUtils; public class SqlUtilsJUnitTestCase extends TestCase { public void testGoodDebugLoggingOfNestedExceptions() { // this is only supposed to complete (in response to a bug where logging of // nested Exceptions was an infinite loop. SQLException original = new SQLException("Original."); SQLWarning nestedWarning = new SQLWarning("Nested Warning."); original.setNextException( nestedWarning ); SqlUtils.toSQLException( original ); } public static void main(String[] argv) { junit.textui.TestRunner.run( new TestSuite( SqlUtilsJUnitTestCase.class ) ); //junit.swingui.TestRunner.run( SqlUtilsJUnitTestCase.class ); //new SqlUtilsJUnitTestCase().testGoodDebugLoggingOfNestedExceptions(); } }c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/sql/SqlUtils.java0000644000175000017500000000714310624366527021666 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.sql; import java.sql.*; import com.mchange.v2.log.*; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; import com.mchange.lang.ThrowableUtils; import com.mchange.v2.lang.VersionUtils; public final class SqlUtils { final static MLogger logger = MLog.getLogger( SqlUtils.class ); // protected by SqlUtils.class' lock final static DateFormat tsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS"); public final static String DRIVER_MANAGER_USER_PROPERTY = "user"; public final static String DRIVER_MANAGER_PASSWORD_PROPERTY = "password"; public static String escapeBadSqlPatternChars(String s) { StringBuffer sb = new StringBuffer(s); for (int i = 0, len = sb.length(); i < len; ++i) if (sb.charAt(i) == '\'') { sb.insert(i, '\''); ++len; i+=2; } return sb.toString(); } public synchronized static String escapeAsTimestamp( Date date ) { return "{ts '" + tsdf.format( date ) + "'}"; } public static SQLException toSQLException(Throwable t) { return toSQLException(null, t ); } public static SQLException toSQLException(String msg, Throwable t) { return toSQLException(msg, null, t);} public static SQLException toSQLException(String msg, String sqlState, Throwable t) { if (t instanceof SQLException) { if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER )) { SQLException s = (SQLException) t; StringBuffer tmp = new StringBuffer(255); tmp.append("Attempted to convert SQLException to SQLException. Leaving it alone."); tmp.append(" [SQLState: "); tmp.append( s.getSQLState() ); tmp.append("; errorCode: " ); tmp.append( s.getErrorCode() ); tmp.append(']'); if (msg != null) tmp.append(" Ignoring suggested message: '" + msg + "'."); logger.log( MLevel.FINER, tmp.toString(), t ); SQLException s2 = s; while ((s2 = s2.getNextException()) != null) logger.log( MLevel.FINER, "Nested SQLException or SQLWarning: ", s2 ); } return (SQLException) t; } else { if (Debug.DEBUG) { //t.printStackTrace(); if ( logger.isLoggable( MLevel.FINE ) ) logger.log( MLevel.FINE, "Converting Throwable to SQLException...", t ); } if (msg == null) msg = "An SQLException was provoked by the following failure: " + t.toString(); if ( VersionUtils.isAtLeastJavaVersion14() ) { SQLException out = new SQLException(msg); out.initCause( t ); return out; } else return new SQLException( msg + System.getProperty( "line.separator" ) + "[Cause: " + ThrowableUtils.extractStackTrace(t) + ']', sqlState); } } private SqlUtils() {} } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/util/0000755000175000017500000000000010673162231017402 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/util/junit/0000755000175000017500000000000010673162231020533 5ustar godgodc3p0-0.9.1.2.orig/src/classes/com/mchange/v2/util/junit/DoubleWeakHashMapJUnitTestCase.java0000644000175000017500000000750010624366530027276 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.util.junit; import java.util.Iterator; import java.util.Map; import com.mchange.v2.util.DoubleWeakHashMap; import junit.framework.TestCase; public class DoubleWeakHashMapJUnitTestCase extends TestCase { public void testGetNeverAdded() { Map m = new DoubleWeakHashMap(); assertNull( m.get("foo") ); } public void testHardAdds() { Integer a = new Integer(1); Integer b = new Integer(2); Integer c = new Integer(3); String poop = new String("poop"); String scoop = new String("scoop"); String doop = new String("dcoop"); Map m = new DoubleWeakHashMap(); m.put(a, poop); m.put(b, scoop); m.put(c, doop); assertEquals("Size should be three, viewed via Map directly.", m.size(), 3); assertEquals("Size should be three, viewed via keySet .", m.keySet().size(), 3); assertEquals("Size should be three, viewed via values Collection.", m.values().size(), 3); int count = 0; for (Iterator ii = m.keySet().iterator(); ii.hasNext();) { count += ((Integer) ii.next()).intValue(); } assertEquals("Count should be six, viewed via values Collection.", count, 6); Integer d = new Integer(4); m.put(d, poop); m.values().remove(poop); assertEquals("After removing a doubled value, size should be 2", m.size(), 2); } public void testWeakness() { Integer a = new Integer(1); Integer b = new Integer(2); Integer c = new Integer(3); String poop = new String("poop"); Map m = new DoubleWeakHashMap(); m.put(a, poop); m.put(b, new Object()); m.put(c, new Object()); //race condition... b & c might already have been removed... but i doubt it assertEquals("1) Weak values should not yet have been removed (but not guaranteed! sometimes fails without a defect!)", m.size(), 3); // we are relying that a full, synchronous GC occurs, // which is not guaranteed in all VMs System.gc(); // let's see if we can force a deeper gc via a big array creation byte[] bArray = new byte[1024 * 1024]; assertEquals("2) Weak values should have been automatically removed (but not guaranteed! sometimes fails without a defect!)", m.size(), 1); m.put( new Object(), b); //race condition... b & c might already have been removed... but i doubt it assertEquals("3) Weak key should not yet have been removed (but not guaranteed! sometimes fails without a defect!)", m.size(), 2); System.gc(); // let's see if we can force a deeper gc via a big array creation bArray = new byte[1024 * 1024]; assertEquals("4) Weak key should have been automatically removed (but not guaranteed! sometimes fails without a defect!)", m.size(), 1); } } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/util/DoubleWeakHashMap.java0000644000175000017500000003631110624366530023541 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.util; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import com.mchange.v1.util.AbstractMapEntry; import com.mchange.v1.util.WrapperIterator; //TODO -- ensure that cleanCleared() gets called only once, even in methods implemented // as loops. (cleanCleared() is idempotent, so the repeated calls are okay, // but they're wasteful. /** *

This class is not Thread safe. * Use in single threaded contexts, or contexts where * single threaded-access can be guaranteed, or * wrap with Collections.synchronizedMap().

* *

This class does not accept null keys or values.

*/ public class DoubleWeakHashMap implements Map { HashMap inner; ReferenceQueue keyQ = new ReferenceQueue(); ReferenceQueue valQ = new ReferenceQueue(); CheckKeyHolder holder = new CheckKeyHolder(); Set userKeySet = null; Collection valuesCollection = null; public DoubleWeakHashMap() { this.inner = new HashMap(); } public DoubleWeakHashMap(int initialCapacity) { this.inner = new HashMap( initialCapacity ); } public DoubleWeakHashMap(int initialCapacity, float loadFactor) { this.inner = new HashMap( initialCapacity, loadFactor ); } public DoubleWeakHashMap(Map m) { this(); putAll(m); } public void cleanCleared() { WKey wk; while ((wk = (WKey) keyQ.poll()) != null) inner.remove(wk); WVal wv; while ((wv = (WVal) valQ.poll()) != null) inner.remove(wv.getWKey()); } public void clear() { cleanCleared(); inner.clear(); } public boolean containsKey(Object key) { cleanCleared(); try { return inner.containsKey( holder.set(key) ); } finally { holder.clear(); } } public boolean containsValue(Object val) { for (Iterator ii = inner.values().iterator(); ii.hasNext();) { WVal wval = (WVal) ii.next(); if (val.equals(wval.get())) return true; } return false; } public Set entrySet() { cleanCleared(); return new UserEntrySet(); } public Object get(Object key) { try { cleanCleared(); WVal wval = (WVal) inner.get(holder.set(key)); return (wval == null ? null : wval.get()); } finally { holder.clear(); } } public boolean isEmpty() { cleanCleared(); return inner.isEmpty(); } public Set keySet() { cleanCleared(); if (userKeySet == null) userKeySet = new UserKeySet(); return userKeySet; } public Object put(Object key, Object val) { cleanCleared(); WVal wout = doPut(key, val); if (wout != null) return wout.get(); else return null; } private WVal doPut(Object key, Object val) { WKey wk = new WKey(key, keyQ); WVal wv = new WVal(wk, val, valQ); return (WVal) inner.put(wk, wv); } public void putAll(Map m) { cleanCleared(); for (Iterator ii = m.entrySet().iterator(); ii.hasNext();) { Map.Entry entry = (Map.Entry) ii.next(); this.doPut( entry.getKey(), entry.getValue() ); } } public Object remove(Object key) { try { cleanCleared(); WVal wv = (WVal) inner.remove( holder.set(key) ); return (wv == null ? null : wv.get()); } finally { holder.clear(); } } public int size() { cleanCleared(); return inner.size(); } public Collection values() { if (valuesCollection == null) this.valuesCollection = new ValuesCollection(); return valuesCollection; } final static class CheckKeyHolder { Object checkKey; public Object get() {return checkKey; } public CheckKeyHolder set(Object ck) { assert this.checkKey == null : "Illegal concurrenct use of DoubleWeakHashMap!"; this.checkKey = ck; return this; } public void clear() { checkKey = null; } public int hashCode() { return checkKey.hashCode(); } public boolean equals(Object o) { assert this.get() != null : "CheckedKeyHolder should never do an equality check while its value is null." ; if (this == o) return true; else if (o instanceof CheckKeyHolder) return this.get().equals( ((CheckKeyHolder) o).get() ); else if (o instanceof WKey) return this.get().equals( ((WKey) o).get() ); else return false; } } final static class WKey extends WeakReference { int cachedHash; WKey(Object keyObj, ReferenceQueue rq) { super(keyObj, rq); this.cachedHash = keyObj.hashCode(); } public int hashCode() { return cachedHash; } public boolean equals(Object o) { if (this == o) return true; else if (o instanceof WKey) { WKey oo = (WKey) o; Object myVal = this.get(); Object ooVal = oo.get(); if (myVal == null || ooVal == null) return false; else return myVal.equals(ooVal); } else if (o instanceof CheckKeyHolder) { CheckKeyHolder oo = (CheckKeyHolder) o; Object myVal = this.get(); Object ooVal = oo.get(); if (myVal == null || ooVal == null) return false; else return myVal.equals(ooVal); } else return false; } } final static class WVal extends WeakReference { WKey key; WVal(WKey key, Object valObj, ReferenceQueue rq) { super(valObj, rq); this.key = key; } public WKey getWKey() { return key; } } private final class UserEntrySet extends AbstractSet { private Set innerEntrySet() { cleanCleared(); return inner.entrySet(); } public Iterator iterator() { return new WrapperIterator(innerEntrySet().iterator(), true) { protected Object transformObject(Object o) { Entry innerEntry = (Entry) o; Object key = ((WKey) innerEntry.getKey()).get(); Object val = ((WVal) innerEntry.getValue()).get(); if (key == null || val == null) return WrapperIterator.SKIP_TOKEN; else return new UserEntry( innerEntry, key, val ); } }; } public int size() { return innerEntrySet().size(); } } class UserEntry extends AbstractMapEntry { Entry innerEntry; Object key; Object val; UserEntry(Entry innerEntry, Object key, Object val) { this.innerEntry = innerEntry; this.key = key; this.val = val; } public final Object getKey() { return key; } public final Object getValue() { return val; } public final Object setValue(Object value) { return innerEntry.setValue( new WVal( (WKey) innerEntry.getKey() ,value, valQ) ); } } class UserKeySet implements Set { public boolean add(Object o) { cleanCleared(); throw new UnsupportedOperationException("You cannot add to a Map's key set."); } public boolean addAll(Collection c) { cleanCleared(); throw new UnsupportedOperationException("You cannot add to a Map's key set."); } public void clear() { DoubleWeakHashMap.this.clear(); } public boolean contains(Object o) { return DoubleWeakHashMap.this.containsKey(o); } public boolean containsAll(Collection c) { for (Iterator ii = c.iterator(); ii.hasNext();) if (! this.contains(ii.next())) return false; return true; } public boolean isEmpty() { return DoubleWeakHashMap.this.isEmpty(); } public Iterator iterator() { cleanCleared(); return new WrapperIterator(DoubleWeakHashMap.this.inner.keySet().iterator(), true) { protected Object transformObject(Object o) { Object key = ((WKey) o).get(); if (key == null) return WrapperIterator.SKIP_TOKEN; else return key; } }; } public boolean remove(Object o) { return (DoubleWeakHashMap.this.remove(o) != null); } public boolean removeAll(Collection c) { boolean out = false; for (Iterator ii = c.iterator(); ii.hasNext();) out |= this.remove(ii.next()); return out; } public boolean retainAll(Collection c) { //we implicitly cleanCleared() by calling iterator() boolean out = false; for (Iterator ii = this.iterator(); ii.hasNext();) { if (!c.contains(ii.next())) { ii.remove(); out = true; } } return out; } public int size() { return DoubleWeakHashMap.this.size(); } public Object[] toArray() { cleanCleared(); return new HashSet( this ).toArray(); } public Object[] toArray(Object[] array) { cleanCleared(); return new HashSet( this ).toArray(array); } } class ValuesCollection implements Collection { public boolean add(Object o) { cleanCleared(); throw new UnsupportedOperationException("DoubleWeakHashMap does not support adding to its values Collection."); } public boolean addAll(Collection c) { cleanCleared(); throw new UnsupportedOperationException("DoubleWeakHashMap does not support adding to its values Collection."); } public void clear() { DoubleWeakHashMap.this.clear(); } public boolean contains(Object o) { return DoubleWeakHashMap.this.containsValue(o); } public boolean containsAll(Collection c) { for (Iterator ii = c.iterator(); ii.hasNext();) if (!this.contains(ii.next())) return false; return true; } public boolean isEmpty() { return DoubleWeakHashMap.this.isEmpty(); } public Iterator iterator() { return new WrapperIterator(inner.values().iterator(), true) { protected Object transformObject(Object o) { Object val = ((WVal) o).get(); if (val == null) return WrapperIterator.SKIP_TOKEN; else return val; } }; } public boolean remove(Object o) { cleanCleared(); return removeValue(o); } public boolean removeAll(Collection c) { cleanCleared(); boolean out = false; for (Iterator ii = c.iterator(); ii.hasNext();) out |= removeValue(ii.next()); return out; } public boolean retainAll(Collection c) { cleanCleared(); return retainValues(c); } public int size() { return DoubleWeakHashMap.this.size(); } public Object[] toArray() { cleanCleared(); return new ArrayList(this).toArray(); } public Object[] toArray(Object[] array) { cleanCleared(); return new ArrayList(this).toArray(array); } private boolean removeValue(Object val) { boolean out = false; for (Iterator ii = inner.values().iterator(); ii.hasNext();) { WVal wv = (WVal) ii.next(); if (val.equals(wv.get())) { ii.remove(); out = true; } } return out; } private boolean retainValues(Collection c) { boolean out = false; for (Iterator ii = inner.values().iterator(); ii.hasNext();) { WVal wv = (WVal) ii.next(); if (! c.contains(wv.get()) ) { ii.remove(); out = true; } } return out; } } /* public static void main(String[] argv) { DoubleWeakHashMap m = new DoubleWeakHashMap(); //Set keySet = new HashSet(); //Set valSet = new HashSet(); while (true) { System.err.println( m.inner.size() ); //if (Math.random() < 0.1f) // valSet.clear(); Object key = new Object(); Object val = new long[100000]; //keySet.add(key); //valSet.add(val); m.put( key, val ); } } */ } c3p0-0.9.1.2.orig/src/classes/com/mchange/v2/util/ResourceClosedException.java0000644000175000017500000000335010624366530025052 0ustar godgod/* * Distributed as part of c3p0 v.0.9.1.2 * * Copyright (C) 2005 Machinery For Change, Inc. * * Author: Steve Waldman * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 2.1, as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; see the file LICENSE. If not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package com.mchange.v2.util; import com.mchange.v2.lang.VersionUtils; public class ResourceClosedException extends RuntimeException { //retaining 1.3.x compatability for now // public ResourceClosedException(String msg, Throwable t) // { super( msg, t ); } // public ResourceClosedException(Throwable t) // { super(t); } Throwable rootCause; public ResourceClosedException(String msg, Throwable t) { super( msg ); setRootCause( t ); } public ResourceClosedException(Throwable t) { super(); setRootCause( t ); } public ResourceClosedException(String msg) { super( msg ); } public ResourceClosedException() { super(); } public Throwable getCause() { return rootCause; } private void setRootCause( Throwable t ) { this.rootCause = t; if ( VersionUtils.isAtLeastJavaVersion14() ) this.initCause( t ); } } c3p0-0.9.1.2.orig/src/codegen/0000755000175000017500000000000007730455106013673 5ustar godgodc3p0-0.9.1.2.orig/src/codegen/com/0000755000175000017500000000000007730455057014456 5ustar godgodc3p0-0.9.1.2.orig/src/codegen/com/mchange/0000755000175000017500000000000007730455057016060 5ustar godgodc3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/0000755000175000017500000000000007731427162016404 5ustar godgodc3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/0000755000175000017500000000000007735772630017160 5ustar godgodc3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/impl/0000755000175000017500000000000010673162231020102 5ustar godgodc3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/impl/DriverManagerDataSourceBase.beangen-xml0000644000175000017500000000657110503115641027521 0ustar godgod com.mchange.v2.c3p0.impl java.util com.mchange.v2.c3p0.impl.AuthMaskingProperties com.mchange.v2.c3p0.cfg.C3P0Config public abstract DriverManagerDataSourceBase IdentityTokenResolvable protected publicsynchronized publicsynchronized String driverClass C3P0Config.initializeStringPropertyVar("driverClass", C3P0Defaults.driverClass()) protected publicsynchronized publicsynchronized String jdbcUrl C3P0Config.initializeStringPropertyVar("jdbcUrl", C3P0Defaults.jdbcUrl()) protected publicsynchronized publicsynchronized Properties properties (Properties) AuthMaskingProperties.fromAnyProperties( properties ) new AuthMaskingProperties() protected publicsynchronized publicsynchronized String description String identityToken publicsynchronized publicsynchronized protected publicsynchronized publicsynchronized String factoryClassLocation C3P0Config.initializeStringPropertyVar("factoryClassLocation", C3P0Defaults.factoryClassLocation()) c3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/impl/JndiRefDataSourceBase.beangen-xml0000644000175000017500000000335310476576742026335 0ustar godgod com.mchange.v2.c3p0.impl java.util.Hashtable javax.naming.Name com.mchange.v2.c3p0.cfg.C3P0Config JndiRefDataSourceBase IdentityTokenResolvable Object jndiName (jndiName instanceof Name ? ((Name) jndiName).clone() : jndiName /* String */) Hashtable jndiEnv (jndiEnv != null ? (Hashtable) jndiEnv.clone() : null) boolean caching true String identityToken publicsynchronized publicsynchronized String factoryClassLocation C3P0Config.initializeStringPropertyVar("factoryClassLocation", C3P0Defaults.factoryClassLocation()) c3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/impl/PoolBackedDataSourceBase.beangen-xml0000644000175000017500000000534410476576676027027 0ustar godgod com.mchange.v2.c3p0.impl javax.sql.DataSource javax.sql.ConnectionPoolDataSource com.mchange.v2.c3p0.cfg.C3P0Config PoolBackedDataSourceBase IdentityTokenResolvable ConnectionPoolDataSource connectionPoolDataSource publicsynchronized publicsynchronized int numHelperThreads C3P0Config.initializeIntPropertyVar("numHelperThreads", C3P0Defaults.numHelperThreads()) publicsynchronized publicsynchronized String identityToken publicsynchronized publicsynchronized String dataSourceName null publicsynchronized publicsynchronized String factoryClassLocation C3P0Config.initializeStringPropertyVar("factoryClassLocation", C3P0Defaults.factoryClassLocation()) publicsynchronized publicsynchronized ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootc3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/impl/WrapperConnectionPoolDataSourceBase.beangen-xmlc3p0-0.9.1.2.orig/src/codegen/com/mchange/v2/c3p0/impl/WrapperConnectionPoolDataSourceBase.beangen-x0000644000175000017500000003556710504055753030753 0ustar godgod com.mchange.v2.c3p0.impl javax.sql.DataSource com.mchange.v2.c3p0.cfg.C3P0Config public abstract WrapperConnectionPoolDataSourceBase IdentityTokenResolvable DataSource nestedDataSource publicsynchronized publicsynchronized int maxStatements C3P0Config.initializeIntPropertyVar("maxStatements", C3P0Defaults.maxStatements()) publicsynchronized publicsynchronized int maxStatementsPerConnection C3P0Config.initializeIntPropertyVar("maxStatementsPerConnection", C3P0Defaults.maxStatementsPerConnection()) publicsynchronized publicsynchronized int initialPoolSize C3P0Config.initializeIntPropertyVar("initialPoolSize", C3P0Defaults.initialPoolSize()) publicsynchronized publicsynchronized int minPoolSize C3P0Config.initializeIntPropertyVar("minPoolSize", C3P0Defaults.minPoolSize()) publicsynchronized publicsynchronized int maxPoolSize C3P0Config.initializeIntPropertyVar("maxPoolSize", C3P0Defaults.maxPoolSize()) publicsynchronized publicsynchronized int maxAdministrativeTaskTime C3P0Config.initializeIntPropertyVar("maxAdministrativeTaskTime", C3P0Defaults.maxAdministrativeTaskTime()) publicsynchronized publicsynchronized int maxIdleTimeExcessConnections C3P0Config.initializeIntPropertyVar("maxIdleTimeExcessConnections", C3P0Defaults.maxIdleTimeExcessConnections()) publicsynchronized publicsynchronized int maxConnectionAge C3P0Config.initializeIntPropertyVar("maxConnectionAge", C3P0Defaults.maxConnectionAge()) publicsynchronized publicsynchronized int unreturnedConnectionTimeout C3P0Config.initializeIntPropertyVar("unreturnedConnectionTimeout", C3P0Defaults.unreturnedConnectionTimeout()) publicsynchronized publicsynchronized int idleConnectionTestPeriod C3P0Config.initializeIntPropertyVar("idleConnectionTestPeriod", C3P0Defaults.idleConnectionTestPeriod()) publicsynchronized publicsynchronized int maxIdleTime C3P0Config.initializeIntPropertyVar("maxIdleTime", C3P0Defaults.maxIdleTime()) publicsynchronized publicsynchronized int propertyCycle C3P0Config.initializeIntPropertyVar("propertyCycle", C3P0Defaults.propertyCycle()) publicsynchronized publicsynchronized int acquireIncrement C3P0Config.initializeIntPropertyVar("acquireIncrement", C3P0Defaults.acquireIncrement()) publicsynchronized publicsynchronized int acquireRetryAttempts C3P0Config.initializeIntPropertyVar("acquireRetryAttempts", C3P0Defaults.acquireRetryAttempts()) publicsynchronized publicsynchronized int acquireRetryDelay C3P0Config.initializeIntPropertyVar("acquireRetryDelay", C3P0Defaults.acquireRetryDelay()) publicsynchronized publicsynchronized String automaticTestTable C3P0Config.initializeStringPropertyVar("automaticTestTable", C3P0Defaults.automaticTestTable()) publicsynchronized publicsynchronized String connectionTesterClassName C3P0Config.initializeStringPropertyVar("connectionTesterClassName", C3P0Defaults.connectionTesterClassName()) publicsynchronized publicsynchronized String connectionCustomizerClassName C3P0Config.initializeStringPropertyVar("connectionCustomizerClassName", C3P0Defaults.connectionCustomizerClassName()) publicsynchronized publicsynchronized boolean debugUnreturnedConnectionStackTraces C3P0Config.initializeBooleanPropertyVar("debugUnreturnedConnectionStackTraces", C3P0Defaults.debugUnreturnedConnectionStackTraces()) publicsynchronized publicsynchronized boolean testConnectionOnCheckout C3P0Config.initializeBooleanPropertyVar("testConnectionOnCheckout", C3P0Defaults.testConnectionOnCheckout()) publicsynchronized publicsynchronized boolean testConnectionOnCheckin C3P0Config.initializeBooleanPropertyVar("testConnectionOnCheckin", C3P0Defaults.testConnectionOnCheckin()) publicsynchronized publicsynchronized String preferredTestQuery C3P0Config.initializeStringPropertyVar("preferredTestQuery", C3P0Defaults.preferredTestQuery()) publicsynchronized publicsynchronized boolean autoCommitOnClose C3P0Config.initializeBooleanPropertyVar("autoCommitOnClose", C3P0Defaults.autoCommitOnClose()) publicsynchronized publicsynchronized boolean forceIgnoreUnresolvedTransactions C3P0Config.initializeBooleanPropertyVar("forceIgnoreUnresolvedTransactions", C3P0Defaults.forceIgnoreUnresolvedTransactions()) publicsynchronized publicsynchronized int checkoutTimeout C3P0Config.initializeIntPropertyVar("checkoutTimeout", C3P0Defaults.checkoutTimeout()) publicsynchronized publicsynchronized boolean breakAfterAcquireFailure C3P0Config.initializeBooleanPropertyVar("breakAfterAcquireFailure", C3P0Defaults.breakAfterAcquireFailure()) publicsynchronized publicsynchronized boolean usesTraditionalReflectiveProxies C3P0Config.initializeBooleanPropertyVar("usesTraditionalReflectiveProxies", C3P0Defaults.usesTraditionalReflectiveProxies()) publicsynchronized publicsynchronized String overrideDefaultUser C3P0Config.initializeStringPropertyVar("overrideDefaultUser", C3P0Defaults.overrideDefaultUser()) publicsynchronized publicsynchronized String overrideDefaultPassword C3P0Config.initializeStringPropertyVar("overrideDefaultPassword", C3P0Defaults.overrideDefaultPassword()) publicsynchronized publicsynchronized String userOverridesAsString C3P0Config.initializeUserOverridesAsString() publicsynchronized publicsynchronized String identityToken publicsynchronized publicsynchronized String factoryClassLocation C3P0Config.initializeStringPropertyVar("factoryClassLocation", C3P0Defaults.factoryClassLocation()) publicsynchronized publicsynchronized c3p0-0.9.1.2.orig/src/dist-static/0000755000175000017500000000000010673162231014511 5ustar godgodc3p0-0.9.1.2.orig/src/dist-static/examples/0000755000175000017500000000000010673162231016327 5ustar godgodc3p0-0.9.1.2.orig/src/dist-static/examples/JndiBindDataSource.java0000644000175000017500000000401707657566055022654 0ustar godgodimport java.sql.*; import javax.naming.*; import javax.sql.DataSource; import com.mchange.v2.c3p0.DataSources; /** * This example shows how to acquire a c3p0 DataSource and * bind it to a JNDI name service. */ public final class JndiBindDataSource { // be sure to load your database driver class, either via // Class.forName() [as shown below] or externally (e.g. by // using -Djdbc.drivers when starting your JVM). static { try { Class.forName( "org.postgresql.Driver" ); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] argv) { try { // let a command line arg specify the name we will // bind our DataSource to. String jndiName = argv[0]; // acquire the DataSource using default pool params... // this is the only c3p0 specific code here DataSource unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/test", "swaldman", "test"); DataSource pooled = DataSources.pooledDataSource( unpooled ); // Create an InitialContext, and bind the DataSource to it in // the usual way. // // We are using the no-arg version of InitialContext's constructor, // therefore, the jndi environment must be first set via a jndi.properties // file, System properties, or by some other means. InitialContext ctx = new InitialContext(); ctx.rebind( jndiName, pooled ); System.out.println("DataSource bound to nameservice under the name \"" + jndiName + '\"'); } catch (Exception e) { e.printStackTrace(); } } static void attemptClose(ResultSet o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Statement o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Connection o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } private JndiBindDataSource() {} } c3p0-0.9.1.2.orig/src/dist-static/examples/UseJndiDataSource.java0000644000175000017500000000405707656562660022535 0ustar godgodimport java.sql.*; import javax.naming.*; import javax.sql.DataSource; /** * This example shows how to programmatically get and directly use * an unpooled DataSource */ public final class UseJndiDataSource { public static void main(String[] argv) { try { // let a command line arg specify the name we will // lookup our DataSource. String jndiName = argv[0]; // Create an InitialContext, and lookup the DataSource in // the usual way. // // We are using the no-arg version of InitialContext's constructor, // therefore, the jndi environment must be first set via a jndi.properties // file, System properties, or by some other means. InitialContext ctx = new InitialContext(); // acquire the DataSource... this is the only c3p0 specific code here DataSource ds = (DataSource) ctx.lookup( jndiName ); // get hold of a Connection an do stuff, in the usual way Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = ds.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT * FROM foo"); while (rs.next()) System.out.println( rs.getString(1) ); } finally { // i try to be neurotic about ResourceManagement, // explicitly closing each resource // but if you are in the habit of only closing // parent resources (e.g. the Connection) and // letting them close their children, all // c3p0 DataSources will properly deal. attemptClose(rs); attemptClose(stmt); attemptClose(con); } } catch (Exception e) { e.printStackTrace(); } } static void attemptClose(ResultSet o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Statement o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Connection o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } private UseJndiDataSource() {} } c3p0-0.9.1.2.orig/src/dist-static/examples/UsePoolBackedDataSource.java0000644000175000017500000000365407657566020023651 0ustar godgodimport java.sql.*; import javax.sql.DataSource; import com.mchange.v2.c3p0.DataSources; /** * This example shows how to programmatically get and directly use * an pool-backed DataSource */ public final class UsePoolBackedDataSource { public static void main(String[] argv) { try { // Note: your JDBC driver must be loaded [via Class.forName( ... ) or -Djdbc.properties] // prior to acquiring your DataSource! // Acquire the DataSource... this is the only c3p0 specific code here DataSource unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/test", "swaldman", "test"); DataSource pooled = DataSources.pooledDataSource( unpooled ); // get hold of a Connection an do stuff, in the usual way Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = pooled.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT * FROM foo"); while (rs.next()) System.out.println( rs.getString(1) ); } finally { //i try to be neurotic about ResourceManagement, //explicitly closing each resource //but if you are in the habit of only closing //parent resources (e.g. the Connection) and //letting them close their children, all //c3p0 DataSources will properly deal. attemptClose(rs); attemptClose(stmt); attemptClose(con); } } catch (Exception e) { e.printStackTrace(); } } static void attemptClose(ResultSet o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Statement o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Connection o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } private UsePoolBackedDataSource() {} } c3p0-0.9.1.2.orig/src/dist-static/examples/UseUnpooledDataSource.java0000644000175000017500000000353407657564673023444 0ustar godgodimport java.sql.*; import javax.sql.DataSource; import com.mchange.v2.c3p0.DataSources; /** * This example shows how to programmatically get and directly use * an unpooled DataSource */ public final class UseUnpooledDataSource { public static void main(String[] argv) { try { // Note: your JDBC driver must be loaded [via Class.forName( ... ) or -Djdbc.properties] // prior to acquiring your DataSource! // Acquire the DataSource... this is the only c3p0 specific code here DataSource ds = DataSources.unpooledDataSource("jdbc:postgresql://localhost/test", "swaldman", "test"); // get hold of a Connection an do stuff, in the usual way Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = ds.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT * FROM foo"); while (rs.next()) System.out.println( rs.getString(1) ); } finally { //i try to be neurotic about ResourceManagement, //explicitly closing each resource //but if you are in the habit of only closing //parent resources (e.g. the Connection) and //letting them close their children, all //c3p0 DataSources will properly deal. attemptClose(rs); attemptClose(stmt); attemptClose(con); } } catch (Exception e) { e.printStackTrace(); } } static void attemptClose(ResultSet o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Statement o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } static void attemptClose(Connection o) { try { if (o != null) o.close();} catch (Exception e) { e.printStackTrace();} } private UseUnpooledDataSource() {} } c3p0-0.9.1.2.orig/src/dist-static/examples/c3p0-service.xml0000644000175000017500000000513410213025717021254 0ustar godgod java:PooledDS jdbc:postgresql://localhost/c3p0-test org.postgresql.Driver swaldman test jboss:service=Naming c3p0-0.9.1.2.orig/src/dist-static/CHANGELOG0000644000175000017500000023260610624365741015743 0ustar godgodc3p0-0.9.1.2 -- Fixed a variety of latent, hidden bugs discovered by "findbugs". Many thanks to Carsten Heyl for running this utility and reporting the issues. -- Added lastAcquisitionFailureDefaultUser to ComboPooledDataSource's TO_STRING_IGNORE_PROPS, as some moments' Exception doesn't belong in a DataSource's toString(), and as trying to find this when stringifying close()ed DataSources provoked an infinte recursion (as an Exception was triggered trying to get the last failure info, which tries to include the stringified DataSource in its message, again provoking an Exception, ad infinitum.) Many thanks to Santiago Aguiar for finding and diagnosing this problem. -- Added better documentation of the com.mchange.v2.c3p0.cfg.xml configuration property. [Thanks to Legolas Wood for calling attention to this shortcoming.] -- Calling getHoldability() to find the default Connection holdability provokes an Error on some DB2 drivers. Added a "careful" check which catches and works around this. [Thanks to Lari Hotari for finding the problem, and providing a solution!] -- Refactored NewPooledConnection to not call event multicaster methods while holding the NewPooledConnection's lock. Holding locks while firing events is an old-fashioned way of provoking deadlocks, and it turns out c3p0 was not immune. Whoops! Another embarrassing one. Many thanks to Rhythm Tyagi and Pappu Sharadavani for finding this deadlock! c3p0-0.9.1.1 -- Marked variable "logger" in Log4jMLogger. Rare null pointer exceptions apparently result from a stale value of the previously set variable. Did the same for Log4jMLogger, although no analoguous issue has thus far been reported. [Thanks to Noa Resare and Denis on sourceforge for calling attention to this issue.] -- Hid the attribute "properties" from access via JMX, since it often contains password information. I don't think properties is particularly useful via JMX, and this seems like a better solution than returning properties with a hidden/modified password property, since users might break things unintuitively be resetting a property to a value that, according to the mbean, was the original value. [Thanks to John Sumsion for calling attention to this issue.] -- Fixed bug whereby setting any positive unreturnedConnectionTimeout forced c3p0's default effectivePropertyCycle down to 1 second. [Many thanks to Luke Dang for tracking down this bug.] -- Fixed an embarrassing bug whereby c3p0 was reflective testing for methods (setHoldability and setReadOnly) whose argument types are primitive int and boolean, by looking for Integer.class instead of int.class and Boolean.class instead of boolean.class. [Many thanks to John Kristian for tracking down this subtle, and embarrassing issue very precisely and suggesting the fix.] c3p0-0.9.1 -- Modified logging of uncleared SQLWarnings, so that warnings are emitted at INFO rather than WARNING, and via a dedicated logger [com.mchange.v2.c3p0.SQLWarnings], so that users can easily turn this behavior off. [Thanks to Oleksandr Alesinskyy for calling attention to the annoyingness of unconditionally logging all of this at WARNING.] c3p0-0.9.1-pre12a -- Fixed a NullPointerException in DoubleWeakHashMap that showed up thanks to the newly implemented canonicalization of Jdk14MLog instances. [Many thanks to Carlos Cajina for finding and reporting this bug.] c3p0-0.9.1-pre12 -- Modified Jdk14MLog to canonicalize named MLogger instances. In doing so, put the getLogger() method behind a synchronization barrier, which hopefully will resolve an odd visibility issue bug reported by a user (wherein the underlying jdk Logger appeared occasionally to be null in threads that might have initialized prior to the logger) [Thanks to Denis on Sourcefore for reporting this subtle and interesting issue.] -- Added a lastAcquisitionFailure property to PooledDataSource (and the JMX view thereof). Thanks to Troy Whittier for the suggestion, and the patch! -- SQL Warnings present at Connection acquisition, or uncleared upon Connection checkin are now logged (at WARNING level) and cleared prior to being made available as part of the pool. This is necessary to sustain the invariant that all pooled Connections are identical and interchangible; warnings are Connection state that must be managed and homogenized. [Thanks to Naxe on the hibernate forums for calling attention to this issue!] -- Resolved a rare NullPointerException which occurs when a Statement cache is closed beneath an active, checked out Connection. A client tries to prepare a Statement, but the closed Statement cache throws an NPE. Resolved this by having the closed Statement cache throw a ResourceClosedException, and having c3p0's proxy Statement recover by generating an uncached PreparedStatement. [Thanks to Sven / ford_perfect on sourceforge for finding and calling attention to this issue.] -- Added c3p0 version to C3P0RegistryManagerMBean [Thanks to Sven / ford_perfect on sourceforge for the suggestion.] c3p0-0.9.1-pre11 -- Documentation updates, and style-sheet fixes for FireFox. -- Despite the ugliness, added logic to prepend a VMID to identity tokens generated for c3p0 DataSources. See the docs (Appendix A, other configuration properties) for more information. Though there's little harm in the longer, uglier identityTokens, users who dislike them can turn them off using the property com.mchange.v2.c3p0.VMID. -- Wrote ScatteringAcquireTask, which represents a significant change to how c3p0's underlying resource pool deals with Connections acquisition failures. c3p0 is designed to retry Connection acquisition up to "c3p0.acquireRetryAttempts" times (30 by default) with a delay of "c3p0.acquireRetryDelay" milliseconds (1000 by default) between tries. Should no Connection be successfully acquired after acquireRetryAttempts, c3p0 gives up, logs an error, and frees clients waiting to check out a Connection with an Exception (declaring the pool permanently broken iff c3p0.breakOnAcquireFailure is set to true). Connection acquisition is performed asynchronously by c3p0's thread pool. Under the old implementation, when database Connections could not be acquired, a single task dispatched to the thread pool would hog a thread for the full length of the cycle -- 30 seconds by default -- spending most of that time sleeping between retries. Under the new implementation, each acquisition attempt is its own separate task, and if an acquire attempt fails, a timer is used to schedule a retry adter acquireRetryDelay without hogging any thread. I think the new implementation is unambiguously superior to the old, as it permits clients to use smaller thread pools (c3p0.numHelperThreads) and diminishes the likelihood of apparent thread pool deadlocks. However, it is too significant a change to introduce this late in the "mature" c3p0-0.9.1 series, so the old implementation is enabled by default until the c3p0-0.9.2 development cycle begins. TO USE THE NEW IMPLEMENTATION WITH c3p0-0.9.1, set... com.mchange.v2.resourcepool.experimental.useScatteredAcquireTask=true in a c3p0.properties file or as a system property. Users are strongly encouraged to set this property. You'll see better resource utilization, and I'll get to hear issue reports if I've screwed anything up in the implementation. -- Modified BasicResourcePool so that checkin (and removal) of resources is always synchronous if the pool is marked broken. [Otherwise the check-ins to a closed or broken pool may fail, as they try to use an already close()ed asynchronous task runner.] -- Modified BasicResourcePool.AcquireTask so that an interrupt always forces the whole task to end, not just a single acquisition attempt. -- Exposed numThreadsAwaitingCheckout in PooledDataSource interface and its associated MBean. [Thanks to John Sumsion for suggesting this property.] -- Prevented password from being exposed via DynamicPooledDataSourceManagerMBean. [Thanks to John Sumsion for calling attention to this oversight!] -- Fixed an error whereby DataSources.pooledDataSource( ... ) methods failed to properly set configuration properties defined on PoolBackedDataSource [e.g. numHelperThreads]. Many thanks to John Sumsion for noticing the problem and sending the fix! -- Fixed AbstractConnectionCustomizer to implement (with no-op) methods the current definition of the ConnectionCustomizer interface. (Failed to update after modifying an early version of this interface.) -- Modified NewPooledConnection to only collect stack trace information on close() when we are debugging at FINEST or DEBUG (log4j) level. Previously, stack trace information was collected anytime a c3p0 PooledConnection was close()ed. This was unnecessary, although the performance cost was probably small to negligible, since PooledConnections are typically reused many times before they are close()ed. Stack trace information is still captured when PooledConnections are destroyed due to an error, rather than an ordinary call to close(). -- Hid the getLastXXXFailure(user, password) from the operations list of DynamicPooledDataSourceManagerMBean. The stack traces of failures are visible via the sampleLastXXXFailureStackTrace(); there's no need to expose the Throwbales as well via JMX. -- Added convenience methods getNumPooledDataSources() and getNumPoolsAllDataSources() to C3P0Registry and the related MBean. [Thanks to lukeda on hibernate forums for calling attention to the need for a pool count, since DataSources can wrap multiple pools associated with different authentications.] -- Eliminated the "trial Connection acquisition" added to c3p0-0.9.1-pre10 when PooledDataSources construct the pool with their default authentification information. Effectively we trust that the default auntentification is good, while we distrust client-specified (or JMX-queried) username/password combinations, and perform the extra check. This is a compromise, as users who frequently create and destroy DataSources don't like the extra overhead of the trial Connection acquisition, but we really want to avoid the initialization of bad pools when users misspecify authentification information. We've also prevented mere queries of pool status from triggering the initialization of a non-default-authentification pool. Only calls to getConnection(user, password) will provoke the initialization of a non-default-auth pool. Querying a non-default pool -- e.g. getNumBusyConnections( "steve", "test" ) -- will throw an Exception if no Conections have ever been requested for ("steve", "test") rather than initializing a new pool. [Thanks to Jiji Sasidharan for calling attention to this issue.] -- Finally rationalized C3P0Registry's Object retention policy. C3P0Registry retains references to all C3P0 DataSources, to provide a central point of client access for users, and to ensure that multiple JNDI lookups within a single VM result in the same DataSource instance. This is both intuitive, and avoids multiplying Threads and pools. In previous versions of c3p0, hard references were retained indefinitely. Closed DataSources hold no non-memory resources, and are small Objects, but in unusual scenarios wherein very many c3p0 DataSources are created and destroyed within the lifetime of a single VM, this amounts to a memory leak. C3P0Registry now retains hard references to DataSources so long as they have not been close()ed (or DataSources.destroy()ed). When they have been close()ed, only weak references to c3p0 DataSources persist, and they are eligible for garbage collection. [Thanks to Jeremy Grodberg for calling attention to this as a real-world issue.] -- Removed some of the new pool stat params which distractingly appear in ComboPooledDataSource's toString() method (and c3p0 pools' config dump). c3p0-0.9.1-pre10 -- Exposed statement pool stats via PooledDataSource interface and MBean. Added accessors to the statement cache, pool, pool manager, and AbstractPoolBackedDataSource. -- Fixed a bug whereby multiple near-simultaneous Connection requests failed to provoke sufficient pool growth/Connection acquisition. This is a bug reintroduced in c3p0-0.9.1-pre4, and is a duplicate of an early issue, resolved under the old pool size management scheme. c3p0 must (and does) keep track not only of its current size and pending growth, but also the number of potentially unserved recent Connection requests. c3p0-0.9.1-pre4 thru c3p0-0.9.1-pre9 failed to make use of the incoming request count when deciding whether and how much to grow the pool. Many thanks to John Kristian for calling attention to this subtle issue. -- Exposed information about Connection test failures (failure count of each type of test, stack trace of last failure and last failure of each type) via the PooledDataSource interface and its assiciated MBean. -- Fixed a rare situation where a Connection test on check-out could be performed by a Thread holding the pool's lock, if an initial attempt to checkout a Connection failed and a second checkout attempt is initiated internally. The recursive checkout is now performed without the pool's lock. -- Established a consisent policy re logging of Connection test failures. They are now logged at FINE level (DEBUG under log4j). Previously tests on checkin and checkout were logged at FINE, but idle tests were logged at INFO. Is it worth letting this be configurable, as some users may prefer to see test failures under normal operation? -- Modified C3P0PooledConnectionPoolManager to perform a trial Connection acquisition before trying to establish a pool, as pools established on bad database or authentification information churn indefinitely trying to acquire minPoolSize Connections, clogging up the thread pool and sometimes leading to "APPARENT DEADLOCKS" if users touch a pool with bad authentification information. -- Defined UnifiedConnectionTester (and AbstractConnectionTester) so that ConnectionTesters can provide any Exception associated with a failure, which will show up as the "root cause" of the Exception eventually thrown to signal the failure. -- Added logging at WARNING level when a Connection tester reports the database is invalid, triggering a reset of the Connection pool. c3p0-0.9.1-pre9 -- Updated the documentation. It is now fully current. -- Changed the name of the jboss configuration mbean from com.mchange.v2.c3p0.mbean.C3P0PooledDataSource to com.mchange.v2.c3p0.jboss.C3P0PooledDataSource, in order to distinguish the jboss configuration stuff from the normal management beans, which really are quite different. The old com.mchange.v2.c3p0.mbean.C3P0PooledDataSource still exists, so that existing users don't see anything break, but only the new version will be updated to support new parameters. -- Added a means by which users can suppress JMX MBean registration if they wish. Setting the property com.mchange.v2.c3p0.management.ManagementCoordinator to com.mchange.v2.c3p0.management.NullManagementCoordinator will prevent mbean registration. (Advanced users can also use this to install their own implementations of the ManagementCoordinator interface, though I doubt many people will find this useful.) -- Fixed infinitely loop in ComboPooledDataSource.setFactoryClassLocation( ... ) [introduced with the reorganization of ComboPooledDataSource to inherit from AbstractPoolBackedDataSource (?)] -- Added some code to warn on common spelling errors of c3p0.properties and c3p0-config.xml (Users have frequently mistaken the digit 0 for the letter O in c3p0.) -- Wrote a DynamicMBean for PooledDataSources. It seems to work, covers both ComboPooledDataSource and "wrapping" PoolBackedDataSources, and should cover new config parameters and accessors automatically. -- More refinements to connection test logic. We test proxy Connections when there's a statement cache and a test query (to save time, since the test query is likely cached), we test physical connections if we'll need to do the slow, default test (statement caching doesn't help), or if there is no statement cache. -- Removed the stub servlet I'd previously added. Although it jdk1.5+, the JMX approach is a better one for monitoring and modifying c3p0 pools at runtime, and I'm going to focus on that for now. (If there's a lot of clamor for it, I'll add back and flesh out the servlet. It just doesn't seem like a great use of my time for now.) -- Modified build to create a separate jdk1.3 compatable jar by stripping source of lines beginning with "assert". I want to start using assertions, but will keep them to recognizable, strippable one-liners. -- Modified DriverManagerDataSource to handle its driverClass parameter in a less fragile way. Rather than attempting to load the driverClass on property set, DriverManagerDataSource now lazily tries to load the class upon its first call to getConnection() after the property is initialized or updated. c3p0-0.9.1-pre8 -- Fixed bug whereby jdbcUrl and driverClass were not initialized properly if set in config files rather than in code. [Thanks to Felipe Dominguez for calling attention to this problem!] -- Changed AbstractPoolBackedDataSource from a non-public class in com.mchange.v2.c3p0 to a public class in com.mchange.v2.c3p0.impl to workaround fragilities associated with sun bug id #6342411, wherein reflective invocation of public methods on a non-public class fail, even when involed via a public base-class. -- Fixed NullPointerException (introduced on -pre7) on initializing with a named config. -- Continuing along the same lines, modified C3P0Registry and C3P0ManagementCoordinator to unregister (both from C3P0Registry and associated MBeans on DataSource close. When all PooledDataSources are unregistered, the C3P0RegistryManager MBean unregisters as well. -- Modified ActiveManagementCoordinator to check for, and unregister, the C3P0Registry mbean prior to registration, to prevent conflicts on undeploy/redepoloy cycle. [Thanks to Ben Groeneveld for calling attention to this problem, and suggesting the fix.] -- Modified C3P0PooledConnectionPool to perform Connection tests on the raw physical Connection rather than the proxy Connection, when possible (i.e. when we're using a C3P0 PooledConnection implementation that we know how to get underneath of). This is better because 1) it's slightly faster; 2) it's significantly faster on failure, as C3P0 PooledConnections test Connections after a failure with statusOnException(), leading to an unnecessary double-check; and 3) authors of custom ConnectionTesters can use vendor-specific API to test Connections if they wish. c3p0-0.9.1-pre7 -- Defined the ConnectionCustomizer interface as a hook through which clients can "set up" newly acquired or checked out connections (and clean up prior to check-in or destruction). Added config param connectionCustomizerClassName. -- Formerly unused config parameter propertyCycle now controls how frequently c3p0 checks timestamps against expiration parameters (maxIdleTime, maxIdleTimeExcessConnections, maxConnectionAge, unreturnedConnectionTimeout) -- Added config parameters unreturnedConnectionTimeout and debugUnreturnedConnectionStackTraces, reluctantly but by popular demand. If unreturnedConnectionTimeout is set, Connections will be automatically destroyed and removed from the pool if not returned in the given number of seconds. If debugUnreturnedConnectionStackTraces is also set, stack traces will be captured on check-out of any Connection, and the stack traces that were unreturned and cleaned up by the pool will be logged. Any clean-up of an unreturned Connection is logged at INFO level, in hopes of annoying people into cleaning up their code and close()-ing their Connections reliably. -- Added config parameter maxIdleTimeExcessConnections. Connections in excess of the pool's minimum size will be expired out if they remain idle for longer than maxIdleTimeExcessConnections. [Thanks to Navin M. and Ben Groeneveld for the suggestion.] -- Added configuration parameter maxConnectionAge to limit the absolute age of Connections (age in seconds from acquisition, rather than in seconds form last check-in). -- Put more status accessors in ThreadPoolAsynchronousRunner and exposed thread pool state via JMX (PooledDataSourceManagerMBean). -- Preliminary support for management via mbeans/jmx under jdk1.5+ is implemented. (These mbeans are distinct from the mbean designed for configuring c3p0 under jboss, and are in the package com.mchange.c3p0.management.) Currently, pool statistics are instrumented, as well as pool reset operations, but viewing and modifying the pool configuration parameters is not supported. (I'll write a dynamic mbean to capture this stuff; there are too many config properties I'm already updating by hand in too many places. Later.) [Thanks to Ben Groeneveld for the suggestion, including some nice sample code!] -- Added configuration parameter maxAdministrativeTaskTime, which forces interrupt() to be called on pool administrative tasks (Connection acquisition, destruction and testing; prepared statement destruction) if these tasks seem to hang. This is one strategy for dealing with database that hang and lead to deadlock messages and eventually large memory footprints. It's useful only if the hanging operations respond to interrupt()s, not thread-monitor related deadlocks (which hopefully don't ever happen). c3p0 should recover from any Exceptions provoked by the interrupt() calls. (Hopefully improvements to GooGooStatementCache have rendered this parameter largely unnecessary by resolving the most common source of deadlocks.) -- Major revision to GooGooStatementCache that may eliminate most APPARENT DEADLOCK messages. c3p0-0.9.0 introduced a complicated implementation of closeAll(), in order to ensure that Statement and Connection close did not happen simultaneously. Upon review, there was a significant bug in the implementation, and even when corrected, the strategy is itself prone to deadlocks should the ThreadPool become saturated with destroy tasks, which block awaiting statement remove tasks. Rewrote closeAll() as a simple synchronous method, rather than simulating synchrony with wait()/notifyAll(), but with care not to hold the StatementCache's lock during Statement.close() calls. There is a slight loss of asynchrony, as Statement.close() methods are executed sequentially rather than simultaneously, but as a practical matter, since the sequential destruction occurs asynchronously in the thread pool and is invisible to clients, both client-observed and over-all performance should not suffer. (It may even be improved, as the 0.9.0.x strategy was complicated and had some overhead.) Note: This revision should also eliminate occasional ConcurrentModificationExceptions associated with the Statement cache. -- Changed asynchronous tasks implemented as anonymous inner classes to named inner classes, so that users reviewing active and pending tasks (usually in trying to make sense of an APPARENT DEADLOCK) have a better idea of what's going on. -- Major revision to GooGooStatementCache that may eliminate most APPARENT DEADLOCK messages. c3p0-0.9.0 introduced a complicated implementation of closeAll(), in order to ensure that Statement and Connection close did not happen simultaneously. Upon review, there was a significant bug in the implementation, and even when corrected, the strategy is itself prone to deadlocks should the ThreadPool become saturated with destroy tasks, which block awaiting statement remove tasks. Rewrote closeAll() as a simple synchronous method, rather than simulating synchrony with wait()/notifyAll(), but with care not to hold the StatementCache's lock during Statement.close() calls. There is a slight loss of asynchrony, as Statement.close() methods are executed sequentially rather than simultaneously, but as a practical matter, since the sequential destruction occurs asynchronously in the thread pool and is invisible to clients, both client-observed and over-all performance should not suffer. (It may even be improved, as the 0.9.0.x strategy was complicated and had some overhead.) -- Users still occasionally report seeing "APPARENT DEADLOCK" messages from ThreadPoolAsynchronousRunner. Previously, most reports had to do with cached PreparedStatements that hang when closed. Previous fixes (in 0.9.0) seemed to resolve these problems. Most new reports have to do with Connection acquisition or Connection close() tasks hanging indefinitely, with statement cacheing not necessarily involved. It's unclear whether these reports stem from a c3p0 bug, or rare situations in which various JDBC driver hangs hang c3p0. (If the condition is temporary, c3p0 recovers after the "APPARENT DEADLOCK" warning. In any case, ThreadPoolAsynchronousRunner has been modified to provide much better debug information, particularly in jdk1.5 environments, where hung Thread stack traces are dumped. -- Modified the build file and refactored C3P0Config / C3P0ConfigUtils / C3P0ConfigXmlUtils to make sure that c3p0 still runs under jdk1.3, even though it only builds under jdk 1.5. JMX support is 1.5 only, and XML config depends on the availability of standard XML extensions under jdk 1.3. (This is going to get harder, as I hope to start using assertions. For the moment, assertions are commented out. I think I'll have ant filter away the assertions for 1.3 builds and leave them in otherwise, based on a build property. -- Significantly reorganized (hopefully simplified) of C3P0Registry and ComboPooledDataSource. Much of the complication of all this is supporting the most annoying, least used, but nevertheless very important feature of supporting JNDI lookups across JVM boundaries via Serialization or JNDI References. -- Reorganized ComboPooledDataSource to inherit from PoolBackedDataSource. In doing so, changed setConnectionPoolDataSource() of PoolBackedDataSource to throw a PropertyVetoException. (It is a "constrained property" now.) The very, very few users who call this method directly may have to update their code to handle the potential Exception. This change does not affect compatability for clients that use ComboPooledDataSource or who create PoolBackedDataSources via the c3p0's factories (e.g. DataSources). -- Fixed bug whereby config parameter breakAfterAcquireFailure did not take effect at the ResourcePool level. -- Fixed bug whereby initialPoolSize parameter failed to take effect at the ResourcePool level. -- Fixed a bug whereby Connection tests on checkout held the pool's lock, preventing other activity during the Connection test. [Thanks to John Sumsion for calling attention to this subtle problem.] -- ThreadPoolAsynchronousRunner has seen some minor efficiency improvements (a task that calls interrupt() long-running tasks on post-deadlock blocked, replaced threads no longer runs when there are no post deadlock blocked, replaced threads). -- Previous versions used a Stringified identityHashCode() as a unique ID for various C3P0 objects. This was not correct (and bit at least one user in practice), as identityHashCode()s are not guaranteed unique, and in practice are not on 64-bit VMs. c3p0 now checks identityHashCodes to make sure they are not reused, and if seen before appends a count to keep unique IDs unique. [Many thanks to Prishan Makandurage for calling attention to this issue.] -- Fixed fact that statusOnException() in NewPooledConnection() ignored preferredTestQuery parameter, always using the very slow default connection test rather than the user-defined test. [Thanks to Andrea Luciano for calling attention to this issue.] -- C3P0PooledConnection (part of the "traditionalReflectiveProxies" codebase that's largely been superceded, but that is still nominally supported) held a static reference to a ClassLoader, in some cases preventing the ClassLoader from being garbage collected (for example when webapp contexts, with context specific Classloaders are undeployed by some app servers). This was entirely unnecessary, as the cached reference was used exactly once in the lifecycle of the class. The reference to the ClassLoader is no longer stored. [Many thanks to Michael Fortin for very specifically tracking down this subtle problem!] -- Added logic to log individual acquisition failures at INFO level if acquireRetryAttempts <= 0. if num_acq_attempts <= 0, we try to acquire forever, so the end-of-batch log message below will never be triggered if there is a persistent problem so in this case, it's better flag a higher-than-debug-level message for each failed attempt. [Thanks to Eric Crahen for calling attention to this issue.] c3p0-0.9.1-pre6 -- Wrote a stub of a status-monitoring servlet. Not yet documented, or even usefully functional, but hopefully will be soon. -- Updated documentation to include new config file format, including named and per-user config. Docs could still use some work, but the functionality is now described. -- For consistency, the parameters user and password are now configurable via config files and System properties. -- Modified DefaultC3P0ConfigFinder to properly give greater precedence to System properties than to XML-defined unspecified user, default config values. -- Added WARNING logging of create SQL and original database Exception when creation of an automaticTestTable fails. [Thanks to Alexander Grivnin.] -- Added logic so that the Exception assoicated with the last failed acquisition attempt in a round of attempts is logged along with the failure if the acquisition attempts. [Thanks to Barthel Steckemetz and Patrick Eger for calling attention to this issue.] -- Fixed a problem whereby modifying the config of a ComboPooledDataSource programmatically, while in use, causes previously checked-out Connections to be close()ed underneath the user. Changing configs midstream still causes a complete resetting of the pool (because the pool holds most config params as immutable to avoid having to synchronized for every config param read), but old Connections from superceded pools will remain valid until they are rechecked into the pool. [Thanks to hhu for noticing this problem!] -- Fixed a resource leak whereby Connections which could not be reset after client-initiated close() were properly "excluded" from future inclusion in the pool, but never checked back into the pool to be destroyed. (Excluded resources are simply marked for destruction rather than reassimilation on checkin.) [Many thanks to Levi Purvis for tracking this down!] c3p0-0.9.1-pre5a -- "test-classpath" was erroneously specified in build.xml to include some extra jar files, which rendered undetectable (to my tests) the fact that com.mchange.v1.lang.BooleanUtils was not jarred up into c3p0-0.9.1-pre5.jar as it needed to be. Very, very embarrrassing. [Thanks to Goksel Uyulmaz for calling attention to this gaffe.] c3p0-0.9.1-pre5 -- reorganized synchronization of getConnection() in DriverManagerDataSource, so that a lock-up in one Connection acquisition attempt does not prevent other threads from accessing the DataSource. [Thanks to Fabian Gonzalez for calling attention to this occasional deadlock.] c3p0-0.9.1-pre4 -- added overrideDefaultUser and overrideDefaultPassword parameters, and a pooledDataSource( ) factory method which specifies override authentification info, regardless of the user and password properties set on the DataSource. -- Reimplemented resource acquisition in BasicResourcePool so that each Connection acquisition is a separate asynchronous task, to avoid tying up the pool with very long, multiple acquisition tasks. Ended up being a total rewrite of pool size management. Pools should be much more conservative in acquiring new Connections. They won't grow to maxPoolSize as easily as before. This is a big change. We'll see how it holds up as people beat the crap out of it. c3p0-0.9.1-pre3 -- Added some extra logging of resource destruction, to help debug cases where the resources are removed from the pool, but appear not to have been properly cleaned up. -- Finished implementation of new C3P0Config, added constructor methods to various DataSource implementations that accept a configName parameter for named configurations, and modified the DataSources class to use the new configuration approach instead of PoolConfig wherever possible. c3p0-0.9.1-pre2 -- Continued implementation of new C3P0Config, including XML parsing and setting of default values. Still have to test XML config, and implement named and per-user configs. -- Changed policy of BasicResourcePool to keep accidentally overacquired resources so long as the pool is kept below maxPoolSize, rather than immediately discarding Connections beyond the number we intended to acquire. -- Fixed two issues whereby checking in resources to closed pools (both Connection and Statement pools) provoked Exceptions. Check-ins should succeed, even to close()ed pools, with resources silently destroyed if the pools ae closed. [Thanks to Chris Kessel for finding both of these issues.] -- Modified to a one-statement-cache-per-pool model, rather than a global-statement-cache-for-all-pools, consistent with the general philosophy that config parameters are on a per-auth-pool basis. -- Fixed a deadlock which could occur if a pool is closed at the same time as one of its Connections is closed. One thread gets the pool's lock, then tries to get a PooledConnections lock to close it. An ordinary client closes a Connection, which acquires the PooledConnection's lock, and then tries to check back in to the pool, requiring the pool's lock. Broke the deadlock by making the destruction of resources on pool close asynchronous, by a Thread without the resource pool's lock.. [Many thanks to Roger Westerlund for sending a full thread-stack dump capturing this deadlock!] -- Completed transformation to one C3P0PooledConnectionPoolManager per PoolBackedDataSource model. c3p0-0.9.1-pre1 [This is a half-assed internal release... it compiles and works, but mostly it's just a checkpoint as c3p0 undergoes significant transformations.] -- Deprecated PoolConfig, and began implementation of new C3P0Config approach to configuration. -- Partial transformation of C3P0PooledConnectionPoolManager from shared-manager for several DataSources model to simple one-pool-per-DataSource model enabled by canonicalization of DataSources. c3p0-0.9.0.4 -- In a subtle but major modification of BasicResourcePool, changed checkin/checkout behavior from FIFO to LIFO to increase the likelihood that unnecessary Connections pooled at peak times idle long enough to expire. [Many thanks to Vlad Ilyushchenko and hontvari on sourceforge for noticing this important issue and suggesting the fix.] c3p0-0.9.0.3 -- Added code to mbean C3P0PooledDataSource to automatically create JNDI subcontexts if a JNDI name is specified for which the full path has not been created (analogous to mkdir -p in UNIX). [Thanks to David D. Kilzer for noticing the issue, and for submitting the fix!] -- Added logic to GooGooStatementCache to ensure that multiple threads do not try to close the same PreparedStatement, in order to try to resolve longstanding PreparedStatement.close() freeze issues. [Thanks to cardgames on sourceforge for noticing that the freezes seem to occur when several threads are trying to close() just one statement!] -- Added some checks in DriverManagerDataSource (as well as WrapperConnectionPoolDataSource) so that a mismatch between JDBC URL and driver does not lead to null Connection references and downstrem NullPointerExceptions. [Thanks to Richard Maher for calling attention to this issue.] -- Undid some unnecessary synchronization in WrapperConnectionPoolDataSource, which would cause deadlocks when the acquisition of a Connection from the underlying driver froze for some Thread. (Other threads would then block trying to access the WrapperConnectionPoolDataSource.) [Thanks to Fabian Gonzales for calling attention to this issue, and for providing a VM thread stack dump to help chase it down!] -- modified BasicMultiPropertiesConfig to never attempt to read the resource "/", representing (in this case) System properties, as a stream, which under some classloaders caused ClassCastExceptions. [Thanks to Joost Schouten for calling attention to this issue.] -- fixed initial check of the readOnly and typeMap properties of Connections, so that users don't see disconcerting Exceptions at debug log levels if their drivers don't support these parameters. -- Added jar attributes Extension-Name, Specification-Vendor, Specification-Version, Implementation-Vendor-Id, Implementation-Vendor, and Implementation-Version [per request of Pascal Grange]. -- Added some extra debugging information for peculiar situation where an IdentityTokenized is constructed and registered with C3P0Registry, but coalesces to a different Object. This should never happen, as freshly constructed IdentityTokenizeds should have String versions of their identity hashcodes as tokens, and upon their registration, no copies should yet have been created and registered. [Thanks to Jose Rodriguez for noting this issue.] c3p0-0.9.0.2 -- added debug-level logging of connection tests and results -- tightened up means by which the readOnly and typeMap properties of Connections are reset, so that users don't see disconcerting Exceptions at debug log levels if their drivers don't support these parameters. -- fixed problem in BasicResourcePool that left the immediately-close-checked-out-connections option in the close() method ineffective, meaning Connections checked-out from a pool would leak unless clients remembered to check them into pool for destruction. -- fixed bug wherein connection-testing on checking occured in a thread holding the pool's lock, leading to pool hangs or deadlocks if a connection hangs. [Thanks to Tobias Jenkner for calling attention to this problem!] c3p0-0.9.0.1 -- modify BasicPropertiesConfig to not throw class cast Exceptions in the rare case that a Properties object (presumably System properties rather than a file derived props Object) contains (via the Map/Hastable API) non-String keys or values. [Thanks to Prima Upot for calling attention to this issue.] -- fixed a build issue where some classes required for code generation were not necessarily compiled prior to the code generation step, causing builds to fail. [Thanks to James Neville for calling attention to this issue.] c3p0-0.9.0 -- under some circumstances, the current list of ThreadPoolAsynchronousRunner's deadlock detector seems to hold onto a lot of memory... presumably this is when long pending task lists build up for some reason... nevertheless, we now dereference the "current" list in between deadlocker detector invocations. The "last" list has to be retained between invocations, but the "current" list need not be. [Thanks to Venkatesh Seetharamaiah for calling attention to this issue, and for documenting the apparent source of object retention.] -- modified log4j and jdk14logging MLog implementations to test for library classes upon classload (MLog class only tests for the presence of the mlog implementations, which doesn't notice if their dependant classes aren't there -- dependent classes must test for the presence of the libraries.) -- Modified GooGooStatementCache to warn as INFO (and with a descriptive message in debug) of multple PreparedStatement preparation. [Thanks to mxnmatch on hibernate's forum for calling attention to this issue.] -- Modified BasicResourcePool to not warn on expected InterruptExceptions that occur if clients are waiting for a Connection when the pool is closed. [Thanks to Blunted on hibernate's forum for calling attention to this issue.] c3p0-0.9.0-pre6 -- Modified thread pool's strategy for dealing with deadlocks to prevent OutOfMemoryErrors from sudden spawning of multiple threads to clear backlogged tasks. [Thanks to Greg Whalin for calling attention to this problem.] -- Fixed bugs in debug reporting of nested Exceptions/Warnings when converting or rethrowing SQLExceptions [thanks to an anonymous sourceforge poster for finding this] -- modified BasicResourcePool to shorten the period during which the pool's lock is held during resource acquisition -- maxIdleTime is generally enforced every (maxIdleTime / 8) seconds. Added logic to ensure that even for very long maxIdleTimes, the longest maxIdleTime will ever go unenforced is 15 minutes. -- Very tentative initial support in build for JUnit tests -- Fixed documentation typos and added sample config for Tomcat 5.5. [Thanks to David Newcomb for finding the typos and to Carl F. Hall for the sample config!] -- ProxyConnections were not properly resetting readOnly, holdability, catalog, and typeMap properties on Connection close. Fixed. [Thanks to Andy (bjorkmann?) for calling attention to this bug.] -- Added a complicated workaround to issues that may occur when a Connection and its child statements simultaneously try to close. GooGooStatementCache's closeAll(Connection c) method now wait()s for all Statements to close prior to returning, avoiding such issues (Oracle deadlock, mysql NullPointerException), though dramatically complicating the code. Grrr. Theoretically, drivers should be robust to the simultaneous closing of Statements and Connections, but they're not, so my code gets to be more complicated. [Thanks to Juan Perez, Daniel Edberg, and Damien Evans for calling attention to this issue.] c3p0-0.9.0-pre5 -- Proxy classes were overaggressively invalidating themselves in response to a signalled Connection error. This problem was very similar to the problem fixed in 0.8.5-pre9, except for rather than the PooledConnection too quickly closing its inner Connection, the proxies too quickly detached themselves from the pooled Connection, considering themselves broken, after a Connection error event. Users expect to be able to work with their Connections even after c3p0 has in its conservatism decided they no are no longer worthy of a place in the pool. [Thanks to "Geoff Fortytwo" for finding and helping to track down this issue.] -- Fixed issue that prevented user-defined ConnectionTesters from being used. c3p0-0.9.0-pre4 -- Fixed NullPointerException on double-close of proxy Statements. [Thanks to Stephen Waud for finding this bug and tracking it down.] -- Modified C3P0PooledConnectionPool to generate a more informative Exception (one that includes the stack trace of the initial problem) when a Connection test fails. [Thanks to novotny from the hibernate forums for calling attention to this issue.] ` -- PooledDataSources now set SQLState 08001 on SQLExceptions resulting from a determination by the pool that the database is down or unavailable. [Thanks to ml2709 on the hibernate forums for calling attention to this issue.] -- Modified ThreadPoolAsynchronousRunner to enforce its max task time even on one-off "emergency threads" used to flush the pool of tasks after an apparent deadlock. Hopefully this will help to eliminate the OutOfMemoryErrors that users occasionally see if some Database operation starts to fail by blocking indefinitely, and is attempted many many times. As long as these operations are susceptable to interrupt(), this should resolve the problem. (If tasks block in a way that is immune to interrupt(), there is little c3p0 can do to recover the Threads and prevent the number of blocked Threads from growing until memory runs out.) [Thanks to Jean-Christophe Rousseau and Arup Vidyerthy for calling attention to this issue.] -- Wrapped System.getProperties() calls in try / catch blocks that catch and log the SecurityExceptions, and ignore System properties if access to them is forbidden. c3p0.properties configuration should work fine in security-controlled apps, but you won't be able to configure c3p0 using "java -Dc3p0.xxxx=yyy ..." Since most users use c3p0.properties for configuration, I don't think this will be a major problem. In the future, I may be able to work around the restriction by having ask only for c3p0-specific System properties, rather than calling the unrestricted System.getProperties() method. [Thanks to zambak on SourceForge for calling attention to this issue.] c3p0-0.9.0-pre3 -- Modified generated proxy classes to properly report the type of the closed Object if used after call to close(). -- Fixed a really embarrassing oversight, wherein cached PreparedStatements were being physically close()ed prior to their return to the cache! Tests on psql failed to reveal this, because psql-7.4 Statement.close() does nothing to invalidate the Statement! [Many thanks to tbayboy on hibernate's forum for discovering this issue, and to fassev, also on hibernate's forum, for correctly deducing the cause!] -- Fixed an embarrassing oversight where operations of proxy Statements and ResultSets failed to mark transactions as potentially dirty, leading to the possibility that Connections with unresolved transactional work could be checked into the pool. -- Modified c3p0 Statements to no longer permit calls to getConnection() after Statement close, and to null out the backreference to the parent Connection. [Thanks to Edward Bridges for pointing out the issue.] -- NewPooledConnection threw a NullPointerException on close() of a ResultSet whose creating Statement had already been closed. Fixed. [Thanks to Edward Bridges for pointing out the problem.] -- Modified PoolConfig to trim() read-in c3p0.properties to avoid NumberFormatExceptions if there is extra spacing in the file. [Thanks to johnchan for calling attention to this issue.] c3p0-0.9.0-pre2 -- Documentation updates and improvements -- Integrated configurable wrapper logging library, so that c3p0 can log to log4j or jdk14logging. c3p0-0.9.0-pre1 -- First pass at documentation of JBoss integration. -- Better one-per-JVM canonicalization (IdentityTokenized, IdentityTokenResolvable, C3P0Registry) -- First implementation of MBean for JBoss compatability -- Fixed JNDI ref-based DataSources c3p0-0.8.5.1 -- Fixed a really embarrassing bug that made Statement pooling worse than useless where users have set maxStatements but not maxStatementsPerConnection. maxStatementsPerConnection -- that is, 0 -- was being used in place of maxStatements on Statement cache initialization. [Thanks to Gwendal Tanguy for not only, calling attention to this issue, but tracking down the precise location of the bug!] c3p0-0.8.5 -- Documentation updates and improvements -- Fixed an issue where failures on reset() of a pooled Connection caused a Connection error to be signalled, without updating the status of the PooledConnection to indicate that it is broken. Thanks to Henry Le for calling attention to this issue. c3p0-0.8.5-pre9 -- Modified c3p0's behavior on detecting an apparently broken Connection. Previously c3p0 would very aggressively close any Connections that, after an Exception, failed to pass a Connection test. This sometimes surprised and confused users, when Conections they expected to remain open were closed from underneath them. Under normal circumstances, a Connection which has failed its Connection test is broken anyway, so closing it does no harm. But under some circumstances, a Connection may fail its Connection test, but still be partly functional from the application's point of view. So, now c3p0 simply marks Connections that fail their Connection test following an Exception as broken, and excludes them from future re-entry into the pool, but leaves those Connections open for users to continue working with them prior to their explicit close() of the Connection. [Thanks to Julian Legeny for calling attention to this issue.] -- Modified c3p0's logging behavior to be a little bit less annoying. Rather than frequently printing duplicate stack traces to be sure root cause Exceptions are logged as well as converted, rethrown Exceptions, c3p0 now checks the Java version, and uses the initCause() method to log the root cause in versions 1.4 and above. Also, some Exceptions that were expected and thrown without information as to the cause now use the initCause() method to provide this in JDK 1.4 and above. [Thanks to Ruslan Gainutdinov, Anthiny Pereira, Carsten ????, and Eric Hsieh for calling attention to these issues.] -- Fixed bug whereby proxy wrappers were sometimes placed around null return values from native Objects, particularly Statement's getResultSets() method. [Thanks to Ruslan Gainutdinov for calling attention to this issue.] -- Fixed bug in NewProxyConnection whereby setTransactionIsolation was called even if the Connections' isolation level had not been changed from its default. [Thanks to Levent Aksu for reporting this bug.] c3p0-0.8.5-pre8 -- Added C3P0ProxyStatement and rawStatementOperations for accessing vendor-specific Statement API. -- Fixed bug whereby recently added properties could not be configured properly via a PoolConfig Object passed to the DataSources factory method. [Thanks to Julian Legeny for finding this bug.] -- Undid new behavior whereby c3p0 warns when it detects that a transaction has not been comitted or rolled-back prior to close and must be automatically rolled-back. Because c3p0 autorollsback conservatively, whenever it is possible that there may be any transactional resources held by the Connection being checked in, users who make read-only queries, then close without commit or rollback, saw the warning, and became annoyed. Warning when it's "right" is hard, and would involve paying attention to the substance of user-queries, as well as the transaction's isolation level. In the future, when c3p0 offers better control over logging, we'll make the warning optional. Note that this release only undoes the warning -- the new logic that detects potential transactional work and only rollsback when there has been some remains. [Thanks to David Graham for calling attention to this issue.] -- Synchronized StatementCacheKey.find( ... ) method. Subclasses of StatementCacheKey have always explicitly relied upon this method being synchronized in the parent class, but somehow it was not... [Thanks to Manfred Hutt for reporting this bug.] -- Modified both PooledConnection implementations to reset the transaction isolation level on PooledConnection.reset() -- Finalized PooledDataSource api for pool stats and resets. c3p0-0.8.5-pre7a -- Fixed some bugs in new Proxy classes relating to close(), methods, especially NullPointerExceptions on duplicate close() operations. -- Fixed some misleading documentation re: testConnectionOnCheckin and automaticTestTable vs. preferredTestQuery -- Changed wording of warning message on purge of idle-test-failing resource to no longer suggest that some user action is required. [Thanks to Krishna Kuchibhotla for calling attention to this issue.] -- Modified GooGooStatementCache so that its close() is synchronous, since when the Statement cache is closed, it's asynchronous runner has often been closed already underneath it. (Actually changed as of c3p0-0.8.5-pre7, but forgot to log it.) c3p0-0.8.5-pre7 -- Added flag (in both new and tradional reflective proxies) to prevent automatic rollbacks on Connection close()es immediately post- commit(), rollback(), or setAutoCommit(). -- DatabaseMetaData now properly returns proxy rather than naked raw Connection. [Thanks to jhoeller on the hibernate forums] -- In response to an apparent BEA WebLogic specific problem with DriverManager.getConnection( ... ), DriverManagerDataSource now caches its driver and uses Driver.connect( ... ) rather than DriverManager.getConnection() when acquiring Connections. Thanks to Lars Torunski for calling attention to this issue. -- Fixed some missing synchroniztion that really should be provided for accessors and mutators of DataSource bean properties. -- Added config parameter automaticTestTable, which takes the name of a table that c3p0 will create and use as the basis for Connection tests. It's easier to use than preferred test query, because you don't have to ensure the existance of any tables in the schema prior to using a Pooled data source. -- Fixed idiotic oversight whereby Connections didn't get their transaction status resolved and reset on check-in... c3p0-0.8.5-pre6 -- Modified resource pools to only conditionally support async ResourcePoolEvent generation. Since c3p0 doesn't use ResourcePoolEvents, we can do without the superfluous CarefulRunnableQueue, and its associated Thread, which was serving as an event queue. -- Fixed bug where asynchronous refurbishment (testing) of resources would be attempted even on check-in to a closed pool, whose async threads had terminated. -- c3p0 now supports the following new configuraion parameters: preferredTestQuery, testConnectionOnCheckin, checkoutTimeout, and maxStatementsPerConnection. preferredTestQuery should allow c3p0 to test Connections (whether on checkout, checkin, or after a specified idle time) much more efficiently than with it's default test [a call to getTables(...) on the Connection's DatabaseMetaData.]. checkoutTimeout allows clients to break out of a getConnection() call after a a specified time period, rather than waiting (potentially indefinitely) for a new Connection to be acquired from the database, or a checked-out Connection to be rechecked in. testConnectionOnCheckin should be self-explanatory. maxStatementsPerConnections allows users to specify how many statements to cache on a per-connection base instead of, or in addition to, the global limit maxStatements. -- Fixed various bugs relating to the referenceMaker and getReference() method of ComboPooledDataSource. -- Added TestUtils class to util package (modified from an old C3P0TestUtils class now removed from the test directory), which now contains facilities for establishing the identity of the physical Connection beneath a proxy, so that tests can check to see when they are seeing the same physical Connections recycled. [Thanks to Julian Legeny for calling attention to this issue.] -- Modified code generators so that inner objects of all NewProxy classes go to null on object close(). Closed proxies should be hopelessly broken. -- Added missing parameter "usesTraditionalReflectiveProxies" to ComboPooledDataSource -- Fixed bug whereby CarefulRunnableQueue threads linger indefinitely, even though their close() method has been called. [Thanks to muirwa on the hibernate forums for calling attention to this issue.] c3p0-0.8.5-pre5 -- added utility class for Oracle users who wish to access vendor specific Connection API relating to BLOBs and CLOBs. [Thanks to Dave Smith for calling attention to this issue.] -- modified ThreadPoolAsynchronousRunner to provide more information should an "apparent deadlock" occur, and fixed that class' recovery strategy from such an event. [Thanks to Damien Evans for calling attention to this issue.] c3p0-0.8.5-pre4 -- added config parameter usesTraditionalReflectiveProxies, which defaults to false, and stitched in the 'new' codegenerated, non-reflective proxy implementation for the default case. c3p0-0.8.5-pre3 -- Added new config parameters breakAfterAcquireFailure, acquireRetryAttempts, and acquireRetryDelay to ComboPoolBackedDataSource (forget to modify this class when I added the params earlier.) -- Added description of raw connection operations to docs. c3p0-0.8.5-pre2 -- Defined AuthMaskedProperties object, and used this to prevent usernames and passwords from being dumped to logs (a security issue). [Thanks to Zac Jacobson for calling attention to this issue.] -- Made BasicResourcePool's refurbishment of checked-in resources asynchronous, and used this to add a test of the resource on check-in. But since the extra test may slow stuff down substantially, I've disabled it pending a testConnectionsOnCheckin config parameter. -- Fixed NullPointerException in C3P0ImplUtils.findAuth(Object o) which occurred when the Object at issue had write-only properties. [Thanks to mrfekson for calling attention to this issue.] -- Added acquireRetryAttempts, acquireRetryDelay, and breakAfterAcquireFailure as configurable properties. Supporting breakAfterAcquireFailure == false required substantial changes to BasicResourcePool. [Thanks to Zac Jacobson for suggesting the behavior for breakAfterAcquireFailure == false.] -- Added poolOwnerIdentityToken property to PoolBackedDataSource, which becomes part of the state of C3P0PooledConectionPoolManager, to avoid possibility that multiple, identically configured pools that users create separately and consider distinct would be closed if any one of them were closed. This parameter ensures that for each user-created DataSource, there will be a distinct C3P0PooledConectionPoolManager. Multiple copies, as often arise via deserialization and/or dereferencing JNDI DataSources, will still share a single pool and configuration. -- Added reset methods, hard and soft, to PooledDataSource and its implementations. Also added some extra aggregate pool statistics methods. [Thanks to Travis Reeder for suggesting the hardReset() behavior.] -- Fixed bug that PoolBackedDataSource always provided statistics for the default authentication pool, even when alternate usernames and passwords were provided. c3p0-0.8.5-pre1 -- Defined the C3P0ProxyConnection interface, and modified both reflective and unreflective proxy Connection code to implement it. The interface provides a method through which advanced users can work with the raw, unproxied database Connection. This was motivated by some Oracle-specific API that could not be passed through the generic Connections returned by c3p0 pools. Thanks to Dave Smith for calling attention to this issue. -- Fixed a NullPointerException that resulted when users called DriverManagerDataSource's getConnection( username, password ) with either username or password as null. Users will now see the SQLException provided by their database for bad authentication, which should make the problem more obvious. c3p0-0.8.4.5 -- Modified all variants of StatementCacheKey, as well as C3P0PooledConnection (proxy Statements) to support jdbc3.0 API for autogenerated keys and ResultSet holdability. All jdbc 3.0 API is now supported. c3p0-0.8.4.2 -- Fixed bug in which proxy Statements and ResultSets returned their naked, unproxied parents from their getConnection() / getStatement() methods. Thanks to Christian Josefsson for noticing this! -- Added check to ensure that ResourcePools are not broken prior to posting asynchronous events. It'd be better to factor the (as yet unutilized async event stuff into a subclass to simplify BasicResourcePool). -- Fixed documentation typo that said default numHelperThreads was "false"... now it's correctly set to "3". -- Added extra System.err information to instrument the causes of broken resource pools. -- finalize() method of BasicResourcePool checks to be sure user has not already closed the pool before closing, to avoid spurious multiple close warnings. Thanks to Gavin King. c3p0-0.8.4.1 -- Added (hopefully not too annoying) dump of DataSource configuration on pool initialization to assist user debugging. -- Added methods to force destroy all resources used by a PooledDataSource, even if other DataSource instances are sharing those resources. This is intended primarily for applications that wish to discard the ClassLoader that loaded c3p0, regardless of whatever's currently going on. -- Turned off annoying trace messages when a C3P0PooledConnection closes. -- Fixed issue in statement cache whereby statements that fail to check-in properly (that throw an exception in "clearParameters") cause an exception in removeStatement, because removeStatement sees a statement that appears neither to be checked-out, nor in the deathmarch for checked-in statements. Resolved by re-adding truculent statement to the checkedOut set, and then destroying using removeStatement's codepath for removing and (force-)destroying checked-out statements. Thanks to Zach Scott for calling attention to this issue. c3p0-0.8.4 -- Updated and HTML-ized documentation, updated READMEs. c3p0-0.8.4-test5 -- Includes, but does not yet use, cleaner, nonreflective reimplementation of C3P0PooledConnection and all of the JDBC proxy wrappers. (c3p0-0.8.4 will stick with the old, tested implementation, c3p0-0.8.5 will replace.) -- Removed temporary debug wrapper around acquired Connections added in c3p0-0.8.4-test4-3. c3p0-0.8.4-test4-3 -- Fixed race condition in BasicResourcePool close(), whereby pooled resources were to be destroyed by an asynchronous thread that itself was shut down by the close() method, so the resource closures did not necessarily occur. Pooled resources are now destroyed synchronously in BasicResourcePool.close() -- Fixed erroneous call to C3P0PooledConnection reset() even when the PooledConnection is known to be broken. -- Added temporary debug wrapper that dumps a stack trace on physical Connection close() to help Adrian track down a stubborn issue. c3p0-0.8.4-test4 -- Made sure PooledConnection's that are known to be broken are not reset() when the ProxyConnection that noticed the break cleans itself up. -- Fixed a problem in C3P0PooledConnection's ProxyConnectionInvocationHandler when Connection-invalidating exceptions occurred inside the factored-out doSilentClose() method rather than in the invoke() method. This could lead to broken PooledConnections not being noticed and expunged from the pool prior to recheck-out. -- Ensured stack-trace of any Connection-invalidating Exceptions are logged. (Previously only the messages were logged.) -- Access to ProxyConnections is now synchronized to avoid a possible race condition where a Connection could close while another method was in progress. -- Cleaned up C3P0PooledConnection a bit, got rid of no longer used reflective code, modified to use new SQL interface filter classes. -- Reorganized bean generation stuff to sit under com.mchange.v2.codegen -- Added com.mchange.v2.sql.filter package, and code generation stuff so that abstract filter classes that implement JDBC interfaces can be easily regenerated from current versions. (This is preparation for JDK 1.4.x build support.) c3p0-0.8.4-test3 -- Reorganized C3P0PooledConnection and C3P0PooledConnectionPool so that PooledConnections only fire connectionErrorOccurred events on errors that signal the Connection is invalid. (Previously we fired the event in all cases, then tested the validity of the connection in the event handler.) -- Fixed a bug where SQLExceptions that do not signal invalid Connections (such as an exception on transaction commit under optimistic concurrency) caused Connections to be closed, but still returned to the pool, leaving the pool corrupt. [Thanks to Adrian Petru Dimulescu for discovering and reporting this subtle problem!] c3p0-0.8.4-test2 -- Backed off a binary incompatible change to DataSources API. Users interested in statistics about running DataSources will need to cast the result of DataSources.pooledDataSource() to a com.mchange.v2.c3p0.PooledDataSource object. Other users should be able to use DataSources without recompilinbg libraries that depend upon it. -- Defined com.mchange.v2.c3p0.ComboPooledDataSource, a single, directly-instantiable JavaBean-style DataSource backed by a c3p0 pool, which makes integration with various app servers easier (e.g. works with Tomcat), and which may provide a more straightforward API for users than DataSources and PoolConfig. c3p0-0.8.4-test1 -- Switched various classes from using RoundRobinAsynchronousRunner to a new ThreadPoolAsynchronousRunner. -- Defined PoolingDataSource interface, which permits clients to access statistics about the state of underlying pools, and made C3P0 pool-backed DataSources implement that interface. -- fixed a subtle bug with respect to ownership of shared resources in which finalize() methods for discarded DataSources could cause helper threads and other resources to be cleaned up prematurely, while they are still in use by other DataSources. -- major reorganization of code generation for DataSources and the resulting objects. -- reorganization of Serializable and Referenceable code of DataSources for JNDI Binding -- made PoolConfig defaults (which are set by system properties, a c3p0.properties file, or else hardcoded defaults) apply to DataSources that are directly instantiated rather than created via the com.mchange.v2.c3p0.DataSources factory class. -- organized scattered stuff into a self-contained, distributable build directly, and divided source and binary distributions -- relicensed library; now available under LGPL. -- THERE ARE SOME MAJOR REORGANIZATIONS IN THIS RELEASE. ANY HELP IN TESTING AND FEEDBACK WOULD BE APPRECIATED! THANKS! c3p0-0.8.3.1 -- take greater care to abort if a helper thread wakes from wait() inside of a broken resource pool -- log more debug information if a pool unexpectedly breaks c3p0-0.8.3 -- resolved a deadlock arising from ConnectionEventSupport objects calling event listener methods while holding the ConnectionEventSupport's lock. (Thanks to an anonymous Sourceforge bug submitter for tracking this down.) -- added two configuration parameters to modify how c3p0 deals with potentially unresolved transactions on transaction close -- autoCommitOnClose and forceIgnoreUnresolvedTransactions. c3p0's default behavior is as it always was (and as I think it nearly always should be) -- by default we roll back any uncommitted work on close. See PoolConfig class for complete documentation. -- fixed stupid build error that made unzipping c3p0 archives messy since c3p0-0.8.2. (SORRY!) c3p0-0.8.3-pre-travis -- fixed problem with c3p0 trying endlessly to connect to a database that is down or not present. c3p0 now tries thirty time, once per second, then gives up. if there's demand, I'll make the delay and number of attempts user configurable. Thanks to Alfonso da Silva for calling attention to this problem. -- modified RoundRobinAsynchronousRunner to die more gracefully if, somehow, one of its CarefulAsynchronousRunners somehow dies. Thanks to Travis Reeder for calling attention to this issue. -- modified ResourcePools to allow resources to be tested periodically and asynchronously while they are idle in the pool. -- added to a new configuration property to PoolConfig and related classes, idleConnectionTestPeriod, which if set to a greater-than-zero value will cause c3p0 to periodically test idle, pooled connection, and remove them from the pool if they are broken. Thanks to Travis Reeder for calling attention to this issue. -- removed SQLState 08S01 from the set of SQL states presumed to mean all connections in the pool have become invalid. Apparently MySQL uses this SQLState to indicate the timing out of idle, individual connections. Thanks to Travis Reeder for calling attention to this issue. -- many (!) bug-fixes, small tweaks and improvements. -- temporarily sprinkled some debugging output prefixed "c3p0-TRAVIS" to try to resolve some issues for Travis Reeder c3p0-0.8.2 -- Addressed a rare problem that ocurred when application servers or other external code calls interrupt() on c3p0 helper threads. Thanks to Travis Reeder for reporting this issue! The endless cascade of ArrayIndexOutOfBoundsException that would occasionallY result has been fixed, and c3p0 helper threads now ignore interupts, which should almost completely prevent such interrupts() from leaving c3p0 pools in a corrupt state. [In the very, very unlikely event that multiple, well-timed interrupts() cause a pool to diagnose itself broken, c3p0 will start throwing clear exceptions to indicate that -- there shouldn't be any deadlock or any subtle kind of corruption.] -- Deprecated PoolBackedDataSourceFactory and DriverManagerDataSourceFactory in favor of the newer DataSources class. -- Updated example code and documentation. -- Moved constants from DataSources to PoolConfig where they belong! c3p0-0.8.2-pre10 -- Removed use of properties default mechanism in setting up JDBC properties for DriverManagerDataSource, as some drivers use get() rather than getProperties(), and the Properties.get() method ignores defaults. [Thanks go to Michael Jakl for both finding and fixing this problem!!!] -- Fixed subtle problem whereby the introspective constructor of C3P0PooledConnectionPoolManager would inadvertently check out an extra pooled connection, by treating the getPooledConnection() as a simple property read and invoking it. [Thanks go to Michael Jakl for both finding and fixing this bug!!!] c3p0-0.8.2-pre9 -- Finished DataSources static factory for, um, DataSources. -- Added PoolConfig class to encapsulate all configuration information from factories -- Set up PoolConfig to pay attention to (in order): 1) explicit, user-defined parameters 2) parameters defined as System properties 3) parameters defined in a Properties file resource, at resource pasth /c3p0.properties in PoolConfig's classloader 4) Hardcoded defaults from the C3P0Defaults class -- Defined a new pool configuration property, "testConnectionOnCheckout". If set to true (it defaults to false), each pooled Connection will be verified at checkout time, before being supplied to clients. THIS SLOWS CONNECTION CHECKOUT DRAMATICALLY (by an order of magnitude on my machine), but some folks may want it. The expensive, verified Connections are still faster to acquire than brand new ones. -- If a Connection experiences an SQLException with a defined SQL State of 08001, 08007, or 08S01, the entire database is considered to have been shutdown, and the pool whose connection experienced the problem is reset -- i.e. all existing Connections are discarded, and new Connections are acquired for the pool. (Thanks! to Gavin King for suggesting the SQL State approach to detecting disconnects.) -- ConnectionTester interface and its default implementation were modified to support reporting DATABASE_IS_INVALID (rather than simply testing a disconnected, individual Connection). c3p0-0.8.2-pre8 -- Fixed some really stupid bugs from pre-7, in particular the static factory methods of the DataSources class were not declared static. Oops. c3p0-0.8.2-pre7 -- Major reorganization of data source implementations. These are now generated from XML templates, because it was becoming difficult to keep multiple versions of multiple types of datasources in sync with one another -- a new factory / utility class has been added, com.mchange.v2.c3p0.DataSources. Soon the older factories (DriverManagerDataSourceFactory and PoolBackedDataSourceFactory) will be deprecated in favor of this. -- Began adding support for wrapper DataSources that lazily bind to an unpooled DataSource specified via JNDI. (Current wrappers require an actual instance, not a mere reference in order to construct a PoolBacked or ConnectionPoolDataSource). c3p0-0.8.2-pre6 -- Fixed bug that led to ConcurrentModificationException when Connection.close() iterates through and closes its unclosed Statements. -- Fixed bug that caused uncached Statements to sometimes be closed twice, as they were not properly removed from the set of Connection-associated statements on user- initiated Statement.close(), and would thus be closed again on Connection.close(). -- Reorganized classes to clean up top-level com.mchange.v2.c3p0 package. The gory innards of c3p0 now live in an impl package. -- Reorganized DataSources so that there are "Base" versions suitable for DBMS-specific subclassing. c3p0-0.8.2-pre5 -- DataSources looked up by JNDI now "coalesce" -- i.e., if two separate calls look-up the same JNDI bound DataSource, they will both see the same DataSource instance in the local VM. This is especially important for PoolBackedDataSources, as they own "helper threads" that help to manage the pool. Now each logical DataSource shares the same pool of helper threads, regardless of whether it is looked up once and cached, or looked up multiple times and at multiple places by an application. -- Number of helper-threads managing a PoolBackedDataSource is now user-configurable c3p0-0.8.2-pre4 -- Fixed BAD memory leak -- cachedStatements were being retained on close. This brings a performance improvement to the StatementCache as well. -- Set-up StatementCacheKey to coalesce, such that its equals method can look like {return (this == o);}. Unfortunately, I did not see the kind of performance increase I'd anticipated from this... in fact, whatever performance changes I did see were pretty negligable. Performed some other, mostly useless, optimizations to the process of acquiring StatementCacheKeys. (I can't decide... I've got 3 usuable, broadly similar versions of StatementCacheKey now.) -- Fixed bugs having to do with when to create and the daemon status of Timers -- Appropriately synchronized access to PoolBackedDataSource. (This should permit me to pull back on synchronization / marking of volatile in some dependent classes, as access to these is now controlled via PoolBackedDataSource.) -- Made instantion of C3P0PooledConnectionPoolManager by WrapperPoolBackedDataSource "lazy", so that Timer / Async task threads are only started up when a Connection is actually requested from a DataSource. This is useful especially for the instance residing in the JNDI server VM, whose purpose is likely only to serve as an instance to be looked up over the network. There's no reason why it should keep several stalled Threads open. -- Fixed DefaultConnectionTester, whose logic was bass-ackwards. c3p0-0.8.2-pre3 -- Factory method for StatementCacheKeys now "coalesce" equivalent instances to conserve memory and to enable a fast (this == o) test to usually work in equals methods. [Value test remains for when identity test fails... maybe later I'll be more comfortable with a 1 instance per value guarantee, and remove the rest of the test. As the constructor is private, the factory method coalesces, and the class is not Serializable, an identity test should suffice. But I'm paranoid.] -- All asynchronous tasks are now distributed to 3 helper threads per DataSource rather than queuing on just one. (Culing of expired Connections is still managed by a single java.util.Timer... I don't think this will be a problem.) c3p0-0.8.2-pre2 -- Total rewite of Statement cache! c3p0-0.9.1.2.orig/src/dist-static/LICENSE0000644000175000017500000006347607736457221015552 0ustar godgod GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! c3p0-0.9.1.2.orig/src/dist-static/README0000644000175000017500000000121310477651155015400 0ustar godgod _____________________________________ ................................. ..(c3p0)......................... ............a.........fresh...... ....coat.......of........stucco.. .........over.......that.....old. ...jdbc........driver............ ................................. ------------------------------------- versions 0.8.4 and above 23-Dec-2003 -> Feedback to Steve Waldman <- -> Please! :) <- Hi. c3p0's docs have been HTML-ized, and moved to the "doc" directory of this distribution. Please check that out. Sorry all you plain text fans! c3p0-0.9.1.2.orig/src/dist-static/TODO0000644000175000017500000000121710505052516015200 0ustar godgodfull status dump operations from JMX beans (two methods, one std err onr to logger at INFO level?) Statement cache statistics exposed via JMX. Interface to Statement-caching statistics make asynchronous checkins optional, let the default depend on the value of testConnectionOnCheckin. A shortcut in acquire tasks that bails before attempting an acquire if the acquisition is no longer necessary. Make visible rootCause exceptions when Connection test fails. (Looks implemented, but I don't see them. Debug.) Less confusing hibernate ConnectionProvider. JUnit testing regime. some validation stuff in C3P0PooledConnectionPoolManager... c3p0-0.9.1.2.orig/src/doc/0000755000175000017500000000000010673162231013026 5ustar godgodc3p0-0.9.1.2.orig/src/doc/arrow_sm.png0000644000175000017500000000056710201573037015372 0ustar godgod‰PNG  IHDR›ÆX pHYs  šœgAMA±Ž|ûQ“ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFíIDATxÚbüÏ@ FbÃ4¥ õ˜*þ3ºB†ó@ù˜ U¡Ã{ „×µ ( d…e @%óôy˜RˆB€B(„)ƒ$¥…SRRèUXvX)D!@1…ö3\`HD G ²ý@#À € ?0, @SxÁáL €=ã€f5Нˆ‰Øˆ ¢Ñ ˆh…D´B€"Z!@­ €ˆV@D+ ¢Ñ ˆèÌ@D+ ¢™ÎLµP¡IEND®B`‚c3p0-0.9.1.2.orig/src/doc/index.html0000644000175000017500000040342410624345654015042 0ustar godgod c3p0-v@c3p0.version@ - JDBC3 Connection and Statement Pooling - Documentation

c3p0 - JDBC3 Connection and Statement Pooling
version @c3p0.version@

by Steve Waldman <swaldman@mchange.com>

© 2006 Machinery For Change, Inc.

This software is made available for use, modification, and redistribution, under the terms of the Lesser GNU Public License (LGPL), which you should have received with this distribution.


Contents

  1. Contents
  2. Quickstart
  3. What is c3p0?
  4. Prerequisites
  5. Installation
  6. Using c3p0
    1. Using ComboPooledDataSource
    2. Using the DataSouces factory class
    3. Querying Pool Status
    4. Cleaning Up Pool Resources
    5. Advanced: Building Your Own PoolBackedDataSource
    6. Advanced: Raw Connection and Statement Operations
  7. Configuration
    1. Introduction
    2. Basic Pool Configuration
    3. Managing Pool Size and Connection Age
    4. Configuring Connection Testing
    5. Configuring Statement Pooling
    6. Configuring Recovery From Database Outages
    7. Managing Connection Lifecycles with Connection Customizers
    8. Configuring Unresolved Transaction Handling
    9. Configuring to Debug and Workaround Broken Client Applications
    10. Other DataSource Configuration
    11. Configuring and Managing c3p0 via JMX
    12. Configuring Logging
  8. Performance
  9. Known shortcomings
  10. Feedback and support
  11. Appendix A: Configuration Properties
  12. Appendix B: Configuation Files, etc.
    1. Overriding c3p0 defaults with a c3p0.properties file
    2. Overriding c3p0 defaults with a System properties
    3. Named and Per-User configuration: Overriding c3p0 defaults via c3p0-config.xml
    4. Precedence of Configuration Settings
  13. Appendix C: Hibernate-specific notes
  14. Appendix D: Configuring c3p0 pooled DataSources for Apache Tomcat
  15. Appendix E: JBoss-specific notes
  16. Appendix F: Oracle-specific API: createTemporaryBLOB() and createTemporaryCLOB()
(See also the API Documentation here)

QuickstartGo To Top

c3p0 was designed to be butt-simple to use. Just put the jar file [lib/c3p0-@c3p0.version@.jar] in your application's effective CLASSPATH, and make a DataSource like this:

import com.mchange.v2.c3p0.*; ... ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" ); cpds.setUser("dbuser"); cpds.setPassword("dbpassword");

[Optional] If you want to turn on PreparedStatement pooling, you must also set maxStatements and/or maxStatementsPerConnection (both default to 0):

cpds.setMaxStatements( 180 );

Do whatever you want with your DataSource, which will be backed by a Connection pool set up with default parameters. You can bind the DataSource to a JNDI name service, or use it directly, as you prefer.

When you are done, you can clean up the DataSource you've created like this:

DataSources.destroy( cpds );

That's it! The rest is detail.

What is c3p0?Go To Top

c3p0 is an easy-to-use library for making traditional JDBC drivers "enterprise-ready" by augmenting them with functionality defined by the jdbc3 spec and the optional extensions to jdbc2. In particular, c3p0 provides several useful services:

  • Classes which adapt traditional DriverManager-based JDBC drivers to the new javax.sql.DataSource scheme for acquiring database Connections.
  • Transparent pooling of Connection and PreparedStatements behind DataSources which can "wrap" around traditional drivers or arbitrary unpooled DataSources.

The library tries hard to get the details right:

  • c3p0 DataSources are both Referenceable and Serializable, and are thus suitable for binding to a wide-variety of JNDI-based naming services.
  • Statement and ResultSets are carefully cleaned up when pooled Connections and Statements are checked in, to prevent resource- exhaustion when clients use the lazy but common resource-management strategy of only cleaning up their Connections....
  • The library adopts the approach defined by the JDBC 2 and 3 specification (even where these conflict with the library author's preferences). DataSources are written in the JavaBean style, offering all the required and most of the optional properties (as well as some non-standard ones), and no-arg constructors. All JDBC-defined internal interfaces are implemented (ConnectionPoolDataSource, PooledConnection, ConnectionEvent-generating Connections, etc.) You can mix c3p0 classes with compliant third-party implementations (although not all c3p0 features will work with external implementations).

c3p0 hopes to provide DataSource implementations more than suitable for use by high-volume "J2EE enterprise applications". Please provide feedback, bug-fixes, etc.!

PrerequisitesGo To Top

c3p0 requires a level 1.3.x or above Java Runtime Environment, and the JDBC 2.x or above javax.sql libraries. c3p0 works fine under Java 1.4.x and 1.5.x as well.

InstallationGo To Top

Put the file lib/c3p0-@c3p0.version@.jar somewhere in your CLASSPATH (or any other place where your application's classloader will find it). That's it!

Using c3p0Go To Top

From a users' perspective, c3p0 simply provides standard jdbc2 DataSource objects. When creating these DataSources, users can control pooling-related, naming-related, and other properties (See Appendix A). All pooling is entirely transparent to users once a DataSource has been created.

There are three ways of acquiring c3p0 pool-backed DataSources: 1) directly instantiate and configure a ComboPooledDataSource bean; 2) use the DataSources factory class; or 3) "build your own" pool-backed DataSource by directly instantiating PoolBackedDataSource and setting its ConectionPoolDataSource. Most users will probably find instantiating ComboPooledDataSource to be the most convenient approach. Once instantiated, c3p0 DataSources can be bound to nearly any JNDI-compliant name service.

Regardless of how you create your DataSource, c3p0 will use defaults for any configuration parameters that you do not specify programmatically. c3p0 has built-in, hard-coded defaults, but you can override these by creating a file called c3p0.properties and storing it as a top-level resource in the same CLASSPATH (or ClassLoader) that loads c3p0's jar file. As of c3p0-0.9.1, you can also supply a file called c3p0-config.xml for more advanced configuration. See Configuration below.

Instantiating and Configuring a ComboPooledDataSource Go To Top

Perhaps the most straightforward way to create a c3p0 pooling DataSource is to instantiate an instance of com.mchange.v2.c3p0.ComboPooledDataSource. This is a JavaBean-style class with a public, no-arg constructor, but before you use the DataSource, you'll have to be sure to set at least the property jdbcUrl. You may also want to set user and password, and if you have not externally preloaded the old-style JDBC driver you'll use you should set the driverClass.

ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" ); cpds.setUser("swaldman"); cpds.setPassword("test-password"); // the settings below are optional -- c3p0 can work with defaults cpds.setMinPoolSize(5); cpds.setAcquireIncrement(5); cpds.setMaxPoolSize(20); // The DataSource cpds is now a fully configured and usable pooled DataSource ...

The defaults of any c3p0 DataSource are determined by configuration you supply, or else revert to hard-coded defaults [see configuration properties]. c3p0-0.9.1 and above supports multiple, named configurations. If you wish to use a named configuration, construct your com.mchange.v2.c3p0.ComboPooledDataSource with the configuration name as a constructor agument:

ComboPooledDataSource cpds = new ComboPooledDataSource("intergalactoApp");

Of course, you can still override any configuration properties programmatically, as above.

Using the DataSources factory class Go To Top

Alternatively, you can use the static factory class com.mchange.v2.c3p0.DataSources to build unpooled DataSources from traditional JDBC drivers, and to build pooled DataSources from unpooled DataSources:

DataSource ds_unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/testdb", "swaldman", "test-password"); DataSource ds_pooled = DataSources.pooledDataSource( ds_unpooled ); // The DataSource ds_pooled is now a fully configured and usable pooled DataSource. // The DataSource is using a default pool configuration, and Postgres' JDBC driver // is presumed to have already been loaded via the jdbc.drivers system property or an // explicit call to Class.forName("org.postgresql.Driver") elsewhere. ...

If you use the DataSources factory class, and you want to programmatically override default configuration parameters, you can supply a map of override properties:

DataSource ds_unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/testdb", "swaldman", "test-password"); Map overrides = new HashMap(); overrides.put("maxStatements", "200"); //Stringified property values work overrides.put("maxPoolSize", new Integer(50)); //"boxed primitives" also work // create the PooledDataSource using the default configuration and our overrides ds_pooled = DataSources.pooledDataSource( ds_unpooled, overrides ); // The DataSource ds_pooled is now a fully configured and usable pooled DataSource, // with Statement caching enabled for a maximum of up to 200 statements and a maximum // of 50 Connections. ...

If you are using named configurations, you can specify the configuration that defines the default configuration for your DataSource:

// create the PooledDataSource using the a named configuration and specified overrides ds_pooled = DataSources.pooledDataSource( ds_unpooled, "intergalactoAppConfig", overrides );

Show deprecated PoolConfig approach...

Querying a PooledDataSource's current status Go To Top

c3p0 DataSources backed by a pool, which include implementations of ComboPooledDataSource and the objects returned by DataSources.pooledDataSource( ... ), all implement the interface com.mchange.v2.c3p0.PooledDataSource, which makes available a number of methods for querying the status of DataSource Connection pools. Below is sample code that queries a DataSource for its status:

// fetch a JNDI-bound DataSource InitialContext ictx = new InitialContext(); DataSource ds = (DataSource) ictx.lookup( "java:comp/env/jdbc/myDataSource" ); // make sure it's a c3p0 PooledDataSource if ( ds instanceof PooledDataSource) { PooledDataSource pds = (PooledDataSource) ds; System.err.println("num_connections: " + pds.getNumConnectionsDefaultUser()); System.err.println("num_busy_connections: " + pds.getNumBusyConnectionsDefaultUser()); System.err.println("num_idle_connections: " + pds.getNumIdleConnectionsDefaultUser()); System.err.println(); } else System.err.println("Not a c3p0 PooledDataSource!");

The status querying methods all come in three overloaded forms, such as:

  • public int getNumConnectionsDefaultUser()
  • public int getNumConnections(String username, String password)
  • public int getNumConnectionsAllUsers()

c3p0 maintains separate pools for Connections with distinct authentications. The various methods let you query the status of pools individually, or aggregate statistics for all authentifications for which your DataSource is maintaining pools. Note that pool configuration parmeters such as maxPoolSize are enforced on a per-authentification basis! For example, if you have set maxPoolSize to 20, and if the DataSource is managing connections under two username-password pairs [the default, and one other pair established via a call to getConnection(user, password), you should expect to see as many as 40 Connections from getNumConnectionsAllUsers().

Most applications only acquire default-authenticated Connections from DataSources, and can typically just use the getXXXDefaultUser() to gather Connection statistics.

As well as Connection pool realted statistics, you can retrieve status information about each DataSource's Thread pool. Please see PooledDataSource for a complete list of available operations.

Using C3P0Registry to get a reference to a DataSource

If it's inconvenient or impossible to get a reference to your DataSource via JNDI or some other means, you can find all live c3p0 DataSources using the C3P0Registry class, which includes three static methods to help you out:

  • public static Set getPooledDataSources()
  • public static Set pooledDataSourcesByName( String dataSourceName )
  • public static PooledDataSource pooledDataSourceByName( String dataSourceName )

The first method will hand you the Set of all live c3p0 PooledDataSources. If you are sure your application only makes one PooledDataSources, or you can distinguish between the DataSources by their configuration properties (inspected via "getters"), the first method may be sufficient. Because this will not always be the case, c3p0 PooledDataSources have a special property called dataSourceName. You can set the dataSourceName property directly when you construct your DataSource, or dataSourceName can be set like any other property in a named or the default config. Otherwise, dataSourceName will default to either 1) the name of your DataSource's configuration, if you constructed it with a named configuration; or 2) a unique (but unpredicatble) name if you are using the default configuration.

There is no guarantee that a dataSourceName will be unique. For example, if two c3p0 DataSources share the same named configuration, and you have not set the dataSourceName programmatically, the two data sources will both share the name of the configuration. To get all of the DataSources with a particular dataSourceName, use pooledDataSourcesByName( ... ). If you've ensured that your DataSource's name is unique (as you will generally want to do, if you intend to use C3P0Registry to find your DataSources), you can use the convenience method pooledDataSourceByName( ... ), which will return your DataSource directly, or null if no DataSource with that name is available. If you use pooledDataSourceByName( ... ) and more than one DataSource shares the name supplied, which one it will return is undefined.

Cleaning up after c3p0 PooledDataSources Go To Top

The easy way to clean up after c3p0-created DataSources is to use the static destroy method defined by the class DataSources. Only PooledDataSources need to be cleaned up, but DataSources.destroy( ... ) does no harm if it is called on an unpooled or non-c3p0 DataSource.

DataSource ds_pooled = null; try { DataSource ds_unpooled = DataSources.unpooledDataSource("jdbc:postgresql://localhost/testdb", "swaldman", "test-password"); ds_pooled = DataSources.pooledDataSource( ds_unpooled ); // do all kinds of stuff with that sweet pooled DataSource... } finally { DataSources.destroy( ds_pooled ); }

Alternatively, c3p0's PooledDataSource interface contains a close() method that you can call when you know you are finished with a DataSource. So, you can cast a c3p0 derived DataSource to a PooledDataSource and close it:

static void cleanup(DataSource ds) throws SQLException { // make sure it's a c3p0 PooledDataSource if ( ds instanceof PooledDataSource) { PooledDataSource pds = (PooledDataSource) ds; pds.close(); } else System.err.println("Not a c3p0 PooledDataSource!"); }

Unreferenced instances of PooledDataSource that are not close()ed by clients close() themselves prior to garbage collection in their finalize() methods. As always, finalization should be considered a backstop and not a prompt or sure approach to resource cleanup.

Advanced: Building your own PoolBackedDataSource Go To Top

There is little reason for most programmers to do this, but you can build a PooledDataSource in a step-by-step way by instantiating and configuring an unpooled DriverManagerDataSource, instantiating a WrapperConnectionPoolDataSource and setting the unpooled DataSource as its nestedDataSource property, and then using that to set the connectionPoolDataSource property of a new PoolBackedDataSource.

This sequence of events is primarily interesting if your driver offers an implementation of ConnectionPoolDataSource, and you'd like c3p0 to use that. Rather than using c3p0's WrapperConnectionPoolDataSource, you can create a PoolBackedDataSource and set its connectionPoolDataSource property. Statement pooling, ConnectionCustomizers, and many c3p0-specific properties are unsupported with third party implementations of ConnectionPoolDataSource. (Third-party DataSource implementations can be substituted for c3p0's DriverManagerDataSource with no significant loss of functionality.)

Advanced: Raw Connection and Statement Operations Go To Top

JDBC drivers sometimes define vendor-specific, non-standard API on Connection and Statement implementations. C3P0 wraps these Objects behind a proxies, so you cannot cast C3P0-returned Connections or Statements to the vendor-specific implementation classes. C3P0 does not provide any means of accessing the raw Connections and Statements directly, because C3P0 needs to keep track of Statements and ResultSets created in order to prevent resource leaks and pool corruption.

C3P0 does provide an API that allows you to invoke non-standard methods reflectively on an underlying Connection. To use it, first cast the returned Connection to a C3P0ProxyConnection. Then call the method rawConnectionOperation, supplying the java.lang.reflect.Method object for the non-standard method you wish to call as an argument. The Method you supply will be invoked on the target you provide on the second argument (null for static methods), and using the arguments you supply in the third argument to that function. For the target, and for any of the method arguments, you can supply the special token C3P0ProxyConnection.RAW_CONNECTION, which will be replaced with the underlying vendor-specific Connection object before the Method is invoked.

C3P0ProxyStatement offers an exactly analogous API.

Any Statements (including Prepared and CallableStatements) and ResultSets returned by raw operations will be c3p0-managed, and will be properly cleaned-up on close() of the parent proxy Connection. Users must take care to clean up any non-standard resources returned by a vendor-specific method.

Here's an example of using Oracle-specific API to call a static method on a raw Connection:

C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0DataSource.getConnection(); Method m = CLOB.class.getMethod("createTemporary", new Class[]{Connection.class, boolean.class, int.class}); Object[] args = new Object[] {C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf( true ), new Integer( 10 )}; CLOB oracleCLOB = (CLOB) castCon.rawConnectionOperation(m, null, args);

Note: C3P0 now includes special support for some Oracle-specific methods. See Appendix F.

ConfigurationGo To Top

Introduction Go To Top

While c3p0 does not require very much configuration, it is very tweakable. Most of the interesting knobs and dials are represented as JavaBean properties. Following JavaBean conventions, we note that if an Object has a property of type T called foo, it will have methods that look like...

public T getFoo();
public void setFoo(T foo);
...or both, depending upon whether the property is read-only, write-only, or read-writable.

There are several ways to modify c3p0 properties: You can directly alter the property values associated with a particular DataSource in your code, or you can configure c3p0 externally, via a simple Java properties file, via an XML configuration file, or via System properties. Configuration files are normally looked up under standard names (c3p0.properties or c3p0-config.xml) at the top level of an application's classpath, but the XML configuration can be placed anywhere in an application's file system, if the system property com.mchange.v2.c3p0.cfg.xml is set (to an absolute filesystem path).

DataSources are usually configured before they are used, either during or immediately following their construction. c3p0 does support property modifications midstream, however.

If you obtain a DataSource by instantiating a ComboPooledDataSource, configure it by simply calling appropriate setter methods offered by that class before attempting a call to getConnection(). See the example above.

If you obtain a DataSource by using factory methods of the utility class com.mchange.v2.c3p0.DataSources, and wish to use a non-default configuration, you can supply a Map of property names (beginning with lower-case letters) to property values (either as Strings or "boxed" Java primitives like Integer or Boolean).

All tweakable properties are documented for reference in Appendix A. The most basic and important c3p0 configuration topics are discussed below.

Basic Pool Configuration Go To Top

c3p0 Connection pools are very easy to configure via the following basic parameters:

initialPoolSize, minPoolSize, maxPoolSize define the number of Connections that will be pooled. Please ensure that minPoolSize <= maxPoolSize. Unreasonable values of initialPoolSize will be ignored, and minPoolSize will be used instead.

Within the range between minPoolSize and maxPoolSize, the number of Connections in a pool varies according to usage patterns. The number of Connections increases whenever a Connection is requested by a user, no Connections are available, and the pool has not yet reached maxPoolSize in the number of Connections managed. Since Connection acquisition is very slow, it is almost always useful to increase the number of Connections eagerly, in batches, rather than forcing each client to wait for a new Connection to provoke a single acquisition when the load is increasing. acquireIncrement determines how many Connections a c3p0 pool will attempt to acquire when the pool has run out of Connections. (Regardless of acquireIncrement, the pool will never allow maxPoolSize to be exceeded.)

The number of Connections in a pool decreases whenever a pool tests a Connection and finds it to be broken (see Configuring Connection Testing below), or when a Connection is expired by the pool after sitting idle for a period of time, or for being too old (See Managing Pool Size and Connection Age.)

Managing Pool Size and Connection Age Go To Top

Different applications have different needs with regard to trade-offs between performance, footprint, and reliability. C3P0 offers a wide variety of options for controlling how quickly pools that have grown large under load revert to minPoolSize, and whether "old" Connections in the pool should be proactively replaced to maintain their reliablity.

By default, pools will never expire Connections. If you wish Connections to be expired over time in order to maintain "freshness", set maxIdleTime and/or maxConnectionAge. maxIdleTime defines how many seconds a Connection should be permitted to go unused before being culled from the pool. maxConnectionAge forces the pool to cull any Connections that were acquired from the database more than the set number of seconds in the past.

maxIdleTimeExcessConnections is about minimizing the number of Connections held by c3p0 pools when the pool is not under load. By default, c3p0 pools grow under load, but only shrink if Connections fail a Connection test or are expired away via the parameters described above. Some users want their pools to quickly release unnecessary Connections after a spike in usage that forces a large pool size. You can achieve this by setting maxIdleTimeExcessConnections to a value much shorter than maxIdleTime, forcing Connections beyond your set minimum size to be released if they sit idle for more than a short period of time.

Some general advice about all of these timeout parameters: Slow down! The point of Connection pooling is to bear the cost of acquiring a Connection only once, and then to reuse the Connection many, many times. Most databases support Connections that remain open for hours at a time. There's no need to churn through all your Connections every few seconds or minutes. Setting maxConnectionAge or maxIdleTime to 1800 (30 minutes) is quite aggressive. For most databases, several hours may be more appropriate. You can ensure the reliability of your Connections by testing them, rather than by tossing them. (see Configuring Connection Testing.) The only one of these parameters that should generally be set to a few minutes or less is maxIdleTimeExcessConnections.

Configuring Connection Testing Go To Top

c3p0 can be configured to test the Connections that it pools in a variety of ways, to minimize the likelihood that your application will see broken or "stale" Connections. Pooled Connections can go bad for a variety of reasons -- some JDBC drivers intentionally "time-out" long-lasting database Connections; back-end databases or networks sometimes go down "stranding" pooled Connections; and Connections can simply become corrupted over time and use due to resource leaks, driver bugs, or other causes.

c3p0 provides users a great deal of flexibility in testing Connections, via the following configuration parameters:

idleConnectionTestPeriod, testConnectionOnCheckout, and testConnectionOnCheckin control when Connections will be tested. automaticTestTable, connectionTesterClassName, and preferredTestQuery control how they will be tested.

When configuring Connection testing, first try to minimize the cost of each test. By default, Connections are tested by calling the getTables() method on a Connection's associated DatabaseMetaData object. This has the advantage of working with any database, and regardless of the database schema. However, empirically a DatabaseMetaData.getTables() call is often much slower than a simple database query.

The most convenient way to speed up Connection testing is to define the parameter automaticTestTable. Using the name you provide, c3p0 will create an empty table, and make a simple query against it to test the database. Alternatively, if your database schema is fixed prior to your application's use of the database, you can simply define a test query with the preferredTestQuery parameter. Be careful, however. Setting preferredTestQuery will lead to errors as Connection tests fail if the query target table does not exist in your database table prior to initialization of your DataSource.

Advanced users may define any kind of Connection testing they wish, by implementing a ConnectionTester and supplying the fully qualified name of the class as connectionTesterClassName. If you'd like your custom ConnectionTesters to honor and support the preferredTestQuery and automaticTestTable parameters, implement UnifiedConnectionTester, most conveniently by extending AbstractConnectionTester. See the api docs for more information.

The most reliable time to test Connections is on check-out. But this is also the most costly choice from a client-performance perspective. Most applications should work quite reliably using a combination of idleConnectionTestPeriod and testConnectionsOnCheckIn. Both the idle test and the check-in test are performed asynchronously, which leads to better performance, both perceived and actual.

Note that for many applications, high performance is more important than the risk of an occasional database exception. In its default configuration, c3p0 does no Connection testing at all. Setting a fairly long idleConnectionTestPeriod, and not testing on checkout and check-in at all is an excellent, high-performance approach.

Configuring Statement Pooling Go To Top

c3p0 implements transparent PreparedStatement pooling as defined by the JDBC spec. Under some circumstances, statement pooling can dramatically improve application performance. Under other circumstances, the overhead of statement pooling can slightly harm performance. Whether and how much statement pooling will help depends on how much parsing, planning, and optimizing of queries your databases does when the statements are prepared. Databases (and JDBC drivers) vary widely in this respect. It's a good idea to benchmark your application with and without statement pooling to see if and how much it helps.

You configure statement pooling in c3p0 via the following configuration parameters:

maxStatements is JDBC's standard parameter for controlling statement pooling. maxStatements defines the total number PreparedStatements a DataSource will cache. The pool will destroy the least-recently-used PreparedStatement when it hits this limit. This sounds simple, but it's actually a strange approach, because cached statements conceptually belong to individual Connections; they are not global resources. To figure out a size for maxStatements that does not "churn" cached statements, you need to consider the number of frequently used PreparedStatements in your application, and multiply that by the number of Connections you expect in the pool (maxPoolSize in a busy application).

maxStatementsPerConnection is a non-standard configuration parameter that makes a bit more sense conceptually. It defines how many statements each pooled Connection is allowed to own. You can set this to a bit more than the number of PreparedStatements your application frequently uses, to avoid churning.

If either of these parameters are greater than zero, statement pooling will be enabled. If both parameters are greater than zero, both limits will be enforced. If only one is greater than zero, statement pooling will be enabled, but only one limit will be enforced.

Configuring Recovery From Database Outages Go To Top

c3p0 DataSources are designed (and configured by default) to recover from temporary database outages, such as those which occur during a database restart or brief loss of network connectivity. You can affect how c3p0 handles errors in acquiring Connections via the following configurable properties:

When a c3p0 DataSource attempts and fails to acquire a Connection, it will retry up to acquireRetryAttempts times, with a delay of acquireRetryDelay between each attempt. If all attempts fail, any clients waiting for Connections from the DataSource will see an Exception, indicating that a Connection could not be acquired. Note that clients do not see any Exception until a full round of attempts fail, which may be some time after the initial Connection attempt. If acquireRetryAttempts is set to 0, c3p0 will attempt to acquire new Connections indefinitely, and calls to getConnection() may block indefinitely waiting for a successful acquisition.

Once a full round of acquisition attempts fails, there are two possible policies. By default, the c3p0 DataSource will remain active, and will try again to acquire Connections in response to future requests for Connections. If you set breakAfterAcquireFailure to true, the DataSource will consider itself broken after a failed round of Connection attempts, and future client requests will fail immediately.

Note that if a database restart occurs, a pool may contain previously acquired but now stale Connections. By default, these stale Connections will only be detected and purged lazily, when an application attempts to use them, and sees an Exception. Setting maxIdleTime or maxConnectionAge can help speed up the replacement of broken Connections. (See Managing ConnectionAge.) If you wish to avoid application Exceptions entirely, you must adopt a connection testing strategy that is likely to detect stale Connections prior to their delivery to clients. (See "Configuring Connection Testing".) Even with active Connection testing (testConnectionsOnCheckout set to true, or testConnectionsOnCheckin and a short idleConnectionTestPeriod), your application may see occasional Exceptions on database restart, for example if the restart occurs after a Connection to the database has already been checked out.

Managing Connection Lifecycles with Connection Customizer Go To Top

Application frequently wish to set up Connections in some standard, reusable way immediately after Connection acquisitions. Examples of this include setting-up character encodings, or date and time related behavior, using vendor-specific APIs or non-standard SQL statement executions. Occasionally it is useful to override the default values of standard Connection properties such as transactionIsolation, holdability, or readOnly. c3p0 provides a "hook" interface that you can implement, which gives you the opportunity to modify or track Connections just after they are checked out from the database, immediately just prior to being handed to clients on checkout, just prior to being returned to the pool on check-in, and just prior to final destruction by the pool. The Connections handed to ConnectionCustomizers are raw, physical Connections, with all vendor-specific API accessible. See the API docs for ConnectionCustomizer.

To install a ConnectionCustomizer just implement the interface, make your class accessible to c3p0's ClassLoader, and set the configuration parameter below:

ConnectionCustomizers are required to be immutable classes with public no argument constructors. They shouldn't store any state. For (rare) applications that wish to track the behavior of individual DataSources with ConnectionCustomizers, the lifecycle methods each accept a DataSource-specific "identityToken", which is unique to each PooledDataSource.

Below is a sample ConnectionCustomizer. Implementations that do not need to override all four ConnectionCustomizer methods can extend AbstractConnectionCustomizer to inherit no-op implementations of all methods.

import com.mchange.v2.c3p0.*; import java.sql.Connection; public class VerboseConnectionCustomizer { public void onAcquire( Connection c, String pdsIdt ) { System.err.println("Acquired " + c + " [" + pdsIdt + "]"); // override the default transaction isolation of // newly acquired Connections c.setTransactionIsolation( Connection.REPEATABLE_READ ); } public void onDestroy( Connection c, String pdsIdt ) { System.err.println("Destroying " + c + " [" + pdsIdt + "]"); } public void onCheckOut( Connection c, String pdsIdt ) { System.err.println("Checked out " + c + " [" + pdsIdt + "]"); } public void onCheckIn( Connection c, String pdsIdt ) { System.err.println("Checking in " + c + " [" + pdsIdt + "]"); } }

Configuring Unresolved Transaction Handling Go To Top

Connections checked into a pool cannot have any unresolved transactional work associated with them. If users have set autoCommit to false on a Connection, and c3p0 cannot guarantee that there is no pending transactional work, c3p0 must either rollback() or commit() on check-in (when a user calls close()). The JDBC spec is (unforgivably) silent on the question of whether unresolved work should be committed or rolled back on Connection close. By default, c3p0 rolls back unresolved transactional work when a user calls close().

You can adjust this behavior via the following configuration properties:

If you wish c3p0 to allow unresolved transactional work to commit on checkin, set autoCommitOnClose to true. If you wish c3p0 to leave transaction management to you, and neither commit nor rollback (nor modify the state of Connection autoCommit), you may set forceIgnoreUnresolvedTransactions to true. Setting forceIgnoreUnresolvedTransactions is strongly discouraged, because if clients are not careful to commit or rollback themselves prior to close(), or do not set Connection autoCommit consistently, bizarre unreproduceable behavior and database lockups can occur.

Configuring to Debug and Workaround Broken Client Applications Go To Top

Sometimes client applications are sloppy about close()ing all Connections they check out. Eventually, the pool grows to maxPoolSize, and then runs out of Connections, because of these bad clients.

The right way to address this problem is to fix the client application. c3p0 can help you debug, by letting you know where Connections are checked out that occasionally don't get checked in. In rare and unfortunate situations, development of the client application is closed, and even though it is buggy, you cannot fix it. c3p0 can help you work around the broken application, preventing it from exhausting the pool.

The following parameters can help you debug or workaround broken client applications.

unreturnedConnectionTimeout defines a limit (in seconds) to how long a Connection may remain checked out. If set to a nozero value, unreturned, checked-out Connections that exceed this limit will be summarily destroyed, and then replaced in the pool. Obviously, you must take care to set this parameter to a value large enough that all intended operations on checked out Connections have time to complete. You can use this parameter to merely workaround unreliable client apps that fail to close() Connections.

Much better than working-around is fixing. If, in addition to setting unreturnedConnectionTimeout, you set debugUnreturnedConnectionStackTraces to true, then a stack trace will be captured each time a Connection is checked-out. Whenever an unreturned Connection times out, that stack trace will be printed, revealing where a Connection was checked out that was not checked in promptly. debugUnreturnedConnectionStackTraces is intended to be used only for debugging, as capturing a stack trace can slow down Connection check-out.

Other DataSource Configuration Go To Top

See Appendix A for information about the following configuration properties:

numHelperThreads and maxAdministrativeTaskTime help to configure the behavior of DataSource thread pools. By default, each DataSource has only three associated helper threads. If performance seems to drag under heavy load, or if you observe via JMX or direct inspection of a PooledDataSource, that the number of "pending tasks" is usually greater than zero, try increasing numHelperThreads. maxAdministrativeTaskTime may be useful for users experiencing tasks that hang indefinitely and "APPARENT DEADLOCK" messages. (See Appendix A for more.)

checkoutTimeout limits how long a client will wait for a Connection, if all Connections are checked out and one cannot be supplied immediately. usesTraditionalReflectiveProxies, which is of little practical use, permits you to use an old, now superceded implementation of C3P0-generated proxy objects. (C3P0 used to use reflective, dynamic proxies. Now, for enhanced performance, it uses code-generated, nonrefective implementations.) factoryClassLocation can be used to indicate where a URL from which c3p0 classes can be downloaded, if c3p0 DataSources will be retrieved as References from a JNDI DataSource by clients who do not have c3p0 locally installed.

Configuring and Managing c3p0 via JMX Go To Top

If JMX libraries and a JMX MBeanServer are available in your environment (they are include in JDK 1.5 and above), you can inspect and configure your c3p0 datasources via a JMX administration tool (such as jconsole, bundled with jdk 1.5). You will find that c3p0 registers MBeans under com.mchange.v2.c3p0, one with statistics about the library as a whole (called C3P0Registry), and an MBean for each PooledDataSource you deploy. You can view and modify your DataSource's configuration properties, track the activity of Connection, Statement, and Thread pools, and reset pools and DataSources via the PooledDataSource MBean. (You may wish to view the API docs of PooledDataSource for documentation of the available operations.)

If you do not want c3p0 to register MBeans with your JMX environment, you can suppress this behavior with the following, set either as a System property or in c3p0.properties:

com.mchange.v2.c3p0.management.ManagementCoordinator=com.mchange.v2.c3p0.management.NullManagementCoordinator

Configuring Logging Go To Top

c3p0 uses a custom logging library similar to jakarta commons-logging. Log messages can be directed to the popular log4j logging library, to the standard logging facility introduced with jdk1.4, or to System.err. Nearly all configuration should be done at the level of your preferred logging library. There are a very few configuration options specific to c3p0's logging, and usually the defaults will be fine. Logging-related parameters may be placed in your c3p0.properties file, in a file called mchange-log.properties at the top-level of your classpath, or they may be defined as System properties. (The logging properties defined below may not be defined in c3p0-config.xml!) See the box below.

c3p0's logging behavior is affected by certain build-time options. If build-option c3p0.debug is set to false, all messages at a logging level below INFO will be suppressed. Build-option c3p0.trace controls how fine-grained c3p0's below INFO level reporting will be. For the moment, distributed c3p0 binaries are compiled with debug set to true and trace set to its maximum level of 10. But binaries may eventually be distributed with debug set to false. (For the moment, the performance impact of the logging level-checks seems very small, and it's most flexible to compile in all the messages, and let your logging library control which are emitted.) When c3p0 starts up, it emits the build-time values of debug and trace, along with the version and build time.

com.mchange.v2.log.MLog
Determines which library c3p0 will output log messages to. By default, if log4j is available, it will use that library, otherwise if jdk1.4 logging apis are available it will use those, and if neither are available, it will use a simple fallback that logs to System.err. If you want to directly control which library is used, you may set this property to one of:
  • com.mchange.v2.log.log4j.Log4jMLog
  • com.mchange.v2.log.jdk14logging.Jdk14MLog
  • com.mchange.v2.log.FallbackMLog
You may also set this property to a comma separated list of the above alternatives, to define an order of preference among logging libraries.
com.mchange.v2.log.NameTransformer
By default, c3p0 uses very fine-grained logging, in general with one logger for each c3p0 class. For a variety of reasons, some users may prefer fewer, more global loggers. You may opt for one-logger-per-package by setting com.mchange.v2.log.NameTransformer to the value com.mchange.v2.log.PackageNames. Advanced users can also define other strategies for organizing the number and names of loggers by setting this variable to the fully-qualified class name of a custom implementation of the com.mchange.v2.log.NameTransformer interface.
com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL
If, whether by choice or by necessity, you are using c3p0's System.err fallback logger, you can use this parameter to control how detailed c3p0's logging should be. Any of the following values (taken from the jdk1.4 logging library) are acceptable:
  • OFF
  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST
  • ALL
This property defaults to INFO.

PerformanceGo To Top

Enhanced performance is the purpose of Connection and Statement pooling, and a major goal of the c3p0 library. For most applications, Connection pooling will provide a significant performance gain, especially if you are acquiring an unpooled Connection for each client access. If you are letting a single, shared Connection serve many clients to avoid Connection acquisition overhead, you may suffer performance issues and problems managing transactions when your Connection is under concurrent load; Connection pooling will enable you to switch to a one Connection-per-client model with little or no cost. If you are writing Enterprise Java Beans, you may be tempted to acquire a Connection once and not return it until the bean is about to be destroyed or passivated. But this can be resource-costly, as dormant pooled beans needlessly hold the Connection's network and database resources. Connection pooling permits beans to only "own" a Connection while they are using it.

But, there are performance costs to c3p0 as well. In order to implement automatic cleanup of unclosed ResultSets and Statements when parent resources are returned to pools, all client-visible Connections, ResultSets, Statements are really wrappers around objects provided by an underlying unpooled DataSource or "traditional" JDBC driver. Thus, there is some extra overhead to all JDBC calls.

Some attention has been paid to minimizing the "wrapper" overhead of c3p0. In my environment, the wrapper overhead amounts from several hundreths to several thousandths of the cost of Connection acquisition, so unless you are making many, many JDBC calls in fast succession, there will be a net gain in performance and resource-utilization efficiency. Significantly, the overhead associated with ResultSet operations (where one might iterate through a table with thousands of records) appears to be negligibly small.

Known ShortcomingsGo To Top

  • Connections and Statements are pooled on a per-authentication basis. So, if one pool-backed DataSource is used to acquire Connections both for [user=alice, password=secret1] and [user=bob, password=secret2], there will be two distinct pools, and the DataSource might in the worst case manage twice the number of Connections specified by the maxPoolSize property.

    This fact is a natural consequence of the definition of the DataSource spec (which allows Connections to be acquired with multiple user authentications), and the requirement that all Connections in a single pool be functionally identical. This "issue" will not be changed or fixed. It's noted here just so you understand what's going on.

  • The overhead of Statement pooling is too high. For drivers that do not perform significant preprocessing of PreparedStatements, the pooling overhead outweighs any savings. Statement pooling is thus turned off by default. If your driver does preprocess PreparedStatements, especially if it does so via IPC with the RDBMS, you will probably see a significant performance gain by turning Statement pooling on. (Do this by setting the configuration property maxStatements or maxStatementsPerConnection to a value greater than zero.).

Feedback and SupportGo To Top

Please provide any and all feedback to <swaldman@mchange.com>! Also, feel free to join and ask questions on the c3p0-users mailing list. Sign up at http://sourceforge.net/projects/c3p0/

Thank you for using c3p0!!!

Appendix A: Configuration PropertiesGo To Top

c3p0 configuration properties can be divided into JavaBeans-style Properties and Other Properties.

JavaBeans-style Properties Go To Top

The following properties can be set directly in code as JavaBeans properties, via a System properties or a c3p0.properties file (with c3p0. prepended to the property name), or in a c3p0-config.xml file. See the section on Configuration above. Click on the property name for a full description.

acquireIncrement
acquireRetryAttempts
acquireRetryDelay
autoCommitOnClose
automaticTestTable
breakAfterAcquireFailure
checkoutTimeout
connectionCustomizerClassName
connectionTesterClassName
debugUnreturnedConnectionStackTraces
factoryClassLocation
forceIgnoreUnresolvedTransactions
idleConnectionTestPeriod
initialPoolSize
maxAdministrativeTaskTime
maxConnectionAge
maxIdleTime
maxIdleTimeExcessConnections
maxPoolSize
maxStatements
maxStatementsPerConnection
minPoolSize
numHelperThreads
overrideDefaultUser
overrideDefaultPassword
password
preferredTestQuery
propertyCycle
testConnectionOnCheckin
testConnectionOnCheckout
unreturnedConnectionTimeout
user
usesTraditionalReflectiveProxies
acquireIncrement
Default: 3
acquireRetryAttempts
Default: 30
acquireRetryDelay
Default: 1000
autoCommitOnClose
Default: false
automaticTestTable
Default: null
breakAfterAcquireFailure
Default: false
checkoutTimeout
Default: 0
The number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or acquired when the pool is exhausted. Zero means wait indefinitely. Setting any positive value will cause the getConnection() call to time-out and break with an SQLException after the specified number of milliseconds.
connectionCustomizerClassName
Default: null
The fully qualified class-name of an implememtation of the ConnectionCustomizer interface, which users can implement to set up Connections when they are acquired from the database, or on check-out, and potentially to clean things up on check-in and Connection destruction. If standard Connection properties (holdability, readOnly, or transactionIsolation) are set in the ConnectionCustomizer's onAcquire() method, these will override the Connection default values.
connectionTesterClassName
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester
The fully qualified class-name of an implememtation of the ConnectionTester interface, or QueryConnectionTester if you would like instances to have access to a user-configured preferredTestQuery. This can be used to customize how c3p0 DataSources test Connections, but with the introduction of automaticTestTable and preferredTestQuery configuration parameters, "rolling your own" should be overkill for most users. [See "Configuring Connection Testing"]
debugUnreturnedConnectionStackTraces
Default: false
If true, and if unreturnedConnectionTimeout is set to a positive value, then the pool will capture the stack trace (via an Exception) of all Connection checkouts, and the stack traces will be printed when unreturned checked-out Connections timeout. This is intended to debug applications with Connection leaks, that is applications that occasionally fail to return Connections, leading to pool growth, and eventually exhaustion (when the pool hits maxPoolSize with all Connections checked-out and lost). This parameter should only be set while debugging, as capturing the stack trace will slow down every Connection check-out.
Does Not Support Per-User Overrides.
factoryClassLocation
Default: null
DataSources that will be bound by JNDI and use that API's Referenceable interface to store themselves may specify a URL from which the class capable of dereferencing a them may be loaded. If (as is usually the case) the c3p0 libraries will be locally available to the JNDI service, leave this set as null.
Does Not Support Per-User Overrides.
forceIgnoreUnresolvedTransactions
Default: false
idleConnectionTestPeriod
Default: 0
initialPoolSize
Default: 3
maxAdministrativeTaskTime
Default: 0
Seconds before c3p0's thread pool will try to interrupt an apparently hung task. Rarely useful. Many of c3p0's functions are not performed by client threads, but asynchronously by an internal thread pool. c3p0's asynchrony enhances client performance directly, and minimizes the length of time that critical locks are held by ensuring that slow jdbc operations are performed in non-lock-holding threads. If, however, some of these tasks "hang", that is they neither succeed nor fail with an Exception for a prolonged period of time, c3p0's thread pool can become exhausted and administrative tasks backed up. If the tasks are simply slow, the best way to resolve the problem is to increase the number of threads, via numHelperThreads. But if tasks sometimes hang indefinitely, you can use this parameter to force a call to the task thread's interrupt() method if a task exceeds a set time limit. [c3p0 will eventually recover from hung tasks anyway by signalling an "APPARENT DEADLOCK" (you'll see it as a warning in the logs), replacing the thread pool task threads, and interrupt()ing the original threads. But letting the pool go into APPARENT DEADLOCK and then recover means that for some periods, c3p0's performance will be impaired. So if you're seeing these messages, increasing numHelperThreads and setting maxAdministrativeTaskTime might help. maxAdministrativeTaskTime should be large enough that any resonable attempt to acquire a Connection from the database, to test a Connection, or two destroy a Connection, would be expected to succeed or fail within the time set. Zero (the default) means tasks are never interrupted, which is the best and safest policy under most circumstances. If tasks are just slow, allocate more threads. If tasks are hanging forever, try to figure out why, and maybe setting maxAdministrativeTaskTime can help in the meantime.
Does Not Support Per-User Overrides.
maxConnectionAge
Default: 0
Seconds, effectively a time to live. A Connection older than maxConnectionAge will be destroyed and purged from the pool. This differs from maxIdleTime in that it refers to absolute age. Even a Connection which has not been much idle will be purged from the pool if it exceeds maxConnectionAge. Zero means no maximum absolute age is enforced.
maxIdleTime
Default: 0
maxIdleTimeExcessConnections
Default: 0
Number of seconds that Connections in excess of minPoolSize should be permitted to remain idle in the pool before being culled. Intended for applications that wish to aggressively minimize the number of open Connections, shrinking the pool back towards minPoolSize if, following a spike, the load level diminishes and Connections acquired are no longer needed. If maxIdleTime is set, maxIdleTimeExcessConnections should be smaller if the parameter is to have any effect. Zero means no enforcement, excess Connections are not idled out.
maxPoolSize
Default: 15
maxStatements
Default: 0
maxStatementsPerConnection
Default: 0
minPoolSize
Default: 3
numHelperThreads
Default: 3
c3p0 is very asynchronous. Slow JDBC operations are generally performed by helper threads that don't hold contended locks. Spreading these operations over multiple threads can significantly improve performance by allowing multiple operations to be performed simultaneously.
Does Not Support Per-User Overrides.
overrideDefaultUser
Default: null
Does Not Support Per-User Overrides.
overrideDefaultPassword
Default: null
Does Not Support Per-User Overrides.
password
Default: null
Does Not Support Per-User Overrides.
preferredTestQuery
Default: null
Defines the query that will be executed for all connection tests, if the default ConnectionTester (or some other implementation of QueryConnectionTester, or better yet FullQueryConnectionTester) is being used. Defining a preferredTestQuery that will execute quickly in your database may dramatically speed up Connection tests. (If no preferredTestQuery is set, the default ConnectionTester executes a getTables() call on the Connection's DatabaseMetaData. Depending on your database, this may execute more slowly than a "normal" database query.) NOTE: The table against which your preferredTestQuery will be run must exist in the database schema prior to your initialization of your DataSource. If your application defines its own schema, try automaticTestTable instead. [See "Configuring Connection Testing"]
propertyCycle
Default: 0
testConnectionOnCheckin
Default: false
testConnectionOnCheckout
Default: false
unreturnedConnectionTimeout
Default: 0
Seconds. If set, if an application checks out but then fails to check-in [i.e. close()] a Connection within the specified period of time, the pool will unceremoniously destroy() the Connection. This permits applications with occasional Connection leaks to survive, rather than eventually exhausting the Connection pool. And that's a shame. Zero means no timeout, applications are expected to close() their own Connections. Obviously, if a non-zero value is set, it should be to a value longer than any Connection should reasonably be checked-out. Otherwise, the pool will occasionally kill Connections in active use, which is bad. This is basically a bad idea, but it's a commonly requested feature. Fix your $%!@% applications so they don't leak Connections! Use this temporarily in combination with debugUnreturnedConnectionStackTraces to figure out where Connections are being checked-out that don't make it back into the pool!
user
Default: null
Does Not Support Per-User Overrides.
usesTraditionalReflectiveProxies
Default: false
c3p0 originally used reflective dynamic proxies for implementations of Connections and other JDBC interfaces. As of c3p0-0.8.5, non-reflective, code-generated implementations are used instead. As this was a major change, and the old codebase had been extensively used and tested, this parameter was added to allow users to revert of they had problems. The new, non-reflexive implementation is faster, and has now been widely deployed and tested, so it is unlikely that this parameter will be useful. Both the old reflective and newer non-reflective codebases are being maintained, but support for the older codebase may (or may not) be dropped in the future.

Other Properties Go To Top

The following configuration properties affect the behavior of the c3p0 library as a whole. They may be set as system properties, or in a c3p0.properties file.

Locating Configuration Information

Normally, c3p0's configuration information is placed in a either a c3p0-config.xml or c3p0.properties file at the top-level of an application's CLASSPATH. However, if you wish to place configuration information elsewhere, you may place c3p0 configuration information (in the XML file format only!) anywhere you'd like in the filesystem visible to your application. Just set the following property to the full, absolute path of the XML config file:

  • com.mchange.v2.c3p0.cfg.xml

Logging-related properties

The following properties affect c3p0's logging behavior. Please see Configuring Logging above for specific information.

  • com.mchange.v2.log.MLog
  • com.mchange.v2.log.NameTransformer
  • com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL

Configuring JMX

The following property controls c3p0's JMX management interface. Plese see Configuring and Managing c3p0 via JMX above for more information.

  • com.mchange.v2.c3p0.management.ManagementCoordinator

Configuring the VMID

Is it better to be beautiful or correct? Beginning with c3p0-0.9.1, c3p0 opts somewhat reluctantly for correctness.

Here's the deal. Every c3p0 DataSource is allocated a unique "identity token", which is used to ensure that multiple JNDI lookups of the same PooledDataSource always return the same instance, even if the JNDI name-server stores a Serialized or Referenced instance. Previously, c3p0 was happy for generated IDs to be unique within a single VM (and it didn't even get that quite right, before c3p0-0.9.1). But in theory, one VM might look up two different DataSources, generated by two different VMs, that by unlikely coincidence have the same "identity token", leading to errors as one of the two DataSources sneakily substitutes for the second. Though this hypothetical issue has never been reported in practice, c3p0 resolves it by prepending a VMID to its identity tokens. This makes them long and ugly, but correct.

If you don't like the long and ugly VMID, you can set your own, or you can turn off this solution to a hypothetical non-problem entirely with the following property:

  • com.mchange.v2.c3p0.VMID

Set it to NONE to turn off the VMID, set it to AUTO to let c3p0 generate a VMID, or provide any other String to set the VMID that will be used directly. The default is AUTO.

Experimental properties

c3p0-0.9.1 includes a new implementation of asynchronous Connection acquisition that should improve c3p0's performance and resource utilization in cases where database acquisition attempts, for whatever reason, occasionally fail. The new implementation should be significantly better than the "traditional" Connection acquisition strategy, but was added too late in the c3p0-0.9.1 development cycle to be fully tested and enabled by default. Users are encouraged to try the new implementation, both because it is better, and to help iron out any unanticipated problems.

For a full description of the new implementation and the resource bottleneck it is designed to overcome, please see the CHANGELOG entry for c3p0-0.9.1-pre11. To enable the new implementation, set the following parameter to "true".

  • com.mchange.v2.resourcepool.experimental.useScatteredAcquireTask

This feature is expected to be enabled by default in c3p0-0.9.2 and above.


Appendix B: Configuration Files, etc. Go To Top

c3p0 configuration parameters can be set directly in Java code, via a simple Java properties file, via an XML configuration file, or via System properties. Any which way works (the the XML configuration is most powerful, though, as it supports multiple named configurations and per-user overrides. Choose whatever works best for you.

Overriding c3p0 defaults via c3p0.properties Go To Top

To override the library's built-in defaults, create a file called c3p0.properties and place it at the "root" of your classpath or classloader. For a typical standalone application, that means place the file in a directory named in your CLASSPATH environment variable. For a typical web-application, the file should be placed in WEB-INF/classes. In general, the file must be available as a classloader resource under the name /c3p0.properties, in the classloader that loaded c3p0's jar file. Review the API docs (especilly getResource... methods) of java.lang.Class, java.lang.ClassLoader, and java.util.ResourceBundle if this is unfamiliar.

The format of c3p0.properties should be a normal Java Properties file format, whose keys are c3p0 configurable properties. See Appendix A. for the specifics. An example c3p0.properties file is produced below:

# turn on statement pooling c3p0.maxStatements=150 # close pooled Connections that go unused for # more than half an hour c3p0.maxIdleTime=1800

Overriding c3p0 defaults with a System properties Go To Top

c3p0 properties can also be defined as System properties, using the same "c3p0." prefix for properties specified in a c3p0.properties file.

swaldman% java -Dc3p0.maxStatements=150 -Dc3p0.maxIdleTime=1800 example.MyC3P0App

System properties override settings in c3p0.properties. Please see Precedence of Configuration Settings for more information.

Named and Per-User configuration: Overriding c3p0 defaults via c3p0-config.xml Go To Top

As of c3p0-0.9.1, you can define multiple configurations in an XML configuration file, and specify in your code which configuration to use. For any configurations (including the unnamed default configuration), you can define overrides for a particular database user. For example, if several applications access your database under different authentication credentials, you might define maxPoolSize to be 100 for user highVolumeApp, but only 10 for user lowLoadApp. (Recall that Connections associated with different authentication credentials are of necessity separated into separate pools, so it makes sense that these could be configured separately.)

You can use the XML config file for all c3p0 configuration, including configuration of defaults. However, for users who don't want or need the extra complexity, the c3p0.properties file will continue to be supported.

By default, c3p0 will look for an XML configuration file in its classloader's resource path under the name "/c3p0-config.xml". That means the XML file should be placed in a directly or jar file directly named in your applications CLASSPATH, in WEB-INF/classes, or some similar location.

If you prefer not to bundle your configuration with your code, you can specify an ordinary filesystem location for c3p0's configuration file via the system property com.mchange.v2.c3p0.cfg.xml.

Here is an example c3p0-config.xml file:

<c3p0-config> <default-config> <property name="automaticTestTable">con_test</property> <property name="checkoutTimeout">30000</property> <property name="idleConnectionTestPeriod">30</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> <property name="maxStatements">200</property> <user-overrides user="test-user"> <property name="maxPoolSize">10</property> <property name="minPoolSize">1</property> <property name="maxStatements">0</property> </user-overrides> </default-config> <!-- This app is massive! --> <named-config name="intergalactoApp"> <property name="acquireIncrement">50</property> <property name="initialPoolSize">100</property> <property name="minPoolSize">50</property> <property name="maxPoolSize">1000</property> <!-- intergalactoApp adopts a different approach to configuring statement caching --> <property name="maxStatements">0</property> <property name="maxStatementsPerConnection">5</property> <!-- he's important, but there's only one of him --> <user-overrides user="master-of-the-universe"> <property name="acquireIncrement">1</property> <property name="initialPoolSize">1</property> <property name="minPoolSize">1</property> <property name="maxPoolSize">5</property> <property name="maxStatementsPerConnection">50</property> </user-overrides> </named-config> </c3p0-config>

To use a named configuration, you specify the config name when creating your DataSource. For example, using ComboPooledDataSource:

ComboPooledDataSource cpds = new ComboPooledDataSource("intergalactoApp");

Or using the DataSources factory class:

DataSource ds_pooled = DataSources.pooledDataSource( ds_unpooled, "intergalactoApp" );

Precedence of Configuration Settings Go To Top

c3p0 now permits configuration parameters to be set in a number of different ways and places. Fortunately, there is a clear order of precedence that determines which configuration will "take" in the event of conflicting settings. Conceptually, c3p0 goes down this list from top to bottom, using the first setting it finds.

Most applications will never use per-user or named configurations. For these applications, we present a simplified precedence hierarchy:

  1. Configuration values programmatically set.
  2. System property setting of configuration value.
  3. Configuration values taken from the default configuration of a c3p0-config.xml file.
  4. Configuration values specified in a c3p0.properties file
  5. c3p0's hard-coded default values.

For applications that do use named and per-user configurations, here is the complete, normative precedence hierarchy:

  1. User-specific overrides programmatically set via: Note that programmatically setting user-specific overrides replaces all user-specific configuration taken from other sources. If you want to merge programmatic changes with preconfigured overrides, you'll have to use getUserOverridesAsString() and modify the original settings before replacing.
  2. User-specific overrides taken from a DataSource's named configuration (specified in c3p0-config.xml)
  3. User-specific overrides taken from the default configuration (specified in c3p0-config.xml)
  4. Non-user-specific values programmatically set.
  5. Non-user-specific values taken from a DataSource's named configuration (specified in c3p0-config.xml)
  6. System property setting of configuration value.
  7. Non-user-specific values taken from the default configuration (specified in c3p0-config.xml)
  8. Values specified in a c3p0.properties file
  9. c3p0's hard-coded default values.

Appendix C: Hibernate-specific notes Go To Top

Hibernate's C3P0ConnectionProvider explicitly sets 7 c3p0 configuration properties, based on your hibernate configuration, overriding any configuration you may have set in a c3p0.properties file. If you are using Hibernate's C3P0ConnectionProvider you must set the following properties in your hibernate configuration, using hibernate-specific configuration keys. All other properties must be defined as usual in a c3p0.properties file. This is confusing, and will hopefully be simplified some time in the future, but for now...

The following properties must be set in your hibernate configuration:

c3p0-native property namehibernate configuration key
c3p0.acquireIncrementhibernate.c3p0.acquire_increment
c3p0.idleConnectionTestPeriodhibernate.c3p0.idle_test_period
c3p0.initialPoolSizenot available -- uses minimum size
c3p0.maxIdleTimehibernate.c3p0.timeout
c3p0.maxPoolSizehibernate.c3p0.max_size
c3p0.maxStatementshibernate.c3p0.max_statements
c3p0.minPoolSizehibernate.c3p0.min_size
c3p0.testConnectionsOnCheckout hibernate.c3p0.validate hibernate 2.x only!

Remember -- these, and only these, properties must be defined in your hibernate configuration, or else they will be set to hibernate-specified defaults. All other configuration properties that you wish to set should be defined in a c3p0.properties file. (See "Overriding c3p0 defaults via c3p0.properties".)


Appendix D: Configuring c3p0 DataSources in TomcatGo To Top

You can easily configure Apache's Tomcat web application server to use c3p0 pooled DataSources. Below is a Tomcat 5.0 sample config to get you started. It's a fragment of Tomcat's conf/server.xml file, which should be modified to suit and placed inside a <Context> element.

<Resource name="jdbc/pooledDS" auth="Container" type="com.mchange.v2.c3p0.ComboPooledDataSource" /> <ResourceParams name="jdbc/pooledDS"> <parameter> <name>factory</name> <value>org.apache.naming.factory.BeanFactory</value> </parameter> <parameter> <name>driverClass</name> <value>org.postgresql.Driver</value> </parameter> <parameter> <name>jdbcUrl</name> <value>jdbc:postgresql://localhost/c3p0-test</value> </parameter> <parameter> <name>user</name> <value>swaldman</value> </parameter> <parameter> <name>password</name> <value>test</value> </parameter> <parameter> <name>minPoolSize</name> <value>5</value> </parameter> <parameter> <name>maxPoolSize</name> <value>15</value> </parameter> <parameter> <name>acquireIncrement</name> <value>5</value> </parameter> </ResourceParams>

For Tomcat 5.5, try something like the following (thanks to Carl F. Hall for the sample!):

<Resource auth="Container" description="DB Connection" driverClass="com.mysql.jdbc.Driver" maxPoolSize="4" minPoolSize="2" acquireIncrement="1" name="jdbc/TestDB" user="test" password="ready2go" factory="org.apache.naming.factory.BeanFactory" type="com.mchange.v2.c3p0.ComboPooledDataSource" jdbcUrl="jdbc:mysql://localhost:3306/test?autoReconnect=true" />

The rest is standard J2EE stuff: You'll need to declare your DataSource reference in your web.xml file:

<resource-ref> <res-ref-name>jdbc/pooledDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>

And you can access your DataSource from code within your web application like this:

InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/pooledDS");

That's it!


Appendix E: JBoss-specific notesGo To Top

To use c3p0 with JBoss:

  1. Place c3p0's jar file in the lib directory of your jboss server instance (e.g. ${JBOSS_HOME}/server/default/lib)
  2. Modify the file below, and save it as c3p0-service.xml in the deploy directory of your jboss server (e.g. ${JBOSS_HOME}/server/default/deploy). Note that parameters must be capitalized in this file, but otherwise they are defined as described above.

Please note: As of c3p0-0.9.1, the class name of the jboss configuration mbean has changed to com.mchange.v2.c3p0.jboss.C3P0PooledDataSource (from com.mchange.v2.c3p0.mbean.C3P0PooledDataSource), in order to distinguish what is really jboss-specific functionality from c3p0's more general JMX support.

The old jboss config mbeans are deprecated, but will still work. However, support for new configuration parameters will only be added under the new name. Updating requires a one-word change to your c3p0-service.xml, change "mbean" to "jboss" where your old file says 'code="com.mchange.v2.c3p0.mbean.C3P0PooledDataSource"'. Just do it!

Hide box.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE server> <server> <mbean code="com.mchange.v2.c3p0.jboss.C3P0PooledDataSource" name="jboss:service=C3P0PooledDataSource"> <attribute name="JndiName">java:PooledDS</attribute> <attribute name="JdbcUrl">jdbc:postgresql://localhost/c3p0-test</attribute> <attribute name="DriverClass">org.postgresql.Driver</attribute> <attribute name="User">swaldman</attribute> <attribute name="Password">test</attribute> <!-- Uncomment and set any of the optional parameters below --> <!-- See c3p0's docs for more info. --> <!-- <attribute name="AcquireIncrement">3</attribute> --> <!-- <attribute name="AcquireRetryAttempts">30</attribute> --> <!-- <attribute name="AcquireRetryDelay">1000</attribute> --> <!-- <attribute name="AutoCommitOnClose">false</attribute> --> <!-- <attribute name="AutomaticTestTable"></attribute> --> <!-- <attribute name="BreakAfterAcquireFailure">false</attribute> --> <!-- <attribute name="CheckoutTimeout">0</attribute> --> <!-- <attribute name="ConnectionCustomizerClassName"></attribute> --> <!-- <attribute name="ConnectionTesterClassName"></attribute> --> <!-- <attribute name="Description">A pooled c3p0 DataSource</attribute> --> <!-- <attribute name="DebugUnreturnedConnectionStackTraces">false</attribute> --> <!-- <attribute name="FactoryClassLocation"></attribute> --> <!-- <attribute name="ForceIgnoreUnresolvedTransactions">false</attribute> --> <!-- <attribute name="IdleConnectionTestPeriod">0</attribute> --> <!-- <attribute name="InitialPoolSize">3</attribute> --> <!-- <attribute name="MaxAdministrativeTaskTime">0</attribute> --> <!-- <attribute name="MaxConnectionAge">0</attribute> --> <!-- <attribute name="MaxIdleTime">0</attribute> --> <!-- <attribute name="MaxIdleTimeExcessConnections">0</attribute> --> <!-- <attribute name="MaxPoolSize">15</attribute> --> <!-- <attribute name="MaxStatements">0</attribute> --> <!-- <attribute name="MaxStatementsPerConnection">0</attribute> --> <!-- <attribute name="MinPoolSize">0</attribute> --> <!-- <attribute name="NumHelperThreads">3</attribute> --> <!-- <attribute name="PreferredTestQuery"></attribute> --> <!-- <attribute name="TestConnectionOnCheckin">false</attribute> --> <!-- <attribute name="TestConnectionOnCheckout">false</attribute> --> <!-- <attribute name="UnreturnedConnectionTimeout">0</attribute> --> <!-- <attribute name="UsesTraditionalReflectiveProxies">false</attribute> --> <depends>jboss:service=Naming</depends> </mbean> </server>


Appendix F: Oracle-specific API: createTemporaryBLOB() and createTemporaryCLOB()Go To Top

The Oracle thin JDBC driver provides a non-standard API for creating temporary BLOBs and CLOBs that requires users to call methods on the raw, Oracle-specific Connection implementation. Advanced users might use the raw connection operations described above to access this functionality, but a convenience class is available in a separate jar file (c3p0-oracle-thin-extras-@c3p0.version@.jar) for easier access to this functionality. Please see the API docs for com.mchange.v2.c3p0.dbms.OracleUtils for details.


Back to Contents c3p0-0.9.1.2.orig/src/docweb/0000755000175000017500000000000010222213216013512 5ustar godgodc3p0-0.9.1.2.orig/src/docweb/docwebapp/0000755000175000017500000000000010222213002015447 5ustar godgodc3p0-0.9.1.2.orig/src/docweb/docwebapp/WEB-INF/0000755000175000017500000000000010673162231016517 5ustar godgodc3p0-0.9.1.2.orig/src/docweb/docwebapp/WEB-INF/jboss-web.xml0000644000175000017500000000036010222221355021124 0ustar godgod @virtual.host@ c3p0-0.9.1.2.orig/src/docweb/docwebapp/WEB-INF/web.xml0000644000175000017500000000027710222214523020014 0ustar godgod c3p0-0.9.1.2.orig/src/docweb/docwebear/0000755000175000017500000000000010222213017015444 5ustar godgodc3p0-0.9.1.2.orig/src/docweb/docwebear/META-INF/0000755000175000017500000000000010673162231016617 5ustar godgodc3p0-0.9.1.2.orig/src/docweb/docwebear/META-INF/application.xml0000644000175000017500000000056110222213120021626 0ustar godgod www.mchange.com @web.uri@ @context.root@ c3p0-0.9.1.2.orig/src/empty/0000755000175000017500000000000010375026574013427 5ustar godgodc3p0-0.9.1.2.orig/src/resources/0000755000175000017500000000000010210514577014274 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/0000755000175000017500000000000010210514577015052 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/mchange/0000755000175000017500000000000010210514577016454 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/mchange/v2/0000755000175000017500000000000010210523131016765 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/mchange/v2/cfg/0000755000175000017500000000000010673162231017541 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/mchange/v2/cfg/junit/0000755000175000017500000000000010673162231020672 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/mchange/v2/cfg/junit/a.properties0000644000175000017500000000002210364121314023214 0ustar godgoduser.home=/a/home c3p0-0.9.1.2.orig/src/resources/com/mchange/v2/cfg/junit/b.properties0000644000175000017500000000002210364121314023215 0ustar godgoduser.home=/b/home c3p0-0.9.1.2.orig/src/resources/com/mchange/v2/cfg/vmConfigResourcePaths.txt0000644000175000017500000000031410366007105024555 0ustar godgod# # note that later files "shadow" earlier ones, and that # the name '/' is reserved as a special token for # System properties. # /mchange-commons.properties /mchange-log.properties /c3p0.properties / c3p0-0.9.1.2.orig/src/resources/com/mchange/v2/log/0000755000175000017500000000000010673162231017563 5ustar godgodc3p0-0.9.1.2.orig/src/resources/com/mchange/v2/log/default-mchange-log.properties0000644000175000017500000000014710624366530025512 0ustar godgodcom.mchange.v2.log.MLog=com.mchange.v2.log.log4j.Log4jMLog,com.mchange.v2.log.jdk14logging.Jdk14MLog c3p0-0.9.1.2.orig/test-properties/0000755000175000017500000000000010673162231014643 5ustar godgodc3p0-0.9.1.2.orig/test-properties/c3p0-config.xml0000644000175000017500000000306510502754724017406 0ustar godgod c3p0-0.9.1.2.orig/test-properties/c3p0.properties0000644000175000017500000000306310576160532017534 0ustar godgod# # This file is detritus from various testing attempts # the values below may change, and often do not represent # reasonable values for the parameters. # #c3p0.testConnectionOnCheckout=true #c3p0.testConnectionOnCheckin=true #c3p0.minPoolSize=3 #c3p0.maxPoolSize=20 #c3p0.checkoutTimeout=2000 #c3p0.idleConnectionTestPeriod=5 #c3p0.maxConnectionAge=10 #c3p0.maxIdleTime=2 #c3p0.maxIdleTimeExcessConnections=1 #c3p0.propertyCycle=1 #c3p0.numHelperThreads=10 #c3p0.unreturnedConnectionTimeout=15 #c3p0.debugUnreturnedConnectionStackTraces=true #c3p0.maxStatements=30 #c3p0.maxStatementsPerConnection=5 #c3p0.maxAdministrativeTaskTime=3 #c3p0.preferredTestQuery=SELECT 1 #c3p0.preferredTestQuery=SELECT a FROM emptyyukyuk WHERE a = 5 #c3p0.preferredTestQuery=SELECT a FROM testpbds WHERE a = 5 #c3p0.usesTraditionalReflectiveProxies=true #c3p0.automaticTestTable=PoopyTestTable #c3p0.acquireIncrement=4 #c3p0.acquireRetryDelay=1000 #c3p0.acquireRetryAttempts=60 #c3p0.connectionTesterClassName=com.mchange.v2.c3p0.test.AlwaysFailConnectionTester #c3p0.initialPoolSize=10 c3p0.jdbcUrl=jdbc:postgresql://localhost/c3p0-test c3p0.driverClass=org.postgresql.Driver c3p0.user=swaldman c3p0.password=test #c3p0.user=poop #c3p0.password=scoop #com.mchange.v2.log.MLog=com.mchange.v2.log.log4j.Log4jMLog #com.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog #com.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog #com.mchange.v2.log.NameTransformer=com.mchange.v2.log.PackageNames #com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=ALL #com.mchange.v2.c3p0.VMID=poop c3p0-0.9.1.2.orig/test-properties/log4j.properties0000644000175000017500000000122510526504013017773 0ustar godgod #log4j.rootLogger=ALL,A1 log4j.rootLogger=INFO,A1 #log4j.logger.com.mchange.v2.resourcepool=ALL,A1 #log4j.logger.com.mchange.v2.c3p0.stmt=ALL #log4j.logger.com.mchange.v2.c3p0.impl=ALL #log4j.logger.com.mchange.v2.c3p0.management=ALL #log4j.logger.com.mchange.v2.resourcepool=ALL log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.SimpleLayout #log4j.appender.A1.layout=org.apache.log4j.PatternLayout #log4j.appender.A1.layout.ConversionPattern=%r [%t] %-5p %c %x - %m\n #log4j.appender.A1.layout.ConversionPattern=%d %-5p %c [%t] %C %M --> %m%n #log4j.appender.A1.layout.ConversionPattern=%-5p %c %C.%M() --> %m%n c3p0-0.9.1.2.orig/test-properties/logging.properties0000644000175000017500000000462710516246522020422 0ustar godgod############################################################ # Default Logging Configuration File # # For example java -Djava.util.logging.config.file=myfile ############################################################ ############################################################ # Global properties ############################################################ # "handlers" specifies a comma separated list of log Handler # classes. These handlers will be installed during VM startup. # Note that these classes must be on the system classpath. # By default we only configure a ConsoleHandler, which will only # show messages at the INFO and above levels. handlers=java.util.logging.ConsoleHandler # To also add the FileHandler, use the following line instead. #handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler # Default global logging level. # This specifies which kinds of events are logged across # all loggers. For any given facility this global level # can be overriden by a facility specific level # Note that the ConsoleHandler also has a separate level # setting to limit messages printed to the console. #.level=ALL #.level=FINER #.level=OFF .level=INFO ############################################################ # Handler specific properties. # Describes specific configuration info for Handlers. ############################################################ # default file output is in user's home directory. java.util.logging.FileHandler.pattern=%h/java%u.log java.util.logging.FileHandler.limit=50000 java.util.logging.FileHandler.count=1 java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter # Limit the message that are printed on the console to INFO and above. java.util.logging.ConsoleHandler.level=ALL java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter ############################################################ # Facility specific properties. # Provides extra control for each logger. ############################################################ # For example, set the com.xyz.foo logger to only log SEVERE # messages: #com.xyz.foo.level = SEVERE #com.mchange.v2.resourcepool.level=INFO #com.mchange.v2.resourcepool.level=FINER com.mchange.v2.resourcepool.level=ALL #com.mchange.v2.c3p0.impl.level=ALL #com.mchange.level=FINE #com.mchange.level=ALL #com.mchange.v2.c3p0.impl.level=ALL #com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.level=ALL c3p0-0.9.1.2.orig/.classpath0000644000175000017500000000035210502776662013467 0ustar godgod c3p0-0.9.1.2.orig/.project0000644000175000017500000000030510502776763013153 0ustar godgod c3p0 c3p0-0.9.1.2.orig/README-SRC0000644000175000017500000000102607772201244013002 0ustar godgodHi. Building c3p0 should be as easy as editing build.properties and typing ant. Please send any feedback / questions to Steve Waldman All of the test related properties are very optional. There are various test tasks in the build file, but they are ad-hoc and unsupported. Someday I plan to get with jUnit and do real testing, but that day has not yet come. Until then, you, my dear user, are my primary testing engine. Sorry. Steve Waldman Machinery For Change, Inc. c3p0-0.9.1.2.orig/build.properties0000644000175000017500000000424710503017467014720 0ustar godgod# >> BASICS << # # You'll need to supply at least one of j2ee.classpath # or j2ee.jar.file.base.dir. All jar files under # ${j2ee.jar.file.base.dir} or its subdirectories # will be added to the effective classpath of the project. # #j2ee.classpath= #j2ee.jar.base.dir= # >> DEBUGGING AND TRACING << # Set this to true if you want logging enabled for logging levels below INFO. # If debug is not set, logging code for these messages will be eliminated from # the compiled code by virtue of "if (false) { ... }" blocks. #c3p0-build.debug= # Set trace to an integer between 0 and 10 (inclusive) to control how the level # of detail of debug logging messages. Only makes a difference if c3p0.debug is # set to true above. Default to 5 if unset. #c3p0-build.trace= # NOTE: You must still configure your logging library to log or display these # debug level messages if you actually want to see any change! #---------------------------------------------------------------------------- # >> OPTIONAL LIBRARY SUPPRT << # # You'll only need this property if you want to # build-in optional log4j support. # #log4j.jar.file= # # You'll only need this property if you want to # build the jar of utilities specific to the # oracle-thin jdbc driver / dbms # #oracle-thin.jdbc.jar.file= #---------------------------------------------------------------------------- # >> OPTIONAL TEST SUPPORT # # this stuff is only required if you want to run # the various tests. very optional # #test.jdbc.driver.jar.file= #test.jdbc.drivers= #test.jdbc.url= #test.jdbc.user= #test.jdbc.password= # # required if you want to run junit tests # #junit.jar.file # >> VERY VERY OPTIONAL DOCS-TO-WEB SUPPORT # # this stuff is only required if you want to deploy # an ear file containing c3p0's docs to a J2EE appserver. # via scp. Requires an available executable "scp". # # this is a convenience for c3p0's developer, not # really intended for other users. just leave blank # # note that virtual.host modifies a jboss-web.xml file, # will do nothing if you are deploying to some other # app server # #docwebapp.context.root= #docwebapp.virtual.host= #docwebear.deploy.user= #docwebear.deploy.host= #docwebear.deploy.path= c3p0-0.9.1.2.orig/build.xml0000644000175000017500000007000610525151714013316 0ustar godgod c3p0-0.9.1.2.orig/build.xml.bkup0000644000175000017500000006364510503325317014267 0ustar godgod c3p0-0.9.1.2.orig/version.properties0000644000175000017500000000012210624366530015274 0ustar godgod#autogenerated -- do not edit! #Mon May 21 15:04:56 EDT 2007 c3p0.version=0.9.1.2