View Javadoc
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.module.ibeans.spi;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.transformer.DataType;
12  import org.mule.api.transformer.Transformer;
13  import org.mule.module.ibeans.spi.support.DataTypeConverter;
14  import org.mule.routing.filters.ExpressionFilter;
15  import org.mule.transformer.types.DataTypeFactory;
16  import org.mule.transport.NullPayload;
17  
18  import java.lang.reflect.Method;
19  
20  import org.ibeans.annotation.Return;
21  import org.ibeans.api.AbstractCallInterceptor;
22  import org.ibeans.api.InvocationContext;
23  import org.ibeans.api.Response;
24  import org.ibeans.spi.ExpressionParser;
25  
26  /**
27   * An interceptor used to process the {@link org.ibeans.annotation.Return} annotation.  This interceptor also
28   * performs automatic transformation
29   */
30  public class MuleResponseTransformInterceptor extends AbstractCallInterceptor
31  {
32      private MuleContext muleContext;
33      private ExpressionParser parser;
34  
35      public MuleResponseTransformInterceptor(MuleContext muleContext, ExpressionParser parser)
36      {
37          this.muleContext = muleContext;
38          this.parser = parser;
39      }
40  
41      @Override
42      public void afterCall(InvocationContext invocationContext) throws Throwable
43      {
44          MuleResponseMessage result = (MuleResponseMessage)invocationContext.getResponse();
45          if (result == null || result.getPayload() == null || invocationContext.getMethod().getReturnType().equals(Void.TYPE))
46          {
47              return;
48          }
49  
50          Object finalResult;
51          Method method = invocationContext.getMethod();
52          //Special handling for Mock ibean methods, need to find a better way of doing this
53          if(method.getName().startsWith("ibean"))
54          {
55              invocationContext.setResult(result.getPayload());
56              return;
57          }
58          DataType requiredType = DataTypeConverter.convertIBeansToMule(invocationContext.getReturnType()); // DataTypeFactory.createFromReturnType(method);
59  
60          if (method.getAnnotation(Return.class) != null)
61          {
62              String returnExpression = method.getAnnotation(Return.class).value();
63  
64              finalResult = handleReturnAnnotation(returnExpression, result, invocationContext);
65  
66              DataType finalType = DataTypeFactory.createFromObject(finalResult);
67              if (!requiredType.isCompatibleWith(finalType))
68              {
69                  Transformer transformer = muleContext.getRegistry().lookupTransformer( finalType, requiredType);
70                  finalResult = transformer.transform(finalResult);
71              }
72          }
73          else
74          {
75  
76              if (requiredType.getType().equals(MuleMessage.class))
77              {
78                  finalResult = result.getMessage();
79              }
80              else if (requiredType.getType().equals(Response.class))
81              {
82                  finalResult = result;
83              }
84              else
85              {
86                  DataType sourceType = DataTypeFactory.createFromObject(result.getMessage());
87                  if(requiredType.isCompatibleWith(sourceType))
88                  {
89                      finalResult = result.getPayload();
90                  }
91                  else
92                  {
93                      Transformer transformer = muleContext.getRegistry().lookupTransformer(sourceType, requiredType);
94                      finalResult = transformer.transform(result.getPayload());
95                  }
96              }
97  
98  
99          }
100         if(finalResult instanceof NullPayload)
101         {
102             finalResult = null;
103         }
104         invocationContext.setResult(finalResult);
105     }
106 
107     protected Object handleReturnAnnotation(String expr, Response message, InvocationContext ctx)
108     {
109         if (parser.hasUriTokens(expr))
110         {
111             expr = parser.parseUriTokens(ctx.getIBeanConfig().getUriParams(), expr);
112             expr = parser.parseUriTokens(ctx.getIBeanConfig().getHeaderParams(), expr);
113             expr = parser.parseUriTokens(ctx.getIBeanConfig().getPropertyParams(), expr);
114         }
115 
116         if(ctx.getMethod().getReturnType().equals(Boolean.class))
117         {
118             return new ExpressionFilter(expr).accept(((MuleResponseMessage)message).getMessage());
119         }
120         return parser.evaluate(expr, message);
121     }
122 }