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  
28  package org.apache.http.protocol;
29  
30  import java.io.IOException;
31  import java.util.ArrayList;
32  import java.util.Iterator;
33  import java.util.List;
34  
35  import org.apache.http.HttpException;
36  import org.apache.http.HttpRequest;
37  import org.apache.http.HttpRequestInterceptor;
38  import org.apache.http.HttpResponse;
39  import org.apache.http.HttpResponseInterceptor;
40  import org.apache.http.annotation.NotThreadSafe;
41  
42  /**
43   * Default implementation of {@link HttpProcessor}.
44   * <p>
45   * Please note access to the internal structures of this class is not
46   * synchronized and therefore this class may be thread-unsafe.
47   *
48   * @since 4.0
49   */
50  @NotThreadSafe
51  public final class BasicHttpProcessor implements
52      HttpProcessor, HttpRequestInterceptorList, HttpResponseInterceptorList, Cloneable {
53  
54      // Don't allow direct access, as nulls are not allowed
55      protected final List<HttpRequestInterceptor> requestInterceptors = new ArrayList<HttpRequestInterceptor>();
56      protected final List<HttpResponseInterceptor> responseInterceptors = new ArrayList<HttpResponseInterceptor>();
57  
58      public void addRequestInterceptor(final HttpRequestInterceptor itcp) {
59          if (itcp == null) {
60              return;
61          }
62          this.requestInterceptors.add(itcp);
63      }
64  
65      public void addRequestInterceptor(
66              final HttpRequestInterceptor itcp, int index) {
67          if (itcp == null) {
68              return;
69          }
70          this.requestInterceptors.add(index, itcp);
71      }
72  
73      public void addResponseInterceptor(
74              final HttpResponseInterceptor itcp, int index) {
75          if (itcp == null) {
76              return;
77          }
78          this.responseInterceptors.add(index, itcp);
79      }
80  
81      public void removeRequestInterceptorByClass(final Class<? extends HttpRequestInterceptor> clazz) {
82          for (Iterator<HttpRequestInterceptor> it = this.requestInterceptors.iterator();
83               it.hasNext(); ) {
84              Object request = it.next();
85              if (request.getClass().equals(clazz)) {
86                  it.remove();
87              }
88          }
89      }
90  
91      public void removeResponseInterceptorByClass(final Class<? extends HttpResponseInterceptor> clazz) {
92          for (Iterator<HttpResponseInterceptor> it = this.responseInterceptors.iterator();
93               it.hasNext(); ) {
94              Object request = it.next();
95              if (request.getClass().equals(clazz)) {
96                  it.remove();
97              }
98          }
99      }
100 
101     public final void addInterceptor(final HttpRequestInterceptor interceptor) {
102         addRequestInterceptor(interceptor);
103     }
104 
105      public final void addInterceptor(final HttpRequestInterceptor interceptor, int index) {
106         addRequestInterceptor(interceptor, index);
107     }
108 
109     public int getRequestInterceptorCount() {
110         return this.requestInterceptors.size();
111     }
112 
113     public HttpRequestInterceptor getRequestInterceptor(int index) {
114         if ((index < 0) || (index >= this.requestInterceptors.size()))
115             return null;
116         return this.requestInterceptors.get(index);
117     }
118 
119     public void clearRequestInterceptors() {
120         this.requestInterceptors.clear();
121     }
122 
123     public void addResponseInterceptor(final HttpResponseInterceptor itcp) {
124         if (itcp == null) {
125             return;
126         }
127         this.responseInterceptors.add(itcp);
128     }
129 
130     public final void addInterceptor(final HttpResponseInterceptor interceptor) {
131         addResponseInterceptor(interceptor);
132     }
133 
134     public final void addInterceptor(final HttpResponseInterceptor interceptor, int index) {
135         addResponseInterceptor(interceptor, index);
136     }
137 
138     public int getResponseInterceptorCount() {
139         return this.responseInterceptors.size();
140     }
141 
142     public HttpResponseInterceptor getResponseInterceptor(int index) {
143         if ((index < 0) || (index >= this.responseInterceptors.size()))
144             return null;
145         return this.responseInterceptors.get(index);
146     }
147 
148     public void clearResponseInterceptors() {
149         this.responseInterceptors.clear();
150     }
151 
152     /**
153      * Sets the interceptor lists.
154      * First, both interceptor lists maintained by this processor
155      * will be cleared.
156      * Subsequently,
157      * elements of the argument list that are request interceptors will be
158      * added to the request interceptor list.
159      * Elements that are response interceptors will be
160      * added to the response interceptor list.
161      * Elements that are both request and response interceptor will be
162      * added to both lists.
163      * Elements that are neither request nor response interceptor
164      * will be ignored.
165      *
166      * @param list      the list of request and response interceptors
167      *                  from which to initialize
168      */
169     public void setInterceptors(final List<?> list) {
170         if (list == null) {
171             throw new IllegalArgumentException("List must not be null.");
172         }
173         this.requestInterceptors.clear();
174         this.responseInterceptors.clear();
175         for (int i = 0; i < list.size(); i++) {
176             Object obj = list.get(i);
177             if (obj instanceof HttpRequestInterceptor) {
178                 addInterceptor((HttpRequestInterceptor)obj);
179             }
180             if (obj instanceof HttpResponseInterceptor) {
181                 addInterceptor((HttpResponseInterceptor)obj);
182             }
183         }
184     }
185 
186     /**
187      * Clears both interceptor lists maintained by this processor.
188      */
189     public void clearInterceptors() {
190         clearRequestInterceptors();
191         clearResponseInterceptors();
192     }
193 
194     public void process(
195             final HttpRequest request,
196             final HttpContext context)
197             throws IOException, HttpException {
198         for (int i = 0; i < this.requestInterceptors.size(); i++) {
199             HttpRequestInterceptor interceptor =
200                 this.requestInterceptors.get(i);
201             interceptor.process(request, context);
202         }
203     }
204 
205     public void process(
206             final HttpResponse response,
207             final HttpContext context)
208             throws IOException, HttpException {
209         for (int i = 0; i < this.responseInterceptors.size(); i++) {
210             HttpResponseInterceptor interceptor =
211                 this.responseInterceptors.get(i);
212             interceptor.process(response, context);
213         }
214     }
215 
216     /**
217      * Sets up the target to have the same list of interceptors
218      * as the current instance.
219      *
220      * @param target object to be initialised
221      */
222     protected void copyInterceptors(final BasicHttpProcessor target) {
223         target.requestInterceptors.clear();
224         target.requestInterceptors.addAll(this.requestInterceptors);
225         target.responseInterceptors.clear();
226         target.responseInterceptors.addAll(this.responseInterceptors);
227     }
228 
229     /**
230      * Creates a copy of this instance
231      *
232      * @return new instance of the BasicHttpProcessor
233      */
234     public BasicHttpProcessor copy() {
235         BasicHttpProcessor clone = new BasicHttpProcessor();
236         copyInterceptors(clone);
237         return clone;
238     }
239 
240     @Override
241     public Object clone() throws CloneNotSupportedException {
242         BasicHttpProcessor clone = (BasicHttpProcessor) super.clone();
243         copyInterceptors(clone);
244         return clone;
245     }
246 
247 }