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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index > 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 < 0 || index >= 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 ? e==null : 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 }