Coverage Report - org.mule.transport.AbstractConnectable
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractConnectable
47%
43/92
38%
10/26
2.15
 
 1  
 /*
 2  
  * $Id: AbstractConnectable.java 11966 2008-06-05 20:27:51Z aguenther $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport;
 12  
 
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.MuleRuntimeException;
 15  
 import org.mule.api.context.WorkManager;
 16  
 import org.mule.api.endpoint.ImmutableEndpoint;
 17  
 import org.mule.api.transport.Connectable;
 18  
 import org.mule.api.transport.ConnectionStrategy;
 19  
 import org.mule.api.transport.Connector;
 20  
 import org.mule.config.i18n.CoreMessages;
 21  
 import org.mule.context.notification.ConnectionNotification;
 22  
 import org.mule.util.ClassUtils;
 23  
 
 24  
 import java.beans.ExceptionListener;
 25  
 
 26  
 import org.apache.commons.logging.Log;
 27  
 import org.apache.commons.logging.LogFactory;
 28  
 
 29  
 /**
 30  
  * Provide a default dispatch (client) support for handling threads lifecycle and validation.
 31  
  */
 32  
 public abstract class AbstractConnectable implements Connectable, ExceptionListener
 33  
 {
 34  
 
 35  
     /**
 36  
      * logger used by this class
 37  
      */
 38  2
     protected transient Log logger = LogFactory.getLog(getClass());
 39  
 
 40  
     protected final ImmutableEndpoint endpoint;
 41  
     protected final AbstractConnector connector;
 42  
 
 43  2
     protected boolean disposed = false;
 44  
 
 45  
     protected ConnectionStrategy connectionStrategy;
 46  
 
 47  2
     protected volatile boolean connecting = false;
 48  2
     protected volatile boolean connected = false;
 49  
 
 50  
     public AbstractConnectable(ImmutableEndpoint endpoint)
 51  2
     {
 52  2
         this.endpoint = endpoint;
 53  2
         this.connector = (AbstractConnector) endpoint.getConnector();
 54  
 
 55  2
         connectionStrategy = endpoint.getConnectionStrategy();
 56  2
         if (connectionStrategy instanceof AbstractConnectionStrategy)
 57  
         {
 58  
             // We don't want to do threading in the dispatcher because we're either
 59  
             // already running in a worker thread (asynchronous) or we need to
 60  
             // complete the operation in a single thread
 61  2
             final AbstractConnectionStrategy connStrategy = (AbstractConnectionStrategy) connectionStrategy;
 62  2
             if (connStrategy.isDoThreading())
 63  
             {
 64  0
                 if (logger.isDebugEnabled())
 65  
                 {
 66  0
                     logger.debug("Overriding doThreading to false on " + connStrategy);
 67  
                 }
 68  0
                 connStrategy.setDoThreading(false);
 69  
             }
 70  
         }
 71  
 
 72  2
         if (isDoThreading())
 73  
         {
 74  
             try
 75  
             {
 76  2
                 connector.getDispatcherWorkManager();
 77  
             }
 78  0
             catch (MuleException e)
 79  
             {
 80  0
                 disposeAndLogException();
 81  0
                 throw new MuleRuntimeException(CoreMessages.failedToStart("WorkManager"), e);
 82  2
             }
 83  
         }
 84  2
     }
 85  
 
 86  
     protected void disposeAndLogException()
 87  
     {
 88  
         try
 89  
         {
 90  0
             dispose();
 91  
         }
 92  0
         catch (Throwable t)
 93  
         {
 94  0
             logger.error("Could not dispose of the message dispatcher!", t);
 95  0
         }
 96  0
     }
 97  
 
 98  
     /*
 99  
      * (non-Javadoc)
 100  
      *
 101  
      * @see org.mule.util.ExceptionListener#onException(java.lang.Throwable)
 102  
      */
 103  
     public void exceptionThrown(Exception e)
 104  
     {
 105  
         try
 106  
         {
 107  0
             getConnector().handleException(e);
 108  
         }
 109  
         finally
 110  
         {
 111  0
             dispose();
 112  0
         }
 113  0
     }
 114  
 
 115  
     public boolean validate()
 116  
     {
 117  
         // by default a dispatcher/requester can be used unless disposed
 118  8
         return !disposed;
 119  
     }
 120  
 
 121  
     public void activate()
 122  
     {
 123  
         // nothing to do by default
 124  8
     }
 125  
 
 126  
     public void passivate()
 127  
     {
 128  
         // nothing to do by default
 129  8
     }
 130  
 
 131  
     /**
 132  
      * Template method to destroy any resources held by the Message Dispatcher
 133  
      */
 134  
     public final synchronized void dispose()
 135  
     {
 136  0
         if (!disposed)
 137  
         {
 138  
             try
 139  
             {
 140  
                 try
 141  
                 {
 142  0
                     this.disconnect();
 143  
                 }
 144  0
                 catch (Exception e)
 145  
                 {
 146  
                     // TODO MULE-863: What should we really do?
 147  0
                     logger.warn(e.getMessage(), e);
 148  0
                 }
 149  
 
 150  0
                 this.doDispose();
 151  
             }
 152  
             finally
 153  
             {
 154  0
                 disposed = true;
 155  0
             }
 156  
         }
 157  0
     }
 158  
 
 159  
     public Connector getConnector()
 160  
     {
 161  0
         return connector;
 162  
     }
 163  
 
 164  
     public ImmutableEndpoint getEndpoint()
 165  
     {
 166  0
         return endpoint;
 167  
     }
 168  
 
 169  
     public synchronized void connect() throws Exception
 170  
     {
 171  10
         if (disposed)
 172  
         {
 173  0
             throw new IllegalStateException("Requester/dispatcher has been disposed; cannot connect to resource");
 174  
         }
 175  
 
 176  10
         if (connected)
 177  
         {
 178  6
             return;
 179  
         }
 180  
 
 181  4
         if (!connecting)
 182  
         {
 183  2
             connecting = true;
 184  
 
 185  2
             if (logger.isDebugEnabled())
 186  
             {
 187  0
                 logger.debug("Connecting: " + this);
 188  
             }
 189  
 
 190  2
             connectionStrategy.connect(this);
 191  
 
 192  2
             logger.info("Connected: " + this);
 193  2
             return;
 194  
         }
 195  
 
 196  
         try
 197  
         {
 198  
             //Make sure the connector has connected. If it is connected, this method does nothing
 199  2
             connectionStrategy.connect(connector);
 200  
 
 201  2
             this.doConnect();
 202  2
             connected = true;
 203  2
             connecting = false;
 204  
 
 205  2
             connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
 206  
                 ConnectionNotification.CONNECTION_CONNECTED));
 207  
         }
 208  0
         catch (Exception e)
 209  
         {
 210  0
             connected = false;
 211  0
             connecting = false;
 212  
 
 213  0
             connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
 214  
                 ConnectionNotification.CONNECTION_FAILED));
 215  
 
 216  0
             if (e instanceof ConnectException)
 217  
             {
 218  0
                 throw (ConnectException) e;
 219  
             }
 220  
             else
 221  
             {
 222  0
                 throw new ConnectException(e, this);
 223  
             }
 224  2
         }
 225  2
     }
 226  
 
 227  
     public synchronized void disconnect() throws Exception
 228  
     {
 229  0
         if (!connected)
 230  
         {
 231  0
             return;
 232  
         }
 233  
 
 234  0
         if (logger.isDebugEnabled())
 235  
         {
 236  0
             logger.debug("Disconnecting: " + this);
 237  
         }
 238  
 
 239  0
         this.doDisconnect();
 240  0
         connected = false;
 241  
 
 242  0
         logger.info("Disconnected: " + this);
 243  
 
 244  0
         connector.fireNotification(new ConnectionNotification(this, getConnectEventId(endpoint),
 245  
             ConnectionNotification.CONNECTION_DISCONNECTED));
 246  0
     }
 247  
 
 248  
     protected String getConnectEventId(ImmutableEndpoint endpoint)
 249  
     {
 250  2
         return connector.getName() + ".dispatcher(" + endpoint.getEndpointURI().getUri() + ")";
 251  
     }
 252  
 
 253  
     public final boolean isConnected()
 254  
     {
 255  0
         return connected;
 256  
     }
 257  
 
 258  
     protected boolean isDoThreading ()
 259  
     {
 260  2
         return connector.getDispatcherThreadingProfile().isDoThreading();
 261  
     }
 262  
 
 263  
     /**
 264  
      * Returns a string identifying the underlying resource
 265  
      *
 266  
      * @return
 267  
      */
 268  
     public String getConnectionDescription()
 269  
     {
 270  0
         return endpoint.getEndpointURI().toString();
 271  
     }
 272  
 
 273  
     public synchronized void reconnect() throws Exception
 274  
     {
 275  0
         disconnect();
 276  0
         connect();
 277  0
     }
 278  
 
 279  
     protected abstract void doDispose();
 280  
 
 281  
     protected abstract void doConnect() throws Exception;
 282  
 
 283  
     protected abstract void doDisconnect() throws Exception;
 284  
 
 285  
     //  @Override
 286  
     public String toString()
 287  
     {
 288  4
         final StringBuffer sb = new StringBuffer(80);
 289  4
         sb.append(ClassUtils.getSimpleName(this.getClass()));
 290  4
         sb.append("{this=").append(Integer.toHexString(System.identityHashCode(this)));
 291  4
         sb.append(", endpoint=").append(endpoint.getEndpointURI().getUri());
 292  4
         sb.append(", disposed=").append(disposed);
 293  4
         sb.append('}');
 294  4
         return sb.toString();
 295  
     }
 296  
 }