View Javadoc

1   /*
2    * $Id: AbstractEntryPointResolver.java 12242 2008-07-07 13:35:38Z 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  package org.mule.model.resolvers;
11  
12  import org.mule.VoidResult;
13  import org.mule.api.MuleEventContext;
14  import org.mule.api.model.EntryPointResolver;
15  import org.mule.api.model.InvocationResult;
16  import org.mule.api.transformer.TransformerException;
17  import org.mule.transport.NullPayload;
18  import org.mule.util.ClassUtils;
19  import org.mule.util.StringMessageUtils;
20  
21  import java.lang.reflect.InvocationTargetException;
22  import java.lang.reflect.Method;
23  
24  import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  /**
30   * A Base class for {@link org.mule.api.model.EntryPointResolver}. It provides parameters for
31   * detemining if the payload of the message should be transformed first and whether void methods are
32   * acceptible. It also provides a method cashe for those resolvers that use reflection to discover methods
33   * on the service.
34   */
35  public abstract class AbstractEntryPointResolver implements EntryPointResolver
36  {
37      /** logger used by this class */
38      protected transient final Log logger = LogFactory.getLog(getClass());
39  
40      private boolean transformFirst = true;
41  
42      private boolean acceptVoidMethods = false;
43  
44  
45      // @GuardedBy(itself)
46      protected final ConcurrentHashMap methodCache = new ConcurrentHashMap(4);
47  
48      public boolean isTransformFirst()
49      {
50          return transformFirst;
51      }
52  
53      public void setTransformFirst(boolean transformFirst)
54      {
55          this.transformFirst = transformFirst;
56      }
57  
58      public boolean isAcceptVoidMethods()
59      {
60          return acceptVoidMethods;
61      }
62  
63      public void setAcceptVoidMethods(boolean acceptVoidMethods)
64      {
65          this.acceptVoidMethods = acceptVoidMethods;
66      }
67  
68      protected Method getMethodByName(String methodName, MuleEventContext context)
69      {
70          StringBuffer key = new StringBuffer(24).append(context.getService().getName())
71                  .append(".").append(methodName);
72          Method method = (Method) methodCache.get(key.toString());
73          return method;
74      }
75  
76      protected Method addMethodByName(Method method, MuleEventContext context)
77      {
78          StringBuffer key = new StringBuffer(24).append(context.getService().getName())
79                  .append(".").append(method.getName());
80          Method previousMethod = (Method) methodCache.putIfAbsent(key.toString(), method);
81          return (previousMethod != null ? previousMethod : method);
82      }
83  
84      protected Method addMethodByArguments(Object component, Method method, Object[] payload)
85      {
86          Method previousMethod = (Method) methodCache.putIfAbsent(getCacheKeyForPayload(component, payload), method);
87          return (previousMethod != null ? previousMethod : method);
88      }
89  
90  
91      protected Method getMethodByArguments(Object component, Object[] payload)
92      {
93          Method method = (Method) methodCache.get(getCacheKeyForPayload(component, payload));
94          return method;
95      }
96  
97      protected String getCacheKeyForPayload(Object component, Object[] payload)
98      {
99          StringBuffer key = new StringBuffer(48);
100         for (int i = 0; i < payload.length; i++)
101         {
102             Object o = payload[i];
103             key.append(o.getClass().getName());
104         }
105         key.append(".").append(ClassUtils.getClassName(component.getClass()));
106         return key.toString();
107     }
108 
109 
110     protected Object[] getPayloadFromMessage(MuleEventContext context) throws TransformerException
111     {
112         Object temp;
113         if (isTransformFirst())
114         {
115             temp = context.transformMessage();
116         }
117         else
118         {
119             temp = context.getMessage().getPayload();
120         }
121         if (temp instanceof Object[])
122         {
123             return (Object[]) temp;
124         }
125         else if (temp instanceof NullPayload)
126         {
127             return ClassUtils.NO_ARGS;
128         }
129         else
130         {
131             return new Object[]{temp};
132         }
133     }
134 
135     protected InvocationResult invokeMethod(Object component, Method method, Object[] arguments)
136             throws InvocationTargetException, IllegalAccessException
137     {
138         String methodCall = null;
139 
140         if (logger.isDebugEnabled())
141         {
142             methodCall = component.getClass().getName() + "." + method.getName() + "("
143                     + StringMessageUtils.toString(ClassUtils.getClassTypes(arguments)) + ")";
144             logger.debug("Invoking " + methodCall);
145         }
146 
147         Object result = method.invoke(component, arguments);
148         if (method.getReturnType().equals(Void.TYPE))
149         {
150             result = VoidResult.getInstance();
151         }
152 
153         if (logger.isDebugEnabled())
154         {
155             logger.debug("Result of call " + methodCall + " is " + (result == null ? "null" : "not null"));
156         }
157 
158         return new InvocationResult(result, method);
159     }
160 
161 
162     public String toString()
163     {
164         final StringBuffer sb = new StringBuffer();
165         sb.append("AbstractEntryPointResolver");
166         sb.append("{transformFirst=").append(transformFirst);
167         sb.append(", acceptVoidMethods=").append(acceptVoidMethods);
168         sb.append('}');
169         return sb.toString();
170     }
171 }