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.config;
8   
9   import org.mule.MessageExchangePattern;
10  import org.mule.api.MuleException;
11  import org.mule.api.annotations.meta.Channel;
12  import org.mule.api.annotations.meta.ChannelType;
13  import org.mule.api.endpoint.InboundEndpoint;
14  import org.mule.api.endpoint.OutboundEndpoint;
15  import org.mule.config.endpoint.AbstractEndpointAnnotationParser;
16  import org.mule.config.endpoint.AnnotatedEndpointData;
17  import org.mule.module.ibeans.i18n.IBeansMessages;
18  import org.mule.module.ibeans.spi.support.CallOutboundEndpoint;
19  import org.mule.module.ibeans.spi.support.CallRequestEndpoint;
20  
21  import java.beans.ExceptionListener;
22  import java.lang.annotation.Annotation;
23  import java.lang.reflect.Member;
24  import java.lang.reflect.Method;
25  import java.util.Map;
26  
27  import org.ibeans.annotation.Call;
28  import org.ibeans.api.CallException;
29  import org.ibeans.api.ExceptionListenerAware;
30  
31  /**
32   * The parser responsible for parsing {@link org.ibeans.annotation.Call} annotations.
33   */
34  public class CallAnnotationParser extends AbstractEndpointAnnotationParser
35  {
36      protected AnnotatedEndpointData createEndpointData(Annotation annotation) throws MuleException
37      {
38          Call call = (Call) annotation;
39          AnnotatedEndpointData epd = new AnnotatedEndpointData(MessageExchangePattern.REQUEST_RESPONSE, ChannelType.Outbound, call);
40          epd.setAddress(call.uri());
41          epd.setProperties(AnnotatedEndpointData.convert(call.properties()));
42          return epd;
43      }
44  
45      protected String getIdentifier()
46      {
47          return Call.class.getAnnotation(Channel.class).identifer();
48      }
49  
50      @Override
51      public boolean supports(Annotation annotation, Class clazz, Member member)
52      {
53          //You cannot use the @Call annotation on an implementation class
54          boolean supports = clazz.isInterface();
55          if (supports)
56          {
57              supports = annotation instanceof Call;  
58          }
59          if (supports)
60          {
61              //Allow services to extend an exception listener that the user can plug in
62              if (ExceptionListenerAware.class.isAssignableFrom(clazz))
63              {
64                  supports = true;
65              }
66              else
67              {
68                  Class[] exceptionTypes = ((Method) member).getExceptionTypes();
69                  boolean hasValidExceptionType = false;
70                  for (int i = 0; i < exceptionTypes.length; i++)
71                  {
72                      Class exceptionType = exceptionTypes[i];
73                      hasValidExceptionType = exceptionType.equals(Exception.class) || exceptionType.isAssignableFrom(CallException.class) || clazz.isAssignableFrom(ExceptionListener.class);
74                  }
75                  if (!hasValidExceptionType)
76                  {
77                      throw new IllegalArgumentException(IBeansMessages.illegalCallMethod((Method)member).getMessage());
78                  }
79              }
80          }
81          return supports;
82      }
83  
84      public OutboundEndpoint parseOutboundEndpoint(Annotation annotation, Map metaInfo) throws MuleException
85      {
86          AnnotatedEndpointData data = createEndpointData(annotation);
87          if (data.getConnectorName() == null)
88          {
89              data.setConnectorName((String) metaInfo.get("connectorName"));
90          }
91          return new CallOutboundEndpoint(muleContext, data);
92      }
93  
94      public InboundEndpoint parseInboundEndpoint(Annotation annotation, Map metaInfo) throws MuleException
95      {
96          AnnotatedEndpointData data = createEndpointData(annotation);
97          if (data.getConnectorName() == null)
98          {
99              data.setConnectorName((String) metaInfo.get("connectorName"));
100         }
101         return new CallRequestEndpoint(muleContext, data);
102     }
103 }