/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.catalina.valves;


import java.io.IOException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Properties;

import javax.servlet.ServletException;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;

/**
 * <p>
 * This Tomcat extension logs server access directly to a database, and can 
 * be used instead of the regular file-based access log implemented in 
 * AccessLogValve.
 * To use, copy into the server/classes directory of the Tomcat installation
 * and configure in server.xml as:
 * <pre>
 * 		&lt;Valve className="JDBCAccessLogValve"
 *        	driverName="<i>your_jdbc_driver</i>"
 *        	connectionURL="<i>your_jdbc_url</i>"
 *        	pattern="combined" resolveHosts="false"
 * 		/&gt;
 * </pre>
 * </p>
 * <p>
 * Many parameters can be configured, such as the database connection (with
 * <code>driverName</code> and <code>connectionURL</code>),
 * the table name (<code>tableName</code>)
 * and the field names (corresponding to the get/set method names).
 * The same options as AccessLogValve are supported, such as
 * <code>resolveHosts</code> and <code>pattern</code> ("common" or "combined" 
 * only).
 * </p>
 * <p>
 * When Tomcat is started, a database connection (with autoReconnect option)
 * is created and used for all the log activity. When Tomcat is shutdown, the
 * database connection is closed.
 * This logger can be used at the level of the Engine context (being shared
 * by all the defined hosts) or the Host context (one instance of the logger 
 * per host, possibly using different databases).
 * </p>
 * <p>
 * The database table can be created with the following command:
 * </p>
 * <pre>
 * CREATE TABLE access (
 * id INT UNSIGNED AUTO_INCREMENT NOT NULL,
 * remoteHost CHAR(15) NOT NULL,
 * userName CHAR(15),
 * timestamp TIMESTAMP NOT NULL,
 * virtualHost VARCHAR(64) NOT NULL,
 * method VARCHAR(8) NOT NULL,
 * query VARCHAR(255) NOT NULL,
 * status SMALLINT UNSIGNED NOT NULL,
 * bytes INT UNSIGNED NOT NULL,
 * referer VARCHAR(128),
 * userAgent VARCHAR(128),
 * PRIMARY KEY (id),
 * INDEX (timestamp),
 * INDEX (remoteHost),
 * INDEX (virtualHost),
 * INDEX (query),
 * INDEX (userAgent)
 * );
 * </pre>
 * <p>
 * If the table is created as above, its name and the field names don't need 
 * to be defined.
 * </p>
 * <p>
 * If the request method is "common", only these fields are used:
 * <code>remoteHost, user, timeStamp, query, status, bytes</code>
 * </p>
 * <p>
 * <i>TO DO: provide option for excluding logging of certain MIME types.</i>
 * </p>
 * 
 * @author Andre de Jesus
 * @author Peter Rossbach
 */

