Coverage Report - org.mule.model.resolvers.AbstractArgumentEntryPointResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractArgumentEntryPointResolver
0%
0/50
0%
0/16
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.model.InvocationResult;
 11  
 import org.mule.util.ClassUtils;
 12  
 import org.mule.util.StringMessageUtils;
 13  
 
 14  
 import java.lang.reflect.Method;
 15  
 import java.util.Arrays;
 16  
 import java.util.HashSet;
 17  
 import java.util.List;
 18  
 import java.util.Set;
 19  
 
 20  
 /**
 21  
  * A base class that allows implementing resolvers to define what parameters it is expecting.  Currently
 22  
  * there are two implementations of this {@link org.mule.model.resolvers.NoArgumentsEntryPointResolver}, that
 23  
  * allows methods with no arguments to be invoked and {@link org.mule.model.resolvers.ArrayEntryPointResolver} that
 24  
  * allows for methods that accept an array type to be invoked.
 25  
  * <p/>
 26  
  * Users can set explicit method names on this resolver to control which methods are allowed to be called. Also a set of
 27  
  * 'ignored' methods are available (and the use can add others) to tell the resolver to not resolve to these methods.
 28  
  * The default ones are:
 29  
  * <ul>
 30  
  * <li>{@link #toString()}
 31  
  * <li>{@link #getClass()}
 32  
  * <li>{@link #notify}
 33  
  * <li>{@link #notifyAll}
 34  
  * <li>{@link #hashCode}
 35  
  * <li>{@link #wait}
 36  
  * <li>'is*'
 37  
  * <li>'get*'.
 38  
  * </ul>
 39  
  * <p/> Note that wildcard expressions can be used.
 40  
  */
 41  
 public abstract class AbstractArgumentEntryPointResolver extends ReflectionEntryPointResolver
 42  
 {
 43  0
     private Set<String> methods = new HashSet<String>(2);
 44  
 
 45  0
     private boolean enableDiscovery = true;
 46  
 
 47  
     public AbstractArgumentEntryPointResolver()
 48  0
     {
 49  
         //By default No arg methods without a return type should be supported
 50  0
         setAcceptVoidMethods(true);
 51  
         // we don't want to match these methods when looking for a service method
 52  
         //If you add to this list please change the javaDoc above too.
 53  0
         setIgnoredMethods(new HashSet<String>(Arrays.asList("toString",
 54  
                 "getClass", "notify", "notifyAll", "wait", "hashCode", "clone", "is*", "get*")));
 55  0
     }
 56  
 
 57  
     public Set<String> getMethods()
 58  
     {
 59  0
         return methods;
 60  
     }
 61  
 
 62  
     public void setMethods(Set<String> methods)
 63  
     {
 64  0
         this.methods = methods;
 65  0
     }
 66  
 
 67  
     public void addMethod(String name)
 68  
     {
 69  0
         this.methods.add(name);
 70  0
     }
 71  
 
 72  
     public boolean removeMethod(String name)
 73  
     {
 74  0
         return this.methods.remove(name);
 75  
     }
 76  
 
 77  
 
 78  
     public boolean isEnableDiscovery()
 79  
     {
 80  0
         return enableDiscovery;
 81  
     }
 82  
 
 83  
     public void setEnableDiscovery(boolean enableDiscovery)
 84  
     {
 85  0
         this.enableDiscovery = enableDiscovery;
 86  0
     }
 87  
 
 88  
     @Override
 89  
     public InvocationResult invoke(Object component, MuleEventContext context) throws Exception
 90  
     {
 91  0
         Method method = null;
 92  0
         Object[] payload = getPayloadFromMessage(context);
 93  
 
 94  0
         if (payload == null)
 95  
         {
 96  0
             return new InvocationResult(this, InvocationResult.State.NOT_SUPPORTED);
 97  
         }
 98  
 
 99  0
         for (String methodName : methods)
 100  
         {
 101  0
             method = getMethodByName(component, methodName, context);
 102  
 
 103  0
             if (method == null)
 104  
             {
 105  0
                 method = ClassUtils.getMethod(component.getClass(), methodName, 
 106  
                     getMethodArgumentTypes(payload));
 107  
             }
 108  0
             if (method != null)
 109  
             {
 110  0
                 addMethodByName(component, method, context);
 111  0
                 break;
 112  
             }
 113  
         }
 114  
         //If the method wasn't explicitly set, lets try and discover it
 115  0
         if (method == null)
 116  
         {
 117  0
             if (isEnableDiscovery())
 118  
             {
 119  0
                 Class<?>[] argTypes = getMethodArgumentTypes(payload);
 120  0
                 List<Method> methods = ClassUtils.getSatisfiableMethods(component.getClass(), argTypes,
 121  
                         isAcceptVoidMethods(), false, getIgnoredMethods(), filter);
 122  
 
 123  0
                 if (methods.size() > 1)
 124  
                 {
 125  0
                     InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED);
 126  
                     // too many methods match the payload argument
 127  0
                     result.setErrorTooManyMatchingMethods(component, argTypes, 
 128  
                         StringMessageUtils.toString(methods));
 129  0
                     return result;
 130  
                 }
 131  0
                 else if (methods.size() == 1)
 132  
                 {
 133  
                     // found exact match for payload argument
 134  0
                     method = this.addMethodByArguments(component, methods.get(0), 
 135  
                         getPayloadFromMessage(context));
 136  
                 }
 137  
                 else
 138  
                 {
 139  0
                     InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED);
 140  
                     // no method for payload argument either - bail out
 141  0
                     result.setErrorNoMatchingMethods(component, ClassUtils.NO_ARGS_TYPE);
 142  0
                     return result;
 143  
                 }
 144  0
             }
 145  
             else
 146  
             {
 147  0
                 InvocationResult result = new InvocationResult(this, InvocationResult.State.FAILED);
 148  
                 // no method for the explicit methods either
 149  0
                 result.setErrorNoMatchingMethodsCalled(component, StringMessageUtils.toString(methods));
 150  0
                 return result;
 151  
             }
 152  
         }
 153  0
         return invokeMethod(component, method, getPayloadFromMessage(context));
 154  
     }
 155  
 
 156  
     protected abstract Class<?>[] getMethodArgumentTypes(Object[] payload);
 157  
 
 158  
     @Override
 159  
     public String toString()
 160  
     {
 161  0
         final StringBuffer sb = new StringBuffer();
 162  0
         sb.append(ClassUtils.getClassName(getClass()));
 163  0
         sb.append("{methods=").append(StringMessageUtils.toString(methods));
 164  0
         sb.append(", acceptVoidMethods=").append(isAcceptVoidMethods());
 165  0
         sb.append('}');
 166  0
         return sb.toString();
 167  
     }
 168  
 }