Coverage Report - org.mule.model.resolvers.MethodHeaderPropertyEntryPointResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
MethodHeaderPropertyEntryPointResolver
78%
40/51
39%
7/18
4.2
 
 1  
 /*
 2  
  * $Id: MethodHeaderPropertyEntryPointResolver.java 10489 2008-01-23 17:53:38Z 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  
 package org.mule.model.resolvers;
 11  
 
 12  
 import org.mule.api.MuleEventContext;
 13  
 import org.mule.api.config.MuleProperties;
 14  
 import org.mule.api.lifecycle.Callable;
 15  
 import org.mule.api.model.InvocationResult;
 16  
 import org.mule.config.i18n.CoreMessages;
 17  
 import org.mule.util.ClassUtils;
 18  
 
 19  
 import java.lang.reflect.Method;
 20  
 
 21  
 import org.apache.commons.lang.BooleanUtils;
 22  
 
 23  
 /**
 24  
  * This resolver will look for a 'method' property on the incoming event to determine which method to invoke
 25  
  * Users can customise the name of the property used to look up the method name on the event
 26  
  */
 27  80
 public class MethodHeaderPropertyEntryPointResolver extends AbstractEntryPointResolver
 28  
 {
 29  
 
 30  80
     private String methodProperty = MuleProperties.MULE_METHOD_PROPERTY;
 31  
 
 32  
     public String getMethodProperty()
 33  
     {
 34  54
         return methodProperty;
 35  
     }
 36  
 
 37  
     public void setMethodProperty(String methodProperty)
 38  
     {
 39  6
         this.methodProperty = methodProperty;
 40  6
     }
 41  
 
 42  
     public InvocationResult invoke(Object component, MuleEventContext context) throws Exception
 43  
     {
 44  
         //TODO: RM* This is a hack that can be fixed by introducing property scoping on the message
 45  
         // Transports such as SOAP need to ignore the method property
 46  36
         boolean ignoreMethod = BooleanUtils.toBoolean((Boolean) context.getMessage().removeProperty(
 47  
                 MuleProperties.MULE_IGNORE_METHOD_PROPERTY));
 48  
 
 49  36
         if (ignoreMethod)
 50  
         {
 51  
             //TODO: Removed once we have property scoping
 52  0
             InvocationResult result = new InvocationResult(InvocationResult.STATE_INVOKE_NOT_SUPPORTED);
 53  0
             result.setErrorMessage("Property: " + MuleProperties.MULE_IGNORE_METHOD_PROPERTY + " was set so skipping this resolver: " + this);
 54  0
             return result;
 55  
         }
 56  
 
 57  
         //TODO: with scoped properties we wouldn't need to remove the property here
 58  36
         Object methodProp = context.getMessage().removeProperty(getMethodProperty());
 59  36
         if (methodProp == null)
 60  
         {
 61  18
             InvocationResult result = new InvocationResult(InvocationResult.STATE_INVOKED_FAILED);
 62  
             // no method for the explicit method header
 63  18
             result.setErrorMessage(CoreMessages.propertyIsNotSetOnEvent(getMethodProperty()).toString());
 64  18
             return result;
 65  
         }
 66  
 
 67  
         Method method;
 68  
         String methodName;
 69  18
         if (methodProp instanceof Method)
 70  
         {
 71  0
             method = (Method) methodProp;
 72  0
             methodName = method.getName();
 73  
         }
 74  
         else
 75  
         {
 76  18
             methodName = methodProp.toString();
 77  18
             method = getMethodByName(methodName, context);
 78  
         }
 79  
 
 80  18
         if (method != null && method.getParameterTypes().length == 0)
 81  
         {
 82  0
             return invokeMethod(component, method, ClassUtils.NO_ARGS_TYPE);
 83  
         }
 84  
 
 85  18
         Object[] payload = getPayloadFromMessage(context);
 86  
 
 87  18
         if (method == null)
 88  
         {
 89  18
             Class[] classTypes = ClassUtils.getClassTypes(payload);
 90  
             try
 91  
             {
 92  18
                 method = component.getClass().getMethod(methodName, classTypes);
 93  
             }
 94  12
             catch (NoSuchMethodException e)
 95  
             {
 96  12
                 InvocationResult result = new InvocationResult(InvocationResult.STATE_INVOKED_FAILED);
 97  12
                 result.setErrorNoMatchingMethods(component, classTypes, this);
 98  12
                 return result;
 99  
 
 100  6
             }
 101  
         }
 102  
 
 103  6
         validateMethod(component, method);
 104  6
         addMethodByName(method, context);
 105  
 
 106  6
         return invokeMethod(component, method, payload);
 107  
 
 108  
     }
 109  
 
 110  
     /**
 111  
      * This method can be used to validate that the method exists and is allowed to
 112  
      * be executed.
 113  
      */
 114  
     protected void validateMethod(Object component, Method method)
 115  
             throws NoSuchMethodException
 116  
     {
 117  6
         boolean fallback = component instanceof Callable;
 118  
 
 119  6
         if (method != null)
 120  
         {
 121  
             // This will throw NoSuchMethodException if it doesn't exist
 122  
             try
 123  
             {
 124  6
                 component.getClass().getMethod(method.getName(), method.getParameterTypes());
 125  
             }
 126  0
             catch (NoSuchMethodException e)
 127  
             {
 128  0
                 if (!fallback)
 129  
                 {
 130  0
                     throw e;
 131  
                 }
 132  6
             }
 133  
         }
 134  
         else
 135  
         {
 136  0
             if (!fallback)
 137  
             {
 138  0
                 throw new NoSuchMethodException(
 139  
                         CoreMessages.methodWithParamsNotFoundOnObject("null", "unknown",
 140  
                                 component.getClass()).toString());
 141  
             }
 142  
         }
 143  6
     }
 144  
 
 145  
     public String toString()
 146  
     {
 147  12
         final StringBuffer sb = new StringBuffer();
 148  12
         sb.append("MethodHeaderPropertyEntryPointResolver");
 149  12
         sb.append("{methodHeader=").append(methodProperty);
 150  12
         sb.append("transformFirst=").append(isTransformFirst());
 151  12
         sb.append(", acceptVoidMethods=").append(isAcceptVoidMethods());
 152  12
         sb.append('}');
 153  12
         return sb.toString();
 154  
     }
 155  
 
 156  
 }