public final class JDBCAccessLogValve 
    extends ValveBase 
    implements Lifecycle {

    // ----------------------------------------------------------- Constructors


    /**
     * Class constructor. Initializes the fields with the default values.
     * The defaults are:
     * <pre>
     * 		driverName = null;
     * 		connectionURL = null;
     * 		tableName = "access";
     * 		remoteHostField = "remoteHost";
     * 		userField = "userName";
     * 		timestampField = "timestamp";
     * 		virtualHostField = "virtualHost";
     * 		methodField = "method";
     * 		queryField = "query";
     * 		statusField = "status";
     * 		bytesField = "bytes";
     * 		refererField = "referer";
     * 		userAgentField = "userAgent";
     * 		pattern = "common";
     * 		resolveHosts = false;
     * </pre>
     */
    public JDBCAccessLogValve() {
        super();
        driverName = null;
        connectionURL = null;
        tableName = "access";
        remoteHostField = "remoteHost";
        userField = "userName";
        timestampField = "timestamp";
        virtualHostField = "virtualHost";
        methodField = "method";
        queryField = "query";
        statusField = "status";
        bytesField = "bytes";
        refererField = "referer";
        userAgentField = "userAgent";
        pattern = "common";
        resolveHosts = false;
        conn = null;
        ps = null;
        currentTimeMillis = new java.util.Date().getTime();
    }


    // ----------------------------------------------------- Instance Variables


   /**
     * The connection username to use when trying to connect to the database.
     */
    protected String connectionName = null;


    /**
     * The connection URL to use when trying to connect to the database.
     */
    protected String connectionPassword = null;

   /**
     * Instance of the JDBC Driver class we use as a connection factory.
     */
    protected Driver driver = null;


    private String driverName;
    private String connectionURL;
    private String tableName;
    private String remoteHostField;
    private String userField;
    private String timestampField;
    private String virtualHostField;
    private String methodField;
    private String queryField;
    private String statusField;
    private String bytesField;
    private String refererField;
    private String userAgentField;
    private String pattern;
    private boolean resolveHosts;


    private Connection conn;
    private PreparedStatement ps;


    private long currentTimeMillis;


    /**
     * The descriptive information about this implementation.
     */
    protected static String info = 
        "org.apache.catalina.valves.JDBCAccessLogValve/1.1";


    /**
     * The lifecycle event support for this component.
     */
    protected LifecycleSupport lifecycle = new LifecycleSupport(this);


    /**
     * The string manager for this package.
     */
    private StringManager sm = StringManager.getManager(Constants.Package);


    /**
     * Has this component been started yet?
     */
    private boolean started = false;


    // ------------------------------------------------------------- Properties
 
    /**
     * Return the username to use to connect to the database.
     *
     */
    public String getConnectionName() {
        return connectionName;
    }

    /**
     * Set the username to use to connect to the database.
     *
     * @param connectionName Username
     */
    public void setConnectionName(String connectionName) {
        this.connectionName = connectionName;
    }

    /**
     * Sets the database driver name.
     * 
     * @param driverName The complete name of the database driver class.
     */
    public void setDriverName(String driverName) {
        this.driverName = driverName;
    }

   /**
     * Return the password to use to connect to the database.
     *
     */
    public String getConnectionPassword() {
        return connectionPassword;
    }

    /**
     * Set the password to use to connect to the database.
     *
     * @param connectionPassword User password
     */
    public void setConnectionPassword(String connectionPassword) {
        this.connectionPassword = connectionPassword;
    }

    /**
     * Sets the JDBC URL for the database where the log is stored.
     * 
     * @param connectionURL The JDBC URL of the database.
     */
    public void setConnectionURL(String connectionURL) {
        this.connectionURL = connectionURL;
    }


    /**
     * Sets the name of the table where the logs are stored.
     * 
     * @param tableName The name of the table.
     */
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }


    /**
     * Sets the name of the field containing the remote host.
     * 
     * @param remoteHostField The name of the remote host field.
     */
    public void setRemoteHostField(String remoteHostField) {
        this.remoteHostField = remoteHostField;
    }


    /**
     * Sets the name of the field containing the remote user name.
     * 
     * @param userField The name of the remote user field.
     */
    public void setUserField(String userField) {
        this.userField = userField;
    }


    /**
     * Sets the name of the field containing the server-determined timestamp.
     * 
     * @param timestampField The name of the server-determined timestamp field.
     */
    public void setTimestampField(String timestampField) {
        this.timestampField = timestampField;
    }


    /**
     * Sets the name of the field containing the virtual host information 
     * (this is in fact the server name).
     * 
     * @param virtualHostField The name of the virtual host field.
     */
    public void setVirtualHostField(String virtualHostField) {
        this.virtualHostField = virtualHostField;
    }


    /**
     * Sets the name of the field containing the HTTP request method.
     * 
     * @param methodField The name of the HTTP request method field.
     */
    public void setMethodField(String methodField) {
        this.methodField = methodField;
    }


    /**
     * Sets the name of the field containing the URL part of the HTTP query.
     * 
     * @param queryField The name of the field containing the URL part of 
     * the HTTP query.
     */
    public void setQueryField(String queryField) {
        this.queryField = queryField;
    }


  /**
   * Sets the name of the field containing the HTTP response status code.
   * 
   * @param statusField The name of the HTTP response status code field.
   */  
    public void setStatusField(String statusField) {
        this.statusField = statusField;
    }


    /**
     * Sets the name of the field containing the number of bytes returned.
     * 
     * @param bytesField The name of the returned bytes field.
     */
    public void setBytesField(String bytesField) {
        this.bytesField = bytesField;
    }


    /**
     * Sets the name of the field containing the referer.
     * 
     * @param refererField The referer field name.
     */
    public void setRefererField(String refererField) {
        this.refererField = refererField;
    }


    /**
     * Sets the name of the field containing the user agent.
     * 
     * @param userAgentField The name of the user agent field.
     */
    public void setUserAgentField(String userAgentField) {
        this.userAgentField = userAgentField;
    }


    /**
     * Sets the logging pattern. The patterns supported correspond to the 
     * file-based "common" and "combined". These are translated into the use 
     * of tables containing either set of fields.
     * <P><I>TO DO: more flexible field choices.</I></P>
     * 
     * @param pattern The name of the logging pattern.
     */
    public void setPattern(String pattern) {
        this.pattern = pattern;
    }


    /**
     * Determines whether IP host name resolution is done.
     * 
     * @param resolveHosts "true" or "false", if host IP resolution 
     * is desired or not.
     */
    public void setResolveHosts(String resolveHosts) {
        this.resolveHosts = new Boolean(resolveHosts).booleanValue();
    }


    // --------------------------------------------------------- Public Methods


    /**
     * This method is invoked by Tomcat on each query.
     * 
     * @param request The Request object.
     * @param response The Response object.
     *
     * @exception IOException Should not be thrown.
     * @exception ServletException Database SQLException is wrapped 
     * in a ServletException.
     */    
    public void invoke(Request request, Response response) 
        throws IOException, ServletException {

        getNext().invoke(request, response);

        String remoteHost = "";
        if(resolveHosts)
            remoteHost = request.getRemoteHost();
        else
            remoteHost = request.getRemoteAddr();
        String user = "";
        if(request != null)
            user = request.getRemoteUser();
        String query="";
        if(request != null)
            query = request.getRequestURI();
        int bytes = response.getContentCount();
        if(bytes < 0)
            bytes = 0;
        int status = response.getStatus();

        synchronized (this) {
          int numberOfTries = 2;
          while (numberOfTries>0) {
            try {
                open();
    
                ps.setString(1, remoteHost);
                ps.setString(2, user);
                ps.setTimestamp(3, new Timestamp(getCurrentTimeMillis()));
                ps.setString(4, query);
                ps.setInt(5, status);
                ps.setInt(6, bytes);
                if (pattern.equals("combined")) {
     
                      String virtualHost = "";
                      if(request != null)
                         virtualHost = request.getServerName();
                      String method = "";
                      if(request != null)
                         method = request.getMethod();
                      String referer = "";
                      if(request != null)
                         referer = request.getHeader("referer");
                      String userAgent = "";
                      if(request != null)
                         userAgent = request.getHeader("user-agent");
                      ps.setString(7, virtualHost);
                      ps.setString(8, method);
                      ps.setString(9, referer);
                      ps.setString(10, userAgent);
                }
                ps.executeUpdate();
                return;
              } catch (SQLException e) {
                // Log the problem for posterity
                  container.getLogger().error(sm.getString("jdbcAccessLogValve.exception"), e);

                // Close the connection so that it gets reopened next time
                if (conn != null)
                    close();
              }
    	      numberOfTries--;        
           }
        }

    }	


    /**
     * Adds a Lifecycle listener.
     * 
     * @param listener The listener to add.
     */  
    public void addLifecycleListener(LifecycleListener listener) {

        lifecycle.addLifecycleListener(listener);

    }


    /**
     * Get the lifecycle listeners associated with this lifecycle. If this 
     * Lifecycle has no listeners registered, a zero-length array is returned.
     */
    public LifecycleListener[] findLifecycleListeners() {

        return lifecycle.findLifecycleListeners();

    }


    /**
     * Removes a Lifecycle listener.
     * 
     * @param listener The listener to remove.
     */
    public void removeLifecycleListener(LifecycleListener listener) {

        lifecycle.removeLifecycleListener(listener);

    }

    /**
     * Open (if necessary) and return a database connection for use by
     * this AccessLogValve.
     *
     * @exception SQLException if a database error occurs
     */
    protected void open() throws SQLException {

        // Do nothing if there is a database connection already open
        if (conn != null)
            return ;

        // Instantiate our database driver if necessary
        if (driver == null) {
            try {
                Class clazz = Class.forName(driverName);
                driver = (Driver) clazz.newInstance();
            } catch (Throwable e) {
                throw new SQLException(e.getMessage());
            }
        }

        // Open a new connection
        Properties props = new Properties();
        props.put("autoReconnect", "true");
        if (connectionName != null)
            props.put("user", connectionName);
        if (connectionPassword != null)
            props.put("password", connectionPassword);
        conn = driver.connect(connectionURL, props);
        conn.setAutoCommit(true);
        if (pattern.equals("common")) {
                ps = conn.prepareStatement
                    ("INSERT INTO " + tableName + " (" 
                     + remoteHostField + ", " + userField + ", "
                     + timestampField +", " + queryField + ", "
                     + statusField + ", " + bytesField 
                     + ") VALUES(?, ?, ?, ?, ?, ?)");
        } else if (pattern.equals("combined")) {
                ps = conn.prepareStatement
                    ("INSERT INTO " + tableName + " (" 
                     + remoteHostField + ", " + userField + ", "
                     + timestampField + ", " + queryField + ", " 
                     + statusField + ", " + bytesField + ", " 
                     + virtualHostField + ", " + methodField + ", "
                     + refererField + ", " + userAgentField
                     + ") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        }
    }

    /**
     * Close the specified database connection.
     */
    protected void close() {

        // Do nothing if the database connection is already closed
        if (conn == null)
            return;

        // Close our prepared statements (if any)
        try {
            ps.close();
        } catch (Throwable f) {
            ;
        }
        this.ps = null;



        // Close this database connection, and log any errors
        try {
            conn.close();
        } catch (SQLException e) {
            container.getLogger().error(sm.getString("jdbcAccessLogValeve.close"), e); // Just log it here            
        } finally {
           this.conn = null;
        }

    }
    /**
     * Invoked by Tomcat on startup. The database connection is set here.
     * 
     * @exception LifecycleException Can be thrown on lifecycle 
     * inconsistencies or on database errors (as a wrapped SQLException).
     */
    public void start() throws LifecycleException {

        if (started)
            throw new LifecycleException
                (sm.getString("accessLogValve.alreadyStarted"));
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;

        try {
            open() ;        
        } catch (SQLException e) {
            throw new LifecycleException(e);
        }

    }


    /**
     * Invoked by tomcat on shutdown. The database connection is closed here.
     * 
     * @exception LifecycleException Can be thrown on lifecycle 
     * inconsistencies or on database errors (as a wrapped SQLException).
     */
    public void stop() throws LifecycleException {

        if (!started)
            throw new LifecycleException
                (sm.getString("accessLogValve.notStarted"));
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        
        close() ;
    	
    }


    public long getCurrentTimeMillis() {
        long systime  =  System.currentTimeMillis();
        if ((systime - currentTimeMillis) > 1000) {
            currentTimeMillis  =  new java.util.Date(systime).getTime();
        }
        return currentTimeMillis;
    }

}
