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

com.sun.gjc.spi.base.AbstractDataSource Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
// Portions Copyright [2018-2021] Payara Foundation and/or affiliates

package com.sun.gjc.spi.base;

import com.sun.appserv.connectors.internal.spi.BadConnectionEventListener;
import com.sun.gjc.spi.ConnectionManagerImplementation;
import com.sun.gjc.spi.ConnectionRequestInfoImpl;
import com.sun.gjc.spi.ManagedConnectionFactoryImpl;
import com.sun.logging.LogDomains;
import com.sun.appserv.connectors.internal.api.ConnectorConstants;
import com.sun.gjc.util.MethodExecutor;

import javax.naming.Reference;
import jakarta.resource.ResourceException;
import jakarta.resource.spi.ConnectionManager;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Holds the java.sql.Connection object, which is to be
 * passed to the application program.
 *
 * @author Binod P.G
 * @version 1.0, 02/07/31
 */
public abstract class AbstractDataSource implements javax.sql.DataSource, java.io.Serializable,
        com.sun.appserv.jdbc.DataSource, jakarta.resource.Referenceable {

    protected ManagedConnectionFactoryImpl mcf;
    protected MethodExecutor executor = null;
    private ConnectionManager cm;
    private int loginTimeout;
    private PrintWriter logWriter;
    private String description;
    private Reference reference;

    private ConnectionHolder.ConnectionType conType_;

    protected static final Logger _logger = LogDomains.getLogger(ManagedConnectionFactoryImpl.class, LogDomains.RSR_LOGGER);

    /**
     * Constructs DataSource object. This is created by the
     * ManagedConnectionFactory object.
     *
     * @param mcf ManagedConnectionFactory object
     *            creating this object.
     * @param cm  ConnectionManager object either associated
     *            with Application server or Resource Adapter.
     */
    public AbstractDataSource(ManagedConnectionFactoryImpl mcf, ConnectionManager cm) {
        this.mcf = mcf;
        executor = new MethodExecutor();
        if (cm == null) {
            this.cm = new ConnectionManagerImplementation();
        } else {
            this.cm = cm;
            conType_ = findConnectionType();
        }
    }

    /**
     * Retrieves the  Connection  object.
     *
     * @return  Connection  object.
     * @throws SQLException In case of an error.
     */
    @Override
    public Connection getConnection() throws SQLException {
        try {
            ConnectionHolder con = (ConnectionHolder)
                    cm.allocateConnection(mcf, null);
            setConnectionType(con);

            return con;
        } catch (ResourceException re) {
            logNonTransientException(re);
            throw new SQLException(re.getMessage(), re);
        }
    }

    /**
     * log the exception if it is a non-transient exception 
* @param re Exception to log */ private void logNonTransientException(ResourceException re) { if(!BadConnectionEventListener.POOL_RECONFIGURED_ERROR_CODE.equals(re.getErrorCode())){ _logger.log(Level.WARNING, "jdbc.exc_get_conn", re.getMessage()); } } /** * Retrieves the Connection object. * * @param user User name for the Connection. * @param pwd Password for the Connection. * @return Connection object. * @throws SQLException In case of an error. */ @Override public Connection getConnection(String user, String pwd) throws SQLException { try { ConnectionRequestInfoImpl info = new ConnectionRequestInfoImpl(user, pwd.toCharArray()); ConnectionHolder con = (ConnectionHolder) cm.allocateConnection(mcf, info); setConnectionType(con); return con; } catch (ResourceException re) { logNonTransientException(re); throw new SQLException(re.getMessage(), re); } } /** * Retrieves the actual SQLConnection from the Connection wrapper * implementation of SunONE application server. If an actual connection is * supplied as argument, then it will be just returned. * * @param con Connection obtained from Datasource.getConnection() * @return java.sql.Connection implementation of the driver. * @throws java.sql.SQLException if connection cannot be obtained. */ @Override public Connection getConnection(Connection con) throws SQLException { Connection driverCon = con; if (con instanceof com.sun.gjc.spi.base.ConnectionHolder) { driverCon = ((com.sun.gjc.spi.base.ConnectionHolder) con).getConnection(); } return driverCon; } /** * Gets a connection that is not in the scope of any transaction. This * can be used to save performance overhead incurred on enlisting/delisting * each connection got, irrespective of whether its required or not. * Note here that this meethod does not fit in the connector contract * per se. * * @return java.sql.Connection * @throws java.sql.SQLException if connection cannot be obtained */ @Override public Connection getNonTxConnection() throws SQLException { try { ConnectionHolder con = (ConnectionHolder) ((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm).allocateNonTxConnection(mcf, null); setConnectionType(con, true); return con; } catch (ResourceException re) { logNonTransientException(re); throw new SQLException(re.getMessage(), re); } } /** * Gets a connection that is not in the scope of any transaction. This * can be used to save performance overhead incurred on enlisting/delisting * each connection got, irrespective of whether its required or not. * Note here that this meethod does not fit in the connector contract * per se. * * @param user User name for authenticating the connection * @param password Password for authenticating the connection * @return java.sql.Connection * @throws java.sql.SQLException if connection cannot be obtained */ @Override public Connection getNonTxConnection(String user, String password) throws SQLException { try { ConnectionRequestInfoImpl cxReqInfo = new ConnectionRequestInfoImpl(user, password.toCharArray()); ConnectionHolder con = (ConnectionHolder) ((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm).allocateNonTxConnection(mcf, cxReqInfo); setConnectionType(con, true); return con; } catch (ResourceException re) { logNonTransientException(re); throw new SQLException(re.getMessage(), re); } } /** * Get the login timeout * * @return login timeout. * @throws SQLException If a database error occurs. */ @Override public int getLoginTimeout() throws SQLException { return loginTimeout; } /** * Set the login timeout * * @param loginTimeout Login timeout. * @throws SQLException If a database error occurs. */ @Override public void setLoginTimeout(int loginTimeout) throws SQLException { this.loginTimeout = loginTimeout; } /** * Get the logwriter object. * * @return PrintWriter object. * @throws SQLException If a database error occurs. */ @Override public PrintWriter getLogWriter() throws SQLException { return logWriter; } /** * Set the logwriter on this object. * * @param logWriter object. * @throws SQLException If a database error occurs. */ @Override public void setLogWriter(PrintWriter logWriter) throws SQLException { this.logWriter = logWriter; } /** * Retrieves the description. * * @return Description about the DataSource. */ public String getDescription() { return description; } /** * Set the description. * * @param description Description about the DataSource. */ public void setDescription(String description) { this.description = description; } /** * Get the reference. * * @return Referenceobject. */ public Reference getReference() { return reference; } /** * Get the reference. * * @param reference Reference object. */ public void setReference(Reference reference) { this.reference = reference; } private ConnectionHolder.ConnectionType findConnectionType() { ConnectionHolder.ConnectionType cmType = ConnectionHolder.ConnectionType.STANDARD; if (cm instanceof jakarta.resource.spi.LazyAssociatableConnectionManager) { if (!((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm). getJndiName().endsWith(ConnectorConstants.PM_JNDI_SUFFIX)) { cmType = ConnectionHolder.ConnectionType.LAZY_ASSOCIATABLE; } } else if (cm instanceof jakarta.resource.spi.LazyEnlistableConnectionManager) { if (!((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm). getJndiName().endsWith(ConnectorConstants.PM_JNDI_SUFFIX) && !((com.sun.appserv.connectors.internal.spi.ConnectionManager) cm). getJndiName().endsWith(ConnectorConstants.NON_TX_JNDI_SUFFIX)) { cmType = ConnectionHolder.ConnectionType.LAZY_ENLISTABLE; } } return cmType; } private void setConnectionType(ConnectionHolder con) { this.setConnectionType(con, false); } private void setConnectionType(ConnectionHolder con, boolean isNonTx) { con.setConnectionType(conType_); if (conType_ == ConnectionHolder.ConnectionType.LAZY_ASSOCIATABLE) { con.setLazyAssociatableConnectionManager( (jakarta.resource.spi.LazyAssociatableConnectionManager) cm); } else if (conType_ == ConnectionHolder.ConnectionType.LAZY_ENLISTABLE) { if (isNonTx) { //if this is a getNonTxConnection call on the DataSource, we //should not LazyEnlist con.setConnectionType(ConnectionHolder.ConnectionType.STANDARD); } else { con.setLazyEnlistableConnectionManager( (jakarta.resource.spi.LazyEnlistableConnectionManager) cm); } } } /** * API to mark a connection as bad. If the application can determine that the connection * is bad, using this api, it can notify the resource-adapter which inturn will notify the * connection-pool. Connection-pool will drop and create a new connection. * eg: *
        com.sun.appserv.jdbc.DataSource ds=
           (com.sun.appserv.jdbc.DataSource)context.lookup("dataSource");
                Connection con = ds.getConnection();
                Statement stmt = null;
                try{
                         stmt = con.createStatement();
                         stmt.executeUpdate("Update");
                }catch(BadConnectionException e){
                        dataSource.markConnectionAsBad(con) //marking it as bad for removal
                }finally{
                        stmt.close();
                        con.close(); //Connection will be destroyed while close or Tx completion
            }
     * 
* * @param conn java.sql.Connection */ @Override public void markConnectionAsBad(Connection conn) { if (conn instanceof ConnectionHolder) { ConnectionHolder userConn = ((ConnectionHolder) conn); userConn.getManagedConnection().markForRemoval(true); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy