View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.client;
20  
21  import org.eclipse.jetty.client.api.Result;
22  import org.eclipse.jetty.util.log.Log;
23  import org.eclipse.jetty.util.log.Logger;
24  
25  public abstract class HttpChannel
26  {
27      protected static final Logger LOG = Log.getLogger(HttpChannel.class);
28  
29      private final HttpDestination _destination;
30      private HttpExchange _exchange;
31  
32      protected HttpChannel(HttpDestination destination)
33      {
34          this._destination = destination;
35      }
36  
37      public HttpDestination getHttpDestination()
38      {
39          return _destination;
40      }
41  
42      /**
43       * <p>Associates the given {@code exchange} to this channel in order to be sent over the network.</p>
44       * <p>If the association is successful, the exchange can be sent. Otherwise, the channel must be
45       * disposed because whoever terminated the exchange did not do it - it did not have the channel yet.</p>
46       *
47       * @param exchange the exchange to associate
48       * @return true if the association was successful, false otherwise
49       */
50      public boolean associate(HttpExchange exchange)
51      {
52          boolean result = false;
53          boolean abort = true;
54          synchronized (this)
55          {
56              if (_exchange == null)
57              {
58                  abort = false;
59                  result = exchange.associate(this);
60                  if (result)
61                      _exchange = exchange;
62              }
63          }
64  
65          if (abort)
66              exchange.getRequest().abort(new UnsupportedOperationException("Pipelined requests not supported"));
67  
68          if (LOG.isDebugEnabled())
69              LOG.debug("{} associated {} to {}", exchange, result, this);
70  
71          return result;
72      }
73  
74      public boolean disassociate(HttpExchange exchange)
75      {
76          boolean result = false;
77          synchronized (this)
78          {
79              HttpExchange existing = _exchange;
80              _exchange = null;
81              if (existing == exchange)
82              {
83                  existing.disassociate(this);
84                  result = true;
85              }
86          }
87  
88          if (LOG.isDebugEnabled())
89              LOG.debug("{} disassociated {} from {}", exchange, result, this);
90          return result;
91      }
92  
93      public HttpExchange getHttpExchange()
94      {
95          synchronized (this)
96          {
97              return _exchange;
98          }
99      }
100 
101     protected abstract HttpSender getHttpSender();
102 
103     protected abstract HttpReceiver getHttpReceiver();
104 
105     public abstract void send();
106 
107     public abstract void release();
108 
109     public void proceed(HttpExchange exchange, Throwable failure)
110     {
111         getHttpSender().proceed(exchange, failure);
112     }
113 
114     public boolean abort(HttpExchange exchange, Throwable requestFailure, Throwable responseFailure)
115     {
116         boolean requestAborted = false;
117         if (requestFailure != null)
118             requestAborted = getHttpSender().abort(exchange, requestFailure);
119 
120         boolean responseAborted = false;
121         if (responseFailure != null)
122             responseAborted = abortResponse(exchange, responseFailure);
123 
124         return requestAborted || responseAborted;
125     }
126 
127     public boolean abortResponse(HttpExchange exchange, Throwable failure)
128     {
129         return getHttpReceiver().abort(exchange, failure);
130     }
131 
132     public void exchangeTerminated(HttpExchange exchange, Result result)
133     {
134         disassociate(exchange);
135     }
136 
137     @Override
138     public String toString()
139     {
140         return String.format("%s@%x(exchange=%s)", getClass().getSimpleName(), hashCode(), getHttpExchange());
141     }
142 }