
package org.mule.modules.salesforce.process;

import java.util.List;
import javax.annotation.Generated;
import org.mule.api.ConnectionManager;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.UnableToAcquireConnectionException;
import org.mule.api.UnableToReleaseConnectionException;
import org.mule.api.process.ProcessCallback;
import org.mule.api.process.ProcessInterceptor;
import org.mule.api.processor.MessageProcessor;
import org.mule.modules.salesforce.adapters.SalesforceModuleConnectionIdentifierAdapter;
import org.mule.modules.salesforce.connectivity.SalesforceModuleConnectionKey;
import org.mule.modules.salesforce.processors.AbstractConnectedProcessor;
import org.mule.modules.salesforce.processors.AbstractExpressionEvaluator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Generated(value = "Mule DevKit Version 3.4-SNAPSHOT", date = "2012-07-18T11:29:04-05:00", comments = "Build UNKNOWN_BUILDNUMBER")
public class ManagedConnectionProcessInterceptor<T >
    extends AbstractExpressionEvaluator
    implements ProcessInterceptor<T, SalesforceModuleConnectionIdentifierAdapter>
{

    private static Logger logger = LoggerFactory.getLogger(ManagedConnectionProcessInterceptor.class);
    private final ConnectionManager<SalesforceModuleConnectionKey, SalesforceModuleConnectionIdentifierAdapter> connectionManager;
    private final MuleContext muleContext;
    private final ProcessInterceptor<T, SalesforceModuleConnectionIdentifierAdapter> next;

    public ManagedConnectionProcessInterceptor(ProcessInterceptor<T, SalesforceModuleConnectionIdentifierAdapter> next, ConnectionManager<SalesforceModuleConnectionKey, SalesforceModuleConnectionIdentifierAdapter> connectionManager, MuleContext muleContext) {
        this.next = next;
        this.connectionManager = connectionManager;
        this.muleContext = muleContext;
    }

    public T execute(ProcessCallback<T, SalesforceModuleConnectionIdentifierAdapter> processCallback, SalesforceModuleConnectionIdentifierAdapter object, MessageProcessor messageProcessor, MuleEvent event)
        throws Exception
    {
        SalesforceModuleConnectionIdentifierAdapter connection = null;
        SalesforceModuleConnectionKey key = null;
        if ((messageProcessor!= null)&&((messageProcessor instanceof AbstractConnectedProcessor)&&(((AbstractConnectedProcessor) messageProcessor).getUsername()!= null))) {
            final String _transformedUsername = ((String) evaluateAndTransform(muleContext, event, AbstractConnectedProcessor.class.getDeclaredField("_usernameType").getGenericType(), null, ((AbstractConnectedProcessor) messageProcessor).getUsername()));
            final String _transformedPassword = ((String) evaluateAndTransform(muleContext, event, AbstractConnectedProcessor.class.getDeclaredField("_passwordType").getGenericType(), null, ((AbstractConnectedProcessor) messageProcessor).getPassword()));
            final String _transformedSecurityToken = ((String) evaluateAndTransform(muleContext, event, AbstractConnectedProcessor.class.getDeclaredField("_securityTokenType").getGenericType(), null, ((AbstractConnectedProcessor) messageProcessor).getSecurityToken()));
            key = new SalesforceModuleConnectionKey(_transformedUsername, _transformedPassword, _transformedSecurityToken);
        } else {
            key = connectionManager.getDefaultConnectionKey();
        }
        try {
            if (logger.isDebugEnabled()) {
                logger.debug(("Attempting to acquire connection using "+ key.toString()));
            }
            connection = connectionManager.acquireConnection(key);
            if (connection == null) {
                throw new UnableToAcquireConnectionException();
            } else {
                if (logger.isDebugEnabled()) {
                    logger.debug((("Connection has been acquired with [id="+ connection.getConnectionIdentifier())+"]"));
                }
            }
            return next.execute(processCallback, connection, messageProcessor, event);
        } catch (Exception e) {
            for (Class exceptionClass: ((List<Class> ) processCallback.getManagedExceptions())) {
                if (exceptionClass.isInstance(e)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug((((("An exception ( "+ exceptionClass.getName())+") has been thrown. Destroying the connection with [id=")+ connection.getConnectionIdentifier())+"]"));
                    }
                    try {
                        connectionManager.destroyConnection(key, connection);
                        connection = null;
                    } catch (Exception innerException) {
                        logger.error(innerException.getMessage(), innerException);
                    }
                }
            }
            throw e;
        } finally {
            try {
                if (connection!= null) {
                    if (logger.isDebugEnabled()) {
                        logger.debug((("Releasing the connection back into the pool [id="+ connection.getConnectionIdentifier())+"]"));
                    }
                }
                connectionManager.releaseConnection(key, connection);
            } catch (Exception e) {
                throw new UnableToReleaseConnectionException(e);
            }
        }
    }

}
