View Javadoc

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