View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.client.methods;
28  
29  import java.io.IOException;
30  import java.util.concurrent.locks.Lock;
31  import java.util.concurrent.locks.ReentrantLock;
32  
33  import org.apache.http.HttpRequest;
34  import org.apache.http.client.utils.CloneUtils;
35  import org.apache.http.concurrent.Cancellable;
36  import org.apache.http.conn.ClientConnectionRequest;
37  import org.apache.http.conn.ConnectionReleaseTrigger;
38  import org.apache.http.message.AbstractHttpMessage;
39  
40  @SuppressWarnings("deprecation")
41  public abstract class AbstractExecutionAwareRequest extends AbstractHttpMessage implements
42          HttpExecutionAware, AbortableHttpRequest, Cloneable, HttpRequest {
43  
44      private Lock abortLock;
45      private volatile boolean aborted;
46      private volatile Cancellable cancellable;
47  
48      protected AbstractExecutionAwareRequest() {
49          super();
50          this.abortLock = new ReentrantLock();
51      }
52  
53      @Deprecated
54      public void setConnectionRequest(final ClientConnectionRequest connRequest) {
55          if (this.aborted) {
56              return;
57          }
58          this.abortLock.lock();
59          try {
60              this.cancellable = new Cancellable() {
61  
62                  public boolean cancel() {
63                      connRequest.abortRequest();
64                      return true;
65                  }
66  
67              };
68          } finally {
69              this.abortLock.unlock();
70          }
71      }
72  
73      @Deprecated
74      public void setReleaseTrigger(final ConnectionReleaseTrigger releaseTrigger) {
75          if (this.aborted) {
76              return;
77          }
78          this.abortLock.lock();
79          try {
80              this.cancellable = new Cancellable() {
81  
82                  public boolean cancel() {
83                      try {
84                          releaseTrigger.abortConnection();
85                          return true;
86                      } catch (final IOException ex) {
87                          return false;
88                      }
89                  }
90  
91              };
92          } finally {
93              this.abortLock.unlock();
94          }
95      }
96  
97      private void cancelExecution() {
98          if (this.cancellable != null) {
99              this.cancellable.cancel();
100             this.cancellable = null;
101         }
102     }
103 
104     public void abort() {
105         if (this.aborted) {
106             return;
107         }
108         this.abortLock.lock();
109         try {
110             this.aborted = true;
111             cancelExecution();
112         } finally {
113             this.abortLock.unlock();
114         }
115     }
116 
117     public boolean isAborted() {
118         return this.aborted;
119     }
120 
121     /**
122      * @since 4.2
123      */
124     public void setCancellable(final Cancellable cancellable) {
125         if (this.aborted) {
126             return;
127         }
128         this.abortLock.lock();
129         try {
130             this.cancellable = cancellable;
131         } finally {
132             this.abortLock.unlock();
133         }
134     }
135 
136     @Override
137     public Object clone() throws CloneNotSupportedException {
138         final AbstractExecutionAwareRequest clone = (AbstractExecutionAwareRequest) super.clone();
139         clone.headergroup = CloneUtils.cloneObject(this.headergroup);
140         clone.params = CloneUtils.cloneObject(this.params);
141         clone.abortLock = new ReentrantLock();
142         clone.cancellable = null;
143         clone.aborted = false;
144         return clone;
145     }
146 
147     /**
148      * @since 4.2
149      */
150     public void completed() {
151         this.abortLock.lock();
152         try {
153             this.cancellable = null;
154         } finally {
155             this.abortLock.unlock();
156         }
157     }
158 
159     /**
160      * Resets internal state of the request making it reusable.
161      *
162      * @since 4.2
163      */
164     public void reset() {
165         this.abortLock.lock();
166         try {
167             cancelExecution();
168             this.aborted = false;
169         } finally {
170             this.abortLock.unlock();
171         }
172     }
173 
174 }