From 05e03b6a0e3981a69e8670ab28add7029ca64fb4 Mon Sep 17 00:00:00 2001 From: Roland Weber Date: Sat, 22 Sep 2007 18:18:54 +0000 Subject: [PATCH] HTTPCLIENT-689: stackable parameters, take 1 git-svn-id: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpclient/trunk@578468 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/impl/client/AbstractHttpClient.java | 3 +- .../http/impl/client/ClientParamsStack.java | 291 ++++++++++++++++++ .../client/DefaultClientRequestDirector.java | 11 +- 3 files changed, 301 insertions(+), 4 deletions(-) create mode 100644 module-client/src/main/java/org/apache/http/impl/client/ClientParamsStack.java diff --git a/module-client/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java b/module-client/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java index 5f1307932..f2cd6558c 100644 --- a/module-client/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java +++ b/module-client/src/main/java/org/apache/http/impl/client/AbstractHttpClient.java @@ -499,10 +499,9 @@ public abstract class AbstractHttpClient getParams()); } - HttpResponse response = director.execute(roureq, context); + HttpResponse response = director.execute(roureq, context); // If the response depends on the connection, the director // will have set up an auto-release input stream. - //@@@ or move that logic here into the client? //@@@ "finalize" response, to allow for buffering of entities? //@@@ here or in director? diff --git a/module-client/src/main/java/org/apache/http/impl/client/ClientParamsStack.java b/module-client/src/main/java/org/apache/http/impl/client/ClientParamsStack.java new file mode 100644 index 000000000..a9c8104f5 --- /dev/null +++ b/module-client/src/main/java/org/apache/http/impl/client/ClientParamsStack.java @@ -0,0 +1,291 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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.impl.client; + + +import org.apache.http.params.HttpParams; +import org.apache.http.params.AbstractHttpParams; + + +/** + * Represents a stack of parameter collections. + * When retrieving a parameter, the stack is searched in a fixed order + * and the first match returned. Setting parameters via the stack is + * not supported. To minimize overhead, the stack has a fixed size and + * does not maintain an internal array. + * The supported stack entries, sorted by increasing priority, are: + *
    + *
  1. Application parameters: + * expected to be the same for all clients used by an application. + * These provide "global", that is application-wide, defaults. + *
  2. + *
  3. Client parameters: + * specific to an instance of + * {@link org.apache.http.client.HttpClient HttpClient}. + * These provide client specific defaults. + *
  4. + *
  5. Request parameters: + * specific to a single request execution. + * For overriding client and global defaults. + *
  6. + *
  7. Override parameters: + * specific to an instance of + * {@link org.apache.http.client.HttpClient HttpClient}. + * These can be used to set parameters that cannot be overridden + * on a per-request basis. + *
  8. + *
