HTTPCLIENT-1387: Replace URICollection with List<URI>

Contributed by James Leigh <james at 3roundstones dot com>

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1514671 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2013-08-16 12:13:27 +00:00
parent ee1fec2a8c
commit 089daca602
8 changed files with 213 additions and 143 deletions

View File

@ -1,113 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.http.annotation.NotThreadSafe;
/**
* This class represents an iterable collection of {@link URI}s.
*
* @since 4.3
*/
@NotThreadSafe // HashSet is not synch.
public class URICollection implements Iterable<URI> {
private final Set<URI> unique;
private final List<URI> all;
public URICollection() {
super();
this.unique = new HashSet<URI>();
this.all = new ArrayList<URI>();
}
/**
* Test if the URI is present in the collection.
*/
public boolean contains(final URI uri) {
return this.unique.contains(uri);
}
/**
* Adds a new URI to the collection.
*/
public void add(final URI uri) {
this.unique.add(uri);
this.all.add(uri);
}
/**
* Removes a URI from the collection.
*/
public boolean remove(final URI uri) {
final boolean removed = this.unique.remove(uri);
if (removed) {
final Iterator<URI> it = this.all.iterator();
while (it.hasNext()) {
final URI current = it.next();
if (current.equals(uri)) {
it.remove();
}
}
}
return removed;
}
public List<URI> getAll() {
return new ArrayList<URI>(this.all);
}
public Set<URI> getUnique() {
return new HashSet<URI>(this.unique);
}
public Iterator<URI> iterator() {
return getAll().iterator();
}
public int getCount() {
return this.all.size();
}
public boolean isEmpty() {
return this.all.isEmpty();
}
public void clear() {
this.all.clear();
this.unique.clear();
}
}

View File

