View Javadoc

1   /*
2    * $Id: AjaxMessageReceiver.java 19191 2010-08-25 21:05:23Z tcarlson $
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.transport.ajax;
11  
12  import org.mule.RequestContext;
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleException;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.construct.FlowConstruct;
17  import org.mule.api.endpoint.ImmutableEndpoint;
18  import org.mule.api.endpoint.InboundEndpoint;
19  import org.mule.api.lifecycle.CreateException;
20  import org.mule.api.transport.Connector;
21  import org.mule.transport.AbstractConnector;
22  import org.mule.transport.AbstractMessageReceiver;
23  import org.mule.transport.ajax.embedded.AjaxConnector;
24  import org.mule.transport.ajax.i18n.AjaxMessages;
25  import org.mule.util.StringUtils;
26  
27  import org.cometd.Bayeux;
28  import org.cometd.Client;
29  import org.mortbay.cometd.AbstractBayeux;
30  import org.mortbay.cometd.BayeuxService;
31  
32  /**
33   * Registers a receiver service with Bayeux.
34   * The {@link AjaxMessageReceiver.ReceiverService#route(org.cometd.Client, Object)}
35   * is invoked when a message is received on the subscription channel
36   */
37  public class AjaxMessageReceiver extends AbstractMessageReceiver implements BayeuxAware
38  {
39      private AbstractBayeux bayeux;
40  
41      public AjaxMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
42              throws CreateException
43      {
44          super(connector, flowConstruct, endpoint);
45          String channel = endpoint.getEndpointURI().getPath();
46          if(StringUtils.isEmpty(channel) || channel.equals("/"))
47          {
48              //TODO i18n
49              throw new CreateException(AjaxMessages.createStaticMessage("The subscription path cannot be empty or equal '/'"), this);
50          }
51      }
52  
53      public class ReceiverService extends BayeuxService
54      {
55          private final ImmutableEndpoint endpoint;
56  
57          public ReceiverService(String channel, Bayeux bayeux, ImmutableEndpoint endpoint)
58          {
59              super(bayeux, channel);
60              this.endpoint = endpoint;
61              subscribe(channel, "route");
62          }
63  
64          public Object route(Client client, Object data) throws Exception
65          {
66              MuleMessage messageToRoute = createMuleMessage(data, endpoint.getEncoding());
67              messageToRoute.setInvocationProperty(AjaxConnector.COMETD_CLIENT, client);
68  
69              Object replyTo = messageToRoute.getReplyTo();
70              MuleEvent event = AjaxMessageReceiver.this.routeMessage(messageToRoute);
71              MuleMessage message = event == null ? null : event.getMessage();
72              //If a replyTo channel is set the client is expecting a response.
73              //Mule does not invoke the replyTo handler if an error occurs, but in this case we want it to.
74              if ((message != null && message.getExceptionPayload() == null) && replyTo != null)
75              {
76                  AbstractConnector conn = (AbstractConnector) getConnector();
77                  conn.getReplyToHandler(endpoint).processReplyTo(RequestContext.getEvent(), message, replyTo);
78              }
79              return null;
80          }
81      }
82  
83      public AbstractBayeux getBayeux()
84      {
85          return bayeux;
86      }
87  
88      public void setBayeux(AbstractBayeux bayeux)
89      {
90          this.bayeux = bayeux;
91      }
92  
93      @Override
94      protected void doStart() throws MuleException
95      {
96          //Register our listener service with Bayeux
97          String channel = endpoint.getEndpointURI().getPath();
98          new ReceiverService(channel, getBayeux(), getEndpoint());
99      }
100 }
101