diff --git a/httpclient/src/main/java/org/apache/http/client/URICollection.java b/httpclient/src/main/java/org/apache/http/client/URICollection.java deleted file mode 100644 index 39c439e87..000000000 --- a/httpclient/src/main/java/org/apache/http/client/URICollection.java +++ /dev/null @@ -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 - * . - * - */ - -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 { - - private final Set unique; - private final List all; - - public URICollection() { - super(); - this.unique = new HashSet(); - this.all = new ArrayList(); - } - - /** - * 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 it = this.all.iterator(); - while (it.hasNext()) { - final URI current = it.next(); - if (current.equals(uri)) { - it.remove(); - } - } - } - return removed; - } - - public List getAll() { - return new ArrayList(this.all); - } - - public Set getUnique() { - return new HashSet(this.unique); - } - - public Iterator 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(); - } - -} diff --git a/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java b/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java index fe892c46f..53e1eefda 100644 --- a/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java +++ b/httpclient/src/main/java/org/apache/http/client/protocol/HttpClientContext.java @@ -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 getRedirectLocations() { + return getAttribute(REDIRECT_LOCATIONS, List.class); } public CookieStore getCookieStore() { diff --git a/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java b/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java index 8ba975066..9f1484220 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/RedirectLocations.java @@ -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 { + + private final Set unique; + private final List all; + + public RedirectLocations() { + super(); + this.unique = new HashSet(); + this.all = new ArrayList(); + } + + /** + * 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 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 getAll() { + return new ArrayList(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 ( + * index < 0 || index >= size()) + * @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 Integer.MAX_VALUE elements, returns + * Integer.MAX_VALUE. + * + * @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 set 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 ( + * index < 0 || index >= size()) + * @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 add 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 ( + * index < 0 || index > size()) + * @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 ( + * index < 0 || index >= size()) + * @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 true if this collection contains the specified element. + * More formally, returns true if and only if this collection + * contains at least one element e such that + * (o==null ? e==null : o.equals(e)). + * + * @param o element whose presence in this collection is to be tested + * @return true if this collection contains the specified + * element + */ + @Override + public boolean contains(final Object o) { + return this.unique.contains(o); + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/execchain/RedirectExec.java b/httpclient/src/main/java/org/apache/http/impl/execchain/RedirectExec.java index 25c640d7a..cdedb3ffd 100644 --- a/httpclient/src/main/java/org/apache/http/impl/execchain/RedirectExec.java +++ b/httpclient/src/main/java/org/apache/http/impl/execchain/RedirectExec.java @@ -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 redirectLocations = context.getRedirectLocations(); if (redirectLocations != null) { redirectLocations.clear(); } diff --git a/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultRedirectStrategy.java b/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultRedirectStrategy.java index 5540f8df5..96c91108e 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultRedirectStrategy.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/TestDefaultRedirectStrategy.java @@ -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 uris = redirectLocations.getAll(); + final List 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)); diff --git a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java index 3359b6a9a..f8a2919e6 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientRequestExecution.java @@ -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 redirectLocations = context.getRedirectLocations(); + final URI location = URIUtils.resolve(uri, target, redirectLocations); Assert.assertEquals(uri, location); } diff --git a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java index 7c62f6ae6..ec20288d8 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestRedirects.java @@ -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 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 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)); diff --git a/src/docbkx/fundamentals.xml b/src/docbkx/fundamentals.xml index b9f6673e6..8f96e4728 100644 --- a/src/docbkx/fundamentals.xml +++ b/src/docbkx/fundamentals.xml @@ -609,7 +609,7 @@ try { - URICollection object representing a collection + java.util.List<URI> object representing a collection of all redirect locations received in the process of request execution. @@ -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 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 {