I don't think we made the decision to move these specific classes into the
core cvs yet.  Did we?

-Mark

> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, June 24, 2003 1:19 AM
> To: [EMAIL PROTECTED]
> Subject: cvs commit: jakarta-log4j/src/java/org/apache/log4j/jdbc
> PreparedStatementSource.java PreparedStatementParameter.java
> ConnectionSource.java JDBCReceiver.java UrlConnectionSource.java
> PreparedStatementAppender.java JNDIConnectionSource.java
> 
> 
> psmith      2003/06/24 01:19:11
> 
>   Added:       src/java/org/apache/log4j/jdbc 
> PreparedStatementSource.java
>                         PreparedStatementParameter.java
>                         ConnectionSource.java JDBCReceiver.java
>                         UrlConnectionSource.java
>                         PreparedStatementAppender.java
>                         JNDIConnectionSource.java
>   Log:
>   moving to jakarta-log4j from jakarta-log4j-sandbox.
>   
>   Revision  Changes    Path
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/PreparedStatement
> Source.java
>   
>   Index: PreparedStatementSource.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.spi.ErrorHandler;
>   import org.apache.log4j.spi.OptionHandler;
>   
>   import java.sql.Connection;
>   import java.sql.PreparedStatement;
>   import java.sql.SQLException;
>   
>   
>   /**
>    *  The <code>PreparedStatementSource</code> interface 
> provides a pluggable
>    *  means of creating [EMAIL PROTECTED] java.sql.PreparedStatement}s 
> for use with the
>    *  [EMAIL PROTECTED] PreparedStatementAppender}.  Create an 
> implementation of this
>    *  interface if the default [EMAIL PROTECTED] 
> java.sql.PreparedStatement} created
>    *  by the appender is not sufficient.
>    *  <p>
>    *  Note that since a [EMAIL PROTECTED] java.sql.CallableStatement} is a
>    *  [EMAIL PROTECTED] java.sql.PreparedStatement} you can use this
>    *  interface to set up calls to stored procedures if desired.
>    *
>    *  @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a>
>    */
>   public interface PreparedStatementSource extends OptionHandler {
>     /**
>      *  Generate a [EMAIL PROTECTED] java.sql.PreparedStatement} for use 
> by the client.
>      *  The client is responsible for closing the statement.
>      */
>     public PreparedStatement generate(
>       PreparedStatementAppender psa, Connection conn) throws 
> SQLException;
>   
>     /**
>      *  Set the error handler.
>      *
>      *  @param errorHanlder  the new error handler
>      */
>     void setErrorHandler(ErrorHandler errorHandler);
>   }
>   
>   
>   
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/PreparedStatement
> Parameter.java
>   
>   Index: PreparedStatementParameter.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.Level;
>   import org.apache.log4j.spi.ErrorHandler;
>   import org.apache.log4j.spi.ThrowableInformation;
>   
>   import java.io.PrintWriter;
>   import java.io.StringReader;
>   import java.io.StringWriter;
>   
>   import java.math.BigDecimal;
>   
>   import java.sql.Date;
>   import java.sql.PreparedStatement;
>   import java.sql.SQLException;
>   import java.sql.Time;
>   import java.sql.Timestamp;
>   
>   
>   /**
>    *  The <code>PreparedStatementParameter</code> class 
> encapsulates the
>    *  information needed to set a parameter on a
>    *  [EMAIL PROTECTED] java.sql.PreparedStatement}.
>    *
>    *  @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a>
>    */
>   public class PreparedStatementParameter implements Comparable {
>     private String columnName;
>     private int order;
>     private String jdbcSetter;
>     private ErrorHandler errorHandler;
>   
>     /**
>      *  Default constructor.
>      */
>     public PreparedStatementParameter() {
>     }
>   
>     /**
>      * Returns the columnName.
>      * @return String
>      */
>     public String getColumnName() {
>       return columnName;
>     }
>   
>     /**
>      * Returns the jdbcSetter.
>      * @return String
>      */
>     public String getJdbcSetter() {
>       return jdbcSetter;
>     }
>   
>     /**
>      * Returns the order.
>      * @return int
>      */
>     public int getOrder() {
>       return order;
>     }
>   
>     /**
>      * Sets the columnName.
>      * @param columnName The columnName to set
>      */
>     public void setColumnName(String columnName) {
>       this.columnName = columnName;
>     }
>   
>     /**
>      * Sets the jdbcSetter.
>      * @param jdbcSetter The jdbcSetter to set
>      */
>     public void setJdbcSetter(String jdbcSetter) {
>       this.jdbcSetter = jdbcSetter;
>     }
>   
>     /**
>      * Sets the order.
>      * @param order The order to set
>      */
>     public void setOrder(int order) {
>       this.order = order;
>     }
>   
>     /**
>      *  Compares based on the order.
>      */
>     public int compareTo(Object obj) {
>       PreparedStatementParameter that = 
> (PreparedStatementParameter) obj;
>   
>       if (this.order < that.order) {
>         return -1;
>       } else if (this.order == that.order) {
>         return 0;
>       } else {
>         return 1;
>       }
>     }
>   
>     /**
>      *  Set this parameter on the given statement with the 
> given value.
>      *
>      *  @param stmt   the statement
>      *  @param value  the value to set
>      *
>      *  @throws SQLException  if the parameter could not be set
>      */
>     public void setParameter(PreparedStatement stmt, String value)
>       throws SQLException {
>       if ("setString".equals(jdbcSetter)) {
>         stmt.setString(order, value);
>       } else if ("setCharacterStream".equals(jdbcSetter)) {
>         if (value == null) {
>           value = "";
>         }
>   
>         stmt.setCharacterStream(order, new 
> StringReader(value), value.length());
>       } else if ("setObject".equals(jdbcSetter)) {
>         stmt.setObject(order, value);
>       } else {
>         errorHandler.error("Unsupported setter for String: " 
> + jdbcSetter);
>       }
>     }
>   
>     /**
>      *  Set this parameter on the given statement with the 
> given value.
>      *
>      *  @param stmt   the statement
>      *  @param value  the value to set
>      *
>      *  @throws SQLException  if the parameter could not be set
>      */
>     public void setParameter(PreparedStatement stmt, 
> ThrowableInformation value)
>       throws SQLException {
>       final StringWriter buf = new StringWriter();
>   
>       if ((value != null) && (value.getThrowable() != null)) {
>         value.getThrowable().printStackTrace(new PrintWriter(buf));
>       }
>   
>       final String str = buf.getBuffer().toString();
>   
>       if ("setString".equals(jdbcSetter)) {
>         stmt.setString(order, str);
>       } else if ("setCharacterStream".equals(jdbcSetter)) {
>         stmt.setCharacterStream(order, new StringReader(str), 
> str.length());
>       } else if ("setObject".equals(jdbcSetter)) {
>         stmt.setObject(order, str);
>       } else {
>         errorHandler.error("Unsupported setter for Throwable: 
> " + jdbcSetter);
>       }
>     }
>   
>     /**
>      *  Set this parameter on the given statement with the 
> given value.
>      *
>      *  @param stmt   the statement
>      *  @param value  the value to set
>      *
>      *  @throws SQLException  if the parameter could not be set
>      */
>     public void setParameter(PreparedStatement stmt, Level value)
>       throws SQLException {
>       if ("setString".equals(jdbcSetter)) {
>         stmt.setString(order, String.valueOf(value));
>       } else if ("setInt".equals(jdbcSetter)) {
>         stmt.setInt(order, value.toInt());
>       } else if ("setObject".equals(jdbcSetter)) {
>         stmt.setObject(order, String.valueOf(value));
>       } else if ("setLong".equals(jdbcSetter)) {
>         stmt.setLong(order, value.toInt());
>       } else if ("setDouble".equals(jdbcSetter)) {
>         stmt.setDouble(order, value.toInt());
>       } else if ("setBigDecimal".equals(jdbcSetter)) {
>         stmt.setBigDecimal(order, new BigDecimal(value.toInt()));
>       } else if ("setFloat".equals(jdbcSetter)) {
>         stmt.setFloat(order, value.toInt());
>       } else {
>         errorHandler.error("Unsupported setter for Level: " + 
> jdbcSetter);
>       }
>     }
>   
>     /**
>      *  Set this parameter on the given statement with the 
> given value.
>      *
>      *  @param stmt   the statement
>      *  @param value  the value to set
>      *
>      *  @throws SQLException  if the parameter could not be set
>      */
>     public void setParameter(PreparedStatement stmt, long value)
>       throws SQLException {
>       if ("setTimestamp".equals(jdbcSetter)) {
>         stmt.setTimestamp(order, new Timestamp(value));
>       } else if ("setDate".equals(jdbcSetter)) {
>         stmt.setDate(order, new Date(value));
>       } else if ("setTime".equals(jdbcSetter)) {
>         stmt.setTime(order, new Time(value));
>       } else if ("setString".equals(jdbcSetter)) {
>         stmt.setString(order, String.valueOf(value));
>       } else if ("setObject".equals(jdbcSetter)) {
>         stmt.setObject(order, new Long(value));
>       } else if ("setLong".equals(jdbcSetter)) {
>         stmt.setLong(order, value);
>       } else if ("setDouble".equals(jdbcSetter)) {
>         stmt.setDouble(order, value);
>       } else if ("setBigDecimal".equals(jdbcSetter)) {
>         stmt.setBigDecimal(order, new BigDecimal(value));
>       } else if ("setInt".equals(jdbcSetter)) {
>         stmt.setInt(order, (int) value);
>       } else if ("setFloat".equals(jdbcSetter)) {
>         stmt.setFloat(order, (float) value);
>       } else {
>         errorHandler.error("Unsupported setter for long: " + 
> jdbcSetter);
>       }
>     }
>   
>     /**
>      * Sets the errorHandler.
>      * @param errorHandler The errorHandler to set
>      */
>     public void setErrorHandler(ErrorHandler errorHandler) {
>       this.errorHandler = errorHandler;
>     }
>   }
>   
>   
>   
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/ConnectionSource.java
>   
>   Index: ConnectionSource.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.spi.ErrorHandler;
>   import org.apache.log4j.spi.OptionHandler;
>   
>   import java.sql.Connection;
>   import java.sql.SQLException;
>   
>   
>   /**
>    *  The <code>ConnectionSource</code> interface provides a 
> pluggable means of
>    *  transparently obtaining JDBC [EMAIL PROTECTED] 
> java.sql.Connection}s for log4j classes
>    *  that require the use of a [EMAIL PROTECTED] java.sql.Connection}.
>    *
>    *  @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a>
>    */
>   public interface ConnectionSource extends OptionHandler {
>     /**
>      *  Obtain a [EMAIL PROTECTED] java.sql.Connection} for use.  The client is
>      *  responsible for closing the [EMAIL PROTECTED] 
> java.sql.Connection} when it is no
>      *  longer required.
>      *
>      *  @throws SQLException  if a [EMAIL PROTECTED] 
> java.sql.Connection} could not be
>      *                        obtained
>      */
>     Connection getConnection() throws SQLException;
>   
>     /**
>      *  Set the error handler.
>      *
>      *  @param errorHanlder  the new error handler
>      */
>     void setErrorHandler(ErrorHandler errorHandler);
>   }
>   
>   
>   
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/JDBCReceiver.java
>   
>   Index: JDBCReceiver.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.Level;
>   import org.apache.log4j.Logger;
>   import org.apache.log4j.plugins.Receiver;
>   import org.apache.log4j.spi.LocationInfo;
>   import org.apache.log4j.spi.LoggingEvent;
>   
>   import java.sql.Connection;
>   import java.sql.DriverManager;
>   import java.sql.ResultSet;
>   import java.sql.SQLException;
>   import java.sql.Statement;
>   
>   import java.util.Hashtable;
>   import java.util.StringTokenizer;
>   
>   
>   /**
>    * Convert Log data stored in a database into LoggingEvents.
>    *
>    * This receiver executes the SQL statement defined in the 
> plugin configuration once,
>    * converting the rows it finds into LoggingEvents, and then ends.
>    *
>    * The configuration of this plugin is very similar to the 
> JDBCAppender, however a
>    * SELECT statement must be provided instead of an INSERT statement.
>    *
>    * The select statement must provide all fields which 
> define a LoggingEvent, with
>    * the column names matching this list: LOGGER, TIMESTAMP, 
> LEVEL, THREAD, MESSAGE,
>    * NDC, MDC, CLASS, METHOD, FILE, LINE, PROPERTIES, EXCEPTION
>    *
>    * If the source table doesn't provide a column for any of 
> the fields, the field must
>    * still be provided in the SELECT statement.  For example, 
> if a JDBCAppender was used
>    * to write only a timestamp, level and patternlayout 
> combination of message and other
>    * fields, here is a sample SQL statement you would provide 
> as the plugin 'sql' param:
>    *
>    * EXAMPLE MYSQL SELECT STATEMENT WHICH CAN BE USED TO 
> PROVIDE EVENTS TO CHAINSAW - 
>    * (counter is an autoincrement int column and timestamp is 
> a datetime column):
>    * 
>    * param name="sql" value='select logger as LOGGER, 
> timestamp as TIMESTAMP, 
>    * level as LEVEL, thread as THREAD, message as MESSAGE, 
> ndc as NDC, mdc as MDC, 
>    * class as CLASS, method as METHOD, file as FILE, line as LINE, 
>    * 
> concat("{{log4japp,databaselogs,log4jmachinename,mymachine,log
> 4jid,", COUNTER, "}}") 
>    * as PROPERTIES, "" as EXCEPTION from logtable' 
>    *
>    * In other words, if a number of LoggingEvent properties 
> were combined into one field
>    * in the database, the combined field should be set as the 
> MESSAGE column in the
>    * SELECT statement.  Missing columns should be set to "".
>    *
>    * Make sure to alias the column names if needed to match 
> the list provided above.
>    *
>    * NOTE: Patternlayout doesn't support Properties and 
> JDBCAppender doesn't support
>    * exceptions, but the fields can be defined in the SQL 
> statement and included in
>    * the event.
>    *
>    * This means that log4japp and/or log4jmachinename 
> properties can be provided and
>    * the properties may be used to create a unique tab for the events.
>    *
>    * Both {{name, value, name2, value2}} formats and formats 
> without the double braces
>    * are supported for MDC and properties fields.
>    * 
>    * NOTE: If refreshMillis is not set, the receiver will run 
> the SQL ONCE.  If it is set,
>    * the SQL will be ran every refreshMillis milliseconds.
>    * 
>    * WARNING: Using refreshMillis with an event processing 
> tool that doesn't know how 
>    * to ignore duplicate events will result in duplicate 
> events being processed.
>    * 
>    * CREATING EVENTS USABLE BY CHAINSAW: 
>    * Chainsaw's event reception ignores duplicate event 
> delivery, so refreshMillis can be 
>    * set and JDBCReceiver can be used as a primary receiver 
> with Chainsaw - allowing 
>    * a timed re-retrieve of events from a database into the 
> UI for analysis of events.
>    * 
>    * Include the properties as provided in the example SQL 
> above to successfully get 
>    * events to be delivered into Chainsaw.  The log4jid 
> property must be provided by the 
>    * database and the timestamp field must be a datetime.  
> The log4jmachinename and log4japp 
>    * properties are specific to your application and define 
> which unique tab the events are 
>    * delivered to.
>    * 
>    * @author Scott Deboy <[EMAIL PROTECTED]>
>    *
>    */
>   public class JDBCReceiver extends Receiver {
>     private boolean isActive = false;
>   
>     /**
>      * URL of the DB for default connection handling
>      */
>     protected String databaseURL = "jdbc:odbc:myDB";
>   
>     /**
>      * User to connect as for default connection handling
>      */
>     protected String databaseUser = "me";
>   
>     /**
>      * User to use for default connection handling
>      */
>     protected String databasePassword = "mypassword";
>     protected Connection connection = null;
>     protected String sqlStatement = "";
>     protected String refreshMillis = null;
>   
>     public JDBCReceiver() {
>     }
>   
>     /**
>      * Start a thread which will handle the retrieval.
>      */
>     public void activateOptions() {
>       new JDBCReceiverThread().start();
>     }
>   
>     protected Connection getConnection() throws SQLException {
>       if (!DriverManager.getDrivers().hasMoreElements()) {
>         setDriver("sun.jdbc.odbc.JdbcOdbcDriver");
>       }
>   
>       if (connection == null) {
>         connection =
>           DriverManager.getConnection(
>             databaseURL, databaseUser, databasePassword);
>       }
>   
>       return connection;
>     }
>   
>     public void close() {
>       try {
>         if ((connection != null) && !connection.isClosed()) {
>           connection.close();
>         }
>       } catch (SQLException e) {
>         e.printStackTrace();
>       }
>     }
>   
>     public void finalize() {
>       close();
>     }
>   
>     public synchronized void shutdown() {
>     }
>   
>     public void setRefreshMillis(String s) {
>       refreshMillis = s;
>     }
>   
>     public String getRefreshMillis() {
>       return refreshMillis;
>     }
>   
>     public void setSql(String s) {
>       sqlStatement = s;
>     }
>   
>     public String getSql() {
>       return sqlStatement;
>     }
>   
>     public void setUser(String user) {
>       databaseUser = user;
>     }
>   
>     public String getUser() {
>       return databaseUser;
>     }
>   
>     public void setURL(String url) {
>       databaseURL = url;
>     }
>   
>     public String getURL() {
>       return databaseURL;
>     }
>   
>     public void setPassword(String password) {
>       databasePassword = password;
>     }
>   
>     public String getPassword() {
>       return databasePassword;
>     }
>   
>     /**
>      * Ensures that the given driver class has been loaded 
> for sql connection
>      * creation.
>      */
>     public void setDriver(String driverClass) {
>       try {
>         Class.forName(driverClass);
>       } catch (Exception e) {
>         e.printStackTrace();
>       }
>     }
>   
>     class JDBCReceiverThread extends Thread {
>       public JDBCReceiverThread() {
>         setDaemon(true);
>       }
>   
>       public void run() {
>         active = true; 
>   
>         do {
>           try {
>             Logger logger = null;
>             long timeStamp = 0L;
>             String level = null;
>             String threadName = null;
>             Object message = null;
>             String ndc = null;
>             Hashtable mdc = null;
>             String[] exception = null;
>             String className = null;
>             String methodName = null;
>             String fileName = null;
>             String lineNumber = null;
>             Hashtable properties = null;
>   
>             Statement statement = getConnection().createStatement();
>             ResultSet rs = statement.executeQuery(sqlStatement);
>   
>             while (rs.next()) {
>               logger = Logger.getLogger(rs.getString("LOGGER"));
>               timeStamp = rs.getTimestamp("TIMESTAMP").getTime();
>   
>               level = rs.getString("LEVEL");
>               threadName = rs.getString("THREAD");
>               message = rs.getString("MESSAGE");
>               ndc = rs.getString("NDC");
>   
>               String mdcString = rs.getString("MDC");
>               mdc = new Hashtable();
>   
>               if (mdcString != null) {
>                 //support MDC being wrapped in {{name, 
> value}} or just name, value
>                 if (
>                   (mdcString.indexOf("{{") > -1)
>                     && (mdcString.indexOf("}}") > -1)) {
>                   mdcString =
>                     mdcString.substring(
>                       mdcString.indexOf("{{") + 2, 
> mdcString.indexOf("}}"));
>                 }
>   
>                 StringTokenizer tok = new 
> StringTokenizer(mdcString, ",");
>   
>                 while (tok.countTokens() > 1) {
>                   mdc.put(tok.nextToken(), tok.nextToken());
>                 }
>               }
>   
>               //although exception is not supported by 
> jdbcappender, it needs to be provided in the SQL string
>               exception = new String[] { rs.getString("EXCEPTION") };
>               className = rs.getString("CLASS");
>               methodName = rs.getString("METHOD");
>               fileName = rs.getString("FILE");
>               lineNumber = rs.getString("LINE");
>   
>               //although properties are not supported by 
> JDBCAppender, if they are provided in the 
>               //SQL they can be used here (for example, to 
> route events to a unique tab if 
>               //the machinename and/or appname property are set)
>               String propertiesString = rs.getString("PROPERTIES");
>               properties = new Hashtable();
>   
>               if (propertiesString != null) {
>                 //support properties being wrapped in {{name, 
> value}} or just name, value
>                 if (
>                   (propertiesString.indexOf("{{") > -1)
>                     && (propertiesString.indexOf("}}") > -1)) {
>                   propertiesString =
>                     propertiesString.substring(
>                       propertiesString.indexOf("{{") + 2,
>                       propertiesString.indexOf("}}"));
>                 }
>   
>                 StringTokenizer tok2 =
>                   new StringTokenizer(propertiesString, ",");
>   
>                 while (tok2.countTokens() > 1) {
>                   properties.put(tok2.nextToken(), tok2.nextToken());
>                 }
>               }
>   
>               Level levelImpl = Level.toLevel(level);
>   
>               LoggingEvent event =
>                 new LoggingEvent(
>                   logger.getName(), logger, timeStamp, 
> levelImpl, threadName,
>                   message, ndc, mdc, exception,
>                   new LocationInfo(fileName, className, 
> methodName, lineNumber),
>                   properties);
>   
>               doPost(event);
>             }
>           } catch (SQLException se) {
>             se.printStackTrace();
>           }
>   
>           if (refreshMillis != null) {
>             try {
>               Thread.sleep(Integer.parseInt(refreshMillis));
>             } catch (InterruptedException ie) {
>             }
>           }
>         } while (refreshMillis != null);
>       }
>     }
>   }
>   
>   
>   
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/UrlConnectionSource.java
>   
>   Index: UrlConnectionSource.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.spi.ErrorCode;
>   import org.apache.log4j.spi.ErrorHandler;
>   
>   import java.sql.Connection;
>   import java.sql.DriverManager;
>   import java.sql.SQLException;
>   
>   
>   /**
>    *  The UrlConnectionSource is an implementation of [EMAIL PROTECTED] 
> ConnectionSource}
>    *  that obtains the Connection in the traditional JDBC 
> manner based on the
>    *  connection URL.
>    *  <p>
>    *  Note that this class will estanblish a new Connection 
> for each call to
>    *  [EMAIL PROTECTED] #getConnection()}.  It is recommended that you 
> either use a JDBC
>    *  driver that natively supported Connection pooling or 
> that you create
>    *  your own implementation of [EMAIL PROTECTED] ConnectionSource} 
> that taps into whatever
>    *  pooling mechanism you are already using.  (If you have 
> access to a JNDI
>    *  implementation that supports [EMAIL PROTECTED] 
> javax.sql.DataSource}s, e.g. within
>    *  a J2EE application server, see [EMAIL PROTECTED] JNDIConnectionSource}).
>    *  <p>
>    *  Sample configuration:<br>
>    *  <pre>
>    *     &lt;connectionSource 
> class="org.apache.log4j.jdbc.UrlConnectionSource"&gt;
>    *        &lt;param name="driver" 
> value="com.mysql.jdbc.Driver" /&gt;
>    *        &lt;param name="url" 
> value="jdbc:mysql://localhost:3306/mydb" /&gt;
>    *        &lt;param name="username" value="myUser" /&gt;
>    *        &lt;param name="password" value="myPassword" /&gt;
>    *     &lt;/connectionSource&gt;
>    *  </pre>
>    *
>    *  @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a>
>    */
>   public class UrlConnectionSource implements ConnectionSource {
>     private String driver = null;
>     private String url = null;
>     private String username = null;
>     private String password = null;
>     private ErrorHandler errorHandler = null;
>   
>     public void activateOptions() {
>       try {
>         Class.forName(driver);
>       } catch (final ClassNotFoundException cnfe) {
>         if (errorHandler != null) {
>           errorHandler.error(
>             "Could not load JDBC driver class: " + driver, cnfe,
>             ErrorCode.GENERIC_FAILURE);
>         } else {
>           cnfe.printStackTrace();
>         }
>       }
>     }
>   
>     /**
>          * @see org.apache.log4j.jdbc.ConnectionSource#getConnection()
>          */
>     public Connection getConnection() throws SQLException {
>       if (username == null) {
>         return DriverManager.getConnection(url);
>       } else {
>         return DriverManager.getConnection(url, username, password);
>       }
>     }
>   
>     /**
>      * Returns the password.
>      * @return String
>      */
>     public String getPassword() {
>       return password;
>     }
>   
>     /**
>      * Returns the url.
>      * @return String
>      */
>     public String getUrl() {
>       return url;
>     }
>   
>     /**
>      * Returns the username.
>      * @return String
>      */
>     public String getUsername() {
>       return username;
>     }
>   
>     /**
>      * Sets the password.
>      * @param password The password to set
>      */
>     public void setPassword(String password) {
>       this.password = password;
>     }
>   
>     /**
>      * Sets the url.
>      * @param url The url to set
>      */
>     public void setUrl(String url) {
>       this.url = url;
>     }
>   
>     /**
>      * Sets the username.
>      * @param username The username to set
>      */
>     public void setUsername(String username) {
>       this.username = username;
>     }
>   
>     /**
>      * Returns the driver.
>      * @return String
>      */
>     public String getDriver() {
>       return driver;
>     }
>   
>     /**
>      * Sets the driver.
>      * @param driver The driver to set
>      */
>     public void setDriver(String driver) {
>       this.driver = driver;
>     }
>   
>     /**
>      * Sets the error handler.
>      * @param errorHandler  the error handler to set
>      */
>     public void setErrorHandler(ErrorHandler errorHandler) {
>       this.errorHandler = errorHandler;
>     }
>   }
>   
>   
>   
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/PreparedStatement
> Appender.java
>   
>   Index: PreparedStatementAppender.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.AppenderSkeleton;
>   import org.apache.log4j.spi.ErrorCode;
>   import org.apache.log4j.spi.LoggingEvent;
>   
>   import java.sql.Connection;
>   import java.sql.PreparedStatement;
>   import java.sql.SQLException;
>   
>   import java.util.ArrayList;
>   
>   
>   /**
>    *  The <code>PreparedStatementAppender</code> class 
> provides a JDBC-based
>    *  appender that uses [EMAIL PROTECTED] java.sql.PreparedStatement}s 
> for efficiency.
>    *  Note that this appender takes advantage of the advanced 
> capabilities of the
>    *  [EMAIL PROTECTED] org.apache.log4j.xml.DOMConfigurator} and 
> therefore must be
>    *  configured with an XML configuration file.
>    *  <p>
>    *  This appender has a number of configurable options.  
> First and foremost is
>    *  the <code>connectionSource</code>, an implementation of
>    *  [EMAIL PROTECTED] ConnectionSource}.  For example, [EMAIL PROTECTED] 
> UrlConnectionSource} and
>    *  [EMAIL PROTECTED] JNDIConnectionSource} are provider by log4j.  It 
> is recommended that
>    *  you use [EMAIL PROTECTED] JNDIConnectionSource} whenever possible 
> and create your own
>    *  implementation of [EMAIL PROTECTED] ConnectionSource} otherwise.  Use
>    *  [EMAIL PROTECTED] UrlConnectionSource} if you just want to get 
> something working fast.
>    *  <p>
>    *  Second is the optional <code>preparedStatementSource</code>, an
>    *  implementation of [EMAIL PROTECTED] PreparedStatementSource}.  
> Only specify this if
>    *  the default statement
>    *  provider by <code>PreparedStatementAppender</code> is 
> not sufficient.
>    *  By default a statement similar to &quot;<code>INSERT 
> INTO LOG4J (message,
>    *  logger, level) VALUES (?, ?, ?)</code>&quot; will be 
> generated based on the
>    *  other parameters (see the example below).
>    *  <p>
>    *  Next, there is a parameter for each part of the logging 
> event you might
>    *  want to include in database:<br>
>    *  <table border="1" rules="all" cellpadding="3">
>    *    <tr>
>    *      <th>Parameter</th>
>    *      <th>Description</th>
>    *      <th>Default JDBC Setter</th>
>    *    </tr>
>    *    <tr>
>    *      <td>messageParameter</td>
>    *      <td>The raw log message</td>
>    *      <td>setString</td>
>    *    </tr>
>    *    <tr>
>    *      <td>formattedMessageParameter</td>
>    *      <td>The formatted log message</td>
>    *      <td>setString</td>
>    *    </tr>
>    *    <tr>
>    *      <td>loggerParameter</td>
>    *      <td>The logger</td>
>    *      <td>setString</td>
>    *    </tr>
>    *    <tr>
>    *      <td>levelParameter</td>
>    *      <td>The log message level</td>
>    *      <td>setString</td>
>    *    </tr>
>    *    <tr>
>    *      <td>ndcParameter</td>
>    *      <td>The NDC (nested diagnostic context) of the log 
> message</td>
>    *      <td>setString</td>
>    *    </tr>
>    *    <tr>
>    *      <td>exceptionParameter</td>
>    *      <td>The message of the exception, i.e. the value of
>    *          <code>Exception.getMessage()</code>, for the 
> exception passed to the
>    *          logger</td>
>    *      <td>setString</td>
>    *    </tr>
>    *    <tr>
>    *      <td>stackParameter</td>
>    *      <td>The stack trace of the exception passed to the 
> logger.  Beware that
>    *          no effort is made to ensure that the stack 
> trace will fit inside the
>    *          database column provided.</td>
>    *      <td>setCharacterStream</td>
>    *    </tr>
>    *    <tr>
>    *      <td>timeStampParameter</td>
>    *      <td>The time stamp of the log message</td>
>    *      <td>setTimerStamp</td>
>    *    </tr>
>    *  </table><br>
>    *  Define whichever subset of these you wish to include in 
> your database table.
>    *  If the JDBC setter referenced above is sufficient for 
> the column in
>    *  question, you may omit the setter value in the configuration.
>    *  <p>
>    *  Finally, the table parameter is used to indicate the 
> table into which to
>    *  insert the rows for the default prepared statement.
>    *
>    *  <h3>Example Configurations</h3>
>    *  All of the example configurations assume that the 
> database vendor is MySQL,
>    *  the instance is test, the user is myUser and the 
> password is myPassword.
>    *  The database table is LOG4J and looks like:<br>
>    *  <pre>
>    *  mysql> desc LOG4J;
>    *  +-----------+--------------+------+-----+---------+-------+
>    *  | Field     | Type         | Null | Key | Default | Extra |
>    *  +-----------+--------------+------+-----+---------+-------+
>    *  | msg       | blob         | YES  |     | NULL    |       |
>    *  | logger    | varchar(255) | YES  |     | NULL    |       |
>    *  | level     | varchar(5)   | YES  |     | NULL    |       |
>    *  | ndc       | varchar(255) | YES  |     | NULL    |       |
>    *  | exception | blob         | YES  |     | NULL    |       |
>    *  | stack     | blob         | YES  |     | NULL    |       |
>    *  | formatted | blob         | YES  |     | NULL    |       |
>    *  | stamp     | datetime     | YES  |     | NULL    |       |
>    *  +-----------+--------------+------+-----+---------+-------+
>    *  </pre>
>    *
>    *  <h4>Quick and dirty</h4>
>    *  Include the following in your log4j.xml file:<br>
>    *  <pre>
>    *  &lt;appender name="X" 
> class="org.apache.log4j.jdbc.PreparedStatementAppender">
>    *    &lt;layout class="org.apache.log4j.PatternLayout">
>    *      &lt;param name="ConversionPattern" value="%d %-5p 
> %c - %m%n"/>
>    *    &lt;/layout>
>    *    &lt;connectionSource 
> class="org.apache.log4j.jdbc.UrlConnectionSource">
>    *        &lt;param name="driver" value="com.mysql.jdbc.Driver" />
>    *        &lt;param name="url" 
> value="jdbc:mysql://localhost:3306/test" />
>    *        &lt;param name="username" value="myUser" />
>    *        &lt;param name="password" value="myPassword" />
>    *    &lt;/connectionSource>
>    *    &lt;param name="table" value="LOG4J"/>
>    *    &lt;messageParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="msg" />
>    *    &lt;/messageParameter>
>    *    &lt;loggerParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="logger" />
>    *    &lt;/loggerParameter>
>    *    &lt;levelParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="level" />
>    *    &lt;/levelParameter>
>    *    &lt;ndcParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="ndc" />
>    *    &lt;/ndcParameter>
>    *    &lt;exceptionParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="exception" />
>    *    &lt;/exceptionParameter>
>    *    &lt;stackParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="stack" />
>    *    &lt;/stackParameter>
>    *    &lt;formattedMessageParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="formatted" />
>    *    &lt;/formattedMessageParameter>
>    *    &lt;timeStampParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="stamp" />
>    *    &lt;/timeStampParameter>
>    *  &lt;/appender&gt;
>    *  </pre>
>    *  <p>
>    *  This configuration will generate a prepared statement 
> of the form
>    *  <code>INSERT INTO LOG4J (msg, logger, level, ndc, 
> exception, stack,
>    *  formatted, stamp) VALUES (?, ?, ?, ?, ?, ?, ?, 
> ?)</code>.  If you do not
>    *  need one of the columns, for example <code>msg</code>, 
> simply do not include
>    *  it in the configuration.
>    *
>    *  <h4>JNDI-based Configuration</h4>
>    *  This example demonstrates the JNDIConnectionSource:<br>
>    *  <pre>
>    *  &lt;appender name="X" 
> class="org.apache.log4j.jdbc.PreparedStatementAppender">
>    *    &lt;layout class="org.apache.log4j.PatternLayout">
>    *      &lt;param name="ConversionPattern" value="%d %-5p 
> %c - %m%n"/>
>    *    &lt;/layout>
>    *  <b>
>    *    &lt;connectionSource 
> class="org.apache.log4j.jdbc.JNDIConnectionSource">
>    *        &lt;param name="jndiLocation" value="jdbc/MySQLDS" />
>    *    &lt;/connectionSource>
>    *  </b>
>    *    &lt;param name="table" value="LOG4J"/>
>    *    &lt;loggerParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="logger" />
>    *    &lt;/loggerParameter>
>    *    &lt;levelParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="level" />
>    *    &lt;/levelParameter>
>    *    &lt;exceptionParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="exception" />
>    *    &lt;/exceptionParameter>
>    *    &lt;stackParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="stack" />
>    *    &lt;/stackParameter>
>    *    &lt;formattedMessageParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="formatted" />
>    *    &lt;/formattedMessageParameter>
>    *    &lt;timeStampParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="stamp" />
>    *    &lt;/timeStampParameter>
>    *  &lt;/appender&gt;
>    *  </pre>
>    *  Note that this configuration will produce a slightly 
> different prepared
>    *  statement: <code>INSERT INTO LOG4J (logger, level, 
> exception, stack,
>    *  formatted, stamp) VALUES (?, ?, ?, ?, ?)</code>.  This 
> was done purely for
>    *  demonstration purposes, there is no reason 
> <code>messageParameter</code> and
>    *  <code>ndcParameter</code> could not be included.
>    *
>    *  <h4>Custom PreparedStatementSopurce Configuration</h4>
>    *  This example demonstrates a custom [EMAIL PROTECTED] 
> PreparedStatementSource}:<br>
>    *  <pre>
>    *  &lt;appender name="X" 
> class="org.apache.log4j.jdbc.PreparedStatementAppender">
>    *    &lt;layout class="org.apache.log4j.PatternLayout">
>    *      &lt;param name="ConversionPattern" value="%d %-5p 
> %c - %m%n"/>
>    *    &lt;/layout>
>    *    &lt;connectionSource 
> class="org.apache.log4j.jdbc.JNDIConnectionSource">
>    *        &lt;param name="jndiLocation" value="jdbc/MySQLDS" />
>    *    &lt;/connectionSource>
>    *  <b>
>    *    &lt;preparedStatementSource 
> class="my.wonderful.implmentation.of.PreparedStatementSource">
>    *        &lt;param name="myParam1" value="myValue1" />
>    *        &lt;param name="myParam2" value="myValue2" />
>    *    &lt;/preparedStatementSource>
>    *  </b>
>    *    &lt;loggerParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="logger" />
>    *    &lt;/loggerParameter>
>    *    &lt;levelParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="level" />
>    *    &lt;/levelParameter>
>    *    &lt;exceptionParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="exception" />
>    *    &lt;/exceptionParameter>
>    *    &lt;stackParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="stack" />
>    *    &lt;/stackParameter>
>    *    &lt;formattedMessageParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="formatted" />
>    *    &lt;/formattedMessageParameter>
>    *    &lt;timeStampParameter 
> class="org.apache.log4j.jdbc.PreparedStatementParameter">
>    *        &lt;param name="columnName" value="stamp" />
>    *    &lt;/timeStampParameter>
>    *  &lt;/appender&gt;
>    *  </pre>
>    *  Use this configuration when you want to provide your own
>    *  [EMAIL PROTECTED] PreparedStatementSource} becuase the default 
> statements are
>    *  insufficient.  For example, you want to call a stored 
> procedure or the like.
>    *  Note that you still must provide the <code>xxxParameter</code>
>    *  configurations.
>    *
>    *  @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a>
>    */
>   public class PreparedStatementAppender extends AppenderSkeleton {
>     private String table = "LOG4J";
>     private PreparedStatementParameter messageParameter = null;
>     private PreparedStatementParameter loggerParameter = null;
>     private PreparedStatementParameter levelParameter = null;
>     private PreparedStatementParameter ndcParameter = null;
>     private PreparedStatementParameter exceptionParameter = null;
>     private PreparedStatementParameter stackParameter = null;
>     private PreparedStatementParameter timeStampParameter = null;
>     private PreparedStatementParameter 
> formattedMessageParameter = null;
>     private ConnectionSource connectionSource = null;
>     private PreparedStatementSource preparedStatementSource = null;
>     private StringBuffer sql = new StringBuffer();
>     private final ArrayList params = new ArrayList();
>   
>     /**
>      *  Default constructor.
>      */
>     public PreparedStatementAppender() {
>     }
>   
>     public String getTable() {
>       return table;
>     }
>   
>     public void setTable(String newTable) {
>       table = newTable;
>     }
>   
>     public void activateOptions() {
>       super.activateOptions();
>   
>       // Set up default setters and create the params list
>       if (messageParameter != null) {
>         params.add(messageParameter);
>         messageParameter.setErrorHandler(errorHandler);
>   
>         if (messageParameter.getJdbcSetter() == null) {
>           messageParameter.setJdbcSetter("setString");
>         }
>       }
>   
>       if (loggerParameter != null) {
>         params.add(loggerParameter);
>         loggerParameter.setErrorHandler(errorHandler);
>   
>         if (loggerParameter.getJdbcSetter() == null) {
>           loggerParameter.setJdbcSetter("setString");
>         }
>       }
>   
>       if (levelParameter != null) {
>         params.add(levelParameter);
>         levelParameter.setErrorHandler(errorHandler);
>   
>         if (levelParameter.getJdbcSetter() == null) {
>           levelParameter.setJdbcSetter("setString");
>         }
>       }
>   
>       if (ndcParameter != null) {
>         params.add(ndcParameter);
>         ndcParameter.setErrorHandler(errorHandler);
>   
>         if (ndcParameter.getJdbcSetter() == null) {
>           ndcParameter.setJdbcSetter("setString");
>         }
>       }
>   
>       if (exceptionParameter != null) {
>         params.add(exceptionParameter);
>         exceptionParameter.setErrorHandler(errorHandler);
>   
>         if (exceptionParameter.getJdbcSetter() == null) {
>           exceptionParameter.setJdbcSetter("setString");
>         }
>       }
>   
>       if (stackParameter != null) {
>         params.add(stackParameter);
>         stackParameter.setErrorHandler(errorHandler);
>   
>         if (stackParameter.getJdbcSetter() == null) {
>           stackParameter.setJdbcSetter("setCharacterStream");
>         }
>       }
>   
>       if (timeStampParameter != null) {
>         params.add(timeStampParameter);
>         timeStampParameter.setErrorHandler(errorHandler);
>   
>         if (timeStampParameter.getJdbcSetter() == null) {
>           timeStampParameter.setJdbcSetter("setTimestamp");
>         }
>       }
>   
>       if (formattedMessageParameter != null) {
>         params.add(formattedMessageParameter);
>         formattedMessageParameter.setErrorHandler(errorHandler);
>   
>         if (formattedMessageParameter.getJdbcSetter() == null) {
>           formattedMessageParameter.setJdbcSetter("setString");
>         }
>       }
>   
>       params.trimToSize();
>   
>       connectionSource.setErrorHandler(errorHandler);
>       connectionSource.activateOptions();
>   
>       if (preparedStatementSource == null) {
>         generateSql();
>       } else {
>         preparedStatementSource.activateOptions();
>       }
>     }
>   
>     public void append(LoggingEvent event) {
>       Throwable throwable = null;
>   
>       if (event.getThrowableInformation() != null) {
>         throwable = event.getThrowableInformation().getThrowable();
>       }
>   
>       Connection conn = null;
>       PreparedStatement stmt = null;
>   
>       try {
>         conn = connectionSource.getConnection();
>   
>         if (preparedStatementSource != null) {
>           stmt = preparedStatementSource.generate(this, conn);
>         } else {
>           stmt = conn.prepareStatement(sql.toString());
>         }
>   
>         // Set stmt parameters
>         if (messageParameter != null) {
>           messageParameter.setParameter(
>             stmt, String.valueOf(event.getMessage()));
>         }
>   
>         if (loggerParameter != null) {
>           loggerParameter.setParameter(stmt, event.getLoggerName());
>         }
>   
>         if (levelParameter != null) {
>           levelParameter.setParameter(stmt, event.getLevel());
>         }
>   
>         if (ndcParameter != null) {
>           ndcParameter.setParameter(stmt, event.getNDC());
>         }
>   
>         if (exceptionParameter != null) {
>           if (throwable != null) {
>             exceptionParameter.setParameter(stmt, 
> throwable.getMessage());
>           } else {
>             exceptionParameter.setParameter(stmt, "");
>           }
>         }
>   
>         if (stackParameter != null) {
>           stackParameter.setParameter(stmt, 
> event.getThrowableInformation());
>         }
>   
>         if (timeStampParameter != null) {
>           timeStampParameter.setParameter(stmt, event.timeStamp);
>         }
>   
>         if (formattedMessageParameter != null) {
>           formattedMessageParameter.setParameter(
>             stmt, getLayout().format(event));
>         }
>   
>         // OK, do the dirty deed
>         stmt.executeUpdate();
>       } catch (final SQLException sqle) {
>         errorHandler.error(
>           "Error executing SQL: " + sql, sqle, 
> ErrorCode.GENERIC_FAILURE, event);
>       } finally {
>         closeJdbc(stmt, conn);
>       }
>     }
>   
>     public boolean requiresLayout() {
>       return true;
>     }
>   
>     public void close() {
>     }
>   
>     private void generateSql() {
>       int colCount = 0;
>       sql.setLength(0);
>       sql.append("INSERT INTO ").append(table).append(" (");
>   
>       for (int i = 0; i < params.size(); i++) {
>         colCount = appendColumn(getParameter(i), colCount);
>       }
>   
>       sql.append(") VALUES (");
>   
>       for (int i = 0; i < colCount; i++) {
>         sql.append((i == 0) ? "?" : ", ?");
>       }
>   
>       sql.append(")");
>       System.out.println(sql);
>     }
>   
>     private int appendColumn(PreparedStatementParameter psp, 
> int colCount) {
>       if ((psp != null) && (psp.getColumnName() != null)) {
>         sql.append((colCount == 0) ? "" : ", 
> ").append(psp.getColumnName());
>         psp.setOrder(++colCount);
>   
>         System.out.println(
>           "JDBC setter for " + psp.getColumnName() + " is "
>           + psp.getJdbcSetter());
>       }
>   
>       return colCount;
>     }
>   
>     private void closeJdbc(PreparedStatement stmt, Connection conn) {
>       try {
>         if (stmt != null) {
>           stmt.close();
>         }
>       } catch (final SQLException sqle) {
>         errorHandler.error(
>           "Error closing prepared statement", sqle, 
> ErrorCode.GENERIC_FAILURE);
>       }
>   
>       try {
>         if (conn != null) {
>           conn.close();
>         }
>       } catch (final SQLException sqle) {
>         errorHandler.error(
>           "Error closing connection", sqle, 
> ErrorCode.GENERIC_FAILURE);
>       }
>     }
>   
>     private PreparedStatementParameter getParameter(int i) {
>       return (PreparedStatementParameter) params.get(i);
>     }
>   
>     /**
>      * Returns the timeStampParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getTimeStampParameter() {
>       return timeStampParameter;
>     }
>   
>     /**
>      * Returns the exceptionParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getExceptionParameter() {
>       return exceptionParameter;
>     }
>   
>     /**
>      * Returns the formattedMessageParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getFormattedMessageParameter() {
>       return formattedMessageParameter;
>     }
>   
>     /**
>      * Returns the levelParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getLevelParameter() {
>       return levelParameter;
>     }
>   
>     /**
>      * Returns the loggerParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getLoggerParameter() {
>       return loggerParameter;
>     }
>   
>     /**
>      * Returns the messageParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getMessageParameter() {
>       return messageParameter;
>     }
>   
>     /**
>      * Returns the ndcParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getNdcParameter() {
>       return ndcParameter;
>     }
>   
>     /**
>      * Returns the stackParameter.
>      * @return PreparedStatementParameter
>      */
>     public PreparedStatementParameter getStackParameter() {
>       return stackParameter;
>     }
>   
>     /**
>      * Sets the timeStampParameter.
>      * @param timeStampParameter The timeStampParameter to set
>      */
>     public void 
> setTimeStampParameter(PreparedStatementParameter date) {
>       this.timeStampParameter = date;
>     }
>   
>     /**
>      * Sets the exceptionParameter.
>      * @param exceptionParameter The exceptionParameter to set
>      */
>     public void 
> setExceptionParameter(PreparedStatementParameter exception) {
>       this.exceptionParameter = exception;
>     }
>   
>     /**
>      * Sets the formattedMessageParameter.
>      * @param formattedMessageParameter The 
> formattedMessageParameter to set
>      */
>     public void setFormattedMessageParameter(
>       PreparedStatementParameter formattedMsg) {
>       this.formattedMessageParameter = formattedMsg;
>     }
>   
>     /**
>      * Sets the levelParameter.
>      * @param levelParameter The levelParameter to set
>      */
>     public void setLevelParameter(PreparedStatementParameter level) {
>       this.levelParameter = level;
>     }
>   
>     /**
>      * Sets the loggerParameter.
>      * @param loggerParameter The loggerParameter to set
>      */
>     public void setLoggerParameter(PreparedStatementParameter 
> logger) {
>       this.loggerParameter = logger;
>     }
>   
>     /**
>      * Sets the messageParameter.
>      * @param messageParameter The messageParameter to set
>      */
>     public void setMessageParameter(PreparedStatementParameter msg) {
>       this.messageParameter = msg;
>     }
>   
>     /**
>      * Sets the ndcParameter.
>      * @param ndcParameter The ndcParameter to set
>      */
>     public void setNdcParameter(PreparedStatementParameter ndc) {
>       this.ndcParameter = ndc;
>     }
>   
>     /**
>      * Sets the stackParameter.
>      * @param stackParameter The stackParameter to set
>      */
>     public void setStackParameter(PreparedStatementParameter stack) {
>       this.stackParameter = stack;
>     }
>   
>     /**
>      * Returns the connectionSource.
>      * @return ConnectionSource
>      */
>     public ConnectionSource getConnectionSource() {
>       return connectionSource;
>     }
>   
>     /**
>      * Sets the connectionSource.
>      * @param connectionSource The connectionSource to set
>      */
>     public void setConnectionSource(ConnectionSource 
> connectionSource) {
>       this.connectionSource = connectionSource;
>     }
>   
>     /**
>      * Returns the preparedStatementSource.
>      * @return PreparedStatementSource
>      */
>     public PreparedStatementSource getPreparedStatementSource() {
>       return preparedStatementSource;
>     }
>   
>     /**
>      * Sets the preparedStatementSource.
>      * @param preparedStatementSource The 
> preparedStatementSource to set
>      */
>     public void setPreparedStatementSource(
>       PreparedStatementSource preparedStatementSource) {
>       this.preparedStatementSource = preparedStatementSource;
>     }
>   }
>   
>   
>   
>   1.1                  
> jakarta-log4j/src/java/org/apache/log4j/jdbc/JNDIConnectionSource.java
>   
>   Index: JNDIConnectionSource.java
>   ===================================================================
>   /*
>    * 
> ==============================================================
> ==============
>    *                   The Apache Software License, Version 1.1
>    * 
> ==============================================================
> ==============
>    *
>    *    Copyright (C) 1999 The Apache Software Foundation. 
> All rights reserved.
>    *
>    * Redistribution and use in source and binary forms, with 
> or without modifica-
>    * tion, are permitted provided that the following 
> conditions are met:
>    *
>    * 1. Redistributions of  source code must  retain the 
> above copyright  notice,
>    *    this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the 
> above copyright notice,
>    *    this list of conditions and the following disclaimer 
> in the documentation
>    *    and/or other materials provided with the distribution.
>    *
>    * 3. The end-user documentation included with the 
> redistribution, if any, must
>    *    include  the following  acknowledgment:  "This 
> product includes  software
>    *    developed  by the  Apache Software Foundation  
> (http://www.apache.org/)."
>    *    Alternately, this  acknowledgment may  appear in the 
> software itself,  if
>    *    and wherever such third-party acknowledgments normally appear.
>    *
>    * 4. The names "log4j" and  "Apache Software Foundation"  
> must not be used to
>    *    endorse  or promote  products derived  from this  
> software without  prior
>    *    written permission. For written permission, please contact
>    *    [EMAIL PROTECTED]
>    *
>    * 5. Products  derived from this software may not  be 
> called "Apache", nor may
>    *    "Apache" appear  in their name,  without prior 
> written permission  of the
>    *    Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR 
> IMPLIED WARRANTIES,
>    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
> MERCHANTABILITY AND
>    * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN 
> NO  EVENT SHALL  THE
>    * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE 
> LIABLE FOR  ANY DIRECT,
>    * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR 
> CONSEQUENTIAL  DAMAGES (INCLU-
>    * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE 
> GOODS OR SERVICES; LOSS
>    * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  
> HOWEVER CAUSED AND ON
>    * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT 
> LIABILITY,  OR TORT
>    * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY 
> WAY OUT OF THE  USE OF
>    * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    *
>    * This software  consists of voluntary contributions made  
> by many individuals
>    * on  behalf of the Apache Software  Foundation.  For more 
>  information on the
>    * Apache Software Foundation, please see <http://www.apache.org/>.
>    *
>    */
>   
>   package org.apache.log4j.jdbc;
>   
>   import org.apache.log4j.spi.ErrorHandler;
>   
>   import java.sql.Connection;
>   import java.sql.SQLException;
>   
>   import javax.naming.Context;
>   import javax.naming.InitialContext;
>   import javax.naming.NamingException;
>   
>   import javax.rmi.PortableRemoteObject;
>   
>   import javax.sql.DataSource;
>   
>   
>   /**
>    *  The <code>JNDIConnectionSource</code> is an implementation of
>    *  [EMAIL PROTECTED] ConnectionSource} that obtains a [EMAIL PROTECTED] 
> javax.sql.DataSource} from a
>    *  JNDI provider and uses it to obtain a [EMAIL PROTECTED] 
> java.sql.Connection}.  It is
>    *  primarily designed to be used inside of J2EE 
> application servers or
>    *  application server clients, assuming the application 
> server supports remote
>    *  access of [EMAIL PROTECTED] javax.sql.DataSource}s.  In this way 
> one can take
>    *  advantage of  connection pooling and whatever other 
> goodies the application
>    *  server provides.
>    *  <p>
>    *  Sample configuration:<br>
>    *  <pre>
>    *    &lt;connectionSource 
> class="org.apache.log4j.jdbc.JNDIConnectionSource"&gt;
>    *        &lt;param name="jndiLocation" value="jdbc/MySQLDS" /&gt;
>    *    &lt;/connectionSource&gt;
>    *  </pre>
>    *  <p>
>    *  Sample configuration (with username and password):<br>
>    *  <pre>
>    *    &lt;connectionSource 
> class="org.apache.log4j.jdbc.JNDIConnectionSource"&gt;
>    *        &lt;param name="jndiLocation" value="jdbc/MySQLDS" /&gt;
>    *        &lt;param name="username" value="myUser" /&gt;
>    *        &lt;param name="password" value="myPassword" /&gt;
>    *    &lt;/connectionSource&gt;
>    *  </pre>
>    *  <p>
>    *  Note that this class will obtain an [EMAIL PROTECTED] 
> javax.naming.InitialContext}
>    *  using the no-argument constructor.  This will usually 
> work when executing
>    *  within a J2EE environment.  When outside the J2EE 
> environment, make sure
>    *  that you provide a jndi.properties file as described by 
> your JNDI
>    *  provider's documentation.
>    *
>    *  @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a>
>    */
>   public class JNDIConnectionSource implements ConnectionSource {
>     private String jndiLocation = null;
>     private DataSource dataSource = null;
>     private ErrorHandler errorHandler = null;
>     private String username = null;
>     private String password = null;
>   
>     /**
>      * @see org.apache.log4j.jdbc.ConnectionSource#getConnection()
>      */
>     public Connection getConnection() throws SQLException {
>       Connection conn = null;
>   
>       try {
>         ensureDataSource();
>   
>         if (username == null) {
>           conn = dataSource.getConnection();
>         } else {
>           conn = dataSource.getConnection(username, password);
>         }
>       } catch (final NamingException ne) {
>         if (errorHandler != null) {
>           errorHandler.error(ne.getMessage(), ne, 0);
>         }
>   
>         throw new SQLException(
>           "NamingException while looking up " + "DataSource: 
> " + ne.getMessage());
>       } catch (final ClassCastException cce) {
>         if (errorHandler != null) {
>           errorHandler.error(cce.getMessage(), cce, 0);
>         }
>   
>         throw new SQLException(
>           "ClassCastException while looking up " + "DataSource: "
>           + cce.getMessage());
>       }
>   
>       return conn;
>     }
>   
>     /**
>      * @see org.apache.log4j.spi.OptionHandler#activateOptions()
>      */
>     public void activateOptions() {
>     }
>   
>     /**
>      * Returns the jndiLocation.
>      * @return String
>      */
>     public String getJndiLocation() {
>       return jndiLocation;
>     }
>   
>     /**
>      * Sets the jndiLocation.
>      * @param jndiLocation The jndiLocation to set
>      */
>     public void setJndiLocation(String jndiLocation) {
>       this.jndiLocation = jndiLocation;
>     }
>   
>     /**
>      * Sets the error handler.
>      * @param errorHandler  the error handler to set
>      */
>     public void setErrorHandler(ErrorHandler errorHandler) {
>       this.errorHandler = errorHandler;
>     }
>   
>     /**
>      * Returns the password.
>      * @return String
>      */
>     public String getPassword() {
>       return password;
>     }
>   
>     /**
>      * Returns the username.
>      * @return String
>      */
>     public String getUsername() {
>       return username;
>     }
>   
>     /**
>      * Sets the password.
>      * @param password The password to set
>      */
>     public void setPassword(String password) {
>       this.password = password;
>     }
>   
>     /**
>      * Sets the username.
>      * @param username The username to set
>      */
>     public void setUsername(String username) {
>       this.username = username;
>     }
>   
>     private void ensureDataSource() throws NamingException, 
> SQLException {
>       if (dataSource == null) {
>         Context ctx = new InitialContext();
>         Object obj = ctx.lookup(jndiLocation);
>         dataSource =
>           (DataSource) PortableRemoteObject.narrow(obj, 
> DataSource.class);
>       }
>   
>       if (dataSource == null) {
>         throw new SQLException(
>           "Failed to obtain data source from JNDI " + 
> "location " + jndiLocation);
>       }
>     }
>   }
>   
>   
>   
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to