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.impl.client;
29  
30  import java.net.URI;
31  import java.util.AbstractList;
32  import java.util.ArrayList;
33  import java.util.HashSet;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Set;
37  
38  /**
39   * This class represents a collection of {@link java.net.URI}s used
40   * as redirect locations.
41   *
42   * @since 4.0
43   */
44  public class RedirectLocations extends AbstractList<Object> {
45  
46      private final Set<URI> unique;
47      private final List<URI> all;
48  
49      public RedirectLocations() {
50          super();
51          this.unique = new HashSet<URI>();
52          this.all = new ArrayList<URI>();
53      }
54  
55      /**
56       * Test if the URI is present in the collection.
57       */
58      public boolean contains(final URI uri) {
59          return this.unique.contains(uri);
60      }
61  
62      /**
63       * Adds a new URI to the collection.
64       */
65      public void add(final URI uri) {
66          this.unique.add(uri);
67          this.all.add(uri);
68      }
69  
70      /**
71       * Removes a URI from the collection.
72       */
73      public boolean remove(final URI uri) {
74          final boolean removed = this.unique.remove(uri);
75          if (removed) {
76              final Iterator<URI> it = this.all.iterator();
77              while (it.hasNext()) {
78                  final URI current = it.next();
79                  if (current.equals(uri)) {
80                      it.remove();
81                  }
82              }
83          }
84          return removed;
85      }
86  
87      /**
88       * Returns all redirect {@link URI}s in the order they were added to the collection.
89       *
90       * @return list of all URIs
91       *
92       * @since 4.1
93       */
94      public List<URI> getAll() {
95          return new ArrayList<URI>(this.all);
96      }
97  
98      /**
99       * Returns the URI at the specified position in this list.
100      *
101      * @param index
102      *            index of the location to return
103      * @return the URI at the specified position in this list
104      * @throws IndexOutOfBoundsException
105      *             if the index is out of range (
106      *             {@code index &lt; 0 || index &gt;= size()})
107      * @since 4.3
108      */
109     @Override
110     public URI get(final int index) {
111         return this.all.get(index);
112     }
113 
114     /**
115      * Returns the number of elements in this list. If this list contains more
116      * than {@code Integer.MAX_VALUE} elements, returns
117      * {@code Integer.MAX_VALUE}.
118      *
119      * @return the number of elements in this list
120      * @since 4.3
121      */
122     @Override
123     public int size() {
124         return this.all.size();
125     }
126 
127     /**
128      * Replaces the URI at the specified position in this list with the
129      * specified element (must be a URI).
130      *
131      * @param index
132      *            index of the element to replace
133      * @param element
134      *            URI to be stored at the specified position
135      * @return the URI previously at the specified position
136      * @throws UnsupportedOperationException
137      *             if the {@code set} operation is not supported by this list
138      * @throws ClassCastException
139      *             if the element is not a {@link URI}
140      * @throws NullPointerException
141      *             if the specified element is null and this list does not
142      *             permit null elements
143      * @throws IndexOutOfBoundsException
144      *             if the index is out of range (
145      *             {@code index &lt; 0 || index &gt;= size()})
146      * @since 4.3
147      */
148     @Override
149     public Object set(final int index, final Object element) {
150         final URI removed = this.all.set(index, (URI) element);
151         this.unique.remove(removed);
152         this.unique.add((URI) element);
153         if (this.all.size() != this.unique.size()) {
154             this.unique.addAll(this.all);
155         }
156         return removed;
157     }
158 
159     /**
160      * Inserts the specified element at the specified position in this list
161      * (must be a URI). Shifts the URI currently at that position (if any) and
162      * any subsequent URIs to the right (adds one to their indices).
163      *
164      * @param index
165      *            index at which the specified element is to be inserted
166      * @param element
167      *            URI to be inserted
168      * @throws UnsupportedOperationException
169      *             if the {@code add} operation is not supported by this list
170      * @throws ClassCastException
171      *             if the element is not a {@link URI}
172      * @throws NullPointerException
173      *             if the specified element is null and this list does not
174      *             permit null elements
175      * @throws IndexOutOfBoundsException
176      *             if the index is out of range (
177      *             {@code index &lt; 0 || index &gt; size()})
178      * @since 4.3
179      */
180     @Override
181     public void add(final int index, final Object element) {
182         this.all.add(index, (URI) element);
183         this.unique.add((URI) element);
184     }
185 
186     /**
187      * Removes the URI at the specified position in this list. Shifts any
188      * subsequent URIs to the left (subtracts one from their indices). Returns
189      * the URI that was removed from the list.
190      *
191      * @param index
192      *            the index of the URI to be removed
193      * @return the URI previously at the specified position
194      * @throws IndexOutOfBoundsException
195      *             if the index is out of range (
196      *             {@code index &lt; 0 || index &gt;= size()})
197      * @since 4.3
198      */
199     @Override
200     public URI remove(final int index) {
201         final URI removed = this.all.remove(index);
202         this.unique.remove(removed);
203         if (this.all.size() != this.unique.size()) {
204             this.unique.addAll(this.all);
205         }
206         return removed;
207     }
208 
209     /**
210      * Returns {@code true} if this collection contains the specified element.
211      * More formally, returns {@code true} if and only if this collection
212      * contains at least one element {@code e} such that
213      * {@code (o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))}.
214      *
215      * @param o element whose presence in this collection is to be tested
216      * @return {@code true} if this collection contains the specified
217      *         element
218      */
219     @Override
220     public boolean contains(final Object o) {
221         return this.unique.contains(o);
222     }
223 
224 }