View Javadoc

1   /*
2    * $Id: AbstractIBeansTestCase.java 19026 2010-08-16 07:30:47Z dirk.olmes $
3    * -------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.module.ibeans.annotations;
11  
12  import org.mule.api.config.MuleProperties;
13  import org.mule.api.transformer.Transformer;
14  import org.mule.api.transformer.TransformerException;
15  import org.mule.module.ibeans.spi.MuleIBeansPlugin;
16  import org.mule.tck.AbstractMuleTestCase;
17  import org.mule.util.IOUtils;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.Collection;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import org.ibeans.annotation.Return;
26  import org.ibeans.api.DataType;
27  import org.ibeans.api.Response;
28  import org.ibeans.api.channel.MimeType;
29  import org.ibeans.api.channel.MimeTypes;
30  import org.ibeans.impl.support.datatype.CollectionDataType;
31  import org.ibeans.impl.support.datatype.DataTypeFactory;
32  import org.ibeans.impl.test.MockIBean;
33  import org.ibeans.impl.test.MockMessageCallback;
34  import org.ibeans.spi.IBeansPlugin;
35  import org.mockito.invocation.InvocationOnMock;
36  import org.mockito.stubbing.Answer;
37  
38  /**
39   * TODO
40   */
41  public abstract class AbstractIBeansTestCase extends AbstractMuleTestCase
42  {
43      protected IBeansPlugin plugin;
44  
45      protected AbstractIBeansTestCase()
46      {
47          setStartContext(true);
48          setDisposeManagerPerSuite(true);
49      }
50  
51      protected IBeansPlugin createPlugin()
52      {
53          return new MuleIBeansPlugin(muleContext);
54      }
55  
56      @Override
57      protected void doSetUp() throws Exception
58      {
59          plugin = createPlugin();
60          //register the test so that the @IntegrationBean annotation is processed
61          muleContext.getRegistry().registerObject("testcase", this);
62      }
63  
64  ////
65      protected Answer withXmlData(final String resource, final Object ibean)
66      {
67          return withData(resource, MimeTypes.XML, null, ibean);
68      }
69  
70      protected Answer withRssData(final String resource, final Object ibean)
71      {
72          return withData(resource, MimeTypes.RSS, null, ibean);
73      }
74  
75      protected Answer withAtomData(final String resource, final Object ibean)
76      {
77          return withData(resource, MimeTypes.ATOM, null, ibean);
78      }
79  
80      protected Answer withJsonData(final String resource, final Object ibean)
81      {
82          return withData(resource, MimeTypes.JSON, null, ibean);
83      }
84  
85      protected Answer withTextData(final String resource, final Object ibean)
86      {
87          return withData(resource, MimeTypes.TEXT, null, ibean);
88      }
89  
90      /**
91       * A mock return for a method call that will load data and transform it into the return type set on the iBean.
92       *
93       * @param resource   the resource file name that contains the data you wish to load
94       * @param returnType the Java type that the data should be converted to
95       * @return a Mockito {@link org.mockito.stubbing.Answer} implementation that will load the data when requested
96       */
97      protected Answer withData(final String resource, final Class returnType)
98      {
99          return new Answer()
100         {
101             public Object answer(InvocationOnMock
102                     invocation) throws Throwable
103             {
104                 return loadData(resource, DataTypeFactory.create(returnType));
105             }
106         };
107     }
108 
109     /**
110      * A mock return for a method call that will load data and transform it into the return type set on the iBean.
111      *
112      * @param resource the resource file name that contains the data you wish to load
113      * @param ibean    the ibean that is being tested
114      * @param mimeType the mime type of the data
115      * @param callback a callback can be used to manipulate the MuleMessage before it it gets returned
116      * @return a Mockito {@link org.mockito.stubbing.Answer} implementation that will load the data when requested
117      */
118     protected Answer withData(final String resource, final MimeType mimeType, final MockMessageCallback callback, final Object ibean)
119     {
120         return new Answer()
121         {
122             public Object answer(InvocationOnMock invocation) throws Throwable
123             {
124                 MimeType mime = mimeType;
125                 DataType ret = ((MockIBean)ibean).ibeanReturnType();
126                 if(ret!=null) ret.setMimeType(mime.toString());
127                 Object data;
128 
129                 /**
130                  * We need to have some special handling when dealing with a Mockito mock
131                  * 1) If the return type on the ibeans is not set, use the method return type
132                  * 2) the return annotation changes the return type so use the one defined on the actual Method
133                  * 3) If the return type and the method return type are not assignable, then use the method return type
134                  */
135                 if (ret == null || invocation.getMethod().isAnnotationPresent(Return.class) ||
136                         !invocation.getMethod().getReturnType().isAssignableFrom(ret.getType()))
137                 {
138                     ret = DataTypeFactory.createFromReturnType(invocation.getMethod());
139                     mime = null;
140                 }
141 
142                 data = loadData(resource, ret);
143                 ((MockIBean)ibean).ibeanSetMimeType(mime);
144                 ((MockIBean)ibean).ibeanSetMessageCallback(callback);
145 
146                 Response response;
147                 Map<String, Object> headers = null;
148                 if(mime!=null)
149                 {
150                     headers = new HashMap<String, Object>();
151                     headers.put(MuleProperties.CONTENT_TYPE_PROPERTY, mime.toString());
152                 }
153                 response = plugin.createResponse(data, headers, null);
154                 if(callback!=null)
155                 {
156                     callback.onMessage(response);
157                 }
158                 return response;
159             }
160         };
161     }
162 
163     protected <T> T loadData(String resource, DataType<T> type) throws IOException, TransformerException
164     {
165         InputStream in = IOUtils.getResourceAsStream(resource, getClass());
166         assertNotNull("Resource stream for: " + resource + " must not be null", in);
167         return getDataAs(in, type);
168     }
169 
170     protected <T> T getDataAs(InputStream data, DataType<T> as) throws TransformerException
171     {
172         org.mule.api.transformer.DataType muleDT;
173         if(as instanceof CollectionDataType)
174         {
175             muleDT = new org.mule.transformer.types.CollectionDataType(
176                     (Class<? extends Collection>)as.getType(),
177                     ((CollectionDataType) as).getItemType(),
178                     as.getMimeType());
179         }
180         else
181         {
182             muleDT = new org.mule.transformer.types.SimpleDataType(
183                     as.getType(),
184                     as.getMimeType());
185         }
186         Transformer t = muleContext.getRegistry().lookupTransformer(org.mule.transformer.types.DataTypeFactory.create(data.getClass()), muleDT);
187         return (T)t.transform(data);
188     }
189 
190 }