View Javadoc

1   /*
2    * $Id: MuleReceiver.java 7963 2007-08-21 08:53:15Z 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  
11  package org.mule.providers.jbi.components;
12  
13  import org.mule.MuleManager;
14  import org.mule.config.converters.QNameConverter;
15  import org.mule.impl.MuleDescriptor;
16  import org.mule.impl.MuleMessage;
17  import org.mule.providers.AbstractMessageReceiver;
18  import org.mule.providers.InternalMessageListener;
19  import org.mule.providers.jbi.JbiMessageAdapter;
20  import org.mule.providers.jbi.JbiUtils;
21  import org.mule.providers.jbi.i18n.JbiMessages;
22  import org.mule.umo.UMOComponent;
23  import org.mule.umo.UMODescriptor;
24  import org.mule.umo.UMOEvent;
25  import org.mule.umo.UMOException;
26  import org.mule.umo.UMOMessage;
27  import org.mule.umo.UMOTransaction;
28  import org.mule.umo.lifecycle.InitialisationException;
29  import org.mule.umo.provider.UMOMessageReceiver;
30  import org.mule.util.SystemUtils;
31  
32  import java.io.OutputStream;
33  import java.util.Arrays;
34  
35  import javax.jbi.JBIException;
36  import javax.jbi.messaging.MessageExchange;
37  import javax.jbi.messaging.MessagingException;
38  import javax.jbi.messaging.NormalizedMessage;
39  import javax.jbi.servicedesc.ServiceEndpoint;
40  import javax.xml.namespace.QName;
41  
42  /**
43   * Can receive events over Mule transports. Given an muleEndpoint (or endpoint string
44   * i.e. jms://my.queue) this component will set up the necessary bindings with Mule.
45   */
46  public class MuleReceiver extends AbstractEndpointComponent implements InternalMessageListener
47  {
48  
49      private AbstractMessageReceiver receiver;
50  
51      protected QName targetService;
52  
53      protected String targetServiceName;
54  
55      public QName getTargetService()
56      {
57          return targetService;
58      }
59  
60      public void setTargetService(QName targetService)
61      {
62          this.targetService = targetService;
63      }
64  
65      public AbstractMessageReceiver getReceiver()
66      {
67          return receiver;
68      }
69  
70      public void setReceiver(AbstractMessageReceiver receiver)
71      {
72          this.receiver = receiver;
73      }
74  
75      public String getTargetServiceName()
76      {
77          return targetServiceName;
78      }
79  
80      public void setTargetServiceName(String targetServiceName)
81      {
82          this.targetServiceName = targetServiceName;
83      }
84  
85      protected void doInit() throws JBIException
86      {
87          super.doInit();
88          try
89          {
90              if (targetService == null)
91              {
92                  if (targetServiceName != null)
93                  {
94                      targetService = (QName)new QNameConverter().convert(QName.class, targetServiceName);
95                  }
96              }
97  
98              UMOMessageReceiver receiver = muleEndpoint.getConnector().registerListener(
99                  new NullUMOComponent(getName()), muleEndpoint);
100 
101             if (receiver == null)
102             {
103                 throw new IllegalArgumentException(
104                     JbiMessages.receiverMustBeSet(this.getName()).toString());
105             }
106             else if (receiver instanceof AbstractMessageReceiver)
107             {
108                 this.receiver = (AbstractMessageReceiver)receiver;
109             }
110             else
111             {
112                 throw new IllegalArgumentException(
113                     JbiMessages.invalidReceiverType(this.getName(), AbstractMessageReceiver.class).toString());
114             }
115 
116             this.receiver.setListener(this);
117         }
118         catch (Exception e)
119         {
120             throw new JBIException(e);
121         }
122     }
123 
124     public UMOMessage onMessage(UMOMessage message,
125                                 UMOTransaction trans,
126                                 boolean synchronous,
127                                 OutputStream outputStream) throws UMOException
128     {
129         MessageExchange me = null;
130         try
131         {
132             if (synchronous)
133             {
134                 me = exchangeFactory.createInOutExchange();
135             }
136             else
137             {
138                 me = exchangeFactory.createInOnlyExchange();
139             }
140             if (targetService != null)
141             {
142                 me.setService(targetService);
143                 ServiceEndpoint endpoint = null;
144                 ServiceEndpoint[] eps = context.getEndpointsForService(targetService);
145                 if (eps.length == 0)
146                 {
147                     // container should handle this
148                     throw new MessagingException("There are no endpoints registered for targetService: "
149                                                  + targetService);
150                 }
151                 else
152                 {
153                     endpoint = eps[0];
154                 }
155 
156                 if (logger.isDebugEnabled())
157                 {
158                     StringBuffer buf = new StringBuffer("Found the following endpoints for: ");
159                     buf.append(targetService).append(SystemUtils.LINE_SEPARATOR);
160                     for (int i = 0; i < eps.length; i++)
161                     {
162                         ServiceEndpoint ep = eps[i];
163                         buf.append(ep.getEndpointName())
164                             .append(";")
165                             .append(ep.getServiceName())
166                             .append(";")
167                             .append(Arrays.asList(ep.getInterfaces()))
168                             .append(SystemUtils.LINE_SEPARATOR);
169                     }
170                     logger.debug(buf.toString());
171                 }
172 
173                 logger.debug("Using Jbi Endpoint for targetService: " + targetService + " is: " + endpoint);
174                 if (endpoint != null)
175                 {
176                     me.setEndpoint(endpoint);
177                 }
178             }
179             else
180             {
181                 logger.debug("Jbi target service is not set Container will need to resolve target");
182             }
183 
184             NormalizedMessage nmessage = me.createMessage();
185             JbiUtils.populateNormalizedMessage(message, nmessage);
186 
187             me.setMessage(nmessage, IN);
188             if (synchronous)
189             {
190                 deliveryChannel.sendSync(me, MuleManager.getConfiguration().getSynchronousEventTimeout());
191                 NormalizedMessage result = null;
192 
193                 result = me.getMessage(OUT);
194                 done(me);
195                 if (result != null)
196                 {
197                     return new MuleMessage(new JbiMessageAdapter(result));
198                 }
199                 else
200                 {
201                     return null;
202                 }
203             }
204             else
205             {
206                 deliveryChannel.send(me);
207                 return null;
208             }
209         }
210         catch (MessagingException e)
211         {
212             try
213             {
214                 error(me, e);
215                 return null;
216             }
217             catch (MessagingException e1)
218             {
219                 handleException(e);
220                 return null;
221             }
222         }
223     }
224 
225     /**
226      * A null component is used when interfacing with JBI components, the Null
227      * component is a placeholder of the JBI component that isn't managed by mule
228      */
229     class NullUMOComponent implements UMOComponent
230     {
231         /**
232          * Serial version
233          */
234         private static final long serialVersionUID = 6446394166371870045L;
235 
236         private UMODescriptor descriptor;
237 
238         public NullUMOComponent(String name)
239         {
240             this.descriptor = new MuleDescriptor(name);
241         }
242 
243         public UMODescriptor getDescriptor()
244         {
245             return descriptor;
246         }
247 
248         public void dispatchEvent(UMOEvent event) throws UMOException
249         {
250             throw new UnsupportedOperationException("NullComponent:dispatchEvent");
251         }
252 
253         public UMOMessage sendEvent(UMOEvent event) throws UMOException
254         {
255             throw new UnsupportedOperationException("NullComponent:sendEvent");
256         }
257 
258         public void pause() throws UMOException
259         {
260             // nothing to do
261         }
262 
263         public void resume() throws UMOException
264         {
265             // nothing to do
266         }
267 
268         public boolean isPaused()
269         {
270             return false;
271         }
272 
273         public void start() throws UMOException
274         {
275             // nothing to do
276         }
277 
278         public void stop() throws UMOException
279         {
280             // nothing to do
281         }
282 
283         public void dispose()
284         {
285             // nothing to do
286         }
287 
288         public void initialise() throws InitialisationException {
289             // nothing to do
290         }
291 
292         public boolean isStarted()
293         {
294             return true;
295         }
296 
297         public Object getInstance() throws UMOException
298         {
299             return null;
300         }
301     }
302 
303 }