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                  public void expired()
50                  {
51                      remove(true);
52                  }
53                  public String toString()
54                  {
55                      return "T-"+ContinuationClient.this.toString();
56                  }
57              };
58              _bayeux.startTimeout(_timeout,getTimeout());
59          }
60      }
61  
62  
63      /* ------------------------------------------------------------ */
64      public void setContinuation(Continuation continuation)
65      {
66          Timeout.Task task=null;
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                  task=_timeout;
79              }
80  
81              if (task!=null)
82                  _bayeux.startTimeout(task,getTimeout());
83          }
84          else
85          {
86              synchronized (this)
87              {
88                  if (_continuation!=null)
89                  {
90                      if(_continuation.isPending())
91                          _continuation.resume(); 
92                  }
93                  _continuation=continuation;
94                  task=_timeout;
95              }
96  
97              if (task!=null)
98                  _bayeux.cancelTimeout(task);
99          }
100     }
101     
102     /* ------------------------------------------------------------ */
103     public Continuation getContinuation()
104     {
105         return _continuation;
106     }
107 
108     /* ------------------------------------------------------------ */
109     public void resume()
110     {
111         Timeout.Task task=null;
112         synchronized (this)
113         {
114             if (_continuation!=null)
115             {
116                 _continuation.resume();
117                 task=_timeout;
118             }
119             _continuation=null;
120         }
121         
122         if (task!=null)
123             _bayeux.startTimeout(task,getTimeout());
124     }
125 
126     /* ------------------------------------------------------------ */
127     public boolean isLocal()
128     {
129         return false;
130     }
131 
132     /* ------------------------------------------------------------ */
133     public void access()
134     {
135         Timeout.Task task=null;
136         synchronized(this)
137         {
138             // distribute access time in cluster
139             _accessed=_bayeux.getNow();
140             if (_timeout!=null && _timeout.isScheduled())
141                 task=_timeout;
142         }
143         
144         if (task!=null)
145             _bayeux.startTimeout(task,getTimeout());
146     }
147 
148 
149     /* ------------------------------------------------------------ */
150     public synchronized long lastAccessed()
151     {
152         return _accessed;
153     }
154     
155     /* ------------------------------------------------------------ */
156     /* (non-Javadoc)
157      * @see org.mortbay.cometd.ClientImpl#remove(boolean)
158      */
159     public void remove(boolean wasTimeout) 
160     {
161         Timeout.Task task=null;
162         synchronized(this)
163         {
164             if (!wasTimeout)
165                 task=_timeout;
166             _timeout=null;
167             super.remove(wasTimeout);
168         }
169         
170         if (task!=null)
171             _bayeux.cancelTimeout(task);
172         
173     }
174 
175 }