1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.servlet.filters.doubleclick;
21  
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.util.servlet.filters.CacheResponse;
24  import com.liferay.util.servlet.filters.CacheResponseData;
25  import com.liferay.util.servlet.filters.CacheResponseUtil;
26  
27  import java.io.IOException;
28  import java.io.Serializable;
29  
30  import javax.servlet.FilterChain;
31  import javax.servlet.ServletException;
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpServletResponse;
34  
35  /**
36   * <a href="DoubleClickController.java.html"><b><i>View Source</i></b></a>
37   *
38   * @author Olaf Fricke
39   * @author Brian Wing Shun Chan
40   *
41   */
42  public class DoubleClickController implements Serializable {
43  
44      public void control(
45              HttpServletRequest request, HttpServletResponse response,
46              FilterChain filterChain)
47          throws IOException, ServletException {
48  
49          boolean firstRequest = false;
50  
51          CacheResponse cacheResponse = null;
52  
53          synchronized (this) {
54              if (_cacheResponse == null) {
55                  firstRequest = true;
56  
57                  _cacheResponse = new CacheResponse(response, StringPool.UTF8);
58                  _throwable = null;
59              }
60  
61              cacheResponse = _cacheResponse;
62          }
63  
64          if (firstRequest) {
65              try {
66                  filterChain.doFilter(request, _cacheResponse);
67              }
68              catch (Throwable t) {
69                  _throwable = t;
70              }
71              finally {
72                  synchronized (this) {
73                      _cacheResponse = null;
74  
75                      notifyAll();
76                  }
77              }
78          }
79          else {
80              synchronized (this) {
81                  while (_cacheResponse != null) {
82                      try {
83                          wait();
84                      }
85                      catch (InterruptedException ie) {
86                          Thread currentThread = Thread.currentThread();
87  
88                          currentThread.interrupt();
89                      }
90                  }
91              }
92          }
93  
94          if (_throwable != null) {
95              try {
96                  throw _throwable;
97              }
98              catch (IOException ioe) {
99                  throw ioe;
100             }
101             catch (ServletException se) {
102                 throw se;
103             }
104             catch (RuntimeException re) {
105                 throw re;
106             }
107             catch (Error e) {
108                 throw e;
109             }
110             catch (Throwable t) {
111                 throw new RuntimeException(t);
112             }
113         }
114 
115         CacheResponseData data = new CacheResponseData(
116             cacheResponse.getData(), cacheResponse.getContentType(),
117             cacheResponse.getHeaders());
118 
119         CacheResponseUtil.write(response, data);
120     }
121 
122     private CacheResponse _cacheResponse;
123     private Throwable _throwable;
124 
125 }