Coverage Report - org.mule.impl.DefaultLifecycleAdapter
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultLifecycleAdapter
51%
47/92
57%
23/40
3.231
 
 1  
 /*
 2  
  * $Id: DefaultLifecycleAdapter.java 10415 2008-01-21 10:46:37Z dirk.olmes $
 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.impl;
 12  
 
 13  
 import org.mule.MuleException;
 14  
 import org.mule.config.i18n.CoreMessages;
 15  
 import org.mule.impl.model.resolvers.DynamicEntryPoint;
 16  
 import org.mule.impl.model.resolvers.DynamicEntryPointResolver;
 17  
 import org.mule.routing.nested.NestedInvocationHandler;
 18  
 import org.mule.umo.ComponentException;
 19  
 import org.mule.umo.Invocation;
 20  
 import org.mule.umo.UMODescriptor;
 21  
 import org.mule.umo.UMOEvent;
 22  
 import org.mule.umo.UMOException;
 23  
 import org.mule.umo.UMOMessage;
 24  
 import org.mule.umo.lifecycle.Disposable;
 25  
 import org.mule.umo.lifecycle.Initialisable;
 26  
 import org.mule.umo.lifecycle.InitialisationException;
 27  
 import org.mule.umo.lifecycle.Startable;
 28  
 import org.mule.umo.lifecycle.Stoppable;
 29  
 import org.mule.umo.lifecycle.UMOLifecycleAdapter;
 30  
 import org.mule.umo.model.UMOEntryPointResolver;
 31  
 import org.mule.umo.routing.UMONestedRouter;
 32  
 import org.mule.util.ClassUtils;
 33  
 
 34  
 import java.lang.reflect.Method;
 35  
 import java.lang.reflect.Proxy;
 36  
 import java.util.HashMap;
 37  
 import java.util.Iterator;
 38  
 import java.util.List;
 39  
 import java.util.Map;
 40  
 
 41  
 import org.apache.commons.logging.Log;
 42  
 import org.apache.commons.logging.LogFactory;
 43  
 
 44  
 /**
 45  
  * <code>DefaultLifecycleAdapter</code> provides lifecycle methods for all Mule
 46  
  * managed components. It's possible to plugin custom lifecycle adapters, this can
 47  
  * provide additional lifecycle methods triggered by an external source.
 48  
  */
 49  
 public class DefaultLifecycleAdapter implements UMOLifecycleAdapter
 50  
 {
 51  
     /**
 52  
      * logger used by this class
 53  
      */
 54  12
     protected static final Log logger = LogFactory.getLog(DefaultLifecycleAdapter.class);
 55  
 
 56  
     private Object component;
 57  
     private UMODescriptor descriptor;
 58  80
     private boolean isStoppable = false;
 59  80
     private boolean isStartable = false;
 60  80
     private boolean isDisposable = false;
 61  
 
 62  80
     private boolean started = false;
 63  80
     private boolean disposed = false;
 64  
 
 65  
     private DynamicEntryPoint entryPoint;
 66  
 
 67  
     public DefaultLifecycleAdapter(Object component, UMODescriptor descriptor) throws UMOException
 68  
     {
 69  0
         this(component, descriptor, new DynamicEntryPointResolver());
 70  0
     }
 71  
 
 72  
     public DefaultLifecycleAdapter(Object component,
 73  
                                    UMODescriptor descriptor,
 74  
                                    UMOEntryPointResolver epResolver) throws UMOException
 75  80
     {
 76  80
         initialise(component, descriptor, epResolver);
 77  80
     }
 78  
 
 79  
     protected void initialise(Object component, UMODescriptor descriptor, UMOEntryPointResolver epDiscovery)
 80  
             throws UMOException
 81  
     {
 82  80
         if (component == null)
 83  
         {
 84  0
             throw new IllegalArgumentException("Component cannot be null");
 85  
         }
 86  80
         if (descriptor == null)
 87  
         {
 88  0
             throw new IllegalArgumentException("Descriptor cannot be null");
 89  
         }
 90  80
         if (epDiscovery == null)
 91  
         {
 92  0
             epDiscovery = new DynamicEntryPointResolver();
 93  
         }
 94  80
         this.component = component;
 95  80
         this.entryPoint = (DynamicEntryPoint) epDiscovery.resolveEntryPoint(descriptor);
 96  80
         this.descriptor = descriptor;
 97  
 
 98  80
         isStartable = Startable.class.isInstance(component);
 99  80
         isStoppable = Stoppable.class.isInstance(component);
 100  80
         isDisposable = Disposable.class.isInstance(component);
 101  
 
 102  80
         if (component instanceof UMODescriptorAware)
 103  
         {
 104  0
             ((UMODescriptorAware) component).setDescriptor(descriptor);
 105  
         }
 106  80
         configureNestedRouter();
 107  80
     }
 108  
 
 109  
     public void start() throws UMOException
 110  
     {
 111  28
         if (isStartable)
 112  
         {
 113  
             try
 114  
             {
 115  0
                 ((Startable) component).start();
 116  
             }
 117  0
             catch (Exception e)
 118  
             {
 119  0
                 throw new MuleException(
 120  
                     CoreMessages.failedToStart("UMO Component: " + descriptor.getName()), e);
 121  0
             }
 122  
         }
 123  28
         started = true;
 124  28
     }
 125  
 
 126  
     public void stop() throws UMOException
 127  
     {
 128  24
         if (isStoppable)
 129  
         {
 130  
             try
 131  
             {
 132  0
                 ((Stoppable) component).stop();
 133  
             }
 134  0
             catch (Exception e)
 135  
             {
 136  0
                 throw new MuleException(
 137  
                     CoreMessages.failedToStop("UMO Component: " + descriptor.getName()), e);
 138  0
             }
 139  
         }
 140  24
         started = false;
 141  24
     }
 142  
 
 143  
     public void dispose()
 144  
     {
 145  26
         if (isDisposable)
 146  
         {
 147  
             try
 148  
             {
 149  0
                 ((Disposable) component).dispose();
 150  
             }
 151  0
             catch (Exception e)
 152  
             {
 153  0
                 logger.error("failed to dispose: " + descriptor.getName(), e);
 154  0
             }
 155  
         }
 156  26
         disposed = true;
 157  26
     }
 158  
 
 159  
     /**
 160  
      * @return true if the component has been started
 161  
      */
 162  
     public boolean isStarted()
 163  
     {
 164  52
         return started;
 165  
     }
 166  
 
 167  
     /**
 168  
      * @return whether the component managed by this lifecycle has been disposed
 169  
      */
 170  
     public boolean isDisposed()
 171  
     {
 172  80
         return disposed;
 173  
     }
 174  
 
 175  
     public UMODescriptor getDescriptor()
 176  
     {
 177  0
         return descriptor;
 178  
     }
 179  
 
 180  
     public void handleException(Object message, Exception e)
 181  
     {
 182  0
         descriptor.getExceptionListener().exceptionThrown(e);
 183  0
     }
 184  
 
 185  
     public UMOMessage intercept(Invocation invocation) throws UMOException
 186  
     {
 187  
         // Invoke method
 188  
         Object result;
 189  6
         UMOEvent event = RequestContext.getEvent();   // new copy here?
 190  
 
 191  
         try
 192  
         {
 193  6
             result = entryPoint.invoke(component, RequestContext.getEventContext());
 194  
         }
 195  0
         catch (Exception e)
 196  
         {
 197  
             // should all Exceptions caught here be a ComponentException?!?
 198  
             // TODO MULE-863: See above
 199  0
             throw new ComponentException(
 200  
                 CoreMessages.failedToInvoke(component.getClass().getName()),
 201  
                 invocation.getMessage(), event.getComponent(), e);
 202  6
         }
 203  
 
 204  6
         UMOMessage resultMessage = null;
 205  6
         if (result instanceof VoidResult)
 206  
         {
 207  2
             resultMessage = new MuleMessage(event.getTransformedMessage(), 
 208  
                 RequestContext.getEventContext().getMessage());
 209  
         }
 210  4
         else if (result != null)
 211  
         {
 212  2
             if (result instanceof UMOMessage)
 213  
             {
 214  0
                 resultMessage = (UMOMessage) result;
 215  
             }
 216  
             else
 217  
             {
 218  2
                 resultMessage = new MuleMessage(result, event.getMessage());
 219  
             }
 220  
         }
 221  6
         return resultMessage;
 222  
     }
 223  
 
 224  
     public void initialise() throws InitialisationException
 225  
     {
 226  80
         if (Initialisable.class.isInstance(component))
 227  
         {
 228  16
             ((Initialisable) component).initialise();
 229  
         }
 230  70
     }
 231  
 
 232  
     protected void configureNestedRouter() throws UMOException
 233  
     {
 234  
         // Initialise the nested router and bind the endpoints to the methods using a Proxy
 235  80
         if (descriptor.getNestedRouter() != null)
 236  
         {
 237  0
             Map bindings = new HashMap();
 238  0
             for (Iterator it = descriptor.getNestedRouter().getRouters().iterator(); it.hasNext();)
 239  
             {
 240  0
                 UMONestedRouter nestedRouter = (UMONestedRouter) it.next();
 241  0
                 Object proxy = bindings.get(nestedRouter.getInterface());
 242  
 
 243  0
                 if (proxy == null)
 244  
                 {
 245  
                     // Create a proxy that implements this interface
 246  
                     // and just routes away using a mule client
 247  
                     // ( using the high level Mule client is probably
 248  
                     // a bit agricultural but this is just POC stuff )
 249  0
                     proxy = nestedRouter.createProxy(component);
 250  0
                     bindings.put(nestedRouter.getInterface(), proxy);
 251  
 
 252  
                     //Now lets set the proxy on the Service object
 253  
                     Method setterMethod;
 254  
 
 255  
 
 256  0
                     List methods = 
 257  
                         ClassUtils.getSatisfiableMethods(component.getClass(), 
 258  
                             new Class[]{nestedRouter.getInterface()}, true, false, null);
 259  0
                     if (methods.size() == 1)
 260  
                     {
 261  0
                         setterMethod = (Method) methods.get(0);
 262  
                     }
 263  0
                     else if (methods.size() > 1)
 264  
                     {
 265  0
                         throw new TooManySatisfiableMethodsException(
 266  
                                 component.getClass(), new Class[]{nestedRouter.getInterface()});
 267  
                     }
 268  
                     else
 269  
                     {
 270  0
                         throw new NoSatisfiableMethodsException(
 271  
                                 component.getClass(), nestedRouter.getInterface());
 272  
                     }
 273  
 
 274  
                     try
 275  
                     {
 276  0
                         setterMethod.invoke(component, new Object[]{proxy});
 277  
                     }
 278  0
                     catch (Exception e)
 279  
                     {
 280  0
                         throw new InitialisationException(
 281  
                             CoreMessages.failedToSetProxyOnService(nestedRouter, 
 282  
                                 component.getClass()), e, this);
 283  0
                     }
 284  0
                 }
 285  
                 else
 286  
                 {
 287  0
                     NestedInvocationHandler handler = (NestedInvocationHandler) Proxy.getInvocationHandler(proxy);
 288  0
                     handler.addRouterForInterface(nestedRouter);
 289  
                 }
 290  0
             }
 291  
         }
 292  80
     }
 293  
 }