View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2012-2015 ForgeRock AS.
15   */
16  
17  package org.forgerock.http.servlet;
18  
19  import java.io.IOException;
20  
21  import jakarta.servlet.AsyncContext;
22  import jakarta.servlet.AsyncEvent;
23  import jakarta.servlet.AsyncListener;
24  import jakarta.servlet.http.HttpServletRequest;
25  import jakarta.servlet.http.HttpServletResponse;
26  
27  import org.forgerock.http.servlet.Servlet2Adapter.Servlet2Synchronizer;
28  
29  /**
30   * An adapter for use in Servlet 3.x containers.
31   */
32  final class Servlet3Adapter implements ServletVersionAdapter {
33  
34      /**
35       * Synchronization implementation - only used when the container supports
36       * asynchronous processing.
37       */
38      private final static class Servlet3Synchronizer implements ServletSynchronizer {
39          private final AsyncContext asyncContext;
40  
41          private Servlet3Synchronizer(HttpServletRequest httpRequest) {
42              if (httpRequest.isAsyncStarted()) {
43                  this.asyncContext = httpRequest.getAsyncContext();
44              } else {
45                  this.asyncContext = httpRequest.startAsync();
46                  // Disable timeouts for certain containers - see http://java.net/jira/browse/GRIZZLY-1325
47                  asyncContext.setTimeout(0);
48              }
49          }
50  
51          @Override
52          public void setAsyncListener(final Runnable runnable) {
53              asyncContext.addListener(new AsyncListener() {
54  
55                  @Override
56                  public void onComplete(AsyncEvent event) throws IOException {
57                      runnable.run();
58                  }
59  
60                  @Override
61                  public void onError(AsyncEvent event) throws IOException {
62                      runnable.run();
63                  }
64  
65                  @Override
66                  public void onStartAsync(AsyncEvent event) throws IOException {
67                      // Reregister.
68                      event.getAsyncContext().addListener(this);
69                  }
70  
71                  @Override
72                  public void onTimeout(AsyncEvent event) throws IOException {
73                      runnable.run();
74                  }
75              });
76          }
77  
78          @Override
79          public void awaitIfNeeded() throws InterruptedException {
80              // Nothing to signal: this dispatcher is non-blocking.
81          }
82  
83          @Override
84          public void signalAndComplete() {
85              asyncContext.complete();
86          }
87      }
88  
89      Servlet3Adapter() {
90          // Nothing to do.
91      }
92  
93      @Override
94      public ServletSynchronizer createServletSynchronizer(HttpServletRequest httpRequest,
95              HttpServletResponse httpResponse) {
96          if (httpRequest.isAsyncSupported()) {
97              return new Servlet3Synchronizer(httpRequest);
98          } else {
99              // Fall-back to Servlet 2 blocking implementation.
100             return new Servlet2Synchronizer();
101         }
102     }
103 }