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.container;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleException;
11  import org.mule.api.construct.FlowConstruct;
12  import org.mule.api.endpoint.ImmutableEndpoint;
13  import org.mule.api.endpoint.InboundEndpoint;
14  import org.mule.api.transport.MessageReceiver;
15  import org.mule.api.transport.ReplyToHandler;
16  import org.mule.transport.AbstractConnector;
17  import org.mule.transport.ajax.AjaxMessageReceiver;
18  import org.mule.transport.ajax.AjaxReplyToHandler;
19  import org.mule.transport.ajax.BayeuxAware;
20  import org.mule.transport.ajax.embedded.AjaxConnector;
21  import org.mule.transport.servlet.ServletConnector;
22  
23  import org.cometd.DataFilter;
24  import org.mortbay.cometd.AbstractBayeux;
25  
26  /**
27   * A servlet connector that binds to the container and makes a configured 
28   * Bayeux available to dispatchers and receivers.
29   */
30  public class AjaxServletConnector extends ServletConnector implements BayeuxAware
31  {
32      public static final String PROTOCOL = "ajax-servlet";
33  
34      /**
35       * The client side poll timeout in milliseconds (default 0). How long a client
36       * will wait between reconnects
37       */
38      private int interval = INT_VALUE_NOT_SET;
39  
40      /**
41       * The max client side poll timeout in milliseconds (default 30000). A client 
42       * will be removed if a connection is not received in this time.
43       */
44      private int maxInterval = INT_VALUE_NOT_SET;
45  
46      /**
47       * The client side poll timeout if multiple connections are detected from the 
48       * same browser (default 1500).
49       */
50      private int multiFrameInterval = INT_VALUE_NOT_SET;
51  
52      /**
53       * 0=none, 1=info, 2=debug
54       */
55      private int logLevel = INT_VALUE_NOT_SET;
56  
57      /**
58       * The server side poll timeout in milliseconds (default 250000). This is how long 
59       * the server will hold a reconnect request before responding.
60       */
61      private int timeout = INT_VALUE_NOT_SET;
62  
63      /**
64       * If "true" (default) then the server will accept JSON wrapped in a comment and 
65       * will generate JSON wrapped in a comment. This is a defence against Ajax Hijacking.
66       */
67      private boolean jsonCommented = true;
68  
69      /**
70       * TODO SUPPORT FILTERS
71       * the location of a JSON file describing {@link DataFilter} instances to be installed
72       */
73      private String filters;
74  
75      /**
76       * If true, the current request is made available via the 
77       * {@link AbstractBayeux#getCurrentRequest()} method
78       */
79      private boolean requestAvailable = true;
80  
81      /**
82       * The number of message refs at which the a single message response will be
83       * cached instead of being generated for every client delivered to. Done to optimize
84       * a single message being sent to multiple clients.
85       */
86      private int refsThreshold = INT_VALUE_NOT_SET;
87      
88  
89      protected AbstractBayeux bayeux;
90  
91      public AjaxServletConnector(MuleContext context) 
92      {
93          super(context);
94          registerSupportedProtocolWithoutPrefix(AjaxConnector.PROTOCOL);
95          //Dont start until the servletContainer is up
96          setInitialStateStopped(true);
97      }
98  
99      public AbstractBayeux getBayeux()
100     {
101         return bayeux;
102     }
103 
104     public void setBayeux(AbstractBayeux bayeux) throws MuleException
105     {
106         this.bayeux = bayeux;
107         this.getBayeux().setJSONCommented(isJsonCommented());
108         if(getLogLevel() != AbstractConnector.INT_VALUE_NOT_SET) this.getBayeux().setLogLevel(getLogLevel());
109         if(getMaxInterval() != AbstractConnector.INT_VALUE_NOT_SET) this.getBayeux().setMaxInterval(getMaxInterval());
110         if(getInterval() != AbstractConnector.INT_VALUE_NOT_SET) this.getBayeux().setInterval(getMaxInterval());
111         if(getMultiFrameInterval() != AbstractConnector.INT_VALUE_NOT_SET) this.getBayeux().setMultiFrameInterval(getMultiFrameInterval());
112         if(getTimeout() != AbstractConnector.INT_VALUE_NOT_SET) this.getBayeux().setTimeout(getMultiFrameInterval());
113         //Only start once we have this
114         this.setInitialStateStopped(false);
115         
116         for (Object receiver : receivers.values())
117         {
118             ((AjaxMessageReceiver)receiver).setBayeux(getBayeux());
119         }
120         start();
121     }
122 
123     @Override
124     public String getProtocol()
125     {
126         return PROTOCOL;
127     }
128 
129     public int getInterval()
130     {
131         return interval;
132     }
133 
134     public void setInterval(int interval)
135     {
136         this.interval = interval;
137     }
138 
139     public int getMaxInterval()
140     {
141         return maxInterval;
142     }
143 
144     public void setMaxInterval(int maxInterval)
145     {
146         this.maxInterval = maxInterval;
147     }
148 
149     public int getMultiFrameInterval()
150     {
151         return multiFrameInterval;
152     }
153 
154     public void setMultiFrameInterval(int multiFrameInterval)
155     {
156         this.multiFrameInterval = multiFrameInterval;
157     }
158 
159     public int getLogLevel()
160     {
161         return logLevel;
162     }
163 
164     public void setLogLevel(int logLevel)
165     {
166         this.logLevel = logLevel;
167     }
168 
169     public int getTimeout()
170     {
171         return timeout;
172     }
173 
174     public void setTimeout(int timeout)
175     {
176         this.timeout = timeout;
177     }
178 
179     public boolean isJsonCommented()
180     {
181         return jsonCommented;
182     }
183 
184     public void setJsonCommented(boolean jsonCommented)
185     {
186         this.jsonCommented = jsonCommented;
187     }
188 
189     public String getFilters()
190     {
191         return filters;
192     }
193 
194     public void setFilters(String filters)
195     {
196         this.filters = filters;
197     }
198 
199     public boolean isRequestAvailable()
200     {
201         return requestAvailable;
202     }
203 
204     public void setRequestAvailable(boolean requestAvailable)
205     {
206         this.requestAvailable = requestAvailable;
207     }
208 
209     public int getRefsThreshold()
210     {
211         return refsThreshold;
212     }
213 
214     public void setRefsThreshold(int refsThreshold)
215     {
216         this.refsThreshold = refsThreshold;
217     }
218 
219     @Override
220     public ReplyToHandler getReplyToHandler(ImmutableEndpoint endpoint)
221     {
222         return new AjaxReplyToHandler(getDefaultResponseTransformers(endpoint), this);
223     }
224 
225     @Override
226     protected MessageReceiver createReceiver(FlowConstruct flowConstruct, InboundEndpoint endpoint) throws Exception
227     {
228         AjaxMessageReceiver receiver = (AjaxMessageReceiver) super.createReceiver(flowConstruct, endpoint);
229         //The Bayeux object will be null of the connector has not started yet, nothing to worry about
230         receiver.setBayeux(getBayeux());
231         return receiver;
232     }
233 }