Package org.apache.ojb.otm.connector

Source Code of org.apache.ojb.otm.connector.OTMJCAManagedConnection

package org.apache.ojb.otm.connector;

/* Copyright 2003-2005 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.
*/

import org.apache.ojb.broker.PBKey;
import org.apache.ojb.otm.OTMConnection;
import org.apache.ojb.otm.core.Transaction;
import org.apache.ojb.otm.core.TransactionException;

import javax.resource.NotSupportedException;
import javax.resource.ResourceException;
import javax.resource.spi.ConnectionEvent;
import javax.resource.spi.ConnectionEventListener;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.LocalTransaction;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;
import javax.resource.spi.ManagedConnectionMetaData;
import javax.security.auth.Subject;
import javax.transaction.xa.XAResource;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
*
* @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird<a>
*/

public class OTMJCAManagedConnection implements ManagedConnection, LocalTransaction
{
    private PBKey m_pbKey;
    private OTMJCAManagedConnectionFactory m_managedConnectionFactory;
    private PrintWriter m_logWriter;
    private boolean m_destroyed;
    private final Set m_handles = new HashSet();
    private final Collection m_connectionEventListeners = new ArrayList();
    private boolean m_managed = false;
    /**
     * the wrapped connection
     */
    private OTMConnection m_connection;
    private Transaction m_tx;

    OTMJCAManagedConnection(ManagedConnectionFactory mcf, OTMConnection conn, PBKey pbKey)
    {
        Util.log("In OTMJCAManagedConnection");
        m_managedConnectionFactory = (OTMJCAManagedConnectionFactory) mcf;
        m_pbKey = pbKey;
        m_connection = conn;
    }

    /**
     * get the underlying wrapped connection
     * @return OTMConnection raw connection to the OTM.
     */
    OTMConnection getConnection()
    {
        if (m_connection == null)
        {
            OTMConnectionRuntimeException ex = new OTMConnectionRuntimeException("Connection is null.");
            sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
        }
        return m_connection;
    }

    public Transaction getTransaction()
    {
        return this.m_tx;
    }

    public void setTransaction(Transaction tx)
    {
        if (this.m_tx != null) throw new IllegalStateException("Connection already has Transaction");
        this.m_tx = tx;
    }

    public String getUserName()
    {
        return m_pbKey.getUser();
    }