@ -27,13 +27,15 @@
package org.apache.http.client.protocol;
import java.net.URI;
import java.util.List;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthState;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.URICollection;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Lookup;
import org.apache.http.conn.routing.HttpRoute;
@ -61,9 +63,8 @@ public class HttpClientContext extends HttpCoreContext {
public static final String HTTP_ROUTE = "http.route";
/**
* Attribute name of a {@link org.apache.http.client.URICollection} object that
* represents a collection of all redirect locations received in the process
* of request execution.
* Attribute name of a {@link List} object that represents a collection of all
* redirect locations received in the process of request execution.
*/
public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations";
@ -157,8 +158,9 @@ public class HttpClientContext extends HttpCoreContext {
return getAttribute(HTTP_ROUTE, HttpRoute.class);
}
public URICollection getRedirectLocations() {
return getAttribute(REDIRECT_LOCATIONS, URICollection.class);
@SuppressWarnings("unchecked") // type parameter
public List<URI> getRedirectLocations() {
return getAttribute(REDIRECT_LOCATIONS, List.class);
}
public CookieStore getCookieStore() {

View File

@ -27,8 +27,15 @@
package org.apache.http.impl.client;
import java.net.URI;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.client.URICollection;
/**
* This class represents a collection of {@link java.net.URI}s used
@ -36,6 +43,185 @@ import org.apache.http.client.URICollection;
*
* @since 4.0
*/
@NotThreadSafe
public class RedirectLocations extends URICollection {
@NotThreadSafe // HashSet/ArrayList are not synch.
public class RedirectLocations extends AbstractList<Object> {
private final Set<URI> unique;
private final List<URI> all;
public RedirectLocations() {
super();
this.unique = new HashSet<URI>();
this.all = new ArrayList<URI>();
}
/**
* Test if the URI is present in the collection.
*/
public boolean contains(final URI uri) {
return this.unique.contains(uri);
}
/**
* Adds a new URI to the collection.
*/
public void add(final URI uri) {
this.unique.add(uri);
this.all.add(uri);
}
/**
* Removes a URI from the collection.
*/
public boolean remove(final URI uri) {
final boolean removed = this.unique.remove(uri);
if (removed) {
final Iterator<URI> it = this.all.iterator();
while (it.hasNext()) {
final URI current = it.next();
if (current.equals(uri)) {
it.remove();
}
}
}
return removed;
}
/**
* Returns all redirect {@link URI}s in the order they were added to the collection.
*
* @return list of all URIs
*
* @since 4.1
*/
public List<URI> getAll() {
return new ArrayList<URI>(this.all);
}
/**
* Returns the URI at the specified position in this list.
*
* @param index
* index of the location to return
* @return the URI at the specified position in this list
* @throws IndexOutOfBoundsException
* if the index is out of range (
* <tt>index &lt; 0 || index &gt;= size()</tt>)
* @since 4.3
*/
@Override
public URI get(final int index) {
return this.all.get(index);
}
/**
* Returns the number of elements in this list. If this list contains more
* than <tt>Integer.MAX_VALUE</tt> elements, returns
* <tt>Integer.MAX_VALUE</tt>.
*
* @return the number of elements in this list
* @since 4.3
*/
@Override
public int size() {
return this.all.size();
}
/**
* Replaces the URI at the specified position in this list with the
* specified element (must be a URI).
*
* @param index
* index of the element to replace
* @param element
* URI to be stored at the specified position
* @return the URI previously at the specified position
* @throws UnsupportedOperationException
* if the <tt>set</tt> operation is not supported by this list
* @throws ClassCastException
* if the element is not a {@link URI}
* @throws NullPointerException
* if the specified element is null and this list does not
* permit null elements
* @throws IndexOutOfBoundsException
* if the index is out of range (
* <tt>index &lt; 0 || index &gt;= size()</tt>)
* @since 4.3
*/
@Override
public Object set(final int index, final Object element) {
final URI removed = this.all.set(index, (URI) element);
this.unique.remove(removed);
this.unique.add((URI) element);
if (this.all.size() != this.unique.size()) {
this.unique.addAll(this.all);
}
return removed;
}
/**
* Inserts the specified element at the specified position in this list
* (must be a URI). Shifts the URI currently at that position (if any) and
* any subsequent URIs to the right (adds one to their indices).
*
* @param index
* index at which the specified element is to be inserted
* @param element
* URI to be inserted
* @throws UnsupportedOperationException
* if the <tt>add</tt> operation is not supported by this list
* @throws ClassCastException
* if the element is not a {@link URI}
* @throws NullPointerException
* if the specified element is null and this list does not
* permit null elements
* @throws IndexOutOfBoundsException
* if the index is out of range (
* <tt>index &lt; 0 || index &gt; size()</tt>)
* @since 4.3
*/
@Override
public void add(final int index, final Object element) {
this.all.add(index, (URI) element);
this.unique.add((URI) element);
}
/**
* Removes the URI at the specified position in this list. Shifts any
* subsequent URIs to the left (subtracts one from their indices). Returns
* the URI that was removed from the list.
*
* @param index
* the index of the URI to be removed
* @return the URI previously at the specified position
* @throws IndexOutOfBoundsException
* if the index is out of range (
* <tt>index &lt; 0 || index &gt;= size()</tt>)
* @since 4.3
*/
@Override
public URI remove(final int index) {
final URI removed = this.all.remove(index);
this.unique.remove(removed);
if (this.all.size() != this.unique.size()) {
this.unique.addAll(this.all);
}
return removed;
}
/**
* Returns <tt>true</tt> if this collection contains the specified element.
* More formally, returns <tt>true</tt> if and only if this collection
* contains at least one element <tt>e</tt> such that
* <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
*
* @param o element whose presence in this collection is to be tested
* @return <tt>true</tt> if this collection contains the specified
* element
*/
@Override
public boolean contains(final Object o) {
return this.unique.contains(o);
}
}

View File

@ -29,6 +29,7 @@ package org.apache.http.impl.execchain;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -42,7 +43,6 @@ import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthState;
import org.apache.http.client.RedirectException;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.URICollection;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpExecutionAware;
@ -88,7 +88,7 @@ public class RedirectExec implements ClientExecChain {
Args.notNull(request, "HTTP request");
Args.notNull(context, "HTTP context");
final URICollection redirectLocations = context.getRedirectLocations();
final List<URI> redirectLocations = context.getRedirectLocations();
if (redirectLocations != null) {
redirectLocations.clear();
}

View File

@ -36,7 +36,6 @@ import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.ProtocolException;
import org.apache.http.client.URICollection;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
@ -293,13 +292,11 @@ public class TestDefaultRedirectStrategy {
Assert.assertEquals(uri2, redirectStrategy.getLocationURI(httpget2, response2, context));
Assert.assertEquals(uri3, redirectStrategy.getLocationURI(httpget3, response3, context));
final URICollection redirectLocations = context.getRedirectLocations();
Assert.assertNotNull(redirectLocations);
Assert.assertTrue(redirectLocations.contains(uri1));
Assert.assertTrue(redirectLocations.contains(uri2));
Assert.assertTrue(redirectLocations.contains(uri3));
final List<URI> uris = redirectLocations.getAll();
final List<URI> uris = context.getRedirectLocations();
Assert.assertNotNull(uris);
Assert.assertTrue(uris.contains(uri1));
Assert.assertTrue(uris.contains(uri2));
Assert.assertTrue(uris.contains(uri3));
Assert.assertEquals(3, uris.size());
Assert.assertEquals(uri1, uris.get(0));
Assert.assertEquals(uri2, uris.get(1));

View File

@ -29,6 +29,7 @@ package org.apache.http.impl.client.integration;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpClientConnection;
@ -41,7 +42,6 @@ import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.NonRepeatableRequestException;
import org.apache.http.client.URICollection;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
@ -260,9 +260,8 @@ public class TestClientRequestExecution extends IntegrationTestBase {
final HttpRequest request = context.getRequest();
Assert.assertEquals("/stuff", request.getRequestLine().getUri());
final URICollection redirectLocations = context.getRedirectLocations();
final URI location = URIUtils.resolve(uri, target,
redirectLocations != null ? redirectLocations.getAll() : null);
final List<URI> redirectLocations = context.getRedirectLocations();
final URI location = URIUtils.resolve(uri, target, redirectLocations);
Assert.assertEquals(uri, location);
}

View File

@ -29,6 +29,7 @@ package org.apache.http.impl.client.integration;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpException;
@ -42,7 +43,6 @@ import org.apache.http.client.CircularRedirectException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.RedirectException;
import org.apache.http.client.URICollection;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
@ -248,7 +248,7 @@ public class TestRedirects extends IntegrationTestBase {
Assert.assertEquals(HttpStatus.SC_MULTIPLE_CHOICES, response.getStatusLine().getStatusCode());
Assert.assertEquals("/oldlocation/", reqWrapper.getRequestLine().getUri());
final URICollection redirects = context.getRedirectLocations();
final List<URI> redirects = context.getRedirectLocations();
Assert.assertNull(redirects);
}
@ -272,9 +272,9 @@ public class TestRedirects extends IntegrationTestBase {
Assert.assertEquals("/newlocation/", reqWrapper.getRequestLine().getUri());
Assert.assertEquals(target, host);
final URICollection redirects = context.getRedirectLocations();
final List<URI> redirects = context.getRedirectLocations();
Assert.assertNotNull(redirects);
Assert.assertEquals(1, redirects.getCount());
Assert.assertEquals(1, redirects.size());
final URI redirect = URIUtils.rewriteURI(new URI("/newlocation/"), target);
Assert.assertTrue(redirects.contains(redirect));

View File

@ -609,7 +609,7 @@ try {
</listitem>
<listitem>
<formalpara>
<para><classname>URICollection</classname> object representing a collection
<para><classname>java.util.List&lt;URI&gt;</classname> object representing a collection
of all redirect locations received in the process of request
execution.</para>
</formalpara>
@ -868,9 +868,8 @@ HttpGet httpget = new HttpGet("http://localhost:8080/");
CloseableHttpResponse response = httpclient.execute(httpget, context);
try {
HttpHost target = context.getTargetHost();
URICollection redirectLocations = context.getRedirectLocations();
URI location = URIUtils.resolve(httpget.getURI(), target,
redirectLocations != null ? redirectLocations.getAll() : null);
List<URI> redirectLocations = context.getRedirectLocations();
URI location = URIUtils.resolve(httpget.getURI(), target, redirectLocations);
System.out.println("Final HTTP location: " + location.toASCIIString());
// Expected to be an absolute URI
} finally {