All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kawanfw.sql.tomcat.AceQLJdbcInterceptor Maven / Gradle / Ivy

Go to download

AceQL HTTP is a framework of REST like http APIs that allow to access to remote SQL databases over http from any device that supports http. AceQL HTTP is provided with four client SDK: - The AceQL C# Client SDK allows to wrap the HTTP APIs using Microsoft SQL Server like calls in their code, just like they would for a local database. - The AceQL Java Client SDK allows to wrap the HTTP APIs using JDBC calls in their code, just like they would for a local database. - The AceQL Python Client SDK allows SQL calls to be encoded with standard unmodified DB-API 2.0 syntax

There is a newer version: 12.2
Show newest version
/*
 * Copyright (c)2022 KawanSoft S.A.S. All rights reserved.
 * 
 * Use of this software is governed by the Business Source License included
 * in the LICENSE.TXT file in the project's root directory.
 *
 * Change Date: 2026-11-01
 *
 * On the date above, in accordance with the Business Source License, use
 * of this software will be governed by version 2.0 of the Apache License.
 */
package org.kawanfw.sql.tomcat;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;
import java.util.Set;

import org.apache.tomcat.jdbc.pool.ConnectionPool;
import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
import org.apache.tomcat.jdbc.pool.PooledConnection;
import org.kawanfw.sql.api.server.connectionstore.ConnectionKey;
import org.kawanfw.sql.servlet.connection.ConnectionStore;
import org.kawanfw.sql.servlet.injection.properties.ConfPropertiesUtil;
import org.kawanfw.sql.util.FrameworkDebug;

/**
 * Allows to clean our ConnectionStore when a Connection is removed by Tomcat
 * JDBC Pool...
 * 
 * @author Nicolas de Pomereu
 *
 */
public class AceQLJdbcInterceptor extends JdbcInterceptor {

    public static boolean DEBUG = FrameworkDebug.isSet(AceQLJdbcInterceptor.class);

    /**
     * Constructor. Just for debug.
     */
    public AceQLJdbcInterceptor() {
	debug("AceQLJdbcInterceptor instance creation.");
    }

    @Override
    public void reset(ConnectionPool parent, PooledConnection con) {
	if (con != null) {
	    Connection connection = con.getConnection();
	    debug("AceQLJdbcInterceptor. reset call: connection borrowed from pool: " + connection);
	}
	else {
	    debug("AceQLJdbcInterceptor. reset call: connection borrowed from pool. con is null!");	    
	}
    }

    @Override
    public void disconnected(ConnectionPool parent, PooledConnection con, boolean finalizing) {

	try {
	    // No clean of course in stateless mode!
	    if (ConfPropertiesUtil.isStatelessMode()) {
		debug("AceQLJdbcInterceptor. Stateless mode. Nothing to do.");
		return;
	    }

	    if (con == null) {
		debug("Can not intercept Connection to use for cleaning our ConnectionStore: PooledConnection is null!");
	    }

	    debug("AceQLJdbcInterceptor. Clean ConnectionStore for intercepted connection...");
	    Connection connection = con.getConnection();

	    if (connection == null) {
		debug("AceQLJdbcInterceptor. Current Connection is null! Nothing to do.");
		return;
	    }

	    Map map = ConnectionStore.getConnectionMap();
	    Set set = map.keySet();

	    if (set == null) {
		debug("AceQLJdbcInterceptor. ConnectionStore Set is null. Nothing to do.");
		return;
	    }

	    if (set.isEmpty()) {
		debug("AceQLJdbcInterceptor. ConnectionStore Set is empty. Nothing to do.");
		return;
	    }

	    for (Map.Entry entry : map.entrySet()) {

		Connection unwrappedStoredConnection = getUnwrappedConnection(entry.getValue());
		
		if (unwrappedStoredConnection != null) {
		    ConnectionKey connectionKey = entry.getKey();
		    
		    debug("AceQLJdbcInterceptor. JdbcInterceptorTest connection.toString(): " + connection.toString());
		    debug("AceQLJdbcInterceptor. unwrappedStoredConnection.toString() : " + unwrappedStoredConnection.toString());
		    
		    if (connection.equals(unwrappedStoredConnection)) {
			ConnectionStore.remove(connectionKey);
			debug("AceQLJdbcInterceptor. ConnectionStore all removed for connectionKey: " + connectionKey);
		    } else {
			debug("AceQLJdbcInterceptor. Current connection does not correspond to connectionKey: "
				+ connectionKey);
		    }
		} else {
		    debug("AceQLJdbcInterceptor. connectionKey is null!");
		}
	    }

	} catch (Exception e) {
	    // NO EXCEPTION THROW ALLOWED!
	    System.err.println(new Date() + " AceQLJdbcInterceptor Failure:");
	    e.printStackTrace();
	}

    }

    /**
     * Unwraps the Connection if it's a PooledConnection
     * @param connection the wrapped Connection
     * @return the unwrapped Connection
     * @throws SQLException 
     */
    public Connection getUnwrappedConnection(Connection connection) throws SQLException {
	
	// Try to unwrap following https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html.
	// Purpose is to be able to compare the two Connections...
	if (connection instanceof javax.sql.PooledConnection) {
	    Connection actual = ((javax.sql.PooledConnection)connection).getConnection(); 
	    return actual;	    
	}
	else {
	    return connection;
	}

    }

    private void debug(String s) {
	if (DEBUG) {
	    System.err.println(new Date() + " " + s);
	}
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy