View Javadoc

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