Coverage Report - org.mule.component.AbstractComponent
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractComponent
59%
50/85
36%
13/36
2.444
 
 1  
 /*
 2  
  * $Id: AbstractComponent.java 12247 2008-07-07 21:25:01Z dfeist $
 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.component;
 12  
 
 13  
 import org.mule.OptimizedRequestContext;
 14  
 import org.mule.api.DefaultMuleException;
 15  
 import org.mule.api.MuleEvent;
 16  
 import org.mule.api.MuleException;
 17  
 import org.mule.api.MuleMessage;
 18  
 import org.mule.api.component.Component;
 19  
 import org.mule.api.context.notification.ServerNotificationHandler;
 20  
 import org.mule.api.endpoint.InboundEndpoint;
 21  
 import org.mule.api.lifecycle.DisposeException;
 22  
 import org.mule.api.lifecycle.InitialisationException;
 23  
 import org.mule.api.service.Service;
 24  
 import org.mule.api.service.ServiceException;
 25  
 import org.mule.config.i18n.CoreMessages;
 26  
 import org.mule.config.i18n.MessageFactory;
 27  
 import org.mule.context.notification.ComponentMessageNotification;
 28  
 import org.mule.context.notification.OptimisedNotificationHandler;
 29  
 import org.mule.management.stats.ComponentStatistics;
 30  
 
 31  
 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
 32  
 
 33  
 import org.apache.commons.logging.Log;
 34  
 import org.apache.commons.logging.LogFactory;
 35  
 
 36  
 /**
 37  
  * Abstract {@link Component} to be used by all {@link Component} implementations.
 38  
  */
 39  
 public abstract class AbstractComponent implements Component
 40  
 {
 41  
 
 42  
     /**
 43  
      * logger used by this class
 44  
      */
 45  852
     protected final Log logger = LogFactory.getLog(this.getClass());
 46  
 
 47  
     protected Service service;
 48  852
     protected ComponentStatistics statistics = null;
 49  852
     protected final AtomicBoolean started = new AtomicBoolean(false);
 50  852
     protected final AtomicBoolean stopping = new AtomicBoolean(false);
 51  852
     protected final AtomicBoolean initialised = new AtomicBoolean(false);
 52  852
     protected final AtomicBoolean disposing = new AtomicBoolean(false);
 53  852
     protected final AtomicBoolean disposed = new AtomicBoolean(false);
 54  
     protected ServerNotificationHandler notificationHandler;
 55  
 
 56  
     public AbstractComponent()
 57  852
     {
 58  852
         statistics = new ComponentStatistics();
 59  852
     }
 60  
 
 61  
     public MuleMessage onCall(MuleEvent event) throws MuleException
 62  
     {
 63  
         // Ensure we have event in ThreadLocal
 64  0
         OptimizedRequestContext.unsafeSetEvent(event);
 65  
 
 66  0
         if (logger.isTraceEnabled())
 67  
         {
 68  0
             logger.trace("Invoking " + this.getClass().getName() + "component for service " + service.getName());
 69  
         }
 70  
 
 71  
         // Do some checks: i) check component is not disposed, ii) that it is started
 72  
         // and iii) that the event's endpoint is an inbound endpoint.
 73  0
         checkDisposed();
 74  0
         if (!(event.getEndpoint() instanceof InboundEndpoint))
 75  
         {
 76  0
             throw new IllegalStateException(
 77  
                     "Unable to process outbound event, components only process incoming events.");
 78  
         }
 79  0
         if (stopping.get() || !started.get())
 80  
         {
 81  0
             throw new DefaultMuleException(CoreMessages.componentIsStopped(service.getName()));
 82  
         }
 83  
 
 84  
         // Invoke component implementation and gather statistics
 85  
         try
 86  
         {
 87  
 
 88  0
             fireComponentNotification(event.getMessage(), ComponentMessageNotification.COMPONENT_PRE_INVOKE);
 89  
 
 90  0
             long startTime = 0;
 91  0
             if (statistics.isEnabled())
 92  
             {
 93  0
                 startTime = System.currentTimeMillis();
 94  
             }
 95  
 
 96  0
             MuleMessage result = doOnCall(event);
 97  
 
 98  0
             if (statistics.isEnabled())
 99  
             {
 100  0
                 statistics.addExecutionTime(System.currentTimeMillis() - startTime);
 101  
             }
 102  
 
 103  0
             fireComponentNotification(result, ComponentMessageNotification.COMPONENT_POST_INVOKE);
 104  
 
 105  0
             return result;
 106  
         }
 107  0
         catch (MuleException me)
 108  
         {
 109  0
             throw me;
 110  
         }
 111  0
         catch (Exception e)
 112  
         {
 113  0
             throw new ServiceException(CoreMessages.failedToInvoke(this.toString()), event.getMessage(), service, e);
 114  
         }
 115  
     }
 116  
 
 117  
     protected abstract MuleMessage doOnCall(MuleEvent event) throws Exception;
 118  
 
 119  
     public String toString()
 120  
     {
 121  0
         return this.getClass().getName() + " component for: " + service.toString();
 122  
     }
 123  
 
 124  
     public void release()
 125  
     {
 126  
         // nothing to do
 127  0
     }
 128  
 
 129  
     public ComponentStatistics getStatistics()
 130  
     {
 131  398
         return statistics;
 132  
     }
 133  
 
 134  
     public void setService(Service service)
 135  
     {
 136  824
         this.service = service;
 137  824
     }
 138  
 
 139  
     public Service getService()
 140  
     {
 141  0
         return service;
 142  
     }
 143  
 
 144  
     public final void initialise() throws InitialisationException
 145  
     {
 146  426
         if (!initialised.get())
 147  
         {
 148  426
             if (logger.isInfoEnabled())
 149  
             {
 150  0
                 logger.info("Initialising: " + this);
 151  
             }
 152  426
             if (service == null)
 153  
             {
 154  0
                 throw new InitialisationException(
 155  
                         MessageFactory.createStaticMessage("Component has not been initialized properly, no service."),
 156  
                         this);
 157  
             }
 158  426
             doInitialise();
 159  426
             initialised.set(true);
 160  
         }
 161  426
     }
 162  
 
 163  
     protected void doInitialise() throws InitialisationException
 164  
     {
 165  
         // Default implementation is no-op
 166  4
     }
 167  
 
 168  
     public void dispose()
 169  
     {
 170  20
         disposing.set(true);
 171  
         try
 172  
         {
 173  20
             if (started.get())
 174  
             {
 175  4
                 stop();
 176  
             }
 177  
         }
 178  0
         catch (MuleException e)
 179  
         {
 180  0
             logger.error(CoreMessages.failedToStop(toString()));
 181  20
         }
 182  
         try
 183  
         {
 184  20
             doDispose();
 185  
         }
 186  0
         catch (Exception e)
 187  
         {
 188  0
             logger.warn(CoreMessages.failedToDispose(toString()), e);
 189  
         }
 190  
         finally
 191  
         {
 192  20
             disposed.set(true);
 193  20
             disposing.set(false);
 194  20
             initialised.set(false);
 195  20
         }
 196  20
     }
 197  
 
 198  
     protected void doDispose()
 199  
     {
 200  
         // Default implementation is no-op
 201  2
     }
 202  
 
 203  
     public void stop() throws MuleException
 204  
     {
 205  
         // If component is already disposed then ignore, don't fails, as stop() might
 206  
         // get called by service after spring has called disposed etc.
 207  34
         if (!disposed.get() && started.get() && !stopping.get())
 208  
         {
 209  34
             stopping.set(true);
 210  34
             if (logger.isInfoEnabled())
 211  
             {
 212  0
                 logger.info("Stopping: " + this);
 213  
             }
 214  34
             doStop();
 215  34
             started.set(false);
 216  34
             stopping.set(false);
 217  
         }
 218  34
     }
 219  
 
 220  
     protected void doStart() throws MuleException
 221  
     {
 222  
         // Default implementation is no-op
 223  4
     }
 224  
 
 225  
     public void start() throws MuleException
 226  
     {
 227  54
         checkDisposed();
 228  54
         if (!started.get())
 229  
         {
 230  54
             if (logger.isInfoEnabled())
 231  
             {
 232  0
                 logger.info("Starting: " + this);
 233  
             }
 234  54
             notificationHandler = new OptimisedNotificationHandler(service.getMuleContext()
 235  
                 .getNotificationManager(), ComponentMessageNotification.class);
 236  54
             doStart();
 237  54
             started.set(true);
 238  
         }
 239  54
     }
 240  
 
 241  
     protected void doStop() throws MuleException
 242  
     {
 243  
         // Default implementation is no-op
 244  34
     }
 245  
 
 246  
     protected void checkDisposed() throws DisposeException
 247  
     {
 248  56
         if (disposed.get())
 249  
         {
 250  2
             throw new DisposeException(CoreMessages.createStaticMessage("Cannot use a disposed component"), this);
 251  
         }
 252  54
     }
 253  
 
 254  
     protected void fireComponentNotification(MuleMessage message, int action)
 255  
     {
 256  0
         if (notificationHandler.isNotificationEnabled(ComponentMessageNotification.class))
 257  
         {
 258  0
             notificationHandler.fireNotification(new ComponentMessageNotification(message, this, action));
 259  
         }
 260  0
     }
 261  
 
 262  
 }