1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/BasicHttpProcessor.java $
3 * $Revision: 613298 $
4 * $Date: 2008-01-18 14:09:22 -0800 (Fri, 18 Jan 2008) $
5 *
6 * ====================================================================
7 * Licensed to the Apache Software Foundation (ASF) under one
8 * or more contributor license agreements.  See the NOTICE file
9 * distributed with this work for additional information
10 * regarding copyright ownership.  The ASF licenses this file
11 * to you under the Apache License, Version 2.0 (the
12 * "License"); you may not use this file except in compliance
13 * with the License.  You may obtain a copy of the License at
14 *
15 *   http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing,
18 * software distributed under the License is distributed on an
19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20 * KIND, either express or implied.  See the License for the
21 * specific language governing permissions and limitations
22 * under the License.
23 * ====================================================================
24 *
25 * This software consists of voluntary contributions made by many
26 * individuals on behalf of the Apache Software Foundation.  For more
27 * information on the Apache Software Foundation, please see
28 * <http://www.apache.org/>.
29 *
30 */
31
32package org.apache.http.protocol;
33
34import java.io.IOException;
35import java.util.ArrayList;
36import java.util.Iterator;
37import java.util.List;
38
39import org.apache.http.HttpException;
40import org.apache.http.HttpRequest;
41import org.apache.http.HttpRequestInterceptor;
42import org.apache.http.HttpResponse;
43import org.apache.http.HttpResponseInterceptor;
44
45/**
46 * Keeps lists of interceptors for processing requests and responses.
47 *
48 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
49 * @author Andrea Selva
50 *
51 * @version $Revision: 613298 $
52 *
53 * @since 4.0
54 */
55public final class BasicHttpProcessor implements
56    HttpProcessor, HttpRequestInterceptorList, HttpResponseInterceptorList, Cloneable {
57
58    protected List requestInterceptors = null;
59    protected List responseInterceptors = null;
60
61
62    // non-Javadoc, see interface HttpRequestInterceptorList
63    public void addRequestInterceptor(final HttpRequestInterceptor itcp) {
64
65        if (itcp == null) {
66            return;
67        }
68        if (this.requestInterceptors == null) {
69            this.requestInterceptors = new ArrayList();
70        }
71        this.requestInterceptors.add(itcp);
72    }
73
74    // non-Javadoc, see interface HttpRequestInterceptorList
75    public void addRequestInterceptor(final HttpRequestInterceptor itcp,
76                                      int index) {
77        if (index < 0) {
78            throw new IndexOutOfBoundsException(String.valueOf(index));
79        }
80        if (itcp == null) {
81            return;
82        }
83
84        if (this.requestInterceptors == null) {
85            if (index > 0) {
86                throw new IndexOutOfBoundsException(String.valueOf(index));
87            }
88            this.requestInterceptors = new ArrayList();
89        }
90        this.requestInterceptors.add(index, itcp);
91    }
92
93
94    public void addResponseInterceptor(HttpResponseInterceptor itcp,
95                                       int index) {
96        if (index < 0) {
97            throw new IndexOutOfBoundsException(String.valueOf(index));
98        }
99        if (itcp == null) {
100            return;
101        }
102
103        if (this.responseInterceptors == null) {
104            if (index > 0) {
105                throw new IndexOutOfBoundsException(String.valueOf(index));
106            }
107            this.responseInterceptors = new ArrayList();
108        }
109        this.responseInterceptors.add(index, itcp);
110    }
111
112
113    // non-Javadoc, see interface HttpRequestInterceptorList
114    public void removeRequestInterceptorByClass(final Class clazz) {
115        if (this.requestInterceptors == null) {
116            return;
117        }
118        for (Iterator it = this.requestInterceptors.iterator();
119             it.hasNext(); ) {
120            Object request = it.next();
121            if (request.getClass().equals(clazz)) {
122                it.remove();
123            }
124        }
125    }
126
127    // non-Javadoc, see interface HttpResponseInterceptorList
128    public void removeResponseInterceptorByClass(final Class clazz) {
129        if (this.responseInterceptors == null) {
130            return;
131        }
132        for (Iterator it = this.responseInterceptors.iterator();
133             it.hasNext(); ) {
134            Object request = it.next();
135            if (request.getClass().equals(clazz)) {
136                it.remove();
137            }
138        }
139    }
140
141    /**
142     * Same as {@link #addRequestInterceptor(HttpRequestInterceptor) addRequestInterceptor}.
143     *
144     * @param interceptor       the interceptor to add
145     */
146    public final
147            void addInterceptor(final HttpRequestInterceptor interceptor) {
148        addRequestInterceptor(interceptor);
149    }
150
151     public final
152            void addInterceptor(final HttpRequestInterceptor interceptor,
153                                int index) {
154        addRequestInterceptor(interceptor, index);
155    }
156
157
158    // non-Javadoc, see interface HttpRequestInterceptorList
159    public int getRequestInterceptorCount() {
160        return (this.requestInterceptors == null) ?
161            0 : this.requestInterceptors.size();
162    }
163
164
165    // non-Javadoc, see interface HttpRequestInterceptorList
166    public HttpRequestInterceptor getRequestInterceptor(int index) {
167
168        if ((this.requestInterceptors == null) ||
169                (index < 0) || (index >= this.requestInterceptors.size()))
170            return null;
171
172        return (HttpRequestInterceptor) this.requestInterceptors.get(index);
173    }
174
175
176    // non-Javadoc, see interface HttpRequestInterceptorList
177    public void clearRequestInterceptors() {
178        this.requestInterceptors = null;
179    }
180
181
182
183    // non-Javadoc, see interface HttpResponseInterceptorList
184    public void addResponseInterceptor(final HttpResponseInterceptor itcp) {
185        if (itcp == null) {
186            return;
187        }
188        if (this.responseInterceptors == null) {
189            this.responseInterceptors = new ArrayList();
190        }
191        this.responseInterceptors.add(itcp);
192    }
193
194    /**
195     * Same as {@link #addResponseInterceptor(HttpResponseInterceptor) addResponseInterceptor}.
196     *
197     * @param interceptor       the interceptor to add
198     */
199    public final
200            void addInterceptor(final HttpResponseInterceptor interceptor) {
201        addResponseInterceptor(interceptor);
202    }
203
204    public final void addInterceptor(final HttpResponseInterceptor interceptor,
205                                     int index) {
206        addResponseInterceptor(interceptor, index);
207    }
208
209
210
211    // non-Javadoc, see interface HttpResponseInterceptorList
212    public int getResponseInterceptorCount() {
213        return (this.responseInterceptors == null) ?
214            0 : this.responseInterceptors.size();
215    }
216
217
218    // non-Javadoc, see interface HttpResponseInterceptorList
219    public HttpResponseInterceptor getResponseInterceptor(int index) {
220
221        if ((this.responseInterceptors == null) ||
222                (index < 0) || (index >= this.responseInterceptors.size()))
223            return null;
224
225        return (HttpResponseInterceptor) this.responseInterceptors.get(index);
226    }
227
228
229    // non-Javadoc, see interface HttpResponseInterceptorList
230    public void clearResponseInterceptors() {
231        this.responseInterceptors = null;
232    }
233
234
235    /**
236     * Sets the interceptor lists.
237     * First, both interceptor lists maintained by this processor
238     * will be cleared.
239     * Subsequently,
240     * elements of the argument list that are request interceptors will be
241     * added to the request interceptor list.
242     * Elements that are response interceptors will be
243     * added to the response interceptor list.
244     * Elements that are both request and response interceptor will be
245     * added to both lists.
246     * Elements that are neither request nor response interceptor
247     * will be ignored.
248     *
249     * @param list      the list of request and response interceptors
250     *                  from which to initialize
251     */
252    public void setInterceptors(final List list) {
253        if (list == null) {
254            throw new IllegalArgumentException("List must not be null.");
255        }
256        if (this.requestInterceptors != null) {
257            this.requestInterceptors.clear();
258        }
259        if (this.responseInterceptors != null) {
260            this.responseInterceptors.clear();
261        }
262        for (int i = 0; i < list.size(); i++) {
263            Object obj = list.get(i);
264            if (obj instanceof HttpRequestInterceptor) {
265                addInterceptor((HttpRequestInterceptor)obj);
266            }
267            if (obj instanceof HttpResponseInterceptor) {
268                addInterceptor((HttpResponseInterceptor)obj);
269            }
270        }
271    }
272
273    /**
274     * Clears both interceptor lists maintained by this processor.
275     */
276    public void clearInterceptors() {
277        clearRequestInterceptors();
278        clearResponseInterceptors();
279    }
280
281    // non-Javadoc, see interface HttpRequestInterceptor (via HttpProcessor)
282    public void process(
283            final HttpRequest request,
284            final HttpContext context)
285            throws IOException, HttpException {
286        if (this.requestInterceptors != null) {
287            for (int i = 0; i < this.requestInterceptors.size(); i++) {
288                HttpRequestInterceptor interceptor =
289                    (HttpRequestInterceptor) this.requestInterceptors.get(i);
290                interceptor.process(request, context);
291            }
292        }
293    }
294
295    // non-Javadoc, see interface HttpResponseInterceptor (via HttpProcessor)
296    public void process(
297            final HttpResponse response,
298            final HttpContext context)
299            throws IOException, HttpException {
300        if (this.responseInterceptors != null) {
301            for (int i = 0; i < this.responseInterceptors.size(); i++) {
302                HttpResponseInterceptor interceptor =
303                    (HttpResponseInterceptor) this.responseInterceptors.get(i);
304                interceptor.process(response, context);
305            }
306        }
307    }
308
309    protected void copyInterceptors(final BasicHttpProcessor target) {
310        if (this.requestInterceptors != null) {
311            target.requestInterceptors =
312                new ArrayList(this.requestInterceptors);
313        }
314        if (this.responseInterceptors != null) {
315            target.responseInterceptors =
316                new ArrayList(this.responseInterceptors);
317        }
318    }
319
320    /**
321     * Creates a copy of this instance
322     *
323     * @return new instance of the BasicHttpProcessor
324     */
325    public BasicHttpProcessor copy() {
326        BasicHttpProcessor clone = new BasicHttpProcessor();
327        copyInterceptors(clone);
328        return clone;
329    }
330
331    public Object clone() throws CloneNotSupportedException {
332        BasicHttpProcessor clone = (BasicHttpProcessor) super.clone();
333        copyInterceptors(clone);
334        return clone;
335    }
336
337}
338