You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ce...@apache.org on 2004/05/18 18:50:43 UTC

cvs commit: logging-log4j/src/java/org/apache/log4j/db/dialect postgresql.sql

ceki        2004/05/18 09:50:43

  Modified:    src/java/org/apache/log4j/db JNDIConnectionSource.java
                        DBAppender.java ConnectionSourceSkeleton.java
               src/java/org/apache/log4j/joran/action LevelAction.java
                        ConversionRuleAction.java LoggerAction.java
                        AppenderRefAction.java AppenderAction.java
                        PropertyAction.java RootLoggerAction.java
                        LayoutAction.java PluginAction.java
               tests/input/db writeCS1.xml mysql.properties.sample
                        readCS1.xml
               tests/src/java/org/apache/log4j/db FullCycleDBTest.java
               src/java/org/apache/joran ExecutionContext.java
               tests    .cvsignore build.xml
               src/java/org/apache/joran/action NewRuleAction.java
                        Action.java ParamAction.java NestComponentIA.java
               src/java/org/apache/log4j/db/dialect postgresql.sql
  Added:       src/java/org/apache/log4j/db DataSourceConnectionSource.java
                        DriverManagerConnectionSource.java
               tests/input/db appendPooled1.xml readPooled1.xml
                        append-with-datasource1.xml
                        read-with-datasource1.xml db.properties .cvsignore
                        postgresql.properties.sample
  Removed:     src/java/org/apache/log4j/db UrlConnectionSource.java
  Log:
  - In the o.a.l.db package added  support for a connection source to be
  obtained through a javax.sql.DataSource implementation.
  
  - Renamed URLConnectionSource to DriverManagerConnectionSource because
  that is what it is.
  
  - Modified NestedComponentIA to support the configuration of multiply
  nested components. The previous version could only support just one
  level of nesting.
  
  - FullCycleDBTest is now tested with both MySQL and PostgreSQL.
  
  - Removed the isInError variable from the Action class. 
  
  Revision  Changes    Path
  1.2       +12 -1     logging-log4j/src/java/org/apache/log4j/db/JNDIConnectionSource.java
  
  Index: JNDIConnectionSource.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/db/JNDIConnectionSource.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JNDIConnectionSource.java	4 May 2004 09:36:02 -0000	1.1
  +++ JNDIConnectionSource.java	18 May 2004 16:50:42 -0000	1.2
  @@ -17,6 +17,7 @@
   
   import java.sql.Connection;
   import java.sql.SQLException;
  +import java.util.Hashtable;
   
   import javax.naming.Context;
   import javax.naming.InitialContext;
  @@ -24,6 +25,8 @@
   import javax.rmi.PortableRemoteObject;
   import javax.sql.DataSource;
   
  +import org.apache.log4j.helpers.LogLog;
  +
   /**
    *  The <id>JNDIConnectionSource</id> is an implementation of
    *  {@link ConnectionSource} that obtains a {@link javax.sql.DataSource} from a
  @@ -84,6 +87,7 @@
           errorHandler.error(ne.getMessage(), ne, 0);
         }
   
  +      LogLog.error("Error while getting data source", ne);
         throw new SQLException("NamingException while looking up DataSource: " + ne.getMessage());
       } catch (final ClassCastException cce) {
         if (errorHandler != null) {
  @@ -142,7 +146,14 @@
            throws NamingException, SQLException {
       DataSource ds;
   
  -    Context ctx = new InitialContext();
  +    Hashtable env = new Hashtable(11);
  +    env.put(Context.INITIAL_CONTEXT_FACTORY,
  +            "com.sun.jndi.fscontext.RefFSContextFactory");
  +    env.put(Context.PROVIDER_URL,
  +            "file:///home/jndi");
  +    Context ctx = new InitialContext(env);
  +    
  +    //Context ctx = new InitialContext();
       Object obj = ctx.lookup(jndiLocation);
       ds = (DataSource)PortableRemoteObject.narrow(obj, DataSource.class);
   
  
  
  
  1.8       +70 -54    logging-log4j/src/java/org/apache/log4j/db/DBAppender.java
  
  Index: DBAppender.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/db/DBAppender.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- DBAppender.java	17 May 2004 16:58:29 -0000	1.7
  +++ DBAppender.java	18 May 2004 16:50:42 -0000	1.8
  @@ -1,27 +1,20 @@
   /*
    * Copyright 1999,2004 The Apache Software Foundation.
  - * 
  + *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
  - * 
  + *
    *      http://www.apache.org/licenses/LICENSE-2.0
  - * 
  + *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
  -package org.apache.log4j.db;
   
  -import java.sql.Connection;
  -import java.sql.PreparedStatement;
  -import java.sql.ResultSet;
  -import java.sql.SQLException;
  -import java.sql.Statement;
  -import java.util.Iterator;
  -import java.util.Set;
  +package org.apache.log4j.db;
   
   import org.apache.log4j.AppenderSkeleton;
   import org.apache.log4j.db.dialect.MySQLDialect;
  @@ -31,38 +24,52 @@
   import org.apache.log4j.helpers.LogLog;
   import org.apache.log4j.spi.LoggingEvent;
   
  +import java.sql.Connection;
  +import java.sql.PreparedStatement;
  +import java.sql.ResultSet;
  +import java.sql.SQLException;
  +import java.sql.Statement;
  +
  +import java.util.Iterator;
  +import java.util.Set;
  +
   
   /**
    *
    * @author Ceki G&uuml;lc&uuml;
    *
    */
  -public class DBAppender
  -       extends AppenderSkeleton {
  +public class DBAppender extends AppenderSkeleton {
     ConnectionSource connectionSource;
     SQLDialect sqlDialect;
   
     public void activateOptions() {
  -    if (connectionSource != null) {
  -      connectionSource.activateOptions();
  -    } else {
  -      throw new IllegalStateException("DBAppender cannot function without a connection source");
  +    LogLog.debug("DBAppender.activateOptions called");
  +
  +    if (connectionSource == null) {
  +      throw new IllegalStateException(
  +        "DBAppender cannot function without a connection source");
       }
   
       switch (connectionSource.getSQLDialect()) {
  -    case ConnectionSource.POSTGRES_DIALECT :
  +    case ConnectionSource.POSTGRES_DIALECT:
         sqlDialect = new PostgreSQLDialect();
  +
         break;
  -    case ConnectionSource.MYSQL_DIALECT :
  +    case ConnectionSource.MYSQL_DIALECT:
         sqlDialect = new MySQLDialect();
  +
         break;
  -    case ConnectionSource.ORACLE_DIALECT :
  +    case ConnectionSource.ORACLE_DIALECT:
         sqlDialect = new OracleDialect();
  +
         break;
  +    default:
  +      throw new IllegalStateException(
  +        "DBAppender cannot function without a determined SQL dialect");
       }
     }
   
  -
     /**
      * @return Returns the connectionSource.
      */
  @@ -70,36 +77,37 @@
       return connectionSource;
     }
   
  -
     /**
      * @param connectionSource The connectionSource to set.
      */
     public void setConnectionSource(ConnectionSource connectionSource) {
  +    LogLog.debug("setConnectionSource called for DBAppender");
       this.connectionSource = connectionSource;
     }
   
  -
     protected void append(LoggingEvent event) {
  - 
       try {
         Connection connection = connectionSource.getConnection();
         connection.setAutoCommit(false);
   
  -//      sequence_number BIGINT NOT NULL,
  -//      timestamp         BIGINT NOT NULL,
  -//      rendered_message  TEXT NOT NULL,
  -//      logger_name       VARCHAR(254) NOT NULL,
  -//      level_string      VARCHAR(254) NOT NULL,
  -//      ndc               TEXT,
  -//      thread_name       VARCHAR(254),
  -//      id                INT NOT NULL AUTO_INCREMENT PRIMARY KEY
  +
  +      //      sequence_number BIGINT NOT NULL,
  +      //      timestamp         BIGINT NOT NULL,
  +      //      rendered_message  TEXT NOT NULL,
  +      //      logger_name       VARCHAR(254) NOT NULL,
  +      //      level_string      VARCHAR(254) NOT NULL,
  +      //      ndc               TEXT,
  +      //      thread_name       VARCHAR(254),
  +      //      id                INT NOT NULL AUTO_INCREMENT PRIMARY KEY
         StringBuffer sql = new StringBuffer();
         sql.append("INSERT INTO logging_event (");
         sql.append("sequence_number, timestamp, rendered_message, ");
  -      sql.append("logger_name, level_string, ndc, thread_name, reference_flag) ");
  +      sql.append(
  +        "logger_name, level_string, ndc, thread_name, reference_flag) ");
         sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?)");
   
  -      PreparedStatement insertStatement = connection.prepareStatement(sql.toString());
  +      PreparedStatement insertStatement =
  +        connection.prepareStatement(sql.toString());
         insertStatement.setLong(1, event.getSequenceNumber());
         insertStatement.setLong(2, event.getTimeStamp());
         insertStatement.setString(3, event.getRenderedMessage());
  @@ -108,7 +116,7 @@
         insertStatement.setString(6, event.getNDC());
         insertStatement.setString(7, event.getThreadName());
         insertStatement.setShort(8, DBHelper.computeReferenceMask(event));
  -      
  +
         int updateCount = insertStatement.executeUpdate();
   
         if (updateCount != 1) {
  @@ -122,59 +130,67 @@
         rs.first();
   
         int eventId = rs.getInt(1);
  -//      LogLog.info("inserted id is " + eventId);
   
  -//      event_id        INT NOT NULL,
  -//      mapped_key        VARCHAR(254) NOT NULL,
  -//      mapped_value      VARCHAR(254),
   
  +      //      LogLog.info("inserted id is " + eventId);
  +      //      event_id        INT NOT NULL,
  +      //      mapped_key        VARCHAR(254) NOT NULL,
  +      //      mapped_value      VARCHAR(254),
         Set propertiesKeys = event.getPropertyKeySet();
  +
         if (propertiesKeys.size() > 0) {
  -        String insertPropertiesSQL = "INSERT INTO  logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
  -        PreparedStatement insertPropertiesStatement = connection.prepareStatement(insertPropertiesSQL);
  +        String insertPropertiesSQL =
  +          "INSERT INTO  logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
  +        PreparedStatement insertPropertiesStatement =
  +          connection.prepareStatement(insertPropertiesSQL);
   
           for (Iterator i = propertiesKeys.iterator(); i.hasNext();) {
  -          String key = (String)i.next();
  -          String value = (String)event.getProperty(key);
  +          String key = (String) i.next();
  +          String value = (String) event.getProperty(key);
             LogLog.info("id " + eventId + ", key " + key + ", value " + value);
             insertPropertiesStatement.setInt(1, eventId);
             insertPropertiesStatement.setString(2, key);
             insertPropertiesStatement.setString(3, value);
             insertPropertiesStatement.addBatch();
           }
  +
           insertPropertiesStatement.executeBatch();
         }
   
         String[] strRep = event.getThrowableStrRep();
  -      if(strRep != null) {
  +
  +      if (strRep != null) {
           LogLog.info("Logging an exception");
  -//        CREATE TABLE logging_event_exception (
  -//          event_id         INT NOT NULL,
  -//          i                SMALLINT NOT NULL,
  -//          trace_line       VARCHAR(254) NOT NULL)
  -        String insertExceptionSQL = "INSERT INTO  logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
  -        PreparedStatement insertExceptionStatement = connection.prepareStatement(insertExceptionSQL);
  -        
  +
  +
  +        //        CREATE TABLE logging_event_exception (
  +        //          event_id         INT NOT NULL,
  +        //          i                SMALLINT NOT NULL,
  +        //          trace_line       VARCHAR(254) NOT NULL)
  +        String insertExceptionSQL =
  +          "INSERT INTO  logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
  +        PreparedStatement insertExceptionStatement =
  +          connection.prepareStatement(insertExceptionSQL);
  +
           for (short i = 0; i < strRep.length; i++) {
             insertExceptionStatement.setInt(1, eventId);
             insertExceptionStatement.setShort(2, i);
             insertExceptionStatement.setString(3, strRep[i]);
             insertExceptionStatement.addBatch();
           }
  +
           insertExceptionStatement.executeBatch();
         }
  +
         connection.commit();
       } catch (SQLException sqle) {
         LogLog.error("problem appending event", sqle);
       }
     }
   
  -
  -
     public void close() {
       // TODO Auto-generated method st  
     }
  -
   
     /*
      * The DBAppender does not require a layout.
  
  
  
  1.2       +0 -1      logging-log4j/src/java/org/apache/log4j/db/ConnectionSourceSkeleton.java
  
  Index: ConnectionSourceSkeleton.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/db/ConnectionSourceSkeleton.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ConnectionSourceSkeleton.java	4 May 2004 09:36:02 -0000	1.1
  +++ ConnectionSourceSkeleton.java	18 May 2004 16:50:42 -0000	1.2
  @@ -2,7 +2,6 @@
   
   import org.apache.log4j.spi.ErrorHandler;
   
  -
   /**
    * @author Ceki G&uuml;lc&uuml;
    */
  
  
  
  1.1                  logging-log4j/src/java/org/apache/log4j/db/DataSourceConnectionSource.java
  
  Index: DataSourceConnectionSource.java
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.db;
  
  import org.apache.log4j.helpers.LogLog;
  
  import java.sql.Connection;
  import java.sql.DatabaseMetaData;
  import java.sql.SQLException;
  
  import javax.sql.DataSource;
  
  
  /**
   *  The DataSourceConnectionSource is an implementation of {@link ConnectionSource}
   *  that obtains the Connection in the recommended JDBC manner based on
   *  a {@link javax.sql.DataSource DataSource}.
   *  <p>
   *
   *  @author Ray DeCampo
   *  @author Ceki G&uuml;lc&uuml;
   */
  public class DataSourceConnectionSource extends ConnectionSourceSkeleton {
    private static final String POSTGRES_PART = "postgresql";
    private static final String MYSQL_PART = "mysql";
    private static final String ORACLE_PART = "oracle";
    private DataSource dataSource;
    int dialectCode;
    
    public void activateOptions() {
      LogLog.debug("**********DataSourceConnectionSource.activateOptions called");
      if (dataSource == null) {
        LogLog.warn("WARNING: No data source specified");
        
        if (errorHandler != null) {
          errorHandler.error("WARNING: No data source specified");
        }
      } else {
        dialectCode = discoverSQLDialect();
      }
    }
  
    /**
     * @see org.apache.log4j.db.ConnectionSource#getConnection()
     */
    public Connection getConnection() throws SQLException {
      if (dataSource == null) {
        if (errorHandler != null) {
          errorHandler.error("WARNING: No data source specified");
        }
  
        return null;
      }
  
      if (user == null) {
        return dataSource.getConnection();
      } else {
        return dataSource.getConnection(user, password);
      }
    }
  
    public DataSource getDataSource() {
      return dataSource;
    }
  
    public void setDataSource(DataSource dataSource) {
      this.dataSource = dataSource;
    }
  
    public int getSQLDialect() {
      return dialectCode;
    }
    public int discoverSQLDialect() {
      int dialectCode = 0;
  
      try {
        Connection connection = getConnection();
        DatabaseMetaData meta = connection.getMetaData();
        String dbName = meta.getDatabaseProductName().toLowerCase();
        LogLog.debug("**************db name is " + dbName);
  
        if (dbName.indexOf(POSTGRES_PART) != -1) {
          LogLog.debug("POSTGRESQL dialect selected"); 
          return ConnectionSource.POSTGRES_DIALECT;
        } else if (dbName.indexOf(MYSQL_PART) != -1) {
          return ConnectionSource.MYSQL_DIALECT;
        } else if (dbName.indexOf(ORACLE_PART) != -1) {
          return ConnectionSource.ORACLE_DIALECT;
        } else {
          return ConnectionSource.UNKNOWN_DIALECT;
        }
      } catch (SQLException sqle) {
        // we can't do much here
      }
  
      return dialectCode;
    }
  }
  
  
  
  1.1                  logging-log4j/src/java/org/apache/log4j/db/DriverManagerConnectionSource.java
  
  Index: DriverManagerConnectionSource.java
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.log4j.db;
  
  import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.SQLException;
  
  import org.apache.log4j.spi.ErrorCode;
  
  
  /**
   *  The DriverManagerConnectionSource is an implementation of {@link ConnectionSource}
   *  that obtains the Connection in the traditional JDBC manner based on the
   *  connection URL.
   *  <p>
   *  Note that this class will establish a new Connection for each call to
   *  {@link #getConnection()}.  It is recommended that you either use a JDBC
   *  driver that natively supported Connection pooling or that you create
   *  your own implementation of {@link ConnectionSource} that taps into whatever
   *  pooling mechanism you are already using.  (If you have access to a JNDI
   *  implementation that supports {@link javax.sql.DataSource}s, e.g. within
   *  a J2EE application server, see {@link JNDIConnectionSource}).  See
   *  <a href="#dbcp">below</a> for a configuration example that uses the
   *  <a href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
   *  package from Apache.
   *  <p>
   *  Sample configuration:<br>
   *  <pre>
   *     &lt;connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource"&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>
   *  <p>
   *  <a name="dbcp">If</a> you do not have another connection pooling mechanism
   *  built into your application, you can use  the
   *  <a href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
   *  package from Apache:<br>
   *  <pre>
   *     &lt;connectionSource class="org.apache.log4j.jdbc.DriverManagerConnectionSource"&gt;
   *        &lt;param name="driver" value="org.apache.commons.dbcp.PoolingDriver" /&gt;
   *        &lt;param name="url" value="jdbc:apache:commons:dbcp:/myPoolingDriver" /&gt;
   *     &lt;/connectionSource&gt;
   *  </pre>
   *  Then the configuration information for the commons-dbcp package goes into
   *  the file myPoolingDriver.jocl and is placed in the classpath.  See the
   *  <a href="http://jakarta.apache.org/commons/dbcp/index.html">commons-dbcp</a>
   *  documentation for details.
   *
   *  @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a>
   */
  public class DriverManagerConnectionSource
         extends ConnectionSourceSkeleton {
    static private final String POSTGRES_PART = "postgresql";
    static private final String MYSQL_PART = "mysql";
    static private final String ORACLE_PART = "oracle";
    
    private String driverClass = null;
    protected String url = null;
  
    public void activateOptions() {
      try {
        if (driverClass != null) {
          Class.forName(driverClass);
        } else if (errorHandler != null) {
          errorHandler.error("WARNING: No JDBC driver specified for log4j " + "DriverManagerConnectionSource.");
        }
      } catch (final ClassNotFoundException cnfe) {
        if (errorHandler != null) {
          errorHandler.error("Could not load JDBC driver class: " + driverClass, cnfe, ErrorCode.GENERIC_FAILURE);
        } else {
          cnfe.printStackTrace();
        }
      }
    }
  
  
    /**
     * @see org.apache.log4j.db.ConnectionSource#getConnection()
     */
    public Connection getConnection()
           throws SQLException {
      if (user == null) {
        return DriverManager.getConnection(url);
      } else {
        return DriverManager.getConnection(url, user, password);
      }
    }
  
  
    /**
     * Returns the url.
     * @return String
     */
    public String getUrl() {
      return url;
    }
  
  
    /**
     * Sets the url.
     * @param url The url to set
     */
    public void setUrl(String url) {
      this.url = url;
    }
  
  
    /**
     * Returns the name of the driver class.
     * @return String
     */
    public String getDriverClass() {
      return driverClass;
    }
  
  
    /**
     * Sets the driver class.
     * @param driver The driver to set
     */
    public void setDriverClass(String driverClass) {
      this.driverClass = driverClass;
    }
  
  
    public int getSQLDialect() {
      int dialectCode = 0;
  
      if (url == null) {
        return ConnectionSource.UNKNOWN_DIALECT;
      }
  
      if (url.indexOf(POSTGRES_PART) != -1) {
        return ConnectionSource.POSTGRES_DIALECT;
      } else if (url.indexOf(MYSQL_PART) != -1) {
        return ConnectionSource.MYSQL_DIALECT;
      } else if (url.indexOf(ORACLE_PART) != -1) {
        return ConnectionSource.ORACLE_DIALECT;
      } else {
        return ConnectionSource.UNKNOWN_DIALECT;
      }
    }
  }
  
  
  
  1.8       +2 -0      logging-log4j/src/java/org/apache/log4j/joran/action/LevelAction.java
  
  Index: LevelAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/LevelAction.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- LevelAction.java	9 Apr 2004 14:03:48 -0000	1.7
  +++ LevelAction.java	18 May 2004 16:50:42 -0000	1.8
  @@ -23,6 +23,8 @@
     static final String EMPTY_STR = "";
     static final Class[] ONE_STRING_PARAM = new Class[] { String.class };
   
  +  boolean inError = false;
  +  
     public void begin(ExecutionContext ec, String name, Attributes attributes) {
       Object o = ec.peekObject();
   
  
  
  
  1.8       +2 -1      logging-log4j/src/java/org/apache/log4j/joran/action/ConversionRuleAction.java
  
  Index: ConversionRuleAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/ConversionRuleAction.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ConversionRuleAction.java	9 Apr 2004 14:03:48 -0000	1.7
  +++ ConversionRuleAction.java	18 May 2004 16:50:42 -0000	1.8
  @@ -32,7 +32,8 @@
   public class ConversionRuleAction extends Action {
     static final Logger logger = Logger.getLogger(ConversionRuleAction.class);
     Layout layout;
  -
  +  boolean inError = false;
  +  
     /**
      * Instantiates an layout of the given class and sets its name.
      *
  
  
  
  1.7       +2 -1      logging-log4j/src/java/org/apache/log4j/joran/action/LoggerAction.java
  
  Index: LoggerAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/LoggerAction.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- LoggerAction.java	9 Apr 2004 14:03:48 -0000	1.6
  +++ LoggerAction.java	18 May 2004 16:50:42 -0000	1.7
  @@ -33,7 +33,8 @@
   
   public class LoggerAction extends Action {
     Logger logger = Logger.getLogger(LoggerAction.class);
  -
  +  boolean inError = false;
  +  
     public void begin(ExecutionContext ec, String name, Attributes attributes) {
       // Let us forget about previous errors (in this object)
       inError = false;
  
  
  
  1.9       +2 -0      logging-log4j/src/java/org/apache/log4j/joran/action/AppenderRefAction.java
  
  Index: AppenderRefAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/AppenderRefAction.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AppenderRefAction.java	9 Apr 2004 14:03:48 -0000	1.8
  +++ AppenderRefAction.java	18 May 2004 16:50:42 -0000	1.9
  @@ -33,6 +33,8 @@
   public class AppenderRefAction extends Action {
     static final Logger logger = Logger.getLogger(AppenderRefAction.class);
   
  +  boolean inError = false;
  +  
     public void begin(
       ExecutionContext ec, String tagName, Attributes attributes) {
       // Let us forget about previous errors (in this object)
  
  
  
  1.9       +2 -0      logging-log4j/src/java/org/apache/log4j/joran/action/AppenderAction.java
  
  Index: AppenderAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/AppenderAction.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AppenderAction.java	12 May 2004 15:39:03 -0000	1.8
  +++ AppenderAction.java	18 May 2004 16:50:42 -0000	1.9
  @@ -34,6 +34,8 @@
     static final Logger logger = Logger.getLogger(AppenderAction.class);
     Appender appender;
   
  +  private boolean inError = false;
  +  
     /**
      * Instantiates an appender of the given class and sets its name.
      *
  
  
  
  1.4       +2 -0      logging-log4j/src/java/org/apache/log4j/joran/action/PropertyAction.java
  
  Index: PropertyAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/PropertyAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- PropertyAction.java	17 May 2004 16:58:29 -0000	1.3
  +++ PropertyAction.java	18 May 2004 16:50:42 -0000	1.4
  @@ -79,6 +79,8 @@
         !(Option.isEmpty(name) || Option.isEmpty(value))
           && Option.isEmpty(fileName)) {
         value = OptionConverter.convertSpecialChars(value);
  +      // now remove both leading and trailing spaces
  +      value = value.trim();
         setProperty(ec, name, value);
       } else {
         LogLog.error(INVALID_ATTRIBUTES);
  
  
  
  1.6       +2 -1      logging-log4j/src/java/org/apache/log4j/joran/action/RootLoggerAction.java
  
  Index: RootLoggerAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/RootLoggerAction.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RootLoggerAction.java	31 Mar 2004 13:13:15 -0000	1.5
  +++ RootLoggerAction.java	18 May 2004 16:50:42 -0000	1.6
  @@ -32,7 +32,8 @@
     static final Class[] ONE_STRING_PARAM = new Class[] { String.class };
     Logger logger = Logger.getLogger(RootLoggerAction.class);
     Logger root;
  -
  +  boolean inError = false;
  +  
     public void begin(ExecutionContext ec, String name, Attributes attributes) {
       inError = false;
       logger.debug("In begin method");
  
  
  
  1.8       +2 -1      logging-log4j/src/java/org/apache/log4j/joran/action/LayoutAction.java
  
  Index: LayoutAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/LayoutAction.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- LayoutAction.java	9 Apr 2004 14:03:48 -0000	1.7
  +++ LayoutAction.java	18 May 2004 16:50:42 -0000	1.8
  @@ -32,7 +32,8 @@
   public class LayoutAction extends Action {
     static final Logger logger = Logger.getLogger(LayoutAction.class);
     Layout layout;
  -
  +  boolean inError = false;
  +  
     /**
      * Instantiates an layout of the given class and sets its name.
      *
  
  
  
  1.2       +2 -1      logging-log4j/src/java/org/apache/log4j/joran/action/PluginAction.java
  
  Index: PluginAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/joran/action/PluginAction.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PluginAction.java	12 May 2004 15:39:03 -0000	1.1
  +++ PluginAction.java	18 May 2004 16:50:42 -0000	1.2
  @@ -31,7 +31,8 @@
   public class PluginAction extends Action {
     static final Logger logger = Logger.getLogger(PluginAction.class);
     Plugin plugin;
  -
  +  boolean inError = false;
  +  
     /**
      * Instantiates an plugin of the given class and sets its name.
      *
  
  
  
  1.3       +1 -1      logging-log4j/tests/input/db/writeCS1.xml
  
  Index: writeCS1.xml
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/input/db/writeCS1.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- writeCS1.xml	17 May 2004 16:58:29 -0000	1.2
  +++ writeCS1.xml	18 May 2004 16:50:43 -0000	1.3
  @@ -6,7 +6,7 @@
     <substitutionProperty file="input/db/db.properties"/>
   	    
     <appender name="DB" class="org.apache.log4j.db.DBAppender">
  -     <connectionSource class="org.apache.log4j.db.UrlConnectionSource">
  +     <connectionSource class="org.apache.log4j.db.DriverManagerConnectionSource">
          <param name="driverClass" value="${driverClass}"/>
          <param name="url" value="${url}"/>
          <param name="user" value="${user}"/>
  
  
  
  1.2       +7 -0      logging-log4j/tests/input/db/mysql.properties.sample
  
  Index: mysql.properties.sample
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/input/db/mysql.properties.sample,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- mysql.properties.sample	18 May 2004 12:05:59 -0000	1.1
  +++ mysql.properties.sample	18 May 2004 16:50:43 -0000	1.2
  @@ -1,7 +1,14 @@
  +# If you would like to test DBAppender/DBReceiver for MySQL, then
  +# set the url and user parameters for your local environment and
  +# copy this file to "mysql.properties".
  +
   # The JDBC driver class for MySQL
   driverClass=com.mysql.jdbc.Driver
   # The DataSource class for MySQL
   dataSourceClass=com.mysql.jdbc.jdbc2.optional.MysqlDataSource
  +
  +
  +# The following parameters should be set for your machine.
   url=jdbc:mysql:///test
   user=root
   password=
  
  
  
  1.3       +1 -1      logging-log4j/tests/input/db/readCS1.xml
  
  Index: readCS1.xml
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/input/db/readCS1.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- readCS1.xml	17 May 2004 16:58:29 -0000	1.2
  +++ readCS1.xml	18 May 2004 16:50:43 -0000	1.3
  @@ -6,7 +6,7 @@
     <substitutionProperty file="input/db/db.properties"/>
   	  
     <plugin name="DB1" class="org.apache.log4j.db.DBReceiver">
  -     <connectionSource class="org.apache.log4j.db.UrlConnectionSource">
  +     <connectionSource class="org.apache.log4j.db.DriverManagerConnectionSource">
          <param name="driverClass" value="${driverClass}"/>
          <param name="url" value="${url}"/>
          <param name="user" value="${user}"/>
  
  
  
  1.1                  logging-log4j/tests/input/db/appendPooled1.xml
  
  Index: appendPooled1.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE log4j:configuration>
  	  
  <log4j:configuration debug="true">
  	  
    <substitutionProperty file="input/db/db.properties"/>
  	    
    <appender name="DB" class="org.apache.log4j.db.DBAppender">
       <connectionSource class="org.apache.log4j.db.DataSourceConnectionSource">
         <dataSource class="${dataSourceClass}">
           <param name="url" value="${url}"/>
         </dataSource>
         <param name="user" value="${user}"/>
         <param name="password" value="${password}"/>
       </connectionSource>
    </appender>
  
    <appender name="VECTOR" class="org.apache.log4j.VectorAppender">
    </appender>
    
    <root>
      <level value ="debug"/>
      <appender-ref ref="DB" />
      <appender-ref ref="VECTOR" />
    </root>  
  </log4j:configuration>
  
  
  
  
  
  1.1                  logging-log4j/tests/input/db/readPooled1.xml
  
  Index: readPooled1.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE log4j:configuration>
  
  <log4j:configuration debug="true">
  	  
    <substitutionProperty file="input/db/db.properties"/>
  	  
    <plugin name="DB1" class="org.apache.log4j.db.DBReceiver">
       <connectionSource class="org.apache.log4j.db.DriverManagerConnectionSource">
         <param name="driverClass" value="${driverClass}"/>
         <param name="url" value="${url}"/>
         <param name="user" value="${user}"/>
         <param name="password" value="${password}"/>
       </connectionSource>
    </plugin>
  
  
    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
       <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="READING %relative %level %logger - %message%n"/>
       </layout>
    </appender>
    
    <appender name="VECTOR" class="org.apache.log4j.VectorAppender">
    </appender>
    
    <root>
      <level value="debug"/>
      <appender-ref ref="VECTOR" />
      <appender-ref ref="CONSOLE" />
    </root>  
  </log4j:configuration>
  
  
  
  
  
  
  1.1                  logging-log4j/tests/input/db/append-with-datasource1.xml
  
  Index: append-with-datasource1.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE log4j:configuration>
  	  
  <log4j:configuration debug="true">
  	  
    <substitutionProperty file="input/db/db.properties"/>
  	    
    <appender name="DB" class="org.apache.log4j.db.DBAppender">
       <connectionSource class="org.apache.log4j.db.DataSourceConnectionSource">
         
         <dataSource class="${dataSourceClass}">
           <param name="url" value="${url}"/>
           <param name="serverName" value="${serverName}"/>
           <param name="databaseName" value="${databaseName}"/>         
         </dataSource>
         
         <param name="user" value="${user}"/>
         <param name="password" value="${password}"/>
       </connectionSource>
    </appender>
  
    <appender name="VECTOR" class="org.apache.log4j.VectorAppender">
    </appender>
    
    <root>
      <level value ="debug"/>
      <appender-ref ref="DB" />
      <appender-ref ref="VECTOR" />
    </root>  
  </log4j:configuration>
  
  
  
  
  
  1.1                  logging-log4j/tests/input/db/read-with-datasource1.xml
  
  Index: read-with-datasource1.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8" ?>
  <!DOCTYPE log4j:configuration>
  
  <log4j:configuration debug="true">
  	  
    <substitutionProperty file="input/db/db.properties"/>
  
    <substitutionProperty file="input/db/db.properties"/>
  	    
  	    
    <plugin name="DBPlugin" class="org.apache.log4j.db.DBReceiver">
       <connectionSource class="org.apache.log4j.db.DataSourceConnectionSource">
         
         <dataSource class="${dataSourceClass}">
           <param name="url" value="${url}"/>
           <param name="serverName" value="${serverName}"/>
           <param name="databaseName" value="${databaseName}"/>          
         </dataSource>
         
         <param name="user" value="${user}"/>
         <param name="password" value="${password}"/>
       </connectionSource>
    </plugin>
    
  
    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
       <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="READING %relative %level %logger - %message%n"/>
       </layout>
    </appender>
    
    <appender name="VECTOR" class="org.apache.log4j.VectorAppender">
    </appender>
    
    <root>
      <level value="debug"/>
      <appender-ref ref="VECTOR" />
      <appender-ref ref="CONSOLE" />
    </root>  
  </log4j:configuration>
  
  
  
  
  
  
  1.3       +25 -4     logging-log4j/tests/input/db/db.properties
  
  
  
  
  1.1                  logging-log4j/tests/input/db/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  mysql.properties
  postgresql.properties
  
  
  
  1.1                  logging-log4j/tests/input/db/postgresql.properties.sample
  
  Index: postgresql.properties.sample
  ===================================================================
  # If you would like to test DBAppender/DBReceiver with PostgreSQL, then
  # set the url and user parameters for your local environment and
  # copy this file to "postgresql.properties".
  
  # The JDBC driver class for PostgreSQL
  driverClass=org.postgresql.Driver
  
  # The DataSource class for PostgreSQL
  dataSourceClass=org.postgresql.jdbc2.optional.SimpleDataSource
  
  
  
  # =======================================================
  # The following parameters should be set for your machine.
  # =======================================================
  
  # you need to set both the url and serverName and databaseName
  # this is redundant but allows the same properties file to be used
  # in different config files
  url=jdbc:postgresql://gil/test
  serverName=gil
  databaseName=test
  
  
  user=pg
  password=pg
  
  
  
  
  1.4       +40 -3     logging-log4j/tests/src/java/org/apache/log4j/db/FullCycleDBTest.java
  
  Index: FullCycleDBTest.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/db/FullCycleDBTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- FullCycleDBTest.java	17 May 2004 16:58:29 -0000	1.3
  +++ FullCycleDBTest.java	18 May 2004 16:50:43 -0000	1.4
  @@ -15,13 +15,13 @@
    */
   package org.apache.log4j.db;
   
  -import java.util.ArrayList;
  -import java.util.Hashtable;
   import java.util.Iterator;
   import java.util.Map;
   import java.util.Vector;
   
  +import junit.framework.Test;
   import junit.framework.TestCase;
  +import junit.framework.TestSuite;
   
   import org.apache.log4j.Hierarchy;
   import org.apache.log4j.Level;
  @@ -99,6 +99,7 @@
       // Write out just one log message
       Logger out = lrWrite.getLogger("testSingleOutput.out");
       out.debug("some message"+startTime);
  +    
       VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR");
       witnessEvents = witnessAppender.getVector();
       assertEquals(1, witnessEvents.size());    
  @@ -108,6 +109,32 @@
   
     }
   
  +  public void testDataSource()
  +         throws Exception {
  +
  +    LogLog.setInternalDebugging(true);
  +    JoranConfigurator jc1 = new JoranConfigurator();
  +    jc1.doConfigure("input/db/append-with-datasource1.xml", lrWrite);
  +  
  +    
  +    long startTime = System.currentTimeMillis();
  +    LogLog.info("startTime is  "+startTime);
  +    
  +    // Write out just one log message
  +    Logger out = lrWrite.getLogger("testSingleOutput.out");
  +    out.debug("some message"+startTime);
  +
  +    VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR");
  +    witnessEvents = witnessAppender.getVector();
  +    assertEquals(1, witnessEvents.size());    
  +    
  +    LogLog.info("----------------------------------------------");
  +    // now read it back
  +    readBack("input/db/read-with-datasource1.xml", startTime);
  +  }
  +  
  +
  +
     /**
      * This test starts by writing a single event to a DB using DBAppender
      * and then reads it back using DBReceiver.
  @@ -128,7 +155,7 @@
       lrWrite.setProperty("key1", "value1-"+startTime);
       MDC.put("key2", "value2-"+startTime);
       Map mdcMap = MDC.getContext();
  -    LogLog.info("**********"+mdcMap.size());
  +//    LogLog.info("**********"+mdcMap.size());
       
       // Write out just one log message
       Logger out = lrWrite.getLogger("out"+startTime);
  @@ -233,4 +260,14 @@
   //    //ctx.addToEnvironment("toto", new Integer(1));
   //    ctx.bind("toto", new Integer(1));
   //  }
  +  
  +  public static Test suite() {
  +    TestSuite suite = new TestSuite();
  +    //suite.addTest(new FullCycleDBTest("test1"));
  +    //suite.addTest(new FullCycleDBTest("testSingleOutput"));
  +    suite.addTest(new FullCycleDBTest("testDataSource"));
  +
  +
  +    return suite;
  +  }
   }
  
  
  
  1.9       +8 -0      logging-log4j/src/java/org/apache/joran/ExecutionContext.java
  
  Index: ExecutionContext.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/joran/ExecutionContext.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ExecutionContext.java	15 May 2004 20:41:05 -0000	1.8
  +++ ExecutionContext.java	18 May 2004 16:50:43 -0000	1.9
  @@ -114,12 +114,17 @@
      * If the property exists already, it is overwritten.
      */
     public void addProperty(String key, String value) {
  +    if(key == null || value == null) {
  +      return;
  +    }
       if (substitutionProperties.contains(key)) {
         LogLog.warn(
           "key [" + key
           + "] already contained in the EC properties. Overwriting.");
       }
   
  +    // values with leading or trailing spaces are bad. We remove them now.
  +    value = value.trim();
       substitutionProperties.put(key, value);
     }
   
  @@ -136,6 +141,9 @@
     }
   
     public String subst(String value) {
  +    if(value == null) {
  +      return null;
  +    }
       try {
         return OptionConverter.substVars(value, substitutionProperties);
       } catch (IllegalArgumentException e) {
  
  
  
  1.2       +1 -0      logging-log4j/tests/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/.cvsignore,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- .cvsignore	23 Jun 2003 17:02:06 -0000	1.1
  +++ .cvsignore	18 May 2004 16:50:43 -0000	1.2
  @@ -2,3 +2,4 @@
   build.properties
   output
   classes
  +lib
  
  
  
  1.54      +65 -2     logging-log4j/tests/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/build.xml,v
  retrieving revision 1.53
  retrieving revision 1.54
  diff -u -r1.53 -r1.54
  --- build.xml	15 May 2004 15:15:43 -0000	1.53
  +++ build.xml	18 May 2004 16:50:43 -0000	1.54
  @@ -6,7 +6,7 @@
   <!-- ================================================================= -->
   <!-- NOTE: all directories are relative to jakarta-log4j/tests         -->
   <!-- ================================================================= -->
  -<project name="log4j" default="usage" basedir="." >
  +<project name="log4j-tests" default="usage" basedir="." >
   
     <property file="build.properties"/>
   
  @@ -31,8 +31,12 @@
       <pathelement location="./classes"/>
       <pathelement location="./resources"/>
       <pathelement location="${jakarta.oro.jar}"/>
  +     <fileset dir="./lib/">
  +      <include name="*.jar"/>
  +    </fileset>
     </path>
   
  +  
     <!-- ================================================================= -->
     <!--                        TARGETS                                    -->
     <!-- ================================================================= -->
  @@ -492,9 +496,68 @@
     </target>
     
     
  +  <!-- ================================================================= -->
  +  <!-- ========================= DB Tests ======================= -->
  +  <!-- ================================================================= -->
  +
  +  <!-- These tests follow the same pattern. They will be run if a property file 
  +       defining access as well as necessary class files are available. Otherwise,
  +       the test is skipped.
  +       --> 
  +       
  +  <target name="mysqlCheck">
  +    <condition property="mysql-present">
  +    <and>
  +      <available file="./input/db/mysql.properties" />
  +      <available classname="com.mysql.jdbc.Driver">
  +        <classpath refid="tests.classpath"/>
  +      </available>
  +    </and>
  +    </condition>
  +  </target>
  +   
  +   
  +  <target name="mysql" depends="mysqlCheck, build" if="mysql-present">
  +    
  +    <delete file="./input/db/db.properties"/>
  +    <echo message="MySQL available"/>
  +    <copy file="./input/db/mysql.properties" tofile="./input/db/db.properties"/>
  +    
  +    <junit printsummary="yes" fork="no" haltonfailure="yes"> 
  +      <sysproperty key="runLen" value="100"/>     
  +      <classpath refid="tests.classpath"/>
  +      <formatter type="plain" usefile="false"/>
  +      <test name="org.apache.log4j.db.FullCycleDBTest" />
  +    </junit>
  +  </target>
  +
   
  +  <target name="postgresqlCheck">
  +    <condition property="postgresql-present">
  +    <and>
  +      <available file="./input/db/postgresql.properties" />
  +      <available classname="org.postgresql.Driver">
  +        <classpath refid="tests.classpath"/>
  +      </available>
  +    </and>
  +    </condition>
  +  </target>
  +   
  +  <target name="postgresql" depends="postgresqlCheck, build" if="postgresql-present">
  +    <delete file="./input/db/db.properties"/>
  +    <echo message="PostgreSQL available"/>
  +    <copy file="./input/db/postgresql.properties" tofile="./input/db/db.properties"/>
  +    
  +    <junit printsummary="yes" fork="no" haltonfailure="yes"> 
  +      <sysproperty key="runLen" value="100"/>     
  +      <classpath refid="tests.classpath"/>
  +      <formatter type="plain" usefile="false"/>
  +      <test name="org.apache.log4j.db.FullCycleDBTest" />
  +    </junit>
  +  </target>
  +  
     <!-- ================================================================= -->
  -  <!-- ========================= Very long Tests ======================= -->
  +  <!-- =========================   long Tests  ========================= -->
     <!-- ================================================================= -->
     
    
  
  
  
  1.10      +2 -0      logging-log4j/src/java/org/apache/joran/action/NewRuleAction.java
  
  Index: NewRuleAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/joran/action/NewRuleAction.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- NewRuleAction.java	9 Apr 2004 18:39:32 -0000	1.9
  +++ NewRuleAction.java	18 May 2004 16:50:43 -0000	1.10
  @@ -28,6 +28,8 @@
   public class NewRuleAction extends Action {
     static final Logger logger = Logger.getLogger(NewRuleAction.class);
   
  +  boolean inError = false;
  +  
     /**
      * Instantiates an layout of the given class and sets its name.
      *
  
  
  
  1.15      +0 -5      logging-log4j/src/java/org/apache/joran/action/Action.java
  
  Index: Action.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/joran/action/Action.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Action.java	15 May 2004 20:41:05 -0000	1.14
  +++ Action.java	18 May 2004 16:50:43 -0000	1.15
  @@ -45,11 +45,6 @@
     public static final String ACTION_CLASS_ATTRIBUTE = "actionClass";
   
     /**
  -   * When actions encounter an error condition they set this variable to true.
  -   */
  -  protected boolean inError = false;
  -
  -  /**
      * Called when the parser first encounters an element.
      *
      * The return value indicates whether child elements should be processed. If
  
  
  
  1.10      +8 -2      logging-log4j/src/java/org/apache/joran/action/ParamAction.java
  
  Index: ParamAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/joran/action/ParamAction.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ParamAction.java	15 May 2004 18:22:56 -0000	1.9
  +++ ParamAction.java	18 May 2004 16:50:43 -0000	1.10
  @@ -5,6 +5,7 @@
   
   import org.apache.log4j.Logger;
   import org.apache.log4j.config.PropertySetter;
  +import org.apache.log4j.helpers.LogLog;
   import org.apache.log4j.helpers.OptionConverter;
   import org.xml.sax.Attributes;
   
  @@ -14,7 +15,9 @@
   
   	static String NO_NAME = "No name attribute in <param> element";
   	static String NO_VALUE = "No name attribute in <param> element";
  -	
  +  
  +  boolean inError = false;
  +  
     public void begin(ExecutionContext ec, String localName, Attributes attributes) {
   		String name = attributes.getValue(NAME_ATTRIBUTE);
   		String value = attributes.getValue(VALUE_ATTRIBUTE);
  @@ -33,10 +36,13 @@
   			return;
   		}
       
  +    // remove both leading and trailing spaces
  +    value = value.trim();
  +    
   		Object o = ec.peekObject();
   		PropertySetter propSetter = new PropertySetter(o);		
   		value = ec.subst(OptionConverter.convertSpecialChars(value));
  -    logger.debug("Setting parameter ["+name+"] to value ["+value+"].");
  +    LogLog.debug("In ParamAction setting parameter ["+name+"] to value ["+value+"].");
   		propSetter.setProperty(name, value);
     }
   
  
  
  
  1.11      +124 -73   logging-log4j/src/java/org/apache/joran/action/NestComponentIA.java
  
  Index: NestComponentIA.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/joran/action/NestComponentIA.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- NestComponentIA.java	10 Apr 2004 13:49:00 -0000	1.10
  +++ NestComponentIA.java	18 May 2004 16:50:43 -0000	1.11
  @@ -1,12 +1,12 @@
   /*
    * Copyright 1999,2004 The Apache Software Foundation.
  - * 
  + *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
  - * 
  + *
    *      http://www.apache.org/licenses/LICENSE-2.0
  - * 
  + *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  @@ -24,10 +24,14 @@
   import org.apache.log4j.Logger;
   import org.apache.log4j.config.PropertySetter;
   import org.apache.log4j.helpers.Loader;
  +import org.apache.log4j.helpers.LogLog;
   import org.apache.log4j.spi.OptionHandler;
   
   import org.xml.sax.Attributes;
   
  +import java.util.Stack;
  +
  +
   /**
    * @author Ceki G&uuml;lc&uuml;
    *
  @@ -35,102 +39,149 @@
   public class NestComponentIA extends ImplicitAction {
     static final Logger logger = Logger.getLogger(NestComponentIA.class);
   
  -  Object nestedComponent;
  -  int containmentType;
  -  PropertySetter parentBean;
  -  
  -  public boolean isApplicable(Pattern pattern, Attributes attributes, ExecutionContext ec) {
  -    
  +  // actionDataStack contains ActionData instances
  +  // We use a stack of ActionData objects in order to support nested
  +  // elements which are handled by the same NestComponentIA instance.
  +  // We push a ActionData instance in the isApplicable method (if the
  +  // action is applicable) and pop it in the end() method.
  +  // The XML well-formedness rule will guarantee that a push will eventually
  +  // be followed by the corresponding pop.
  +  Stack actionDataStack = new Stack();
  +
  +  public boolean isApplicable(
  +    Pattern pattern, Attributes attributes, ExecutionContext ec) {
  +    //LogLog.debug("in NestComponentIA.isApplicable <" + pattern + ">");
  +
       String nestedElementTagName = pattern.peekLast();
  -    
  -    inError = false;
  +
       Object o = ec.peekObject();
  -    parentBean = new PropertySetter(o);
  +    PropertySetter parentBean = new PropertySetter(o);
   
  -    containmentType = parentBean.canContainComponent(nestedElementTagName);
  +    int containmentType = parentBean.canContainComponent(nestedElementTagName);
   
       switch (containmentType) {
       case PropertySetter.NOT_FOUND:
         return false;
   
  +    // we only push action data if NestComponentIA is applicable
       case PropertySetter.AS_COLLECTION:
  -      return true;
  -
       case PropertySetter.AS_PROPERTY:
  +
  +      ActionData ad = new ActionData(parentBean, containmentType);
  +      actionDataStack.push(ad);
  +
         return true;
  -      
  -      default: 
  -      inError= true;
  -      ec.addError(new ErrorItem("PropertySetter.canContainComponent returned "+containmentType));
  +
  +    default:
  +      ec.addError(
  +        new ErrorItem(
  +          "PropertySetter.canContainComponent returned " + containmentType));
  +
         return false;
       }
     }
   
  -  public void begin(ExecutionContext ec, String localName, Attributes attributes) {
  -    // inError was reset in isApplicable. It should not be touched here
  +  public void begin(
  +    ExecutionContext ec, String localName, Attributes attributes) {
  +    //LogLog.debug("in NestComponentIA begin method");
   
  -      String className = attributes.getValue(CLASS_ATTRIBUTE);
  -      
  -     
  -      if(Option.isEmpty(className)) {
  -        inError = true;
  -        String errMsg = "No class name attribute in <"+localName+">";
  -        logger.error(errMsg);
  -        ec.addError(new ErrorItem(errMsg));
  -        return;
  -      }
  -      
  -      try {
  -        logger.debug("About to instantiate component <"+localName+ "> of type [" + className + "]");
  -
  -        nestedComponent = Loader.loadClass(className).newInstance();
  -         
  -            
  -        logger.debug("Pushing component <"+localName+"> on top of the object stack.");
  -        ec.pushObject(nestedComponent);
  -      } catch (Exception oops) {
  -        inError = true;      
  -        String msg =  "Could not create component <"+localName+">.";
  -        logger.error(msg, oops);
  -        ec.addError(new ErrorItem(msg));
  -      }
  +    // get the action data object pushed in isApplicable() method call
  +    ActionData actionData = (ActionData) actionDataStack.peek();
  +
  +    String className = attributes.getValue(CLASS_ATTRIBUTE);
  +
  +    // perform variable name substitution
  +    className = ec.subst(className);
  +
  +    if (Option.isEmpty(className)) {
  +      actionData.inError = true;
  +
  +      String errMsg = "No class name attribute in <" + localName + ">";
  +      logger.error(errMsg);
  +      ec.addError(new ErrorItem(errMsg));
  +
  +      return;
  +    }
  +
  +    try {
  +      LogLog.debug(
  +        "About to instantiate component <" + localName + "> of type ["
  +        + className + "]");
  +
  +      actionData.nestedComponent = Loader.loadClass(className).newInstance();
  +
  +      LogLog.debug(
  +        "Pushing component <" + localName + "> on top of the object stack.");
  +      ec.pushObject(actionData.nestedComponent);
  +    } catch (Exception oops) {
  +      actionData.inError = true;
  +
  +      String msg = "Could not create component <" + localName + ">.";
  +      LogLog.error(msg, oops);
  +      ec.addError(new ErrorItem(msg));
  +    }
     }
   
     public void end(ExecutionContext ec, String tagName) {
  -    
       logger.debug("entering end method");
  -    if (inError) {
  -        return;
  -      }
   
  -      if (nestedComponent instanceof OptionHandler) {
  -        ((OptionHandler) nestedComponent).activateOptions();
  -      }
  +    // pop the action data object pushed in isApplicable() method call
  +    // we assume that each this begin
  +    ActionData actionData = (ActionData) actionDataStack.pop();
   
  -      Object o = ec.peekObject();
  +    if (actionData.inError) {
  +      return;
  +    }
   
  -      if (o != nestedComponent) {
  -        logger.warn(
  -          "The object on the top the of the stack is not the component pushed earlier.");
  -      } else {
  -        logger.warn("Removing component from the object stack");
  -        ec.popObject();
  -
  -        // Now let us attach the component
  -        switch (containmentType) {
  -        case PropertySetter.AS_PROPERTY:
  -        logger.debug("Setting ["+tagName+"] to parent.");
  -          parentBean.setComponent(tagName, nestedComponent);
  -          break;
  -
  -        case PropertySetter.AS_COLLECTION:
  -        logger.debug("Adding ["+tagName+"] to parent.");
  -          parentBean.addComponent(tagName, nestedComponent);
  -          break;
  -        } 
  +    if (actionData.nestedComponent instanceof OptionHandler) {
  +      ((OptionHandler) actionData.nestedComponent).activateOptions();
  +    }
  +
  +    Object o = ec.peekObject();
  +
  +    if (o != actionData.nestedComponent) {
  +      logger.warn(
  +        "The object on the top the of the stack is not the component pushed earlier.");
  +    } else {
  +      logger.warn("Removing component from the object stack");
  +      ec.popObject();
  +
  +      // Now let us attach the component
  +      switch (actionData.containmentType) {
  +      case PropertySetter.AS_PROPERTY:
  +        LogLog.debug(
  +          "Setting [" + tagName + "] to parent of type ["
  +          + actionData.parentBean.getObjClass() + "]");
  +        actionData.parentBean.setComponent(
  +          tagName, actionData.nestedComponent);
  +
  +        break;
  +
  +      case PropertySetter.AS_COLLECTION:
  +        LogLog.debug(
  +          "Adding [" + tagName + "] to parent of type ["
  +          + actionData.parentBean.getObjClass() + "]");
  +        actionData.parentBean.addComponent(
  +          tagName, actionData.nestedComponent);
  +
  +        break;
         }
  +    }
     }
   
     public void finish(ExecutionContext ec) {
  +  }
  +}
  +
  +
  +class ActionData {
  +  PropertySetter parentBean;
  +  Object nestedComponent;
  +  int containmentType;
  +  boolean inError;
  +
  +  ActionData(PropertySetter parentBean, int containmentType) {
  +    this.parentBean = parentBean;
  +    this.containmentType = containmentType;
     }
   }
  
  
  
  1.8       +6 -4      logging-log4j/src/java/org/apache/log4j/db/dialect/postgresql.sql
  
  Index: postgresql.sql
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/db/dialect/postgresql.sql,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- postgresql.sql	15 May 2004 18:23:35 -0000	1.7
  +++ postgresql.sql	18 May 2004 16:50:43 -0000	1.8
  @@ -3,9 +3,11 @@
   #
   # It is intended for PostgreSQL databases.
   
  -DROP TABLE    mdc;
  -DROP TABLE    logging_event;
  +DROP TABLE    logging_event_property;
  +DROP TABLE    logging_event_exception;
   DROP SEQUENCE logging_event_id_seq;
  +DROP TABLE    logging_event;
  +
   
   CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START 1;
   
  @@ -29,7 +31,7 @@
       mapped_key        VARCHAR(254) NOT NULL,
       mapped_value      VARCHAR(1024),
       PRIMARY KEY(event_id, mapped_key),
  -    FOREIGN KEY (event_id) REFERENCES logging_event(id)
  +    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
     );
   
   CREATE TABLE logging_event_exception
  @@ -38,5 +40,5 @@
       i                SMALLINT NOT NULL,
       trace_line       VARCHAR(254) NOT NULL,
       PRIMARY KEY(event_id, i),
  -    FOREIGN KEY (event_id) REFERENCES logging_event(id)
  +    FOREIGN KEY (event_id) REFERENCES logging_event(event_id)
     );
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org