Coverage Report - org.mule.model.resolvers.MethodHeaderPropertyEntryPointResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
MethodHeaderPropertyEntryPointResolver
0%
0/51
0%
0/22
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.model.resolvers;
 8  
 
 9  
 import org.mule.api.MuleEventContext;
 10  
 import org.mule.api.config.MuleProperties;
 11  
 import org.mule.api.lifecycle.Callable;
 12  
 import org.mule.api.model.InvocationResult;
 13  
 import org.mule.api.transport.PropertyScope;
 14  
 import org.mule.config.i18n.CoreMessages;
 15  
 import org.mule.util.ClassUtils;
 16  
 
 17  
 import java.lang.reflect.Method;
 18  
 
 19  
 import org.apache.commons.lang.BooleanUtils;
 20  
 
 21  
 /**
 22  
  * This resolver will look for a {@link org.mule.api.config.MuleProperties#MULE_METHOD_PROPERTY} 
 23  
  * property on the incoming event to determine which method to invoke Users can customise the name 
 24  
  * of the property used to look up the method name on the event
 25  
  */
 26  0
 public class MethodHeaderPropertyEntryPointResolver extends AbstractEntryPointResolver
 27  
 {
 28  
 
 29  0
     private String methodProperty = MuleProperties.MULE_METHOD_PROPERTY;
 30  
 
 31  
     public String getMethodProperty()
 32  
     {
 33  0
         return methodProperty;
 34  
     }
 35  
 
 36  
     public void setMethodProperty(String methodProperty)
 37  
     {
 38  0
         this.methodProperty = methodProperty;
 39  0
     }
 40  
 
 41  
     public InvocationResult invoke(Object component, MuleEventContext context) throws Exception
 42  
     {
 43  
         // Transports such as SOAP need to ignore the method property
 44  0
         boolean ignoreMethod = BooleanUtils.toBoolean(context.getMessage().<Boolean>getInboundProperty(MuleProperties.MULE_IGNORE_METHOD_PROPERTY));
 45  
 
 46  0
         if (ignoreMethod)
 47  
         {
 48  
             //TODO: Removed once we have property scoping
 49  0
             InvocationResult result = new InvocationResult(this, InvocationResult.State.NOT_SUPPORTED);
 50  0
             result.setErrorMessage("Property: " + MuleProperties.MULE_IGNORE_METHOD_PROPERTY + " was set so skipping this resolver");
 51  0
             return result;
 52  
         }
 53  
 
 54  
         // MULE-4874: this is needed in order to execute the transformers before determining the methodProp
 55  0
         Object[] payload = getPayloadFromMessage(context);
 56  
 
 57  
         //TODO MULE-4953 I don't think the VM transport if managing invocation properties correctly, or maybe it is and this
 58  
         //is valid
 59  
         //Here I have to remove the 'method' property rather than just read it
 60  0
         Object methodProp = context.getMessage().removeProperty(getMethodProperty(), PropertyScope.INVOCATION);
 61  0
         if (methodProp == null)
 62  
         {
 63  0
             methodProp = context.getMessage().getInboundProperty(getMethodProperty());
 64  
         }
 65  0
         if (methodProp == null)
 66  
         {
 67  0
             InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED);
 68  
             // no method for the explicit method header
 69  0
             result.setErrorMessage(CoreMessages.propertyIsNotSetOnEvent(getMethodProperty()).toString());
 70  0
             return result;
 71  
         }
 72  
 
 73  
         Method method;
 74  
         String methodName;
 75  0
         if (methodProp instanceof Method)
 76  
         {
 77  0
             method = (Method) methodProp;
 78  0
             methodName = method.getName();
 79  
         }
 80  
         else
 81  
         {
 82  0
             methodName = methodProp.toString();
 83  0
             method = getMethodByName(component, methodName, context);
 84  
         }
 85  
 
 86  0
         if (method != null && method.getParameterTypes().length == 0)
 87  
         {
 88  0
             return invokeMethod(component, method, ClassUtils.NO_ARGS_TYPE);
 89  
         }
 90  
 
 91  0
         if (method == null)
 92  
         {
 93  0
             Class<?>[] classTypes = ClassUtils.getClassTypes(payload);
 94  
 
 95  0
             method = ClassUtils.getMethod(component.getClass(), methodName, classTypes);
 96  
             
 97  0
             if (method == null)
 98  
             {
 99  0
                 InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED);
 100  0
                 result.setErrorNoMatchingMethods(component, classTypes);
 101  0
                 return result;
 102  
             }
 103  
 
 104  
         }
 105  
 
 106  0
         validateMethod(component, method);
 107  0
         addMethodByName(component, method, context);
 108  
 
 109  0
         return invokeMethod(component, method, payload);
 110  
     }
 111  
 
 112  
     /**
 113  
      * This method can be used to validate that the method exists and is allowed to
 114  
      * be executed.
 115  
      *
 116  
      * @param component the service component being invoked
 117  
      * @param method the method to invoke on the component
 118  
      * @throws NoSuchMethodException if the method does not exist on the component
 119  
      */
 120  
     protected void validateMethod(Object component, Method method) throws NoSuchMethodException
 121  
     {
 122  0
         boolean fallback = component instanceof Callable;
 123  
 
 124  0
         if (method != null)
 125  
         {
 126  
             // This will throw NoSuchMethodException if it doesn't exist
 127  
             try
 128  
             {
 129  0
                 component.getClass().getMethod(method.getName(), method.getParameterTypes());
 130  
             }
 131  0
             catch (NoSuchMethodException e)
 132  
             {
 133  0
                 if (!fallback)
 134  
                 {
 135  0
                     throw e;
 136  
                 }
 137  0
             }
 138  
         }
 139  
         else
 140  
         {
 141  0
             if (!fallback)
 142  
             {
 143  0
                 throw new NoSuchMethodException(
 144  
                         CoreMessages.methodWithParamsNotFoundOnObject("null", "unknown",
 145  
                                 component.getClass()).toString());
 146  
             }
 147  
         }
 148  0
     }
 149  
 
 150  
     @Override
 151  
     public String toString()
 152  
     {
 153  0
         final StringBuffer sb = new StringBuffer();
 154  0
         sb.append("MethodHeaderPropertyEntryPointResolver");
 155  0
         sb.append("{methodHeader=").append(methodProperty);
 156  0
         sb.append(", acceptVoidMethods=").append(isAcceptVoidMethods());
 157  0
         sb.append('}');
 158  0
         return sb.toString();
 159  
     }
 160  
 
 161  
 }