+ * Each stack entry may be null. That is preferable over + * an empty params collection, since it avoids searching the empty collection + * when looking up parameters. + * + * @author Roland Weber + * + * + * @version $Revision$ + */ +public class ClientParamsStack extends AbstractHttpParams { + + /** The application parameter collection, or null. */ + protected final HttpParams applicationParams; + + /** The client parameter collection, or null. */ + protected final HttpParams clientParams; + + /** The request parameter collection, or null. */ + protected final HttpParams requestParams; + + /** The override parameter collection, or null. */ + protected final HttpParams overrideParams; + + + /** + * Creates a new parameter stack from elements. + * The arguments will be stored as-is, there is no copying to + * prevent modification. + * + * @param aparams application parameters, or null + * @param cparams client parameters, or null + * @param rparams request parameters, or null + * @param oparams override parameters, or null + */ + public ClientParamsStack(HttpParams aparams, HttpParams cparams, + HttpParams rparams, HttpParams oparams) { + applicationParams = aparams; + clientParams = cparams; + requestParams = rparams; + overrideParams = oparams; + } + + + /** + * Creates a copy of a parameter stack. + * The new stack will have the exact same entries as the argument stack. + * There is no copying of parameters. + * + * @param stack the stack to copy + */ + public ClientParamsStack(ClientParamsStack stack) { + this(stack.getApplicationParams(), + stack.getClientParams(), + stack.getRequestParams(), + stack.getOverrideParams()); + } + + + /** + * Creates a modified copy of a parameter stack. + * The new stack will contain the explicitly passed elements. + * For elements where the explicit argument is null, + * the corresponding element from the argument stack is used. + * There is no copying of parameters. + * + * @param stack the stack to modify + * @param aparams application parameters, or null + * @param cparams client parameters, or null + * @param rparams request parameters, or null + * @param oparams override parameters, or null + */ + public ClientParamsStack(ClientParamsStack stack, + HttpParams aparams, HttpParams cparams, + HttpParams rparams, HttpParams oparams) { + this((aparams != null) ? aparams : stack.getApplicationParams(), + (cparams != null) ? cparams : stack.getClientParams(), + (rparams != null) ? rparams : stack.getRequestParams(), + (oparams != null) ? oparams : stack.getOverrideParams()); + } + + + /** + * Obtains the application parameters of this stack. + * + * @return the application parameters, or null + */ + public final HttpParams getApplicationParams() { + return applicationParams; + } + + /** + * Obtains the client parameters of this stack. + * + * @return the client parameters, or null + */ + public final HttpParams getClientParams() { + return clientParams; + } + + /** + * Obtains the request parameters of this stack. + * + * @return the request parameters, or null + */ + public final HttpParams getRequestParams() { + return requestParams; + } + + /** + * Obtains the override parameters of this stack. + * + * @return the override parameters, or null + */ + public final HttpParams getOverrideParams() { + return overrideParams; + } + + + /** + * Obtains a parameter from this stack. + * See class comment for search order. + * + * @param name the name of the parameter to obtain + * + * @return the highest-priority value for that parameter, or + * null if it is not set anywhere in this stack + */ + public Object getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException + ("Parameter name must not be null."); + } + + Object result = null; + + if (overrideParams != null) { + result = overrideParams.getParameter(name); + } + if ((result == null) && (requestParams != null)) { + result = requestParams.getParameter(name); + } + if ((result == null) && (clientParams != null)) { + result = clientParams.getParameter(name); + } + if ((result == null) && (applicationParams != null)) { + result = applicationParams.getParameter(name); + } + + return result; + } + + + /** + * Checks whether a parameter is set in this stack. + * + * @param name the name of the parameter to check for + * + * @return true if the parameter is set in this stack, + * false otherwise + */ + public boolean isParameterSet(String name) { + if (name == null) { + throw new IllegalArgumentException + ("Parameter name must not be null."); + } + + boolean found = false; + + if (overrideParams != null) { + found = overrideParams.isParameterSet(name); + } + if (!found && (requestParams != null)) { + found = requestParams.isParameterSet(name); + } + if (!found && (clientParams != null)) { + found = clientParams.isParameterSet(name); + } + if (!found && (applicationParams != null)) { + found = applicationParams.isParameterSet(name); + } + + return found; + } + + + /** + * Does not set a parameter. + * Parameter stacks are read-only. It is possible, though discouraged, + * to access and modify specific stack entries. + * Derived classes may change this behavior. + * + * @param name ignored + * @param value ignored + * + * @return nothing + * + * @throws UnsupportedOperationException always + */ + public HttpParams setParameter(String name, Object value) + throws UnsupportedOperationException { + + throw new UnsupportedOperationException + ("Setting parameters in a stack is not supported."); + } + + + /** + * Does not copy parameters. + * Parameter stacks are lightweight objects, expected to be instantiated + * as needed and to be used only in a very specific context. On top of + * that, they are read-only. The typical copy operation to prevent + * accidental modification of parameters passed by the application to + * a framework object is therefore pointless and disabled. + * Create a new stack if you really need a copy. + *
+ * Derived classes may change this behavior. + * + * @return this parameter stack + */ + public HttpParams copy() { + return this; + } + + +} diff --git a/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java b/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java index 89b4021b5..d9b6b9892 100644 --- a/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java +++ b/module-client/src/main/java/org/apache/http/impl/client/DefaultClientRequestDirector.java @@ -257,7 +257,13 @@ public class DefaultClientRequestDirector throws HttpException, IOException, InterruptedException { HttpRequest orig = roureq.getRequest(); - HttpParamsLinker.link(orig, this.params); + + //@@@ build the parameter stack in the client? + //@@@ that's the place to keep application and override params + final HttpParams stackedparams = new ClientParamsStack + (null, this.params, orig.getParams(), null); + orig.setParams(stackedparams); + // was: HttpParamsLinker.link(orig, this.params); // Add default headers Collection defHeaders = (Collection) orig.getParams().getParameter( @@ -369,7 +375,8 @@ public class DefaultClientRequestDirector throw ex; } - HttpParamsLinker.link(request, this.params); + // no need to link parameters, stack is copied to the wrapper: + // HttpParamsLinker.link(request, this.params); requestExec.postProcess(response, httpProcessor, context); RoutedRequest followup =