View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.ajax;
8   
9   import org.mule.RequestContext;
10  import org.mule.api.MuleEvent;
11  import org.mule.api.MuleException;
12  import org.mule.api.MuleMessage;
13  import org.mule.api.config.MuleProperties;
14  import org.mule.api.construct.FlowConstruct;
15  import org.mule.api.endpoint.ImmutableEndpoint;
16  import org.mule.api.endpoint.InboundEndpoint;
17  import org.mule.api.lifecycle.CreateException;
18  import org.mule.api.transport.Connector;
19  import org.mule.api.transport.PropertyScope;
20  import org.mule.transport.AbstractMessageReceiver;
21  import org.mule.transport.ajax.embedded.AjaxConnector;
22  import org.mule.transport.ajax.i18n.AjaxMessages;
23  import org.mule.util.StringUtils;
24  
25  import org.cometd.Bayeux;
26  import org.cometd.Client;
27  import org.mortbay.cometd.AbstractBayeux;
28  import org.mortbay.cometd.BayeuxService;
29  
30  /**
31   * Registers a receiver service with Bayeux.
32   * The {@link AjaxMessageReceiver.ReceiverService#route(org.cometd.Client, Object)}
33   * is invoked when a message is received on the subscription channel
34   */
35  public class AjaxMessageReceiver extends AbstractMessageReceiver implements BayeuxAware
36  {
37      private AbstractBayeux bayeux;
38  
39      public AjaxMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
40              throws CreateException
41      {
42          super(connector, flowConstruct, endpoint);
43          String channel = endpoint.getEndpointURI().getPath();
44          if(StringUtils.isEmpty(channel) || channel.equals("/"))
45          {
46              //TODO i18n
47              throw new CreateException(AjaxMessages.createStaticMessage("The subscription path cannot be empty or equal '/'"), this);
48          }
49      }
50  
51      public class ReceiverService extends BayeuxService
52      {
53          private final ImmutableEndpoint endpoint;
54  
55          public ReceiverService(String channel, Bayeux bayeux, ImmutableEndpoint endpoint)
56          {
57              super(bayeux, channel);
58              this.endpoint = endpoint;
59              subscribe(channel, "route");
60          }
61  
62          public Object route(Client client, Object data) throws Exception
63          {
64              MuleMessage messageToRoute = createMuleMessage(data, endpoint.getEncoding());
65              messageToRoute.setInvocationProperty(AjaxConnector.COMETD_CLIENT, client);
66  
67              Object replyTo = messageToRoute.getReplyTo();
68              if (replyTo != null)
69              {
70                  messageToRoute.setProperty(MuleProperties.MULE_FORCE_SYNC_PROPERTY, Boolean.TRUE, PropertyScope.INBOUND);
71              }
72  
73              MuleEvent event = AjaxMessageReceiver.this.routeMessage(messageToRoute);
74              MuleMessage message = event == null ? null : event.getMessage();
75  
76              // only the AjaxConnector (as opposed to the AjaxServletConnector) has the
77              // isDisableReplyTo() method and both inherit from different superclasses
78              if (getConnector() instanceof AjaxConnector)
79              {
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
82                  // want it to.
83                  AjaxConnector ajaxConnector = (AjaxConnector) getConnector();
84                  if (!ajaxConnector.isDisableReplyTo() && message != null && message.getExceptionPayload() == null && replyTo != null)
85                  {
86                      ajaxConnector.getReplyToHandler(endpoint).processReplyTo(RequestContext.getEvent(), message, replyTo);
87                  }
88              }
89              return null;
90          }
91      }
92  
93      public AbstractBayeux getBayeux()
94      {
95          return bayeux;
96      }
97  
98      public void setBayeux(AbstractBayeux bayeux)
99      {
100         this.bayeux = bayeux;
101     }
102 
103     @Override
104     protected void doStart() throws MuleException
105     {
106         //Register our listener service with Bayeux
107         String channel = endpoint.getEndpointURI().getPath();
108         new ReceiverService(channel, getBayeux(), getEndpoint());
109     }
110 }