    public Object getConnection(Subject subject, ConnectionRequestInfo connectionRequestInfo)
            throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.getConnection");
        OTMJCAConnection myCon = new OTMJCAConnection(this);
        synchronized (m_handles)
        {
            m_handles.add(myCon);
        }
        return myCon;
    }

    public void destroy()
    {
        Util.log("In OTMJCAManagedConnection.destroy");
        cleanup();
        m_connection.close();
        m_destroyed = true;
    }

    public void cleanup()
    {
        Util.log("In OTMJCAManagedConnection.cleanup");
        synchronized (m_handles)
        {
            for (Iterator i = m_handles.iterator(); i.hasNext();)
            {
                OTMJCAConnection lc = (OTMJCAConnection) i.next();
                lc.setManagedConnection(null);
            }
            m_handles.clear();
        }
    }

    void closeHandle(OTMJCAConnection handle)
    {
        synchronized (m_handles)
        {
            m_handles.remove(handle);
        }
        sendEvents(ConnectionEvent.CONNECTION_CLOSED, null, handle);
    }

    public void associateConnection(Object connection)
    {
        Util.log("In OTMJCAManagedConnection.associateConnection");
        if (connection == null)
        {
            throw new OTMConnectionRuntimeException("Cannot associate a null connection");
        }
        if (!(connection instanceof OTMJCAConnection))
        {
            throw new OTMConnectionRuntimeException("Cannot associate a connection of type: " + connection.getClass().getName() + " to a handle that manages: " + OTMJCAConnection.class.getName());
        }
        ((OTMJCAConnection) connection).setManagedConnection(this);
        synchronized (m_handles)
        {
            m_handles.add(connection);
        }
    }

    public void addConnectionEventListener(ConnectionEventListener cel)
    {
        synchronized (m_connectionEventListeners)
        {
            m_connectionEventListeners.add(cel);
        }
    }

    public void removeConnectionEventListener(ConnectionEventListener cel)
    {
        synchronized (m_connectionEventListeners)
        {
            m_connectionEventListeners.remove(cel);
        }
    }

    public XAResource getXAResource()
            throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.getXAResource");
        throw new NotSupportedException("public XAResource getXAResource() not supported in this release.");
    }

    /**
     * the OTMConnection is the transaction
     * @return
     */
    public LocalTransaction getLocalTransaction()
    {
        Util.log("In OTMJCAManagedConnection.getLocalTransaction");
        return this;
    }

    public ManagedConnectionMetaData getMetaData()
            throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.getMetaData");
        return new OTMConnectionMetaData(this);
    }

    public void setLogWriter(PrintWriter out)
            throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.setLogWriter");
        m_logWriter = out;
    }

    public PrintWriter getLogWriter()
            throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.getLogWriter");
        return m_logWriter;
    }

    boolean isDestroyed()
    {
        Util.log("In OTMJCAManagedConnection.isDestroyed");
        return m_destroyed;
    }

    ManagedConnectionFactory getManagedConnectionFactory()
    {
        Util.log("In OTMJCAManagedConnection.getManagedConnectionFactory");
        return m_managedConnectionFactory;
    }

    public void begin() throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.begin");
        if (!isManaged())
        {
            try
            {
                m_tx = m_managedConnectionFactory.getKit().getTransaction(m_connection);
                m_tx.begin();
                setManaged(true);
            }
            catch (TransactionException e)
            {
                ResourceException ex = new ResourceException(e.getMessage());
                sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
                throw ex;
            }
        }
        else
        {
            ResourceException ex = new ResourceException("You probably called begin again without calling Commit or Rollback, OTM does not support nested Local Transactions.");
            sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
            throw ex;
        }
    }

    public void commit() throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.commit");
        if (isManaged())
        {
            try
            {
                setManaged(false);
                m_tx.commit();
            }
            catch (TransactionException e)
            {
                m_tx.rollback();
                ResourceException ex = new ResourceException(e.getMessage());
                sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
                throw ex;
            }
        }
        else
        {
            ResourceException ex = new ResourceException("Cannot call commit when you are not in a Local Transaction.");
            sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
            throw ex;
        }
    }

    public void rollback() throws ResourceException
    {
        Util.log("In OTMJCAManagedConnection.rollback");
        if (isManaged())
        {
            try
            {
                m_tx.rollback();
                setManaged(false);
            }
            catch (TransactionException e)
            {
                ResourceException ex = new ResourceException(e.getMessage());
                sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
                throw ex;
            }
        }
        else
        {
            ResourceException ex = new ResourceException("Cannot call rollback when you are not in a Local Transaction.");
            sendEvents(ConnectionEvent.CONNECTION_ERROR_OCCURRED, ex, null);
            throw ex;
        }
    }

    private boolean isManaged()
    {
        return m_managed;
    }

    private void setManaged(boolean flag)
    {
        m_managed = flag;
    }

    /**
     * Section 6.5.6 of the JCA 1.5 spec instructs ManagedConnection instances to notify connection listeners with
     * close/error and local transaction-related events to its registered set of listeners.
     *
     * The events for begin/commit/rollback are only sent if the application server did NOT
     * initiate the actions.
     *
     * This method dispatchs all events to the listeners based on the eventType
     * @param eventType as enumerated in the ConnectionEvents interface
     * @param ex an optional exception if we are sending an error message
     * @param connectionHandle an optional connectionHandle if we have access to it.
     */
    void sendEvents(int eventType, Exception ex, Object connectionHandle)
    {
        ConnectionEvent ce = null;
        if (ex == null)
        {
            ce = new ConnectionEvent(this, eventType);
        }
        else
        {
            ce = new ConnectionEvent(this, eventType, ex);
        }
        ce.setConnectionHandle(connectionHandle);
        Collection copy = null;
        synchronized (m_connectionEventListeners)
        {
            copy = new ArrayList(m_connectionEventListeners);
        }
        switch (ce.getId())
        {
            case ConnectionEvent.CONNECTION_CLOSED:
                for (Iterator i = copy.iterator(); i.hasNext();)
                {
                    ConnectionEventListener cel = (ConnectionEventListener) i.next();
                    cel.connectionClosed(ce);
                }
                break;
            case ConnectionEvent.LOCAL_TRANSACTION_STARTED:
                for (Iterator i = copy.iterator(); i.hasNext();)
                {
                    ConnectionEventListener cel = (ConnectionEventListener) i.next();
                    cel.localTransactionStarted(ce);
                }
                break;
            case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED:
                for (Iterator i = copy.iterator(); i.hasNext();)
                {
                    ConnectionEventListener cel = (ConnectionEventListener) i.next();
                    cel.localTransactionCommitted(ce);
                }
                break;
            case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK:
                for (Iterator i = copy.iterator(); i.hasNext();)
                {
                    ConnectionEventListener cel = (ConnectionEventListener) i.next();
                    cel.localTransactionRolledback(ce);
                }
                break;
            case ConnectionEvent.CONNECTION_ERROR_OCCURRED:
                for (Iterator i = copy.iterator(); i.hasNext();)
                {
                    ConnectionEventListener cel = (ConnectionEventListener) i.next();
                    cel.connectionErrorOccurred(ce);
                }
                break;
            default:
                throw new IllegalArgumentException("Illegal eventType: " + ce.getId());
        }
    }
}
TOP

Related Classes of org.apache.ojb.otm.connector.OTMJCAManagedConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.