1   // ========================================================================
2   // Copyright 2006 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package org.mortbay.cometd.continuation;
16  
17  import org.mortbay.cometd.ClientImpl;
18  import org.mortbay.thread.Timeout;
19  import org.mortbay.util.ajax.Continuation;
20  
21  /* ------------------------------------------------------------ */
22  /**
23   * Extension of {@link ClientImpl} that uses {@link Continuation}s to
24   * resume clients waiting for messages. Continuation clients are used for
25   * remote clients and have removed if they are not accessed within
26   * an idle timeout (@link {@link ContinuationBayeux#_clientTimer}).
27   * 
28   * @author gregw
29   * @deprecated use {@link org.mortbay.cometd.SuspendingClient}
30   *
31   */
32  public class ContinuationClient extends ClientImpl
33  {
34      private long _accessed;
35      public transient Timeout.Task _timeout; 
36      private ContinuationBayeux _bayeux;
37      private transient Continuation _continuation;
38  
39      /* ------------------------------------------------------------ */
40      protected ContinuationClient(ContinuationBayeux bayeux)
41      {
42          super(bayeux);
43          _bayeux=bayeux;
44  
45          if (!isLocal())
46          {
47              _timeout=new Timeout.Task()
48              {
49                  @Override
50  				public void expired()
51                  {
52                      remove(true);
53                  }
54                  @Override
55  				public String toString()
56                  {
57                      return "T-"+ContinuationClient.this.toString();
58                  }
59              };
60              _bayeux.startTimeout(_timeout,getTimeout());
61          }
62      }
63  
64  
65      /* ------------------------------------------------------------ */
66      public void setContinuation(Continuation continuation)
67      {
68          if (continuation==null)
69          {
70              synchronized (this)
71              {
72                  if (_continuation!=null)
73                  {
74                      if(_continuation.isPending())
75                          _continuation.resume(); 
76                  }
77                  _continuation=null;
78                  if(_timeout!=null)
79                      _bayeux.startTimeout(_timeout,getTimeout());
80              }
81          }
82          else
83          {
84              synchronized (this)
85              {
86                  if (_continuation!=null)
87                  {
88                      if(_continuation.isPending())
89                          _continuation.resume(); 
90                  }
91                  _continuation=continuation;
92                  _bayeux.cancelTimeout(_timeout);
93              }
94          }
95      }
96      
97      /* ------------------------------------------------------------ */
98      public Continuation getContinuation()
99      {
100         return _continuation;
101     }
102 
103     /* ------------------------------------------------------------ */
104     @Override
105 	public void resume()
106     {
107         synchronized (this)
108         {
109             if (_continuation!=null)
110             {
111                 _continuation.resume();
112             }
113             _continuation=null;
114         }        
115     }
116 
117     /* ------------------------------------------------------------ */
118     @Override
119     public boolean isLocal()
120     {
121         return false;
122     }
123 
124     /* ------------------------------------------------------------ */
125     public void access()
126     {
127         synchronized(this)
128         {
129             // distribute access time in cluster
130             _accessed=_bayeux.getNow();
131             if (_timeout!=null && _timeout.isScheduled())
132             {
133                 _timeout.reschedule();
134             }
135         }
136     }
137 
138 
139     /* ------------------------------------------------------------ */
140     public synchronized long lastAccessed()
141     {
142         return _accessed;
143     }
144     
145     /* ------------------------------------------------------------ */
146     /* (non-Javadoc)
147      * @see org.mortbay.cometd.ClientImpl#remove(boolean)
148      */
149     @Override
150     public void remove(boolean wasTimeout) 
151     {
152         synchronized(this)
153         {
154             if (!wasTimeout && _timeout!=null)
155                 _bayeux.cancelTimeout(_timeout);
156             _timeout=null;
157             super.remove(wasTimeout);
158         }        
159     }
160 
161 }