001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest.client;
014
015import static org.apache.juneau.httppart.HttpPartType.*;
016import static org.apache.juneau.http.HttpMethod.*;
017import static org.apache.juneau.http.HttpHeaders.*;
018import static org.apache.juneau.http.HttpParts.*;
019import static org.apache.juneau.collections.JsonMap.*;
020import static org.apache.juneau.common.internal.ArgUtils.*;
021import static org.apache.juneau.common.internal.StringUtils.*;
022import static org.apache.juneau.common.internal.ThrowableUtils.*;
023import static org.apache.juneau.http.HttpEntities.*;
024import static org.apache.juneau.rest.client.RestOperation.*;
025import static java.util.logging.Level.*;
026import static org.apache.juneau.internal.CollectionUtils.*;
027import static org.apache.juneau.internal.StateMachineState.*;
028import static java.lang.Character.*;
029
030import java.io.*;
031import java.lang.annotation.Annotation;
032import java.lang.reflect.*;
033import java.lang.reflect.Proxy;
034import java.net.*;
035import java.nio.charset.*;
036import java.text.*;
037import java.util.*;
038import java.util.concurrent.*;
039import java.util.function.*;
040import java.util.logging.*;
041import java.util.regex.*;
042
043import javax.net.ssl.*;
044
045import org.apache.http.*;
046import org.apache.http.Header;
047import org.apache.http.auth.*;
048import org.apache.http.client.*;
049import org.apache.http.client.CookieStore;
050import org.apache.http.client.config.*;
051import org.apache.http.client.entity.*;
052import org.apache.http.client.methods.*;
053import org.apache.http.client.utils.*;
054import org.apache.http.config.*;
055import org.apache.http.conn.*;
056import org.apache.http.conn.routing.*;
057import org.apache.http.conn.socket.*;
058import org.apache.http.conn.util.*;
059import org.apache.http.cookie.*;
060import org.apache.http.impl.client.*;
061import org.apache.http.impl.conn.*;
062import org.apache.http.params.*;
063import org.apache.http.protocol.*;
064import org.apache.juneau.*;
065import org.apache.juneau.annotation.*;
066import org.apache.juneau.collections.*;
067import org.apache.juneau.cp.*;
068import org.apache.juneau.html.*;
069import org.apache.juneau.http.remote.RemoteReturn;
070import org.apache.juneau.http.resource.*;
071import org.apache.juneau.http.entity.*;
072import org.apache.juneau.http.header.*;
073import org.apache.juneau.http.part.*;
074import org.apache.juneau.http.remote.*;
075import org.apache.juneau.httppart.*;
076import org.apache.juneau.httppart.bean.*;
077import org.apache.juneau.internal.*;
078import org.apache.juneau.json.*;
079import org.apache.juneau.marshaller.*;
080import org.apache.juneau.msgpack.*;
081import org.apache.juneau.oapi.*;
082import org.apache.juneau.objecttools.*;
083import org.apache.juneau.parser.*;
084import org.apache.juneau.parser.ParseException;
085import org.apache.juneau.plaintext.*;
086import org.apache.juneau.reflect.*;
087import org.apache.juneau.rest.client.assertion.*;
088import org.apache.juneau.rest.client.remote.*;
089import org.apache.juneau.serializer.*;
090import org.apache.juneau.uon.*;
091import org.apache.juneau.urlencoding.*;
092import org.apache.juneau.utils.*;
093import org.apache.juneau.xml.*;
094
095/**
096 * Utility class for interfacing with remote REST interfaces.
097 *
098 * <p>
099 * Built upon the feature-rich Apache HttpClient library, the Juneau RestClient API adds support for fluent-style
100 * REST calls and the ability to perform marshalling of POJOs to and from HTTP parts.
101 *
102 * <h5 class='figure'>Example:</h5>
103 * <p class='bjava'>
104 *    <jc>// Create a basic REST client with JSON support and download a bean.</jc>
105 *    MyBean <jv>bean</jv> = RestClient.<jsm>create</jsm>()
106 *       .json5()
107 *       .build()
108 *       .get(<jsf>URI</jsf>)
109 *       .run()
110 *       .assertStatus().asCode().is(200)
111 *       .assertHeader(<js>"Content-Type"</js>).matchesSimple(<js>"application/json*"</js>)
112 *       .getContent().as(MyBean.<jk>class</jk>);
113 * </p>
114 *
115 * <p>
116 * Breaking apart the fluent call, we can see the classes being used:
117 * <p class='bjava'>
118 *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>().json5();
119 *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
120 *    RestRequest <jv>req</jv> = <jv>client</jv>.get(<jsf>URI</jsf>);
121 *    RestResponse <jv>res</jv> = <jv>req</jv>.run();
122 *    RestResponseStatusLineAssertion <jv>statusLineAssertion</jv> = <jv>res</jv>.assertStatus();
123 *    FluentIntegerAssertion&lt;RestResponse&gt; <jv>codeAssertion</jv> = <jv>statusLineAssertion</jv>.asCode();
124 *    <jv>res</jv> = <jv>codeAssertion</jv>.is(200);
125 *    FluentStringAssertion&lt;RestResponse&gt; <jv>headerAssertion</jv> = <jv>res</jv>.assertHeader(<js>"Content-Type"</js>);
126 *    <jv>res</jv> = <jv>headerAssertion</jv>.matchesSimple(<js>"application/json*"</js>);
127 *    RestResponseBody <jv>content</jv> = <jv>res</jv>.getContent();
128 *    MyBean <jv>bean</jv> = <jv>content</jv>.as(MyBean.<jk>class</jk>);
129 * </p>
130 *
131 * <p>
132 * It additionally provides support for creating remote proxy interfaces using REST as the transport medium.
133 *
134 * <h5 class='figure'>Example:</h5>
135 * <p class='bjava'>
136 *    <jc>// Define a Remote proxy for interacting with a REST interface.</jc>
137 *    <ja>@Remote</ja>(path=<js>"/petstore"</js>)
138 *    <jk>public interface</jk> PetStore {
139 *
140 *       <ja>@RemotePost</ja>(<js>"/pets"</js>)
141 *       Pet addPet(
142 *          <ja>@Content</ja> CreatePet <jv>pet</jv>,
143 *          <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
144 *          <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
145 *       );
146 *    }
147 *
148 *    <jc>// Use a RestClient with default JSON 5 support.</jc>
149 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build();
150 *
151 *    PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
152 *    CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
153 *    Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
154 * </p>
155 *
156 * <p>
157 * The classes are closely tied to Apache HttpClient, yet provide lots of additional functionality:
158 * <ul class='javatree'>
159 *    <li class='jc'>{@link RestClient} <jk>extends</jk> {@link HttpClient}, creates {@link RestRequest} objects.
160 *    <li class='jc'>{@link RestRequest} <jk>extends</jk> {@link HttpUriRequest}, creates {@link RestResponse} objects.
161 *    <li class='jc'>{@link RestResponse} creates {@link ResponseContent} and {@link ResponseHeader} objects.
162 *    <li class='jc'>{@link ResponseContent} <jk>extends</jk> {@link HttpEntity}
163 *    <li class='jc'>{@link ResponseHeader} <jk>extends</jk> {@link Header}
164 * </ul>
165 *
166 *
167 * <p>
168 * Instances of this class are built using the {@link Builder} class which can be constructed using
169 * the {@link #create() RestClient.create()} method as shown above.
170 *
171 * <p>
172 * Clients are typically created with a root URI so that relative URIs can be used when making requests.
173 * This is done using the {@link Builder#rootUrl(Object)} method.
174 *
175 * <h5 class='figure'>Example:</h5>
176 * <p class='bjava'>
177 *    <jc>// Create a client where all URIs are relative to localhost.</jc>
178 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:5000"</js>).build();
179 *
180 *    <jc>// Use relative paths.</jc>
181 *    String <jv>body</jv> = <jv>client</jv>.get(<js>"/subpath"</js>).run().getContent().asString();
182 * </p>
183 *
184 * <p>
185 * The {@link RestClient} class creates {@link RestRequest} objects using the following methods:
186 *
187 * <ul class='javatree'>
188 *    <li class='jc'>{@link RestClient}
189 *    <ul>
190 *       <li class='jm'>{@link RestClient#get(Object) get(uri)} / {@link RestClient#get() get()}
191 *       <li class='jm'>{@link RestClient#put(Object,Object) put(uri,body)} / {@link RestClient#put(Object) put(uri)}
192 *       <li class='jm'>{@link RestClient#post(Object) post(uri,body)} / {@link RestClient#post(Object) post(uri)}
193 *       <li class='jm'>{@link RestClient#patch(Object,Object) patch(uri,body)} / {@link RestClient#patch(Object) patch(uri)}
194 *       <li class='jm'>{@link RestClient#delete(Object) delete(uri)}
195 *       <li class='jm'>{@link RestClient#head(Object) head(uri)}
196 *       <li class='jm'>{@link RestClient#options(Object) options(uri)}
197 *       <li class='jm'>{@link RestClient#formPost(Object,Object) formPost(uri,body)} / {@link RestClient#formPost(Object) formPost(uri)}
198 *       <li class='jm'>{@link RestClient#formPostPairs(Object,String...) formPostPairs(uri,parameters...)}
199 *       <li class='jm'>{@link RestClient#request(String,Object,Object) request(method,uri,body)}
200 *    </ul>
201 * </ul>
202 *
203 * <p>
204 * The {@link RestRequest} class creates {@link RestResponse} objects using the following methods:
205 *
206 * <ul class='javatree'>
207 *    <li class='jc'>{@link RestRequest}
208 *    <ul>
209 *       <li class='jm'>{@link RestRequest#run() run()}
210 *       <li class='jm'>{@link RestRequest#complete() complete()}
211 *    </ul>
212 * </ul>
213 *
214 * <p>
215 * The distinction between the two methods is that {@link RestRequest#complete() complete()} automatically consumes the response body and
216 * {@link RestRequest#run() run()} does not.  Note that you must consume response bodies in order for HTTP connections to be freed up
217 * for reuse!  The {@link InputStream InputStreams} returned by the {@link ResponseContent} object are auto-closing once
218 * they are exhausted, so it is often not necessary to explicitly close them.
219 *
220 * <p>
221 * The following examples show the distinction between the two calls:
222 *
223 * <p class='bjava'>
224 *    <jc>// Consuming the response, so use run().</jc>
225 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).run().getContent().asString();
226 *
227 *    <jc>// Only interested in response status code, so use complete().</jc>
228 *    <jk>int</jk> <jv>status</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
229 * </p>
230 *
231 *
232 * <h4 class='topic'>POJO Marshalling</h4>
233 *
234 * <p>
235 * By default, JSON support is provided for HTTP request and response bodies.
236 * Other languages can be specified using any of the following builder methods:
237 * <ul class='javatree'>
238 *    <li class='jc'>{@link Builder}
239 *    <ul>
240 *       <li class='jm'>{@link Builder#json() json()}
241 *       <li class='jm'>{@link Builder#json5() json5()}
242 *       <li class='jm'>{@link Builder#xml() xml()}
243 *       <li class='jm'>{@link Builder#html() html()}
244 *       <li class='jm'>{@link Builder#plainText() plainText()}
245 *       <li class='jm'>{@link Builder#msgPack() msgPack()}
246 *       <li class='jm'>{@link Builder#uon() uon()}
247 *       <li class='jm'>{@link Builder#urlEnc() urlEnc()}
248 *       <li class='jm'>{@link Builder#openApi() openApi()}
249 *    </ul>
250 * </ul>
251 *
252 * <h5 class='figure'>Example:</h5>
253 * <p class='bjava'>
254 *    <jc>// Create a basic REST client with JSON 5 support.</jc>
255 *    <jc>// Typically easier to use when performing unit tests.</jc>
256 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build();
257 * </p>
258 *
259 * <p>
260 * Clients can also support multiple languages:
261 *
262 * <h5 class='figure'>Example:</h5>
263 * <p class='bjava'>
264 *    <jc>// Create a REST client with support for multiple languages.</jc>
265 *    RestClient <jv>client1</jv> = RestClient.<jsm>create</jsm>().json().xml().openApi().build();
266 *
267 *    <jc>// Create a REST client with support for all supported languages.</jc>
268 *    RestClient <jv>client2</jv> = RestClient.<jsm>create</jsm>().universal().build();
269 * </p>
270 *
271 * <p>
272 * When using clients with multiple language support, you must specify the <c>Content-Type</c> header on requests
273 * with bodies to specify which serializer should be selected.
274 *
275 * <p class='bjava'>
276 *    <jc>// Create a REST client with support for multiple languages.</jc>
277 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().universal().build();
278 *
279 *    <jv>client</jv>
280 *       .post(<jsf>URI</jsf>, <jv>myBean</jv>)
281 *       .contentType(<js>"application/json"</js>)
282 *       .complete()
283 *       .assertStatus().is(200);
284 * </p>
285 *
286 * <p>
287 * Languages can also be specified per-request.
288 *
289 * <p class='bjava'>
290 *    <jc>// Create a REST client with no default languages supported.</jc>
291 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().build();
292 *
293 *    <jc>// Use JSON for this request.</jc>
294 *    <jv>client</jv>
295 *       .post(<jsf>URI</jsf>, <jv>myBean</jv>)
296 *       .json()
297 *       .complete()
298 *       .assertStatus().is(200);
299 * </p>
300 *
301 *
302 * <p>
303 * The {@link Builder} class provides convenience methods for setting common serializer and parser
304 * settings.
305 *
306 * <h5 class='figure'>Example:</h5>
307 * <p class='bjava'>
308 *    <jc>// Create a basic REST client with JSON support.</jc>
309 *    <jc>// Use single-quotes and whitespace.</jc>
310 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().sq().ws().build();
311 * </p>
312 *
313 * <p>
314 *    Other methods are also provided for specifying the serializers and parsers used for lower-level marshalling support:
315 * <ul class='javatree'>
316 *    <li class='jc'>{@link Builder}
317 *    <ul>
318 *       <li class='jm'>{@link Builder#serializer(Serializer) serializer(Serializer)}
319 *       <li class='jm'>{@link Builder#parser(Parser) parser(Parser)}
320 *       <li class='jm'>{@link Builder#marshaller(Marshaller) marshaller(Marshaller)}
321 *    </ul>
322 * </ul>
323 *
324 * <p>
325 * HTTP parts (headers, query parameters, form data...) are serialized and parsed using the {@link HttpPartSerializer}
326 * and {@link HttpPartParser} APIs.  By default, clients are configured to use {@link OpenApiSerializer} and
327 * {@link OpenApiParser}.  These can be overridden using the following methods:
328 * <ul class='javatree'>
329 *    <li class='jc'>{@link Builder}
330 *    <ul>
331 *       <li class='jm'>{@link Builder#partSerializer(Class) partSerializer(Class&lt;? extends HttpPartSerializer>)}
332 *       <li class='jm'>{@link Builder#partParser(Class) partParser(Class&lt;? extends HttpPartParser>)}
333 *    </ul>
334 * </ul>
335 *
336 *
337 * <h4 class='topic'>Request Headers</h4>
338 * <p>
339 * Per-client or per-request headers can be specified using the following methods:
340 * <ul class='javatree'>
341 *    <li class='jc'>{@link Builder}
342 *    <ul>
343 *       <li class='jm'>{@link Builder#headers() headerData()}
344 *       <li class='jm'>{@link Builder#header(String,String) header(String,Object)}
345 *       <li class='jm'>{@link Builder#header(String,Supplier) header(String,Supplier&lt;?&gt;)}
346 *       <li class='jm'>{@link Builder#headers(Header...) headers(Header...)}
347 *       <li class='jm'>{@link Builder#headersDefault(Header...) defaultHeaders(Header...)}
348 *    </ul>
349 *    <li class='jc'>{@link RestRequest}
350 *    <ul>
351 *       <li class='jm'>{@link RestRequest#header(String,Object) header(String,Object)}
352 *       <li class='jm'>{@link RestRequest#headers(Header...) headers(Header...)}
353 *       <li class='jm'>{@link RestRequest#headersBean(Object) headersBean(Object)}
354 *       <li class='jm'>{@link RestRequest#headerPairs(String...) headerPairs(String...)}
355 *    </ul>
356 * </ul>
357 *
358 * <p>
359 * The supplier methods are particularly useful for header values whose values may change over time (such as <c>Authorization</c> headers
360 * which may need to change every few minutes).
361 * </p>
362 *
363 * <h5 class='figure'>Example:</h5>
364 * <p class='bjava'>
365 *    <jc>// Create a client that adds a dynamic Authorization header to every request.</jc>
366 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().header(<js>"Authorization"</js>, ()-&gt;getMyAuthToken()).build();
367 * </p>
368 *
369 * <p>
370 * The {@link HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on both requests
371 * and responses.
372 *
373 * <h5 class='figure'>Example:</h5>
374 * <p class='bjava'>
375 *    <jc>// Create a client that adds a header "Foo: bar|baz" to every request.</jc>
376 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>()
377 *       .header(<js>"Foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
378 *       .build();
379 * </p>
380 *
381 * <p>
382 * The methods with {@link ListOperation} parameters allow you to control whether new headers get appended, prepended, or
383 * replace existing headers with the same name.
384 *
385 * <h5 class='section'>Notes:</h5><ul>
386 *    <li class='note'>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>Header</c> or
387 *       <c>NameValuePair</c> objects use the values returned by that bean directly.
388 * </ul>
389 *
390 *
391 * <h4 class='topic'>Request Query Parameters</h4>
392 * <p>
393 * Per-client or per-request query parameters can be specified using the following methods:
394 * <ul class='javatree'>
395 *    <li class='jc'>{@link Builder}
396 *    <ul>
397 *       <li class='jm'>{@link Builder#queryData() queryData()}
398 *       <li class='jm'>{@link Builder#queryData(String,String) queryData(String,String)}
399 *       <li class='jm'>{@link Builder#queryData(String,Supplier) queryData(String,Supplier&lt;?&gt;)}
400 *       <li class='jm'>{@link Builder#queryData(NameValuePair...) queryData(NameValuePair...)}
401 *       <li class='jm'>{@link Builder#queryDataDefault(NameValuePair...) defaultQueryData(NameValuePair...)}
402 *    </ul>
403 *    <li class='jc'>{@link RestRequest}
404 *    <ul>
405 *       <li class='jm'>{@link RestRequest#queryData(String,Object) queryData(String,Object)}
406 *       <li class='jm'>{@link RestRequest#queryData(NameValuePair...) queryData(NameValuePair...)}
407 *       <li class='jm'>{@link RestRequest#queryDataBean(Object) queryDataBean(Object)}
408 *       <li class='jm'>{@link RestRequest#queryCustom(Object) queryCustom(Object)}
409 *       <li class='jm'>{@link RestRequest#queryDataPairs(String...) queryDataPairs(String...)}
410 *    </ul>
411 * </ul>
412 *
413 * <h5 class='figure'>Example:</h5>
414 * <p class='bjava'>
415 *    <jc>// Create a client that adds a ?foo=bar query parameter to every request.</jc>
416 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().query(<js>"foo"</js>, <js>"bar"</js>).build();
417 *
418 *    <jc>// Or do it on every request.</jc>
419 *    String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getContent().asString();
420 * </p>
421 *
422 * <h5 class='section'>Notes:</h5><ul>
423 *    <li class='note'>Like header values, dynamic values and OpenAPI schemas are supported.
424 *    <li class='note'>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>NameValuePair</c>
425 *       objects use the values returned by that bean directly.
426 * </ul>
427 *
428 *
429 * <h4 class='topic'>Request Form Data</h4>
430 *
431 * <p>
432 * Per-client or per-request form-data parameters can be specified using the following methods:
433 * <ul class='javatree'>
434 *    <li class='jc'>{@link Builder}
435 *    <ul>
436 *       <li class='jm'>{@link Builder#formData() formData()}
437 *       <li class='jm'>{@link Builder#formData(String,String) formData(String,String)}
438 *       <li class='jm'>{@link Builder#formData(String,Supplier) formData(String,Supplier&lt;?&gt;)}
439 *       <li class='jm'>{@link Builder#formData(NameValuePair...) formDatas(NameValuePair...)}
440 *       <li class='jm'>{@link Builder#formDataDefault(NameValuePair...) defaultFormData(NameValuePair...)}
441 *    </ul>
442 *    <li class='jc'>{@link RestRequest}
443 *    <ul>
444 *       <li class='jm'>{@link RestRequest#formData(String,Object) formData(String,Object)}
445 *       <li class='jm'>{@link RestRequest#formData(NameValuePair...) formData(NameValuePair...)}
446 *       <li class='jm'>{@link RestRequest#formDataBean(Object) formDataBean(Object)}
447 *       <li class='jm'>{@link RestRequest#formDataCustom(Object) formDataCustom(Object)}
448 *       <li class='jm'>{@link RestRequest#formDataPairs(String...) formDataPairs(String...)}
449 *    </ul>
450 * </ul>
451 *
452 * <h5 class='section'>Notes:</h5><ul>
453 *    <li class='note'>Like header values, dynamic values and OpenAPI schemas are supported.
454 *    <li class='note'>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>NameValuePair</c>
455 *       objects use the values returned by that bean directly.
456 * </ul>
457 *
458 *
459 * <h4 class='topic'>Request Body</h4>
460 *
461 * <p>
462 * The request body can either be passed in with the client creator method (e.g. {@link RestClient#post(Object,Object) post(uri,body)}),
463 * or can be specified via the following methods:
464 *
465 * <ul class='javatree'>
466 *    <li class='jc'>{@link RestRequest}
467 *    <ul>
468 *       <li class='jm'>{@link RestRequest#content(Object) body(Object)}
469 *       <li class='jm'>{@link RestRequest#content(Object,HttpPartSchema) body(Object,HttpPartSchema)}
470 *    </ul>
471 * </ul>
472 *
473 * <p>
474 * The request body can be any of the following types:
475 * <ul class='javatree'>
476 *       <li class='jc'>
477 *          {@link Object} - POJO to be converted to text using the {@link Serializer} defined on the client or request.
478 *       <li class='jc'>
479 *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
480 *       <li class='jc'>
481 *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
482 *       <li class='jc'>
483 *          {@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
484 *       <li class='jc'>
485 *          {@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
486 *       <li class='jc'>
487 *          {@link PartList} - Converted to a URL-encoded FORM post.
488 *       <li class='jc'>
489 *          {@link Supplier} - A supplier of anything on this list.
490 *    </ul>
491 *
492 * <h5 class='section'>Notes:</h5><ul>
493 *    <li class='note'>If the serializer on the client or request is explicitly set to <jk>null</jk>, POJOs will be converted to strings
494 *       using the registered part serializer as content type <js>"text/plain</js>.  If the part serializer is also <jk>null</jk>,
495 *       POJOs will be converted to strings using {@link ClassMeta#toString(Object)} which typically just calls {@link Object#toString()}.
496 * </ul>
497 *
498 *
499 * <h4 class='topic'>Response Status</h4>
500 *
501 * <p>
502 * After execution using {@link RestRequest#run()} or {@link RestRequest#complete()}, the following methods can be used
503 * to get the response status:
504 *
505 * <ul class='javatree'>
506 *    <li class='jc'>{@link RestResponse}
507 *    <ul>
508 *       <li class='jm'><c>{@link RestResponse#getStatusLine() getStatusLine()} <jk>returns</jk> {@link StatusLine}</c>
509 *       <li class='jm'><c>{@link RestResponse#getStatusCode() getStatusCode()} <jk>returns</jk> <jk>int</jk></c>
510 *       <li class='jm'><c>{@link RestResponse#getReasonPhrase() getReasonPhrase()} <jk>returns</jk> String</c>
511 *       <li class='jm'><c>{@link RestResponse#assertStatus() assertStatus()} <jk>returns</jk> {@link FluentResponseStatusLineAssertion}</c>
512 *    </ul>
513 * </ul>
514 *
515 * <h5 class='figure'>Example:</h5>
516 * <p class='bjava'>
517 *    <jc>// Only interested in status code.</jc>
518 *    <jk>int</jk> <jv>statusCode</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
519 * </p>
520 *
521 * <p>
522 * Equivalent methods with mutable parameters are provided to allow access to status values without breaking fluent call chains.
523 *
524 * <h5 class='figure'>Example:</h5>
525 * <p class='bjava'>
526 *    <jc>// Interested in multiple values.</jc>
527 *    Value&lt;Integer&gt; <jv>statusCode</jv> = Value.<jsm>create</jsm>();
528 *    Value&lt;String&gt; <jv>reasonPhrase</jv> = Value.<jsm>create</jsm>();
529 *
530 *    <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode(<jv>statusCode</jv>).getReasonPhrase(<jv>reasonPhrase</jv>);
531 *    System.<jsf>err</jsf>.println(<js>"statusCode="</js>+<jv>statusCode</jv>.get()+<js>", reasonPhrase="</js>+<jv>reasonPhrase</jv>.get());
532 * </p>
533 *
534 * <h5 class='section'>Notes:</h5><ul>
535 *    <li class='note'>If you are only interested in the response status and not the response body, be sure to use {@link RestRequest#complete()} instead
536 *       of {@link RestRequest#run()} to make sure the response body gets automatically cleaned up.  Otherwise you must
537 *       consume the response yourself.
538 * </ul>
539 *
540 * <p>
541 * The assertion method is provided for quickly asserting status codes in fluent calls.
542 *
543 * <h5 class='figure'>Example:</h5>
544 * <p class='bjava'>
545 *    <jc>// Status assertion using a static value.</jc>
546 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
547 *       .run()
548 *       .assertStatus().asCode().isBetween(200,399)
549 *       .getContent().asString();
550 *
551 *    <jc>// Status assertion using a predicate.</jc>
552 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
553 *       .run()
554 *       .assertStatus().asCode().is(<jv>x</jv> -&gt; <jv>x</jv>&lt;400)
555 *       .getContent().asString();
556 * </p>
557 *
558 *
559 * <h4 class='topic'>Response Headers</h4>
560 *
561 * <p>
562 * Response headers are accessed through the following methods:
563 *
564 * <ul class='javatree'>
565 *    <li class='jc'>{@link RestResponse}
566 *    <ul>
567 *       <li class='jm'><c>{@link RestResponse#getHeaders(String) getHeaders(String)} <jk>returns</jk> {@link ResponseHeader}[]</c>
568 *       <li class='jm'><c>{@link RestResponse#getFirstHeader(String) getFirstHeader(String)} <jk>returns</jk> {@link ResponseHeader}</c>
569 *       <li class='jm'><c>{@link RestResponse#getLastHeader(String) getLastHeader(String)} <jk>returns</jk> {@link ResponseHeader}</c>
570 *       <li class='jm'><c>{@link RestResponse#getAllHeaders() getAllHeaders()} <jk>returns</jk> {@link ResponseHeader}[]</c>
571 *       <li class='jm'><c>{@link RestResponse#getStringHeader(String) getStringHeader(String)} <jk>returns</jk> String</c>
572 *       <li class='jm'><c>{@link RestResponse#containsHeader(String) containsHeader(String)} <jk>returns</jk> <jk>boolean</jk></c>
573 *    </ul>
574 * </ul>
575 *
576 * <p>
577 * The {@link RestResponse#getFirstHeader(String)} and {@link RestResponse#getLastHeader(String)} methods return an empty {@link ResponseHeader} object instead of<jk>null</jk>.
578 * This allows it to be used more easily in fluent calls.
579 *
580 * <h5 class='figure'>Example:</h5>
581 * <p class='bjava'>
582 *    <jc>// See if response contains Location header.</jc>
583 *    <jk>boolean</jk> <jv>hasLocationHeader</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getLastHeader(<js>"Location"</js>).exists();
584 * </p>
585 *
586 * <p>
587 * The {@link ResponseHeader} class extends from the HttpClient {@link Header} class and provides several convenience
588 * methods:
589 *
590 * <ul class='javatree'>
591 *    <li class='jc'>{@link ResponseHeader}
592 *    <ul>
593 *       <li class='jm'><c>{@link ResponseHeader#isPresent() isPresent()} <jk>returns</jk> <jk>boolean</jk></c>
594 *       <li class='jm'><c>{@link ResponseHeader#asString() asString()} <jk>returns</jk> String</c>
595 *       <li class='jm'><c>{@link ResponseHeader#as(Type,Type...) as(Type,Type...)} <jk>returns</jk> T</c>
596 *       <li class='jm'><c>{@link ResponseHeader#as(Class) as(Class&lt;T&gt;)} <jk>returns</jk> T</c>
597 *       <li class='jm'><c>{@link ResponseHeader#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
598 *       <li class='jm'><c>{@link ResponseHeader#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
599 *       <li class='jm'><c>{@link ResponseHeader#asHeader(Class) asHeader(Class&lt;T <jk>extends</jk> BasicHeader&gt; c)} <jk>returns</jk> {@link BasicHeader}</c>
600 *       <li class='jm'><c>{@link ResponseHeader#asStringHeader() asStringHeader()} <jk>returns</jk> {@link BasicStringHeader}</c>
601 *       <li class='jm'><c>{@link ResponseHeader#asIntegerHeader() asIntegerHeader()} <jk>returns</jk> {@link BasicIntegerHeader}</c>
602 *       <li class='jm'><c>{@link ResponseHeader#asLongHeader() asLongHeader()} <jk>returns</jk> {@link BasicLongHeader}</c>
603 *       <li class='jm'><c>{@link ResponseHeader#asDateHeader() asDateHeader()} <jk>returns</jk> {@link BasicDateHeader}</c>
604 *       <li class='jm'><c>{@link ResponseHeader#asCsvHeader() asCsvHeader()} <jk>returns</jk> {@link BasicCsvHeader}</c>
605 *       <li class='jm'><c>{@link ResponseHeader#asEntityTagsHeader() asEntityTagsHeader()} <jk>returns</jk> {@link BasicEntityTagsHeader}</c>
606 *       <li class='jm'><c>{@link ResponseHeader#asStringRangesHeader() asStringRangesHeader()} <jk>returns</jk> {@link BasicStringRangesHeader}</c>
607 *       <li class='jm'><c>{@link ResponseHeader#asUriHeader() asUriHeader()} <jk>returns</jk> {@link BasicUriHeader}</c>
608 *    </ul>
609 * </ul>
610 *
611 * <p>
612 * The {@link ResponseHeader#schema(HttpPartSchema)} method allows you to perform parsing of OpenAPI formats for
613 * header parts.
614 *
615 * <h5 class='figure'>Example:</h5>
616 * <p class='bjava'>
617 *    <jc>// Parse the header "Foo: bar|baz".</jc>
618 *    List&lt;String&gt; <jv>fooHeader</jv> = <jv>client</jv>
619 *       .get(<jsf>URI</jsf>)
620 *       .complete()
621 *       .getHeader(<js>"Foo"</js>).schema(<jsf>T_ARRAY_PIPES</jsf>).as(List.<jk>class</jk>, String.<jk>class</jk>);
622 * </p>
623 *
624 * <p>
625 * Assertion methods are also provided for fluent-style calls:
626 *
627 * <ul class='javatree'>
628 *    <li class='jc'>{@link ResponseHeader}
629 *    <ul>
630 *       <li class='jm'><c>{@link ResponseHeader#assertValue() assertValue()} <jk>returns</jk> {@link FluentResponseHeaderAssertion}</c>
631 *    </ul>
632 * </ul>
633 *
634 * <p>
635 * Note how in the following example, the fluent assertion returns control to the {@link RestResponse} object after
636 * the assertion has been completed:
637 *
638 * <h5 class='figure'>Example:</h5>
639 * <p class='bjava'>
640 *    <jc>// Assert the response content type is any sort of JSON.</jc>
641 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
642 *       .run()
643 *       .getHeader(<js>"Content-Type"</js>).assertValue().matchesSimple(<js>"application/json*"</js>)
644 *       .getContent().asString();
645 * </p>
646 *
647 *
648 * <h4 class='topic'>Response Body</h4>
649 *
650 * <p>
651 * The response body is accessed through the following method:
652 *
653 * <ul class='javatree'>
654 *    <li class='jc'>{@link RestResponse}
655 *    <ul>
656 *       <li class='jm'><c>{@link RestResponse#getContent() getContent()} <jk>returns</jk> {@link ResponseContent}</c>
657 *    </ul>
658 * </ul>
659 *
660 * <p>
661 * The {@link ResponseContent} class extends from the HttpClient {@link HttpEntity} class and provides several convenience
662 * methods:
663 *
664 * <ul class='javatree'>
665 *    <li class='jc'>{@link ResponseContent}
666 *    <ul>
667 *       <li class='jm'><c>{@link ResponseContent#asInputStream() asInputStream()} <jk>returns</jk> InputStream</c>
668 *       <li class='jm'><c>{@link ResponseContent#asReader() asReader()} <jk>returns</jk> Reader</c>
669 *       <li class='jm'><c>{@link ResponseContent#asReader(Charset) asReader(Charset)} <jk>returns</jk> Reader</c>
670 *       <li class='jm'><c>{@link ResponseContent#pipeTo(OutputStream) pipeTo(OutputStream)} <jk>returns</jk> {@link RestResponse}</c>
671 *       <li class='jm'><c>{@link ResponseContent#pipeTo(Writer) pipeTo(Writer)} <jk>returns</jk> {@link RestResponse}</c>
672 *       <li class='jm'><c>{@link ResponseContent#as(Type,Type...) as(Type,Type...)} <jk>returns</jk> T</c>
673 *       <li class='jm'><c>{@link ResponseContent#as(Class) as(Class&lt;T&gt;)} <jk>returns</jk> T</c>
674 *       <li class='jm'><c>{@link ResponseContent#asFuture(Class) asFuture(Class&lt;T&gt;)} <jk>returns</jk> Future&lt;T&gt;</c>
675 *       <li class='jm'><c>{@link ResponseContent#asFuture(Type,Type...) asFuture(Type,Type...)} <jk>returns</jk> Future&lt;T&gt;</c>
676 *       <li class='jm'><c>{@link ResponseContent#asString() asString()} <jk>returns</jk> String</c>
677 *       <li class='jm'><c>{@link ResponseContent#asStringFuture() asStringFuture()} <jk>returns</jk> Future&lt;String&gt;</c>
678 *       <li class='jm'><c>{@link ResponseContent#asAbbreviatedString(int) asAbbreviatedString(int)} <jk>returns</jk> String</c>
679 *       <li class='jm'><c>{@link ResponseContent#asObjectRest(Class) asObjectRest(Class&lt;?&gt;)} <jk>returns</jk> {@link ObjectRest}</c>
680 *       <li class='jm'><c>{@link ResponseContent#asObjectRest() asObjectRest()} <jk>returns</jk> {@link ObjectRest}</c>
681 *       <li class='jm'><c>{@link ResponseContent#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
682 *       <li class='jm'><c>{@link ResponseContent#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
683 *    </ul>
684 * </ul>
685 *
686 * <br>
687 *
688 * <h5 class='figure'>Examples:</h5>
689 * <p class='bjava'>
690 *    <jc>// Parse into a linked-list of strings.</jc>
691 *    List&lt;String&gt; <jv>list1</jv> = <jv>client</jv>
692 *       .get(<jsf>URI</jsf>)
693 *       .run()
694 *       .getContent().as(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
695 *
696 *    <jc>// Parse into a linked-list of beans.</jc>
697 *    List&lt;MyBean&gt; <jv>list2</jv> = <jv>client</jv>
698 *       .get(<jsf>URI</jsf>)
699 *       .run()
700 *       .getContent().as(LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
701 *
702 *    <jc>// Parse into a linked-list of linked-lists of strings.</jc>
703 *    List&lt;List&lt;String&gt;&gt; <jv>list3</jv> = <jv>client</jv>
704 *       .get(<jsf>URI</jsf>)
705 *       .run()
706 *       .getContent().as(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
707 *
708 *    <jc>// Parse into a map of string keys/values.</jc>
709 *    Map&lt;String,String&gt; <jv>map1</jv> = <jv>client</jv>
710 *       .get(<jsf>URI</jsf>)
711 *       .run()
712 *       .getContent().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
713 *
714 *    <jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
715 *    Map&lt;String,List&lt;MyBean&gt;&gt; <jv>map2</jv> = <jv>client</jv>
716 *       .get(<jsf>URI</jsf>)
717 *       .run()
718 *       .getContent().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
719 * </p>
720 *
721 * <p>
722 * The response body can only be consumed once unless it has been cached into memory.  In many cases, the body is
723 * automatically cached when using the assertions methods or methods such as {@link ResponseContent#asString()}.
724 * However, methods that involve reading directly from the input stream cannot be called twice.
725 * In these cases, the {@link RestResponse#cacheContent()} and {@link ResponseContent#cache()} methods are provided
726 * to cache the response body in memory so that you can perform several operations against it.
727 *
728 * <p class='bjava'>
729 *    <jc>// Cache the response body so we can access it twice.</jc>
730 *    InputStream <jv>inputStream</jv> = <jv>client</jv>
731 *       .get(<jsf>URI</jsf>)
732 *       .run()
733 *       .cacheBody()
734 *       .getContent().pipeTo(<jv>someOtherStream</jv>)
735 *       .getContent().asInputStream();
736 * </p>
737 *
738 * <p>
739 * Assertion methods are also provided for fluent-style calls:
740 *
741 * <ul class='javatree'>
742 *    <li class='jc'>{@link ResponseContent}
743 *    <ul>
744 *       <li class='jm'><c>{@link ResponseContent#assertValue() assertValue()} <jk>returns</jk> {@link FluentResponseBodyAssertion}</c>
745 *    </ul>
746 * </ul>
747 *
748 * <br>
749 *
750 * <h5 class='figure'>Example:</h5>
751 * <p class='bjava'>
752 *    <jc>// Assert that the body contains the string "Success".</jc>
753 *    String <jv>body</jv> = <jv>client</jv>
754 *       .get(<jsf>URI</jsf>)
755 *       .run()
756 *       .getContent().assertString().contains(<js>"Success"</js>)
757 *       .getContent().asString();
758 * </p>
759 *
760 * <p>
761 * Object assertions allow you to parse the response body into a POJO and then perform various tests on that resulting
762 * POJO.
763 *
764 * <h5 class='figure'>Example:</h5>
765 * <p class='bjava'>
766 *    <jc>// Parse bean into POJO and then validate that it was parsed correctly.</jc>
767 *    MyBean <jv>bean</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
768 *       .run()
769 *       .getContent().assertObject(MyBean.<jk>class</jk>).asJson().is(<js>"{foo:'bar'}"</js>)
770 *       .getContent().as(MyBean.<jk>class</jk>);
771 * </p>
772 *
773 *
774 * <h4 class='topic'>Custom Call Handlers</h4>
775 *
776 * <p>
777 * The {@link RestCallHandler} interface provides the ability to provide custom handling of requests.
778 *
779 * <ul class='javatree'>
780 *    <li class='jc'>{@link Builder}
781 *    <ul>
782 *       <li class='jm'>{@link Builder#callHandler() callHandler()}
783 *    </ul>
784 *    <li class='jic'>{@link RestCallHandler}
785 *    <ul>
786 *       <li class='jm'><c>{@link RestCallHandler#run(HttpHost,HttpRequest,HttpContext) run(HttpHost,HttpRequest,HttpContext)} <jk>returns</jk> HttpResponse</c>
787 *    </ul>
788 * </ul>
789 *
790 * <p>
791 * Note that there are other ways of accomplishing this such as extending the {@link RestClient} class and overriding
792 * the {@link #run(HttpHost,HttpRequest,HttpContext)} method
793 * or by defining your own {@link HttpRequestExecutor}.  Using this interface is often simpler though.
794 *
795 *
796 * <h4 class='topic'>Interceptors</h4>
797 *
798 * <p>
799 * The {@link RestCallInterceptor} API provides a quick way of intercepting and manipulating requests and responses beyond
800 * the existing {@link HttpRequestInterceptor} and {@link HttpResponseInterceptor} APIs.
801 *
802 * <ul class='javatree'>
803 *    <li class='jc'>{@link Builder}
804 *    <ul>
805 *       <li class='jm'>{@link Builder#interceptors(Object...) interceptors(Object...)}
806 *    </ul>
807 *    <li class='jc'>{@link RestRequest}
808 *    <ul>
809 *       <li class='jm'>{@link RestRequest#interceptors(RestCallInterceptor...) interceptors(RestCallInterceptor...)}
810 *    </ul>
811 *    <li class='jic'>{@link RestCallInterceptor}
812 *    <ul>
813 *       <li class='jm'>{@link RestCallInterceptor#onInit(RestRequest) onInit(RestRequest)}
814 *       <li class='jm'>{@link RestCallInterceptor#onConnect(RestRequest,RestResponse) onConnect(RestRequest,RestResponse)}
815 *       <li class='jm'>{@link RestCallInterceptor#onClose(RestRequest,RestResponse) onClose(RestRequest,RestResponse)}
816 *    </ul>
817 * </ul>
818 *
819 *
820 * <h4 class='topic'>Logging / Debugging</h4>
821 *
822 * <p>
823 * The following methods provide logging of requests and responses:
824 *
825 * <ul class='javatree'>
826 *    <li class='jc'>{@link Builder}
827 *    <ul>
828 *       <li class='jm'>{@link Builder#logger(Logger) logger(Logger)}
829 *       <li class='jm'>{@link Builder#logToConsole() logToConsole()}
830 *       <li class='jm'>{@link Builder#logRequests(DetailLevel,Level,BiPredicate) logRequests(DetailLevel,Level,BiPredicate)}
831 *    </ul>
832 * </ul>
833 *
834 * <p>
835 * The following example shows the results of logging all requests that end with <c>/bean</c>.
836 *
837 * <h5 class='figure'>Examples:</h5>
838 * <p class='bjava'>
839 *    MyBean <jv>bean</jv> = RestClient
840 *       .<jsm>create</jsm>()
841 *       .json5()
842 *       .logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (<jv>req</jv>,<jv>res</jv>)-&gt;<jv>req</jv>.getUri().endsWith(<js>"/bean"</js>))
843 *       .logToConsole()
844 *       .build()
845 *       .post(<js>"http://localhost/bean"</js>, <jv>anotherBean</jv>)
846 *       .run()
847 *       .getContent().as(MyBean.<jk>class</jk>);
848 * </p>
849 *
850 * <p>
851 * This produces the following console output:
852 *
853 * <p class='bconsole'>
854 *    === HTTP Call (outgoing) ======================================================
855 *    === REQUEST ===
856 *    POST http://localhost/bean
857 *    ---request headers---
858 *       Accept: application/json5
859 *    ---request entity---
860 *    Content-Type: application/json5
861 *    ---request content---
862 *    {f:1}
863 *    === RESPONSE ===
864 *    HTTP/1.1 200
865 *    ---response headers---
866 *       Content-Type: application/json
867 *    ---response content---
868 *    {f:1}
869 *    === END =======================================================================",
870 * </p>
871 *
872 *
873 * <p class='notes'>
874 * It should be noted that if you enable request logging detail level {@link DetailLevel#FULL}, response bodies will be cached by default which may introduce
875 * a performance penalty.
876 *
877 * <p>
878 * Additionally, the following method is also provided for enabling debug mode:
879 *
880 * <ul class='javatree'>
881 *    <li class='jc'>{@link Builder}
882 *    <ul>
883 *       <li class='jm'>{@link Builder#debug() debug()}
884 *    </ul>
885 * </ul>
886 *
887 * <p>
888 * Enabling debug mode has the following effects:
889 * <ul>
890 *    <li>{@link org.apache.juneau.Context.Builder#debug()} is enabled.
891 *    <li>{@link Builder#detectLeaks()} is enabled.
892 *    <li>{@link Builder#logToConsole()} is called.
893 * </ul>
894 *
895 *
896 * <h4 class='topic'>REST Proxies</h4>
897 *
898 * <p>
899 * One of the more powerful features of the REST client class is the ability to produce Java interface proxies against
900 * arbitrary remote REST resources.
901 *
902 * <h5 class='figure'>Example:</h5>
903 * <p class='bjava'>
904 *    <jc>// Define a Remote proxy for interacting with a REST interface.</jc>
905 *    <ja>@Remote</ja>(path=<js>"/petstore"</js>)
906 *    <jk>public interface</jk> PetStore {
907 *
908 *       <ja>@RemotePost</ja>(<js>"/pets"</js>)
909 *       Pet addPet(
910 *          <ja>@Content</ja> CreatePet <jv>pet</jv>,
911 *          <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
912 *          <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
913 *       );
914 *    }
915 *
916 *    <jc>// Use a RestClient with default JSON 5 support.</jc>
917 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build())
918 *
919 *    PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
920 *    CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
921 *    Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
922 * </p>
923 *
924 * <p>
925 * The methods to retrieve remote interfaces are:
926 *
927 * <ul class='javatree'>
928 *    <li class='jc'>{@link RestClient}
929 *    <ul>
930 *       <li class='jm'><c>{@link RestClient#getRemote(Class) getRemote(Class&lt;T&gt;)} <jk>returns</jk> T</c>
931 *       <li class='jm'><c>{@link RestClient#getRemote(Class,Object) getRemote(Class&lt;T&gt;,Object)} <jk>returns</jk> T</c>
932 *       <li class='jm'><c>{@link RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class&lt;T&gt;,Object,Serializer,Parser)} <jk>returns</jk> T</c>
933 *       <li class='jm'><c>{@link RestClient#getRrpcInterface(Class) getRrpcInterface(Class&lt;T&gt;)} <jk>returns</jk> T</c>
934 *       <li class='jm'><c>{@link RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class&lt;T&gt;,Object)} <jk>returns</jk> T</c>
935 *       <li class='jm'><c>{@link RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class&lt;T&gt;,Object,Serializer,Parser)} <jk>returns</jk> T</c>
936 *    </ul>
937 * </ul>
938 *
939 * <p>
940 * Two basic types of remote interfaces are provided:
941 *
942 * <ul class='spaced-list'>
943 *    <li>{@link Remote @Remote}-annotated interfaces.  These can be defined against arbitrary external REST resources.
944 *    <li>RPC-over-REST interfaces.  These are Java interfaces that allow you to make method calls on server-side POJOs.
945 * </ul>
946 *
947 * <p>
948 * Refer to the following documentation on both flavors:
949 *
950 * <ul class='doctree'>
951 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
952 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
953 * </ul>
954 *
955 * <br>
956 * <hr>
957 * <h4 class='topic'>Customizing Apache HttpClient</h4>
958 *
959 * <p>
960 * Several methods are provided for customizing the underlying HTTP client and client builder classes:
961 * <ul class='javatree'>
962 *    <li class='jc'>{@link Builder}
963 *    <ul>
964 *       <li class='jm'>{@link Builder#httpClientBuilder(HttpClientBuilder) httpClientBuilder(HttpClientBuilder)} - Set the client builder yourself.
965 *       <li class='jm'>{@link Builder#createHttpClientBuilder() createHttpClientBuilder()} - Override to create the client builder.
966 *       <li class='jm'>{@link Builder#createHttpClient() createHttpClient()} - Override to create the client.
967 *       <li class='jm'>{@link Builder#createConnectionManager() createConnectionManager()} - Override to create the connection management.
968 *    </ul>
969 * </ul>
970 *
971 * <p>
972 * Additionally, all methods on the <c>HttpClientBuilder</c> class have been extended with fluent setters.
973 *
974 * <h5 class='figure'>Example:</h5>
975 * <p class='bjava'>
976 *    <jc>// Create a client with customized HttpClient settings.</jc>
977 *    MyBean <jv>bean</jv> = RestClient
978 *       .<jsm>create</jsm>()
979 *       .disableRedirectHandling()
980 *       .connectionManager(<jv>myConnectionManager</jv>)
981 *       .addInterceptorFirst(<jv>myHttpRequestInterceptor</jv>)
982 *       .build();
983 * </p>
984 *
985 * <p>
986 * Refer to the {@link HttpClientBuilder HTTP Client Builder API} for more information.
987 *
988 *
989 * <h4 class='topic'>Extending RestClient</h4>
990 *
991 * <p>
992 * The <c>RestClient</c> API has been designed to allow for the ability to be easily extended.
993 * The following example that overrides the primary run method shows how this can be done.
994 *
995 * <h5 class='figure'>Example:</h5>
996 * <p class='bjava'>
997 *    <jk>public class</jk> MyRestClient <jk>extends</jk> RestClient {
998 *
999 *       <jc>// Must provide this constructor!</jc>
1000 *       <jk>public</jk> MyRestClient(RestClient.Builder <jv>builder</jv>) {
1001 *          <jk>super</jk>(<jv>builder</jv>);
1002 *       }
1003 *
1004 *       <jd>/** Optionally override to customize builder settings before initialization. </jd>
1005 *       <ja>@Override</ja>
1006 *       <jk>protected void</jk> init(RestClient.Builder) {...}
1007 *
1008 *       <jd>/** Optionally override to provide post-initialization (e.g. setting up SAML handshakes, etc...). </jd>
1009 *       <ja>@Override</ja>
1010 *       <jk>protected void</jk> init() {...}
1011 *
1012 *       <jd>/** Optionally override to customize requests when they're created (e.g. add headers to each request). </jd>
1013 *       <ja>@Override</ja>
1014 *       <jk>protected</jk> RestRequest request(RestOperation) {...}
1015 *
1016 *       <jd>/** Optionally override to implement your own call handling. </jd>
1017 *       <ja>@Override</ja>
1018 *       <jk>protected</jk> HttpResponse run(HttpHost, HttpRequest, HttpContext) {...}
1019 *
1020 *       <jd>/** Optionally override to customize requests before they're executed. </jd>
1021 *       <ja>@Override</ja>
1022 *       <jk>protected void</jk> onCallInit(RestRequest) {...}
1023 *
1024 *       <jd>/** Optionally override to customize responses as soon as a connection is made. </jd>
1025 *       <ja>@Override</ja>
1026 *       <jk>protected void</jk> onCallConnect(RestRequest, RestResponse) {...}
1027 *
1028 *       <jd>/** Optionally override to perform any call cleanup. </jd>
1029 *       <ja>@Override</ja>
1030 *       <jk>protected void</jk> onCallClose(RestRequest, RestResponse) {...}
1031 *    }
1032 *
1033 *    <jc>// Instantiate your client.</jc>
1034 *    MyRestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().build(MyRestClient.<jk>class</jk>);
1035 * </p>
1036 *
1037 * <p>
1038 * The {@link RestRequest} and {@link RestResponse} objects can also be extended and integrated by overriding the
1039 * {@link RestClient#createRequest(URI,String,boolean)} and {@link RestClient#createResponse(RestRequest,HttpResponse,Parser)} methods.
1040 *
1041 * <h5 class='section'>Notes:</h5><ul>
1042 *    <li class='note'>This class is thread safe and reusable.
1043 * </ul>
1044 *
1045 * <h5 class='section'>See Also:</h5><ul>
1046 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-client">juneau-rest-client</a>
1047 * </ul>
1048 */
1049public class RestClient extends BeanContextable implements HttpClient, Closeable {
1050
1051   //-------------------------------------------------------------------------------------------------------------------
1052   // Static
1053   //-------------------------------------------------------------------------------------------------------------------
1054
1055   private static final RestCallInterceptor[] EMPTY_REST_CALL_INTERCEPTORS = {};
1056
1057   /**
1058    * Instantiates a new clean-slate {@link Builder} object.
1059    *
1060    * @return A new {@link Builder} object.
1061    */
1062   public static Builder create() {
1063      return new Builder();
1064   }
1065
1066   //-------------------------------------------------------------------------------------------------------------------
1067   // Builder
1068   //-------------------------------------------------------------------------------------------------------------------
1069
1070   /**
1071    * Builder class.
1072    */
1073   @FluentSetters(ignore={"beanMapPutReturnsOldValue","example","exampleJson","debug","mediaType"})
1074   public static class Builder extends BeanContextable.Builder {
1075
1076      BeanStore beanStore = BeanStore.create().build();
1077
1078      private HttpClientBuilder httpClientBuilder;
1079      private CloseableHttpClient httpClient;
1080
1081      private HeaderList headerData;
1082      private PartList queryData, formData, pathData;
1083      private BeanCreator<RestCallHandler> callHandler;
1084      private SerializerSet.Builder serializers;
1085      private ParserSet.Builder parsers;
1086      private HttpPartSerializer.Creator partSerializer;
1087      private HttpPartParser.Creator partParser;
1088      private UrlEncodingSerializer.Builder urlEncodingSerializer;
1089
1090      private boolean pooled;
1091
1092      String rootUrl;
1093      boolean skipEmptyHeaderData, skipEmptyFormData, skipEmptyQueryData, executorServiceShutdownOnClose, ignoreErrors, keepHttpClientOpen, detectLeaks,
1094         logToConsole;
1095      Logger logger;
1096      DetailLevel logRequests;
1097      Level logRequestsLevel;
1098      BiPredicate<RestRequest,RestResponse> logRequestsPredicate;
1099      Predicate<Integer> errorCodes = x ->  x<=0 || x>=400;
1100      HttpClientConnectionManager connectionManager;
1101      PrintStream console;
1102      ExecutorService executorService;
1103      List<RestCallInterceptor> interceptors;
1104
1105      /**
1106       * Constructor.
1107       */
1108      protected Builder() {
1109      }
1110
1111      @Override /* Context.Builder */
1112      public Builder copy() {
1113         throw new NoSuchMethodError("Not implemented.");
1114      }
1115
1116      @Override /* Context.Builder */
1117      public RestClient build() {
1118         return build(RestClient.class);
1119      }
1120
1121      //------------------------------------------------------------------------------------------------------------------
1122      // Convenience marshalling support methods.
1123      //------------------------------------------------------------------------------------------------------------------
1124
1125      /**
1126       * Convenience method for specifying JSON as the marshalling transmission media type.
1127       *
1128       * <p>
1129       * {@link JsonSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1130       *    <ul>
1131       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1132       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1133       *    </ul>
1134       * <p>
1135       *    {@link JsonParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1136       *    <ul>
1137       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1138       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1139       *    </ul>
1140       * <p>
1141       *    <c>Accept</c> request header will be set to <js>"application/json"</js> unless overridden
1142       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}}.
1143       * <p>
1144       *    <c>Content-Type</c> request header will be set to <js>"application/json"</js> unless overridden
1145       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1146       * <p>
1147       *    Can be combined with other marshaller setters such as {@link #xml()} to provide support for multiple languages.
1148       *    <ul>
1149       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1150       *       last-enabled language if the headers are not set.
1151       *    </ul>
1152       * <p>
1153       *    Identical to calling <c>serializer(JsonSerializer.<jk>class</jk>).parser(JsonParser.<jk>class</jk>)</c>.
1154       *
1155       * <h5 class='section'>Example:</h5>
1156       * <p class='bjava'>
1157       *    <jc>// Construct a client that uses JSON marshalling.</jc>
1158       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().build();
1159       * </p>
1160       *
1161       * @return This object.
1162       */
1163      @FluentSetter
1164      public Builder json() {
1165         return serializer(JsonSerializer.class).parser(JsonParser.class);
1166      }
1167
1168      /**
1169       * Convenience method for specifying Simplified JSON as the marshalling transmission media type.
1170       *
1171       * <p>
1172       * Simplified JSON is typically useful for automated tests because you can do simple string comparison of results
1173       * without having to escape lots of quotes.
1174       *
1175       * <p>
1176       *    {@link Json5Serializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1177       *    <ul>
1178       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1179       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1180       *    </ul>
1181       * <p>
1182       *    {@link Json5Parser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1183       *    <ul>
1184       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1185       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1186       *    </ul>
1187       * <p>
1188       *    <c>Accept</c> request header will be set to <js>"application/json"</js> unless overridden
1189       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1190       * <p>
1191       *    <c>Content-Type</c> request header will be set to <js>"application/json5"</js> unless overridden
1192       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1193       * <p>
1194       *    Can be combined with other marshaller setters such as {@link #xml()} to provide support for multiple languages.
1195       *    <ul>
1196       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1197       *       last-enabled language if the headers are not set.
1198       *    </ul>
1199       * <p>
1200       *    Identical to calling <c>serializer(Json5Serializer.<jk>class</jk>).parser(Json5Parser.<jk>class</jk>)</c>.
1201       *
1202       * <h5 class='section'>Example:</h5>
1203       * <p class='bjava'>
1204       *    <jc>// Construct a client that uses Simplified JSON marshalling.</jc>
1205       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build();
1206       * </p>
1207       *
1208       * @return This object.
1209       */
1210      @FluentSetter
1211      public Builder json5() {
1212         return serializer(Json5Serializer.class).parser(Json5Parser.class);
1213      }
1214
1215      /**
1216       * Convenience method for specifying XML as the marshalling transmission media type.
1217       *
1218       * <p>
1219       * {@link XmlSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1220       *    <ul>
1221       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1222       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1223       *    </ul>
1224       * <p>
1225       *    {@link XmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1226       *    <ul>
1227       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1228       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1229       *    </ul>
1230       * <p>
1231       *    <c>Accept</c> request header will be set to <js>"text/xml"</js> unless overridden
1232       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1233       * <p>
1234       *    <c>Content-Type</c> request header will be set to <js>"text/xml"</js> unless overridden
1235       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1236       * <p>
1237       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1238       *    <ul>
1239       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1240       *       last-enabled language if the headers are not set.
1241       *    </ul>
1242       * <p>
1243       *    Identical to calling <c>serializer(XmlSerializer.<jk>class</jk>).parser(XmlParser.<jk>class</jk>)</c>.
1244       *
1245       * <h5 class='section'>Example:</h5>
1246       * <p class='bjava'>
1247       *    <jc>// Construct a client that uses XML marshalling.</jc>
1248       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().xml().build();
1249       * </p>
1250       *
1251       * @return This object.
1252       */
1253      @FluentSetter
1254      public Builder xml() {
1255         return serializer(XmlSerializer.class).parser(XmlParser.class);
1256      }
1257
1258      /**
1259       * Convenience method for specifying HTML as the marshalling transmission media type.
1260       *
1261       * <p>
1262       * POJOs are converted to HTML without any sort of doc wrappers.
1263       *
1264       * <p>
1265       *    {@link HtmlSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1266       *    <ul>
1267       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1268       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1269       *    </ul>
1270       * <p>
1271       *    {@link HtmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1272       *    <ul>
1273       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1274       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1275       *    </ul>
1276       * <p>
1277       *    <c>Accept</c> request header will be set to <js>"text/html"</js> unless overridden
1278       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1279       * <p>
1280       *    <c>Content-Type</c> request header will be set to <js>"text/html"</js> unless overridden
1281       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1282       * <p>
1283       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1284       *    <ul>
1285       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1286       *       last-enabled language if the headers are not set.
1287       *    </ul>
1288       * <p>
1289       *    Identical to calling <c>serializer(HtmlSerializer.<jk>class</jk>).parser(HtmlParser.<jk>class</jk>)</c>.
1290       *
1291       * <h5 class='section'>Example:</h5>
1292       * <p class='bjava'>
1293       *    <jc>// Construct a client that uses HTML marshalling.</jc>
1294       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().html().build();
1295       * </p>
1296       *
1297       * @return This object.
1298       */
1299      @FluentSetter
1300      public Builder html() {
1301         return serializer(HtmlSerializer.class).parser(HtmlParser.class);
1302      }
1303
1304      /**
1305       * Convenience method for specifying HTML DOC as the marshalling transmission media type.
1306       *
1307       * <p>
1308       * POJOs are converted to fully renderable HTML pages.
1309       *
1310       * <p>
1311       *    {@link HtmlDocSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1312       *    <ul>
1313       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()} or
1314       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1315       *    </ul>
1316       * <p>
1317       *    {@link HtmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1318       *    <ul>
1319       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1320       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1321       *    </ul>
1322       * <p>
1323       *    <c>Accept</c> request header will be set to <js>"text/html"</js> unless overridden
1324       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1325       * <p>
1326       *    <c>Content-Type</c> request header will be set to <js>"text/html"</js> unless overridden
1327       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1328       * <p>
1329       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1330       *    <ul>
1331       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1332       *       last-enabled language if the headers are not set.
1333       *    </ul>
1334       * <p>
1335       *    Identical to calling <c>serializer(HtmlDocSerializer.<jk>class</jk>).parser(HtmlParser.<jk>class</jk>)</c>.
1336       *
1337       * <h5 class='section'>Example:</h5>
1338       * <p class='bjava'>
1339       *    <jc>// Construct a client that uses HTML Doc marshalling.</jc>
1340       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().htmlDoc().build();
1341       * </p>
1342       *
1343       * @return This object.
1344       */
1345      @FluentSetter
1346      public Builder htmlDoc() {
1347         return serializer(HtmlDocSerializer.class).parser(HtmlParser.class);
1348      }
1349
1350      /**
1351       * Convenience method for specifying Stripped HTML DOC as the marshalling transmission media type.
1352       *
1353       * <p>
1354       * Same as {@link #htmlDoc()} but without the header and body tags and page title and description.
1355       *
1356       * <p>
1357       *    {@link HtmlStrippedDocSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1358       *    <ul>
1359       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1360       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1361       *    </ul>
1362       * <p>
1363       *    {@link HtmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1364       *    <ul>
1365       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1366       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1367       *    </ul>
1368       * <p>
1369       *    <c>Accept</c> request header will be set to <js>"text/html+stripped"</js> unless overridden
1370       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1371       * <p>
1372       *    <c>Content-Type</c> request header will be set to <js>"text/html+stripped"</js> unless overridden
1373       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1374       * <p>
1375       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1376       *    <ul>
1377       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1378       *       last-enabled language if the headers are not set.
1379       *    </ul>
1380       * <p>
1381       *    Identical to calling <c>serializer(HtmlStrippedDocSerializer.<jk>class</jk>).parser(HtmlParser.<jk>class</jk>)</c>.
1382       *
1383       * <h5 class='section'>Example:</h5>
1384       * <p class='bjava'>
1385       *    <jc>// Construct a client that uses HTML Stripped Doc marshalling.</jc>
1386       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().htmlStrippedDoc().build();
1387       * </p>
1388       *
1389       * @return This object.
1390       */
1391      @FluentSetter
1392      public Builder htmlStrippedDoc() {
1393         return serializer(HtmlStrippedDocSerializer.class).parser(HtmlParser.class);
1394      }
1395
1396      /**
1397       * Convenience method for specifying Plain Text as the marshalling transmission media type.
1398       *
1399       * <p>
1400       * Plain text marshalling typically only works on simple POJOs that can be converted to and from strings using
1401       * swaps, swap methods, etc...
1402       *
1403       * <p>
1404       *    {@link PlainTextSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1405       *    <ul>
1406       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1407       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1408       *    </ul>
1409       * <p>
1410       *    {@link PlainTextParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1411       *    <ul>
1412       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1413       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1414       *    </ul>
1415       * <p>
1416       *    <c>Accept</c> request header will be set to <js>"text/plain"</js> unless overridden
1417       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1418       * <p>
1419       *    <c>Content-Type</c> request header will be set to <js>"text/plain"</js> unless overridden
1420       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1421       * <p>
1422       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1423       *    <ul>
1424       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1425       *       last-enabled language if the headers are not set.
1426       *    </ul>
1427       * <p>
1428       *    Identical to calling <c>serializer(PlainTextSerializer.<jk>class</jk>).parser(PlainTextParser.<jk>class</jk>)</c>.
1429       *
1430       * <h5 class='section'>Example:</h5>
1431       * <p class='bjava'>
1432       *    <jc>// Construct a client that uses Plain Text marshalling.</jc>
1433       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().plainText().build();
1434       * </p>
1435       *
1436       * @return This object.
1437       */
1438      @FluentSetter
1439      public Builder plainText() {
1440         return serializer(PlainTextSerializer.class).parser(PlainTextParser.class);
1441      }
1442
1443      /**
1444       * Convenience method for specifying MessagePack as the marshalling transmission media type.
1445       *
1446       * <p>
1447       * MessagePack is a binary equivalent to JSON that takes up considerably less space than JSON.
1448       *
1449       * <p>
1450       *    {@link MsgPackSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1451       *    <ul>
1452       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1453       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1454       *    </ul>
1455       * <p>
1456       *    {@link MsgPackParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1457       *    <ul>
1458       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1459       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1460       *    </ul>
1461       * <p>
1462       *    <c>Accept</c> request header will be set to <js>"octal/msgpack"</js> unless overridden
1463       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1464       * <p>
1465       *    <c>Content-Type</c> request header will be set to <js>"octal/msgpack"</js> unless overridden
1466       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1467       * <p>
1468       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1469       *    <ul>
1470       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1471       *       last-enabled language if the headers are not set.
1472       *    </ul>
1473       * <p>
1474       *    Identical to calling <c>serializer(MsgPackSerializer.<jk>class</jk>).parser(MsgPackParser.<jk>class</jk>)</c>.
1475       *
1476       * <h5 class='section'>Example:</h5>
1477       * <p class='bjava'>
1478       *    <jc>// Construct a client that uses MessagePack marshalling.</jc>
1479       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().msgPack().build();
1480       * </p>
1481       *
1482       * @return This object.
1483       */
1484      @FluentSetter
1485      public Builder msgPack() {
1486         return serializer(MsgPackSerializer.class).parser(MsgPackParser.class);
1487      }
1488
1489      /**
1490       * Convenience method for specifying UON as the marshalling transmission media type.
1491       *
1492       * <p>
1493       * UON is Url-Encoding Object notation that is equivalent to JSON but suitable for transmission as URL-encoded
1494       * query and form post values.
1495       *
1496       * <p>
1497       *    {@link UonSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1498       *    <ul>
1499       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1500       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1501       *    </ul>
1502       * <p>
1503       *    {@link UonParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1504       *    <ul>
1505       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1506       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1507       *    </ul>
1508       * <p>
1509       *    <c>Accept</c> request header will be set to <js>"text/uon"</js> unless overridden
1510       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1511       * <p>
1512       *    <c>Content-Type</c> request header will be set to <js>"text/uon"</js> unless overridden
1513       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1514       * <p>
1515       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1516       *    <ul>
1517       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1518       *       last-enabled language if the headers are not set.
1519       *    </ul>
1520       * <p>
1521       *    Identical to calling <c>serializer(UonSerializer.<jk>class</jk>).parser(UonParser.<jk>class</jk>)</c>.
1522       *
1523       * <h5 class='section'>Example:</h5>
1524       * <p class='bjava'>
1525       *    <jc>// Construct a client that uses UON marshalling.</jc>
1526       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().uon().build();
1527       * </p>
1528       *
1529       * @return This object.
1530       */
1531      @FluentSetter
1532      public Builder uon() {
1533         return serializer(UonSerializer.class).parser(UonParser.class);
1534      }
1535
1536      /**
1537       * Convenience method for specifying URL-Encoding as the marshalling transmission media type.
1538       *
1539       * <p>
1540       *    {@link UrlEncodingSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1541       *    <ul>
1542       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1543       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1544       *       <li>This serializer is NOT used when using the {@link RestRequest#formData(String, Object)} (and related) methods for constructing
1545       *          the request body.  Instead, the part serializer specified via {@link #partSerializer(Class)} is used.
1546       *    </ul>
1547       * <p>
1548       *    {@link UrlEncodingParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1549       *    <ul>
1550       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1551       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1552       *    </ul>
1553       * <p>
1554       *    <c>Accept</c> request header will be set to <js>"application/x-www-form-urlencoded"</js> unless overridden
1555       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1556       * <p>
1557       *    <c>Content-Type</c> request header will be set to <js>"application/x-www-form-urlencoded"</js> unless overridden
1558       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1559       * <p>
1560       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1561       *    <ul>
1562       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1563       *       last-enabled language if the headers are not set.
1564       *    </ul>
1565       * <p>
1566       *    Identical to calling <c>serializer(UrlEncodingSerializer.<jk>class</jk>).parser(UrlEncodingParser.<jk>class</jk>)</c>.
1567       *
1568       * <h5 class='section'>Example:</h5>
1569       * <p class='bjava'>
1570       *    <jc>// Construct a client that uses URL-Encoded marshalling.</jc>
1571       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().urlEnc().build();
1572       * </p>
1573       *
1574       * @return This object.
1575       */
1576      @FluentSetter
1577      public Builder urlEnc() {
1578         return serializer(UrlEncodingSerializer.class).parser(UrlEncodingParser.class);
1579      }
1580
1581      /**
1582       * Convenience method for specifying OpenAPI as the marshalling transmission media type.
1583       *
1584       * <p>
1585       * OpenAPI is a language that allows serialization to formats that use {@link HttpPartSchema} objects to describe their structure.
1586       *
1587       * <p>
1588       *    {@link OpenApiSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1589       *    <ul>
1590       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1591       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1592       *       <li>Typically the {@link RestRequest#content(Object, HttpPartSchema)} method will be used to specify the body of the request with the
1593       *          schema describing it's structure.
1594       *    </ul>
1595       * <p>
1596       *    {@link OpenApiParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1597       *    <ul>
1598       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1599       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1600       *       <li>Typically the {@link ResponseContent#schema(HttpPartSchema)} method will be used to specify the structure of the response body.
1601       *    </ul>
1602       * <p>
1603       *    <c>Accept</c> request header will be set to <js>"text/openapi"</js> unless overridden
1604       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1605       * <p>
1606       *    <c>Content-Type</c> request header will be set to <js>"text/openapi"</js> unless overridden
1607       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1608       * <p>
1609       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1610       *    <ul>
1611       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1612       *       last-enabled language if the headers are not set.
1613       *    </ul>
1614       * <p>
1615       *    Identical to calling <c>serializer(OpenApiSerializer.<jk>class</jk>).parser(OpenApiParser.<jk>class</jk>)</c>.
1616       *
1617       * <h5 class='section'>Example:</h5>
1618       * <p class='bjava'>
1619       *    <jc>// Construct a client that uses OpenAPI marshalling.</jc>
1620       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().openApi().build();
1621       * </p>
1622       *
1623       * @return This object.
1624       */
1625      @FluentSetter
1626      public Builder openApi() {
1627         return serializer(OpenApiSerializer.class).parser(OpenApiParser.class);
1628      }
1629
1630      /**
1631       * Convenience method for specifying all available transmission types.
1632       *
1633       * <p>
1634       *    All basic Juneau serializers will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1635       *    <ul>
1636       *       <li>The serializers can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1637       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1638       *    </ul>
1639       * <p>
1640       *    All basic Juneau parsers will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1641       *    <ul>
1642       *       <li>The parsers can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1643       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1644       *    </ul>
1645       * <p>
1646       *    <c>Accept</c> request header must be set via {@link #headers()}, or per-request
1647       *       via {@link RestRequest#header(Header)} in order for the correct parser to be selected.
1648       * <p>
1649       *    <c>Content-Type</c> request header must be set via {@link #headers()},
1650       *       or per-request via {@link RestRequest#header(Header)} in order for the correct serializer to be selected.
1651       * <p>
1652       *    Similar to calling <c>json().json5().html().xml().uon().urlEnc().openApi().msgPack().plainText()</c>.
1653       *
1654       * <h5 class='section'>Example:</h5>
1655       * <p class='bjava'>
1656       *    <jc>// Construct a client that uses universal marshalling.</jc>
1657       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().universal().build();
1658       * </p>
1659       *
1660       * @return This object.
1661       */
1662      @SuppressWarnings("unchecked")
1663      public Builder universal() {
1664         return
1665            serializers(
1666               JsonSerializer.class,
1667               Json5Serializer.class,
1668               HtmlSerializer.class,
1669               XmlSerializer.class,
1670               UonSerializer.class,
1671               UrlEncodingSerializer.class,
1672               OpenApiSerializer.class,
1673               MsgPackSerializer.class,
1674               PlainTextSerializer.class
1675            )
1676            .parsers(
1677               JsonParser.class,
1678               Json5Parser.class,
1679               XmlParser.class,
1680               HtmlParser.class,
1681               UonParser.class,
1682               UrlEncodingParser.class,
1683               OpenApiParser.class,
1684               MsgPackParser.class,
1685               PlainTextParser.class
1686            );
1687      }
1688
1689      //------------------------------------------------------------------------------------------------------------------
1690      // httpClientBuilder
1691      //------------------------------------------------------------------------------------------------------------------
1692
1693      /**
1694       * Returns the HTTP client builder.
1695       *
1696       * @return The HTTP client builder.
1697       */
1698      public final HttpClientBuilder httpClientBuilder() {
1699         if (httpClientBuilder == null)
1700            httpClientBuilder = createHttpClientBuilder();
1701         return httpClientBuilder;
1702      }
1703
1704      /**
1705       * Creates an instance of an {@link HttpClientBuilder} to be used to create the {@link HttpClient}.
1706       *
1707       * <p>
1708       * Subclasses can override this method to provide their own client builder.
1709       * The builder can also be specified using the {@link #httpClientBuilder(HttpClientBuilder)} method.
1710       *
1711       * <h5 class='section'>Example:</h5>
1712       * <p class='bjava'>
1713       *    <jc>// A Builder that provides it's own customized HttpClientBuilder.</jc>
1714       *    <jk>public class</jk> MyBuilder <jk>extends</jk> Builder {
1715       *       <ja>@Override</ja>
1716       *       <jk>protected</jk> HttpClientBuilder createHttpClientBuilder() {
1717       *          <jk>return</jk> HttpClientBuilder.<jsm>create</jsm>();
1718       *       }
1719       *    }
1720       *
1721       *    <jc>// Instantiate.</jc>
1722       *    RestClient <jv>client</jv> = <jk>new</jk> MyBuilder().build();
1723       * </p>
1724       *
1725       * @return The HTTP client builder to use to create the HTTP client.
1726       */
1727      protected HttpClientBuilder createHttpClientBuilder() {
1728         return HttpClientBuilder.create();
1729      }
1730
1731      /**
1732       * Sets the {@link HttpClientBuilder} that will be used to create the {@link HttpClient} used by {@link RestClient}.
1733       *
1734       * <p>
1735       * This can be used to bypass the builder created by {@link #createHttpClientBuilder()} method.
1736       *
1737       * <h5 class='section'>Example:</h5>
1738       * <p class='bjava'>
1739       *    <jc>// Construct a client that uses a customized HttpClientBuilder.</jc>
1740       *    RestClient <jv>client</jv> = RestClient
1741       *       .<jsm>create</jsm>()
1742       *       .httpClientBuilder(HttpClientBuilder.<jsm>create</jsm>())
1743       *       .build();
1744       * </p>
1745       *
1746       * @param value The {@link HttpClientBuilder} that will be used to create the {@link HttpClient} used by {@link RestClient}.
1747       * @return This object.
1748       */
1749      @FluentSetter
1750      public Builder httpClientBuilder(HttpClientBuilder value) {
1751         this.httpClientBuilder = value;
1752         return this;
1753      }
1754
1755      //------------------------------------------------------------------------------------------------------------------
1756      // httpClient
1757      //------------------------------------------------------------------------------------------------------------------
1758
1759      /**
1760       * Creates an instance of an {@link HttpClient} to be used to handle all HTTP communications with the target server.
1761       *
1762       * <p>
1763       * This HTTP client is used when the HTTP client is not specified through one of the constructors or the
1764       * {@link #httpClient(CloseableHttpClient)} method.
1765       *
1766       * <p>
1767       * Subclasses can override this method to provide specially-configured HTTP clients to handle stuff such as
1768       * SSL/TLS certificate handling, authentication, etc.
1769       *
1770       * <p>
1771       * The default implementation returns an instance of {@link HttpClient} using the client builder returned by
1772       * {@link #createHttpClientBuilder()}.
1773       *
1774       * <h5 class='section'>Example:</h5>
1775       * <p class='bjava'>
1776       *    <jc>// A Builder that provides it's own customized HttpClient.</jc>
1777       *    <jk>public class</jk> MyBuilder <jk>extends</jk> Builder {
1778       *       <ja>@Override</ja>
1779       *       <jk>protected</jk> HttpClientBuilder createHttpClient() {
1780       *          <jk>return</jk> HttpClientBuilder.<jsm>create</jsm>().build();
1781       *       }
1782       *    }
1783       *
1784       *    <jc>// Instantiate.</jc>
1785       *    RestClient <jv>client</jv> = <jk>new</jk> MyBuilder().build();
1786       * </p>
1787       *
1788       * @return The HTTP client to use.
1789       */
1790      protected CloseableHttpClient createHttpClient() {
1791         if (connectionManager == null)
1792            connectionManager = createConnectionManager();
1793         httpClientBuilder().setConnectionManager(connectionManager);
1794         return httpClientBuilder().build();
1795      }
1796
1797      /**
1798       * Sets the {@link HttpClient} to be used to handle all HTTP communications with the target server.
1799       *
1800       * <p>
1801       * This can be used to bypass the client created by {@link #createHttpClient()} method.
1802       *
1803       * <h5 class='section'>Example:</h5>
1804       * <p class='bjava'>
1805       *    <jc>// Construct a client that uses a customized HttpClient.</jc>
1806       *    RestClient <jv>client</jv> = RestClient
1807       *       .<jsm>create</jsm>()
1808       *       .httpClient(HttpClientBuilder.<jsm>create</jsm>().build())
1809       *       .build();
1810       * </p>
1811       *
1812       * @param value The {@link HttpClient} to be used to handle all HTTP communications with the target server.
1813       * @return This object.
1814       */
1815      @FluentSetter
1816      public Builder httpClient(CloseableHttpClient value) {
1817         this.httpClient = value;
1818         return this;
1819      }
1820
1821      final CloseableHttpClient getHttpClient() {
1822         return httpClient != null ? httpClient : createHttpClient();
1823      }
1824
1825      //------------------------------------------------------------------------------------------------------------------
1826      // serializers
1827      //------------------------------------------------------------------------------------------------------------------
1828
1829      /**
1830       * Returns the serializer group sub-builder.
1831       *
1832       * @return The serializer group sub-builder.
1833       */
1834      public final SerializerSet.Builder serializers() {
1835         if (serializers == null)
1836            serializers = createSerializers();
1837         return serializers;
1838      }
1839
1840      /**
1841       * Instantiates the serializer group sub-builder.
1842       *
1843       * @return A new serializer group sub-builder.
1844       */
1845      protected SerializerSet.Builder createSerializers() {
1846         return SerializerSet.create().beanContext(beanContext());
1847      }
1848
1849      /**
1850       * Serializer.
1851       *
1852       * <p>
1853       * Associates the specified {@link Serializer Serializer} with the HTTP client.
1854       *
1855       * <p>
1856       * The serializer is used to serialize POJOs into the HTTP request body.
1857       *
1858       * <h5 class='section'>Notes:</h5><ul>
1859       *    <li class='note'>When using this method that takes in a class, the serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1860       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1861       * </ul>
1862       *
1863       * <h5 class='section'>Example:</h5>
1864       * <p class='bjava'>
1865       *    <jc>// Create a client that uses JSON transport for request bodies.</jc>
1866       *    RestClient <jv>client</jv> = RestClient
1867       *       .<jsm>create</jsm>()
1868       *       .serializer(JsonSerializer.<jk>class</jk>)
1869       *       .sortCollections()  <jc>// Sort any collections being serialized.</jc>
1870       *       .build();
1871       * </p>
1872       *
1873       * @param value
1874       *    The new value for this setting.
1875       *    <br>The default is {@link JsonSerializer}.
1876       * @return This object.
1877       */
1878      @SuppressWarnings("unchecked")
1879      @FluentSetter
1880      public Builder serializer(Class<? extends Serializer> value) {
1881         return serializers(value);
1882      }
1883
1884      /**
1885       * Serializer.
1886       *
1887       * <p>
1888       * Associates the specified {@link Serializer Serializer} with the HTTP client.
1889       *
1890       * <p>
1891       * The serializer is used to serialize POJOs into the HTTP request body.
1892       *
1893       * <h5 class='section'>Notes:</h5><ul>
1894       *    <li class='note'>When using this method that takes in a pre-instantiated serializer, the serializer property setters (e.g. {@link #sortCollections()}) or
1895       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
1896       *    on this builder class have no effect.
1897       * </ul>
1898       *
1899       * <h5 class='section'>Example:</h5>
1900       * <p class='bjava'>
1901       *    <jc>// Create a client that uses a predefined JSON serializer request bodies.</jc>
1902       *    RestClient <jv>client</jv> = RestClient
1903       *       .<jsm>create</jsm>()
1904       *       .serializer(JsonSerializer.<jsf>DEFAULT_READABLE</jsf>)
1905       *       .build();
1906       * </p>
1907       *
1908       * @param value
1909       *    The new value for this setting.
1910       *    <br>The default is {@link JsonSerializer}.
1911       * @return This object.
1912       */
1913      @FluentSetter
1914      public Builder serializer(Serializer value) {
1915         return serializers(value);
1916      }
1917
1918      /**
1919       * Serializers.
1920       *
1921       * <p>
1922       * Associates the specified {@link Serializer Serializers} with the HTTP client.
1923       *
1924       * <p>
1925       * The serializer is used to serialize POJOs into the HTTP request body.
1926       *
1927       * <p>
1928       * The serializer that best matches the <c>Content-Type</c> header will be used to serialize the request body.
1929       * <br>If no <c>Content-Type</c> header is specified, the first serializer in the list will be used.
1930       *
1931       * <h5 class='section'>Notes:</h5><ul>
1932       *    <li class='note'>When using this method that takes in classes, the serializers can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1933       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1934       * </ul>
1935       *
1936       * <h5 class='section'>Example:</h5>
1937       * <p class='bjava'>
1938       *    <jc>// Create a client that uses JSON and XML transport for request bodies.</jc>
1939       *    RestClient <jv>client</jv> = RestClient
1940       *       .<jsm>create</jsm>()
1941       *       .serializers(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>)
1942       *       .sortCollections()  <jc>// Sort any collections being serialized.</jc>
1943       *       .build();
1944       * </p>
1945       *
1946       * @param value
1947       *    The new value for this setting.
1948       *    <br>The default is {@link JsonSerializer}.
1949       * @return This object.
1950       */
1951      @SuppressWarnings("unchecked")
1952      @FluentSetter
1953      public Builder serializers(Class<? extends Serializer>...value) {
1954         serializers().add(value);
1955         return this;
1956      }
1957
1958      /**
1959       * Serializers.
1960       *
1961       * <p>
1962       * Associates the specified {@link Serializer Serializers} with the HTTP client.
1963       *
1964       * <p>
1965       * The serializer is used to serialize POJOs into the HTTP request body.
1966       *
1967       * <p>
1968       * The serializer that best matches the <c>Content-Type</c> header will be used to serialize the request body.
1969       * <br>If no <c>Content-Type</c> header is specified, the first serializer in the list will be used.
1970       *
1971       * <h5 class='section'>Notes:</h5><ul>
1972       *    <li class='note'>When using this method that takes in a pre-instantiated serializers, the serializer property setters (e.g. {@link #sortCollections()}) or
1973       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
1974       *    on this builder class have no effect.
1975       * </ul>
1976       *
1977       * <h5 class='section'>Example:</h5>
1978       * <p class='bjava'>
1979       *    <jc>// Create a client that uses predefined JSON and XML serializers for request bodies.</jc>
1980       *    RestClient <jv>client</jv> = RestClient
1981       *       .<jsm>create</jsm>()
1982       *       .serializers(JsonSerializer.<jsf>DEFAULT_READABLE</jsf>, XmlSerializer.<jsf>DEFAULT_READABLE</jsf>)
1983       *       .build();
1984       * </p>
1985       *
1986       * @param value
1987       *    The new value for this setting.
1988       *    <br>The default is {@link JsonSerializer}.
1989       * @return This object.
1990       */
1991      @FluentSetter
1992      public Builder serializers(Serializer...value) {
1993         serializers().add(value);
1994         return this;
1995      }
1996
1997      //------------------------------------------------------------------------------------------------------------------
1998      // parsers
1999      //------------------------------------------------------------------------------------------------------------------
2000
2001      /**
2002       * Returns the parser group sub-builder.
2003       *
2004       * @return The parser group sub-builder.
2005       */
2006      public final ParserSet.Builder parsers() {
2007         if (parsers == null)
2008            parsers = createParsers();
2009         return parsers;
2010      }
2011
2012      /**
2013       * Instantiates the parser group sub-builder.
2014       *
2015       * @return A new parser group sub-builder.
2016       */
2017      protected ParserSet.Builder createParsers() {
2018         return ParserSet.create().beanContext(beanContext());
2019      }
2020
2021      /**
2022       * Parser.
2023       *
2024       * <p>
2025       * Associates the specified {@link Parser Parser} with the HTTP client.
2026       *
2027       * <p>
2028       * The parser is used to parse the HTTP response body into a POJO.
2029       *
2030       * <h5 class='section'>Notes:</h5><ul>
2031       *    <li class='note'>When using this method that takes in a class, the parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
2032       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
2033       * </ul>
2034       *
2035       * <h5 class='section'>Example:</h5>
2036       * <p class='bjava'>
2037       *    <jc>// Create a client that uses JSON transport for response bodies.</jc>
2038       *    RestClient <jv>client</jv> = RestClient
2039       *       .<jsm>create</jsm>()
2040       *       .parser(JsonParser.<jk>class</jk>)
2041       *       .strict()  <jc>// Enable strict mode on JsonParser.</jc>
2042       *       .build();
2043       * </p>
2044       *
2045       * @param value
2046       *    The new value for this setting.
2047       *    <br>The default value is {@link JsonParser#DEFAULT}.
2048       * @return This object.
2049       */
2050      @SuppressWarnings("unchecked")
2051      @FluentSetter
2052      public Builder parser(Class<? extends Parser> value) {
2053         return parsers(value);
2054      }
2055
2056      /**
2057       * Parser.
2058       *
2059       * <p>
2060       * Associates the specified {@link Parser Parser} with the HTTP client.
2061       *
2062       * <p>
2063       * The parser is used to parse the HTTP response body into a POJO.
2064       *
2065       * <h5 class='section'>Notes:</h5><ul>
2066       *    <li class='note'>When using this method that takes in a pre-instantiated parser, the parser property setters (e.g. {@link #strict()}) or
2067       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
2068       *    on this builder class have no effect.
2069       * </ul>
2070       *
2071       * <h5 class='section'>Example:</h5>
2072       * <p class='bjava'>
2073       *    <jc>// Create a client that uses a predefined JSON parser for response bodies.</jc>
2074       *    RestClient <jv>client</jv> = RestClient
2075       *       .<jsm>create</jsm>()
2076       *       .parser(JsonParser.<jsf>DEFAULT_STRICT</jsf>)
2077       *       .build();
2078       * </p>
2079       *
2080       * @param value
2081       *    The new value for this setting.
2082       *    <br>The default value is {@link JsonParser#DEFAULT}.
2083       * @return This object.
2084       */
2085      @FluentSetter
2086      public Builder parser(Parser value) {
2087         return parsers(value);
2088      }
2089
2090      /**
2091       * Parsers.
2092       *
2093       * <p>
2094       * Associates the specified {@link Parser Parsers} with the HTTP client.
2095       *
2096       * <p>
2097       * The parsers are used to parse the HTTP response body into a POJO.
2098       *
2099       * <p>
2100       * The parser that best matches the <c>Accept</c> header will be used to parse the response body.
2101       * <br>If no <c>Accept</c> header is specified, the first parser in the list will be used.
2102       *
2103       * <h5 class='section'>Notes:</h5><ul>
2104       *    <li class='note'>When using this method that takes in classes, the parsers can be configured using any of the parser property setters (e.g. {@link #strict()}) or
2105       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
2106       * </ul>
2107       *
2108       * <h5 class='section'>Example:</h5>
2109       * <p class='bjava'>
2110       *    <jc>// Create a client that uses JSON and XML transport for response bodies.</jc>
2111       *    RestClient <jv>client</jv> = RestClient
2112       *       .<jsm>create</jsm>()
2113       *       .parser(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>)
2114       *       .strict()  <jc>// Enable strict mode on parsers.</jc>
2115       *       .build();
2116       * </p>
2117       *
2118       * @param value
2119       *    The new value for this setting.
2120       *    <br>The default value is {@link JsonParser#DEFAULT}.
2121       * @return This object.
2122       */
2123      @SuppressWarnings("unchecked")
2124      @FluentSetter
2125      public Builder parsers(Class<? extends Parser>...value) {
2126         parsers().add(value);
2127         return this;
2128      }
2129
2130      /**
2131       * Parsers.
2132       *
2133       * <p>
2134       * Associates the specified {@link Parser Parsers} with the HTTP client.
2135       *
2136       * <p>
2137       * The parsers are used to parse the HTTP response body into a POJO.
2138       *
2139       * <p>
2140       * The parser that best matches the <c>Accept</c> header will be used to parse the response body.
2141       * <br>If no <c>Accept</c> header is specified, the first parser in the list will be used.
2142       *
2143       * <h5 class='section'>Notes:</h5><ul>
2144       *    <li class='note'>When using this method that takes in pre-instantiated parsers, the parser property setters (e.g. {@link #strict()}) or
2145       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
2146       *    on this builder class have no effect.
2147       * </ul>
2148       *
2149       * <h5 class='section'>Example:</h5>
2150       * <p class='bjava'>
2151       *    <jc>// Create a client that uses JSON and XML transport for response bodies.</jc>
2152       *    RestClient <jv>client</jv> = RestClient
2153       *       .<jsm>create</jsm>()
2154       *       .parser(JsonParser.<jsf>DEFAULT_STRICT</jsf>, XmlParser.<jsf>DEFAULT</jsf>)
2155       *       .build();
2156       * </p>
2157       *
2158       * @param value
2159       *    The new value for this setting.
2160       *    <br>The default value is {@link JsonParser#DEFAULT}.
2161       * @return This object.
2162       */
2163      @FluentSetter
2164      public Builder parsers(Parser...value) {
2165         parsers().add(value);
2166         return this;
2167      }
2168
2169      //------------------------------------------------------------------------------------------------------------------
2170      // partSerializer
2171      //------------------------------------------------------------------------------------------------------------------
2172
2173      /**
2174       * Returns the part serializer sub-builder.
2175       *
2176       * @return The part serializer sub-builder.
2177       */
2178      public final HttpPartSerializer.Creator partSerializer() {
2179         if (partSerializer == null)
2180            partSerializer = createPartSerializer();
2181         return partSerializer;
2182      }
2183
2184      /**
2185       * Instantiates the part serializer sub-builder.
2186       *
2187       * @return A new part serializer sub-builder.
2188       */
2189      protected HttpPartSerializer.Creator createPartSerializer() {
2190         return HttpPartSerializer.creator().type(OpenApiSerializer.class).beanContext(beanContext());
2191      }
2192
2193      /**
2194       * Part serializer.
2195       *
2196       * <p>
2197       * The serializer to use for serializing POJOs in form data, query parameters, headers, and path variables.
2198       *
2199       * <p>
2200       * The default part serializer is {@link OpenApiSerializer} which allows for schema-driven marshalling.
2201       *
2202       * <h5 class='section'>Example:</h5>
2203       * <p class='bjava'>
2204       *    <jc>// Create a client that uses UON format by default for outgoing HTTP parts.</jc>
2205       *    RestClient <jv>client</jv> = RestClient
2206       *       .<jsm>create</jsm>()
2207       *       .partSerializer(UonSerializer.<jk>class</jk>)
2208       *       .build();
2209       * </p>
2210       *
2211       * @param value
2212       *    The new value for this setting.
2213       *    <br>The default value is {@link OpenApiSerializer}.
2214       * @return This object.
2215       */
2216      @FluentSetter
2217      public Builder partSerializer(Class<? extends HttpPartSerializer> value) {
2218         partSerializer().type(value);
2219         return this;
2220      }
2221
2222      /**
2223       * Part serializer.
2224       *
2225       * <p>
2226       * The serializer to use for serializing POJOs in form data, query parameters, headers, and path variables.
2227       *
2228       * <p>
2229       * The default part serializer is {@link OpenApiSerializer} which allows for schema-driven marshalling.
2230       *
2231       * <h5 class='section'>Example:</h5>
2232       * <p class='bjava'>
2233       *    <jc>// Create a client that uses UON format by default for outgoing HTTP parts.</jc>
2234       *    RestClient <jv>client</jv> = RestClient
2235       *       .<jsm>create</jsm>()
2236       *       .partSerializer(UonSerializer.<jsf>DEFAULT</jsf>)
2237       *       .build();
2238       * </p>
2239       *
2240       * @param value
2241       *    The new value for this setting.
2242       *    <br>The default value is {@link OpenApiSerializer}.
2243       * @return This object.
2244       */
2245      @FluentSetter
2246      public Builder partSerializer(HttpPartSerializer value) {
2247         partSerializer().impl(value);
2248         return this;
2249      }
2250
2251      //------------------------------------------------------------------------------------------------------------------
2252      // partParser
2253      //------------------------------------------------------------------------------------------------------------------
2254
2255      /**
2256       * Returns the part parser sub-builder.
2257       *
2258       * @return The part parser sub-builder.
2259       */
2260      public final HttpPartParser.Creator partParser() {
2261         if (partParser == null)
2262            partParser = createPartParser();
2263         return partParser;
2264      }
2265
2266      /**
2267       * Instantiates the part parser sub-builder.
2268       *
2269       * @return A new part parser sub-builder.
2270       */
2271      protected HttpPartParser.Creator createPartParser() {
2272         return HttpPartParser.creator().type(OpenApiParser.class).beanContext(beanContext());
2273      }
2274
2275      /**
2276       * Part parser.
2277       *
2278       * <p>
2279       * The parser to use for parsing POJOs from form data, query parameters, headers, and path variables.
2280       *
2281       * <p>
2282       * The default part parser is {@link OpenApiParser} which allows for schema-driven marshalling.
2283       *
2284       * <h5 class='section'>Example:</h5>
2285       * <p class='bjava'>
2286       *    <jc>// Create a client that uses UON format by default for incoming HTTP parts.</jc>
2287       *    RestClient <jv>client</jv> = RestClient
2288       *       .<jsm>create</jsm>()
2289       *       .partParser(UonParser.<jk>class</jk>)
2290       *       .build();
2291       * </p>
2292       *
2293       * @param value
2294       *    The new value for this setting.
2295       *    <br>The default value is {@link OpenApiParser}.
2296       * @return This object.
2297       */
2298      @FluentSetter
2299      public Builder partParser(Class<? extends HttpPartParser> value) {
2300         partParser().type(value);
2301         return this;
2302      }
2303
2304      /**
2305       * Part parser.
2306       *
2307       * <p>
2308       * The parser to use for parsing POJOs from form data, query parameters, headers, and path variables.
2309       *
2310       * <p>
2311       * The default part parser is {@link OpenApiParser} which allows for schema-driven marshalling.
2312       *
2313       * <h5 class='section'>Example:</h5>
2314       * <p class='bjava'>
2315       *    <jc>// Create a client that uses UON format by default for incoming HTTP parts.</jc>
2316       *    RestClient <jv>client</jv> = RestClient
2317       *       .<jsm>create</jsm>()
2318       *       .partParser(UonParser.<jsf>DEFAULT</jsf>)
2319       *       .build();
2320       * </p>
2321       *
2322       * @param value
2323       *    The new value for this setting.
2324       *    <br>The default value is {@link OpenApiParser}.
2325       * @return This object.
2326       */
2327      @FluentSetter
2328      public Builder partParser(HttpPartParser value) {
2329         partParser().impl(value);
2330         return this;
2331      }
2332
2333      //------------------------------------------------------------------------------------------------------------------
2334      // urlEncodingSerializer
2335      //------------------------------------------------------------------------------------------------------------------
2336
2337      /**
2338       * Returns the URL-encoding serializer sub-builder.
2339       *
2340       * @return The URL-encoding serializer sub-builder.
2341       */
2342      public final UrlEncodingSerializer.Builder urlEncodingSerializer() {
2343         if (urlEncodingSerializer == null)
2344            urlEncodingSerializer = createUrlEncodingSerializer();
2345         return urlEncodingSerializer;
2346      }
2347
2348      /**
2349       * Instantiates the URL-encoding serializer sub-builder.
2350       *
2351       * @return A new URL-encoding serializer sub-builder.
2352       */
2353      protected UrlEncodingSerializer.Builder createUrlEncodingSerializer() {
2354         return UrlEncodingSerializer.create().beanContext(beanContext());
2355      }
2356
2357      //------------------------------------------------------------------------------------------------------------------
2358      // headerData
2359      //------------------------------------------------------------------------------------------------------------------
2360
2361      /**
2362       * Returns the builder for the list of headers that get applied to all requests created by this builder.
2363       *
2364       * <p>
2365       * This is the primary method for accessing the request header list.
2366       * On first call, the builder is created via the method {@link #createHeaderData()}.
2367       *
2368       * <h5 class='section'>Example:</h5>
2369       * <p class='bjava'>
2370       *    <jc>// Create a client that adds a "Foo: bar" header on every request.</jc>
2371       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2372       *    <jv>builder</jv>.headerData().setDefault(<js>"Foo"</js>, <js>"bar"</js>));
2373       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2374       * </p>
2375       *
2376       * <p>
2377       * The following convenience methods are also provided for updating the headers:
2378       * <ul>
2379       *    <li class='jm'>{@link #headers(Header...)}
2380       *    <li class='jm'>{@link #headersDefault(Header...)}
2381       *    <li class='jm'>{@link #header(String,String)}
2382       *    <li class='jm'>{@link #header(String,Supplier)}
2383       *    <li class='jm'>{@link #mediaType(String)}
2384       *    <li class='jm'>{@link #mediaType(MediaType)}
2385       *    <li class='jm'>{@link #accept(String)}
2386       *    <li class='jm'>{@link #acceptCharset(String)}
2387       *    <li class='jm'>{@link #clientVersion(String)}
2388       *    <li class='jm'>{@link #contentType(String)}
2389       *    <li class='jm'>{@link #debug()}
2390       *    <li class='jm'>{@link #noTrace()}
2391       * </ul>
2392       *
2393       * @return The header list builder.
2394       */
2395      public final HeaderList headers() {
2396         if (headerData == null)
2397            headerData = createHeaderData();
2398         return headerData;
2399      }
2400
2401      /**
2402       * Creates the builder for the header list.
2403       *
2404       * <p>
2405       * Subclasses can override this method to provide their own implementation.
2406       *
2407       * <p>
2408       * The default behavior creates an empty builder.
2409       *
2410       * @return The header list builder.
2411       * @see #headers()
2412       */
2413      protected HeaderList createHeaderData() {
2414         return HeaderList.create();
2415      }
2416
2417      /**
2418       * Appends multiple headers to all requests.
2419       *
2420       * <h5 class='section'>Example:</h5>
2421       * <p class='bjava'>
2422       *    <jk>import static</jk> org.apache.juneau.http.HttpHeaders.*;
2423       *
2424       *    RestClient <jv>client</jv> = RestClient
2425       *       .<jsm>create</jsm>()
2426       *       .headers(
2427       *          <jsf>ACCEPT_TEXT_XML</jsf>,
2428       *          <jsm>stringHeader</jsm>(<js>"Foo"</js>, <js>"bar"</js>)
2429       *       )
2430       *       .build();
2431       * </p>
2432       *
2433       * <p>
2434       * This is a shortcut for calling <c>headerData().append(<jv>parts</jv>)</c>.
2435       *
2436       * @param parts
2437       *    The header to set.
2438       * @return This object.
2439       * @see #headers()
2440       */
2441      @FluentSetter
2442      public Builder headers(Header...parts) {
2443         headers().append(parts);
2444         return this;
2445      }
2446
2447      /**
2448       * Sets default header values.
2449       *
2450       * <p>
2451       * Uses default values for specified headers if not otherwise specified on the outgoing requests.
2452       *
2453       * <h5 class='section'>Example:</h5>
2454       * <p class='bjava'>
2455       *    RestClient <jv>client</jv> = RestClient
2456       *       .<jsm>create</jsm>()
2457       *       .headersDefault(<jsm>stringHeader</jsm>(<js>"Foo"</js>, ()-&gt;<js>"bar"</js>));
2458       *       .build();
2459       * </p>
2460       *
2461       * <p>
2462       * This is a shortcut for calling <c>headerData().setDefault(<jv>parts</jv>)</c>.
2463       *
2464       * @param parts The header values.
2465       * @return This object.
2466       * @see #headers()
2467       */
2468      public Builder headersDefault(Header...parts) {
2469         headers().setDefault(parts);
2470         return this;
2471      }
2472
2473      /**
2474       * Appends a header to all requests.
2475       *
2476       * <h5 class='section'>Example:</h5>
2477       * <p class='bjava'>
2478       *    RestClient <jv>client</jv> = RestClient
2479       *       .<jsm>create</jsm>()
2480       *       .header(<js>"Foo"</js>, <js>"bar"</js>);
2481       *       .build();
2482       * </p>
2483       *
2484       * <p>
2485       * This is a shortcut for calling <c>headerData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2486       *
2487       * @param name The header name.
2488       * @param value The header value.
2489       * @return This object.
2490       * @see #headers()
2491       */
2492      @FluentSetter
2493      public Builder header(String name, String value) {
2494         headers().append(name, value);
2495         return this;
2496      }
2497
2498      /**
2499       * Appends a header to all requests using a dynamic value.
2500       *
2501       * <h5 class='section'>Example:</h5>
2502       * <p class='bjava'>
2503       *    RestClient <jv>client</jv> = RestClient
2504       *       .<jsm>create</jsm>()
2505       *       .header(<js>"Foo"</js>, ()-&gt;<js>"bar"</js>);
2506       *       .build();
2507       * </p>
2508       *
2509       * <p>
2510       * This is a shortcut for calling <c>headerData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2511       *
2512       * @param name The header name.
2513       * @param value The header value supplier.
2514       * @return This object.
2515       * @see #headers()
2516       */
2517      @FluentSetter
2518      public Builder header(String name, Supplier<String> value) {
2519         headers().append(name, value);
2520         return this;
2521      }
2522
2523      /**
2524       * Appends the <c>Accept</c> and <c>Content-Type</c> headers on all requests made by this client.
2525       *
2526       * <p>
2527       * Headers are appended to the end of the current header list.
2528       *
2529       * <p>
2530       * This is a shortcut for calling <c>headerData().append(Accept.<jsm>of</jsm>(<jv>value</jv>), ContentType.<jsm>of</jsm>(<jv>value</jv>))</c>.
2531       *
2532       * @param value The new header values.
2533       * @return This object.
2534       * @see #headers()
2535       */
2536      @FluentSetter
2537      public Builder mediaType(String value) {
2538         super.mediaType(MediaType.of(value));
2539         return headers(Accept.of(value), ContentType.of(value));
2540      }
2541
2542      /**
2543       * Appends the <c>Accept</c> and <c>Content-Type</c> headers on all requests made by this client.
2544       *
2545       * <p>
2546       * Headers are appended to the end of the current header list.
2547       *
2548       * <p>
2549       * This is a shortcut for calling <c>headerData().append(Accept.<jsm>of</jsm>(<jv>value</jv>), ContentType.<jsm>of</jsm>(<jv>value</jv>))</c>.
2550       *
2551       * @param value The new header values.
2552       * @return This object.
2553       * @see #headers()
2554       */
2555      @Override
2556      @FluentSetter
2557      public Builder mediaType(MediaType value) {
2558         super.mediaType(value);
2559         return headers(Accept.of(value), ContentType.of(value));
2560      }
2561
2562      /**
2563       * Appends an <c>Accept</c> header on this request.
2564       *
2565       * <p>
2566       * This is a shortcut for calling <c>headerData().append(Accept.<jsm>of</jsm>(<jv>value</jv>))</c>.
2567       *
2568       * @param value
2569       *    The new header value.
2570       * @return This object.
2571       * @see #headers()
2572       */
2573      @FluentSetter
2574      public Builder accept(String value) {
2575         return headers(Accept.of(value));
2576      }
2577
2578      /**
2579       * Sets the value for the <c>Accept-Charset</c> request header on all requests.
2580       *
2581       * <p>
2582       * This is a shortcut for calling <c>headerData().append(AcceptCharset.<jsm>of</jsm>(<jv>value</jv>))</c>.
2583       *
2584       * @param value The new header value.
2585       * @return This object.
2586       * @see #headers()
2587       */
2588      @FluentSetter
2589      public Builder acceptCharset(String value) {
2590         return headers(AcceptCharset.of(value));
2591      }
2592
2593      /**
2594       * Sets the client version by setting the value for the <js>"Client-Version"</js> header.
2595       *
2596       * <p>
2597       * This is a shortcut for calling <c>headerData().append(ClientVersion.<jsm>of</jsm>(<jv>value</jv>))</c>.
2598       *
2599       * @param value The version string (e.g. <js>"1.2.3"</js>)
2600       * @return This object.
2601       * @see #headers()
2602       */
2603      @FluentSetter
2604      public Builder clientVersion(String value) {
2605         return headers(ClientVersion.of(value));
2606      }
2607
2608      /**
2609       * Sets the value for the <c>Content-Type</c> request header on all requests.
2610       *
2611       * <p>
2612       * This is a shortcut for calling <c>headerData().append(ContentType.<jsm>of</jsm>(<jv>value</jv>))</c>.
2613       *
2614       * <p>
2615       * This overrides the media type specified on the serializer.
2616       *
2617       * @param value The new header value.
2618       * @return This object.
2619       * @see #headers()
2620       */
2621      @FluentSetter
2622      public Builder contentType(String value) {
2623         return headers(ContentType.of(value));
2624      }
2625
2626      /**
2627       * Sets the value for the <c>Debug</c> request header on all requests.
2628       *
2629       * <p>
2630       * This is a shortcut for calling <c>headerData().append(Debug.<jsm>of</jsm>(<jv>value</jv>))</c>.
2631       *
2632       * @return This object.
2633       * @see #headers()
2634       */
2635      @Override
2636      @FluentSetter
2637      public Builder debug() {
2638         super.debug();
2639         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::debug);
2640         return headers(Debug.TRUE);
2641      }
2642
2643      /**
2644       * When called, <c>No-Trace: true</c> is added to requests.
2645       *
2646       * <p>
2647       * This gives the opportunity for the servlet to not log errors on invalid requests.
2648       * This is useful for testing purposes when you don't want your log file to show lots of errors that are simply the
2649       * results of testing.
2650       *
2651       * <p>
2652       * It's up to the server to decide whether to allow for this.
2653       * The <c>BasicTestRestLogger</c> class watches for this header and prevents logging of status 400+ responses to
2654       * prevent needless logging of test scenarios.
2655       *
2656       * @return This object.
2657       * @see #headers()
2658       */
2659      @FluentSetter
2660      public Builder noTrace() {
2661         return headers(NoTrace.of(true));
2662      }
2663
2664      //------------------------------------------------------------------------------------------------------------------
2665      // queryData
2666      //------------------------------------------------------------------------------------------------------------------
2667
2668      /**
2669       * Returns the builder for the list of query parameters that get applied to all requests created by this builder.
2670       *
2671       * <p>
2672       * This is the primary method for accessing the query parameter list.
2673       * On first call, the builder is created via the method {@link #createQueryData()}.
2674       *
2675       * <h5 class='section'>Example:</h5>
2676       * <p class='bjava'>
2677       *    <jc>// Create a client that adds a "foo=bar" query parameter on every request.</jc>
2678       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2679       *    <jv>builder</jv>.queryData().setDefault(<js>"foo"</js>, <js>"bar"</js>));
2680       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2681       * </p>
2682       *
2683       * <p>
2684       * The following convenience methods are also provided for updating the parameters:
2685       * <ul>
2686       *    <li class='jm'>{@link #queryData(NameValuePair...)}
2687       *    <li class='jm'>{@link #queryDataDefault(NameValuePair...)}
2688       *    <li class='jm'>{@link #queryData(String,String)}
2689       *    <li class='jm'>{@link #queryData(String,Supplier)}
2690       * </ul>
2691       *
2692       * @return The query data list builder.
2693       */
2694      public final PartList queryData() {
2695         if (queryData == null)
2696            queryData = createQueryData();
2697         return queryData;
2698      }
2699
2700      /**
2701       * Creates the builder for the query data list.
2702       *
2703       * <p>
2704       * Subclasses can override this method to provide their own implementation.
2705       *
2706       * <p>
2707       * The default behavior creates an empty builder.
2708       *
2709       * @return The query data list builder.
2710       * @see #queryData()
2711       */
2712      protected PartList createQueryData() {
2713         return PartList.create();
2714      }
2715
2716      /**
2717       * Appends multiple query parameters to the URI of all requests.
2718       *
2719       * <h5 class='section'>Example:</h5>
2720       * <p class='bjava'>
2721       *    <jk>import static</jk> org.apache.juneau.http.HttpParts.*;
2722       *
2723       *    RestClient <jv>client</jv> = RestClient
2724       *       .<jsm>create</jsm>()
2725       *       .queryData(
2726       *          <jsm>stringPart</jsm>(<js>"foo"</js>, <js>"bar"</js>),
2727       *          <jsm>booleanPart</jsm>(<js>"baz"</js>, <jk>true</jk>)
2728       *       )
2729       *       .build();
2730       * </p>
2731       *
2732       * <p>
2733       * This is a shortcut for calling <c>queryData().append(<jv>parts</jv>)</c>.
2734       *
2735       * @param parts
2736       *    The query parameters.
2737       * @return This object.
2738       * @see #queryData()
2739       */
2740      @FluentSetter
2741      public Builder queryData(NameValuePair...parts) {
2742         queryData().append(parts);
2743         return this;
2744      }
2745
2746      /**
2747       * Sets default query parameter values.
2748       *
2749       * <p>
2750       * Uses default values for specified parameters if not otherwise specified on the outgoing requests.
2751       *
2752       * <h5 class='section'>Example:</h5>
2753       * <p class='bjava'>
2754       *    RestClient <jv>client</jv> = RestClient
2755       *       .<jsm>create</jsm>()
2756       *       .queryDataDefault(<jsm>stringPart</jsm>(<js>"foo"</js>, ()-&gt;<js>"bar"</js>));
2757       *       .build();
2758       * </p>
2759       *
2760       * <p>
2761       * This is a shortcut for calling <c>queryData().setDefault(<jv>parts</jv>)</c>.
2762       *
2763       * @param parts The parts.
2764       * @return This object.
2765       * @see #queryData()
2766       */
2767      public Builder queryDataDefault(NameValuePair...parts) {
2768         queryData().setDefault(parts);
2769         return this;
2770      }
2771
2772      /**
2773       * Appends a query parameter to the URI.
2774       *
2775       * <h5 class='section'>Example:</h5>
2776       * <p class='bjava'>
2777       *    RestClient <jv>client</jv> = RestClient
2778       *       .<jsm>create</jsm>()
2779       *       .queryData(<js>"foo"</js>, <js>"bar"</js>)
2780       *       .build();
2781       * </p>
2782       *
2783       * <p>
2784       * This is a shortcut for calling <c>queryData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2785       *
2786       * @param name The parameter name.
2787       * @param value The parameter value.
2788       * @return This object.
2789       * @see #queryData()
2790       */
2791      @FluentSetter
2792      public Builder queryData(String name, String value) {
2793         queryData().append(name, value);
2794         return this;
2795      }
2796
2797      /**
2798       * Appends a query parameter with a dynamic value to the URI.
2799       *
2800       * <h5 class='section'>Example:</h5>
2801       * <p class='bjava'>
2802       *    RestClient <jv>client</jv> = RestClient
2803       *       .<jsm>create</jsm>()
2804       *       .queryData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
2805       *       .build();
2806       * </p>
2807       *
2808       * <p>
2809       * This is a shortcut for calling <c>queryData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2810       *
2811       * @param name The parameter name.
2812       * @param value The parameter value supplier.
2813       * @return This object.
2814       * @see #queryData()
2815       */
2816      @FluentSetter
2817      public Builder queryData(String name, Supplier<String> value) {
2818         queryData().append(name, value);
2819         return this;
2820      }
2821
2822      //------------------------------------------------------------------------------------------------------------------
2823      // formData
2824      //------------------------------------------------------------------------------------------------------------------
2825
2826      /**
2827       * Returns the builder for the list of form data parameters that get applied to all requests created by this builder.
2828       *
2829       * <p>
2830       * This is the primary method for accessing the form data parameter list.
2831       * On first call, the builder is created via the method {@link #createFormData()}.
2832       *
2833       * <h5 class='section'>Example:</h5>
2834       * <p class='bjava'>
2835       *    <jc>// Create a client that adds a "foo=bar" form-data parameter on every request.</jc>
2836       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2837       *    <jv>builder</jv>.formData().setDefault(<js>"foo"</js>, <js>"bar"</js>));
2838       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2839       * </p>
2840       *
2841       * <p>
2842       * The following convenience methods are also provided for updating the parameters:
2843       * <ul>
2844       *    <li class='jm'>{@link #formData(NameValuePair...)}
2845       *    <li class='jm'>{@link #formDataDefault(NameValuePair...)}
2846       *    <li class='jm'>{@link #formData(String,String)}
2847       *    <li class='jm'>{@link #formData(String,Supplier)}
2848       * </ul>
2849       *
2850       * @return The form data list builder.
2851       */
2852      public final PartList formData() {
2853         if (formData == null)
2854            formData = createFormData();
2855         return formData;
2856      }
2857
2858      /**
2859       * Creates the builder for the form data list.
2860       *
2861       * <p>
2862       * Subclasses can override this method to provide their own implementation.
2863       *
2864       * <p>
2865       * The default behavior creates an empty builder.
2866       *
2867       * @return The query data list builder.
2868       * @see #formData()
2869       */
2870      protected PartList createFormData() {
2871         return PartList.create();
2872      }
2873
2874      /**
2875       * Appends multiple form-data parameters to the request bodies of all URL-encoded form posts.
2876       *
2877       * <h5 class='section'>Example:</h5>
2878       * <p class='bjava'>
2879       *    <jk>import static</jk> org.apache.juneau.http.HttpParts.*;
2880       *
2881       *    RestClient <jv>client</jv> = RestClient
2882       *       .<jsm>create</jsm>()
2883       *       .formData(
2884       *          <jsm>stringPart</jsm>(<js>"foo"</js>, <js>"bar"</js>),
2885       *          <jsm>booleanPart</jsm>(<js>"baz"</js>, <jk>true</jk>)
2886       *       )
2887       *       .build();
2888       * </p>
2889       *
2890       * <p>
2891       * This is a shortcut for calling <c>formData().append(<jv>parts</jv>)</c>.
2892       *
2893       * @param parts
2894       *    The form-data parameters.
2895       * @return This object.
2896       * @see #formData()
2897       */
2898      @FluentSetter
2899      public Builder formData(NameValuePair...parts) {
2900         formData().append(parts);
2901         return this;
2902      }
2903
2904      /**
2905       * Sets default form-data parameter values.
2906       *
2907       * <p>
2908       * Uses default values for specified parameters if not otherwise specified on the outgoing requests.
2909       *
2910       * <h5 class='section'>Example:</h5>
2911       * <p class='bjava'>
2912       *    RestClient <jv>client</jv> = RestClient
2913       *       .<jsm>create</jsm>()
2914       *       .formDataDefault(<jsm>stringPart</jsm>(<js>"foo"</js>, ()-&gt;<js>"bar"</js>));
2915       *       .build();
2916       * </p>
2917       *
2918       * <p>
2919       * This is a shortcut for calling <c>formData().setDefault(<jv>parts</jv>)</c>.
2920       *
2921       * @param parts The parts.
2922       * @return This object.
2923       * @see #formData()
2924       */
2925      public Builder formDataDefault(NameValuePair...parts) {
2926         formData().setDefault(parts);
2927         return this;
2928      }
2929
2930      /**
2931       * Appends a form-data parameter to all request bodies.
2932       *
2933       * <h5 class='section'>Example:</h5>
2934       * <p class='bjava'>
2935       *    RestClient <jv>client</jv> = RestClient
2936       *       .<jsm>create</jsm>()
2937       *       .formData(<js>"foo"</js>, <js>"bar"</js>)
2938       *       .build();
2939       * </p>
2940       *
2941       * <p>
2942       * This is a shortcut for calling <c>formData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2943       *
2944       * @param name The parameter name.
2945       * @param value The parameter value.
2946       * @return This object.
2947       * @see #formData()
2948       */
2949      @FluentSetter
2950      public Builder formData(String name, String value) {
2951         formData().append(name, value);
2952         return this;
2953      }
2954
2955      /**
2956       * Appends a form-data parameter with a dynamic value to all request bodies.
2957       *
2958       * <h5 class='section'>Example:</h5>
2959       * <p class='bjava'>
2960       *    RestClient <jv>client</jv> = RestClient
2961       *       .<jsm>create</jsm>()
2962       *       .formData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
2963       *       .build();
2964       * </p>
2965       *
2966       * <p>
2967       * This is a shortcut for calling <c>formData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2968       *
2969       * @param name The parameter name.
2970       * @param value The parameter value supplier.
2971       * @return This object.
2972       * @see #formData()
2973       */
2974      @FluentSetter
2975      public Builder formData(String name, Supplier<String> value) {
2976         formData().append(name, value);
2977         return this;
2978      }
2979
2980      //------------------------------------------------------------------------------------------------------------------
2981      // pathData
2982      //------------------------------------------------------------------------------------------------------------------
2983
2984      /**
2985       * Returns the builder for the list of path data parameters that get applied to all requests created by this builder.
2986       *
2987       * <p>
2988       * This is the primary method for accessing the path data parameter list.
2989       * On first call, the builder is created via the method {@link #createFormData()}.
2990       *
2991       * <h5 class='section'>Example:</h5>
2992       * <p class='bjava'>
2993       *    <jc>// Create a client that uses "bar" for the "{foo}" path variable on every request.</jc>
2994       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2995       *    <jv>builder</jv>.pathData().setDefault(<js>"foo"</js>, <js>"bar"</js>));
2996       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2997       * </p>
2998       *
2999       * <p>
3000       * The following convenience methods are also provided for updating the parameters:
3001       * <ul>
3002       *    <li class='jm'>{@link #pathData(NameValuePair...)}
3003       *    <li class='jm'>{@link #pathDataDefault(NameValuePair...)}
3004       *    <li class='jm'>{@link #pathData(String,String)}
3005       *    <li class='jm'>{@link #pathData(String,Supplier)}
3006       * </ul>
3007       *
3008       * @return The form data list builder.
3009       */
3010      public final PartList pathData() {
3011         if (pathData == null)
3012            pathData = createPathData();
3013         return pathData;
3014      }
3015
3016      /**
3017       * Creates the builder for the path data list.
3018       *
3019       * <p>
3020       * Subclasses can override this method to provide their own implementation.
3021       *
3022       * <p>
3023       * The default behavior creates an empty builder.
3024       *
3025       * @return The query data list builder.
3026       * @see #pathData()
3027       */
3028      protected PartList createPathData() {
3029         return PartList.create();
3030      }
3031
3032      /**
3033       * Sets multiple path parameters on all requests.
3034       *
3035       * <h5 class='section'>Example:</h5>
3036       * <p class='bjava'>
3037       *    <jk>import static</jk> org.apache.juneau.http.HttpParts.*;
3038       *
3039       *    RestClient <jv>client</jv> = RestClient
3040       *       .<jsm>create</jsm>()
3041       *       .pathData(
3042       *          <jsm>stringPart</jsm>(<js>"foo"</js>, <js>"bar"</js>),
3043       *          <jsm>booleanPart</jsm>(<js>"baz"</js>, <jk>true</jk>)
3044       *       )
3045       *       .build();
3046       * </p>
3047       *
3048       * <p>
3049       * This is a shortcut for calling <c>pathData().append(<jv>parts</jv>)</c>.
3050       *
3051       * @param parts
3052       *    The path parameters.
3053       * @return This object.
3054       * @see #pathData()
3055       */
3056      @FluentSetter
3057      public Builder pathData(NameValuePair...parts) {
3058         pathData().append(parts);
3059         return this;
3060      }
3061
3062      /**
3063       * Sets default path parameter values.
3064       *
3065       * <p>
3066       * Uses default values for specified parameters if not otherwise specified on the outgoing requests.
3067       *
3068       * <h5 class='section'>Example:</h5>
3069       * <p class='bjava'>
3070       *    RestClient <jv>client</jv> = RestClient
3071       *       .<jsm>create</jsm>()
3072       *       .pathDataDefault(<jsm>stringPart</jsm>(<js>"foo"</js>, ()-&gt;<js>"bar"</js>));
3073       *       .build();
3074       * </p>
3075       *
3076       * <p>
3077       * This is a shortcut for calling <c>pathData().setDefault(<jv>parts</jv>)</c>.
3078       *
3079       * @param parts The parts.
3080       * @return This object.
3081       * @see #pathData()
3082       */
3083      public Builder pathDataDefault(NameValuePair...parts) {
3084         pathData().setDefault(parts);
3085         return this;
3086      }
3087
3088      /**
3089       * Appends a path parameter to all request bodies.
3090       *
3091       * <h5 class='section'>Example:</h5>
3092       * <p class='bjava'>
3093       *    RestClient <jv>client</jv> = RestClient
3094       *       .<jsm>create</jsm>()
3095       *       .pathData(<js>"foo"</js>, <js>"bar"</js>)
3096       *       .build();
3097       * </p>
3098       *
3099       * <p>
3100       * This is a shortcut for calling <c>pathData().append(<jv>name</jv>,<jv>value</jv>)</c>.
3101       *
3102       * @param name The parameter name.
3103       * @param value The parameter value.
3104       * @return This object.
3105       * @see #pathData()
3106       */
3107      @FluentSetter
3108      public Builder pathData(String name, String value) {
3109         pathData().append(name, value);
3110         return this;
3111      }
3112
3113      /**
3114       * Sets a path parameter with a dynamic value to all request bodies.
3115       *
3116       * <h5 class='section'>Example:</h5>
3117       * <p class='bjava'>
3118       *    RestClient <jv>client</jv> = RestClient
3119       *       .<jsm>create</jsm>()
3120       *       .pathData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
3121       *       .build();
3122       * </p>
3123       *
3124       * <p>
3125       * This is a shortcut for calling <c>pathData().append(<jv>name</jv>,<jv>value</jv>)</c>.
3126       *
3127       * @param name The parameter name.
3128       * @param value The parameter value supplier.
3129       * @return This object.
3130       * @see #pathData()
3131       */
3132      @FluentSetter
3133      public Builder pathData(String name, Supplier<String> value) {
3134         pathData().set(name, value);
3135         return this;
3136      }
3137
3138      //------------------------------------------------------------------------------------------------------------------
3139      // callHandler
3140      //------------------------------------------------------------------------------------------------------------------
3141
3142      /**
3143       * Returns the creator for the rest call handler.
3144       *
3145       * <p>
3146       * Allows you to provide a custom handler for making HTTP calls.
3147       *
3148       * <h5 class='section'>Example:</h5>
3149       * <p class='bjava'>
3150       *    <jc>// Create a client that handles processing of requests using a custom handler.</jc>
3151       *    <jk>public class</jk> MyRestCallHandler <jk>implements</jk> RestCallHandler {
3152       *
3153       *       <ja>@Override</ja>
3154       *       <jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
3155       *          <jc>// Custom handle requests.</jc>
3156       *       }
3157       *    }
3158       *
3159       *    RestClient <jv>client</jv> = RestClient
3160       *       .<jsm>create</jsm>()
3161       *       .callHandler(MyRestCallHandler.<jk>class</jk>)
3162       *       .build();
3163       * </p>
3164       *
3165       * <h5 class='section'>Notes:</h5><ul>
3166       *    <li class='note'>
3167       *       The {@link RestClient#run(HttpHost, HttpRequest, HttpContext)} method can also be overridden to produce the same results.
3168       *    <li class='note'>
3169       *       Use {@link BeanCreator#impl(Object)} to specify an already instantiated instance.
3170       *    <li class='note'>
3171       *       Use {@link BeanCreator#type(Class)} to specify a subtype to instantiate.
3172       *       <br>Subclass must have a public constructor that takes in any args available
3173       *       in the bean store of this builder (including {@link RestClient} itself).
3174       * </ul>
3175       *
3176       * <h5 class='section'>See Also:</h5><ul>
3177       *    <li class='jic'>{@link RestCallHandler}
3178       * </ul>
3179       *
3180       * @return The creator for the rest call handler.
3181       */
3182      public final BeanCreator<RestCallHandler> callHandler() {
3183         if (callHandler == null)
3184            callHandler = createCallHandler();
3185         return callHandler;
3186      }
3187
3188      /**
3189       * Creates the creator for the rest call handler.
3190       *
3191       * <p>
3192       * Subclasses can override this method to provide their own implementation.
3193       *
3194       * <p>
3195       * The default behavior creates a bean creator initialized to return a {@link BasicRestCallHandler}.
3196       *
3197       * @return The creator for the rest call handler.
3198       * @see #callHandler()
3199       */
3200      protected BeanCreator<RestCallHandler> createCallHandler() {
3201         return beanStore.createBean(RestCallHandler.class).type(BasicRestCallHandler.class);
3202      }
3203
3204      /**
3205       * REST call handler class.
3206       *
3207       * <p>
3208       * Specifies a custom handler for making HTTP calls.
3209       *
3210       * <p>
3211       * This is a shortcut for <c>callHandler().type(<jv>value</jv>)</c>.
3212       *
3213       * @param value
3214       *    The new value for this setting.
3215       * @return This object.
3216       * @see #callHandler()
3217       */
3218      @FluentSetter
3219      public Builder callHandler(Class<? extends RestCallHandler> value) {
3220         callHandler().type(value);
3221         return this;
3222      }
3223
3224      //------------------------------------------------------------------------------------------------------------------
3225      // errorCodes
3226      //------------------------------------------------------------------------------------------------------------------
3227
3228      /**
3229       * Errors codes predicate.
3230       *
3231       * <p>
3232       * Defines a predicate to test for error codes.
3233       *
3234       * <h5 class='section'>Example:</h5>
3235       * <p class='bjava'>
3236       *    <jc>// Create a client that considers any 300+ responses to be errors.</jc>
3237       *    RestClient <jv>client</jv> = RestClient
3238       *       .<jsm>create</jsm>()
3239       *       .errorCodes(<jv>x</jv> -&gt; <jv>x</jv>&gt;=300)
3240       *       .build();
3241       * </p>
3242       *
3243       * @param value
3244       *    The new value for this setting.
3245       *    <br>The default value is <code>x -&gt; x &gt;= 400</code>.
3246       * @return This object.
3247       */
3248      @FluentSetter
3249      public Builder errorCodes(Predicate<Integer> value) {
3250         errorCodes = assertArgNotNull("value", value);
3251         return this;
3252      }
3253
3254      //------------------------------------------------------------------------------------------------------------------
3255      // Logging.
3256      //------------------------------------------------------------------------------------------------------------------
3257
3258      /**
3259       * Logger.
3260       *
3261       * <p>
3262       * Specifies the logger to use for logging.
3263       *
3264       * <p>
3265       * If not specified, uses the following logger:
3266       * <p class='bjava'>
3267       *    Logger.<jsm>getLogger</jsm>(RestClient.<jk>class</jk>.getName());
3268       * </p>
3269       *
3270       * <h5 class='section'>Example:</h5>
3271       * <p class='bjava'>
3272       *    <jc>// Construct a client that logs messages to a special logger.</jc>
3273       *    RestClient <jv>client</jv> = RestClient
3274       *       .<jsm>create</jsm>()
3275       *       .logger(Logger.<jsm>getLogger</jsm>(<js>"MyLogger"</js>))  <jc>// Log to MyLogger logger.</jc>
3276       *       .logToConsole()  <jc>// Also log to console.</jc>
3277       *       .logRequests(<jsf>FULL</jsf>, <jsf>WARNING</jsf>)  <jc>// Log requests with full detail at WARNING level.</jc>
3278       *       .build();
3279       * </p>
3280       *
3281       * @param value The logger to use for logging.
3282       * @return This object.
3283       */
3284      @FluentSetter
3285      public Builder logger(Logger value) {
3286         logger = value;
3287         return this;
3288      }
3289
3290      /**
3291       * Log to console.
3292       *
3293       * <p>
3294       * Specifies to log messages to the console.
3295       *
3296       * <h5 class='section'>Example:</h5>
3297       * <p class='bjava'>
3298       *    <jc>// Construct a client that logs messages to a special logger.</jc>
3299       *    RestClient <jv>client</jv> = RestClient
3300       *       .<jsm>create</jsm>()
3301       *       .logToConsole()
3302       *       .logRequests(<jsf>FULL</jsf>, <jsf>INFO</jsf>)  <jc>// Level is ignored when logging to console.</jc>
3303       *       .build();
3304       * </p>
3305       *
3306       * @return This object.
3307       */
3308      @FluentSetter
3309      public Builder logToConsole() {
3310         logToConsole = true;
3311         return this;
3312      }
3313
3314      /**
3315       * Log requests.
3316       *
3317       * <p>
3318       * Causes requests/responses to be logged at the specified log level at the end of the request.
3319       *
3320       * <p>
3321       * <jsf>SIMPLE</jsf> detail produces a log message like the following:
3322       * <p class='bconsole'>
3323       *    POST http://localhost:10000/testUrl, HTTP/1.1 200 OK
3324       * </p>
3325       *
3326       * <p>
3327       * <jsf>FULL</jsf> detail produces a log message like the following:
3328       * <p class='bconsole'>
3329       *    === HTTP Call (outgoing) =======================================================
3330       *    === REQUEST ===
3331       *    POST http://localhost:10000/testUrl
3332       *    ---request headers---
3333       *       Debug: true
3334       *       No-Trace: true
3335       *       Accept: application/json
3336       *    ---request entity---
3337       *       Content-Type: application/json
3338       *    ---request content---
3339       *    {"foo":"bar","baz":123}
3340       *    === RESPONSE ===
3341       *    HTTP/1.1 200 OK
3342       *    ---response headers---
3343       *       Content-Type: application/json;charset=utf-8
3344       *       Content-Length: 21
3345       *       Server: Jetty(8.1.0.v20120127)
3346       *    ---response content---
3347       *    {"message":"OK then"}
3348       *    === END ========================================================================
3349       * </p>
3350       *
3351       * <p>
3352       * By default, the message is logged to the default logger.  It can be logged to a different logger via the
3353       * {@link #logger(Logger)} method or logged to the console using the
3354       * {@link #logToConsole()} method.
3355       *
3356       * @param detail The detail level of logging.
3357       * @param level The log level.
3358       * @param test A predicate to use per-request to see if the request should be logged.  If <jk>null</jk>, always logs.
3359       * @return This object.
3360       */
3361      @FluentSetter
3362      public Builder logRequests(DetailLevel detail, Level level, BiPredicate<RestRequest,RestResponse> test) {
3363         logRequests = detail;
3364         logRequestsLevel = level;
3365         logRequestsPredicate = test;
3366         return this;
3367      }
3368
3369      //------------------------------------------------------------------------------------------------------------------
3370      // HttpClientConnectionManager methods.
3371      //------------------------------------------------------------------------------------------------------------------
3372
3373      /**
3374       * Creates the {@link HttpClientConnectionManager} returned by {@link #createConnectionManager()}.
3375       *
3376       * <p>
3377       * Subclasses can override this method to provide their own connection manager.
3378       *
3379       * <p>
3380       * The default implementation returns an instance of a {@link PoolingHttpClientConnectionManager} if {@link #pooled()}
3381       * was called or {@link BasicHttpClientConnectionManager} if not..
3382       *
3383       * <h5 class='section'>Example:</h5>
3384       * <p class='bjava'>
3385       *    <jc>// A Builder that provides it's own customized HttpClientConnectionManager.</jc>
3386       *    <jk>public class</jk> MyBuilder <jk>extends</jk> Builder {
3387       *       <ja>@Override</ja>
3388       *       <jk>protected</jk> HttpClientConnectionManager createConnectionManager() {
3389       *          <jk>return new</jk> PoolingHttpClientConnectionManager();
3390       *       }
3391       *    }
3392       *
3393       *    <jc>// Instantiate.</jc>
3394       *    RestClient <jv>client</jv> = <jk>new</jk> MyBuilder().build();
3395       * </p>
3396       *
3397       * @return The HTTP client builder to use to create the HTTP client.
3398       */
3399      protected HttpClientConnectionManager createConnectionManager() {
3400         return (pooled ? new PoolingHttpClientConnectionManager() : new BasicHttpClientConnectionManager());
3401      }
3402
3403      /**
3404       * When called, the {@link #createConnectionManager()} method will return a {@link PoolingHttpClientConnectionManager}
3405       * instead of a {@link BasicHttpClientConnectionManager}.
3406       *
3407       * <h5 class='section'>Example:</h5>
3408       * <p class='bjava'>
3409       *    <jc>// Construct a client that uses pooled connections.</jc>
3410       *    RestClient <jv>client</jv> = RestClient
3411       *       .<jsm>create</jsm>()
3412       *       .pooled()
3413       *       .build();
3414       * </p>
3415       *
3416       * @return This object.
3417       */
3418      @FluentSetter
3419      public Builder pooled() {
3420         this.pooled = true;
3421         return this;
3422      }
3423
3424      /**
3425       * Assigns {@link HttpClientConnectionManager} instance.
3426       *
3427       * @param value New property value.
3428       * @return This object.
3429       * @see HttpClientBuilder#setConnectionManager(HttpClientConnectionManager)
3430       */
3431      @FluentSetter
3432      public Builder connectionManager(HttpClientConnectionManager value) {
3433         connectionManager = value;
3434         httpClientBuilder().setConnectionManager(value);
3435         return this;
3436      }
3437
3438      /**
3439       * Defines the connection manager is to be shared by multiple client instances.
3440       *
3441       * <h5 class='section'>Notes:</h5><ul>
3442       *    <li class='note'>If the connection manager is shared its life-cycle is expected to be managed by the caller and it will not be shut down if the client is closed.
3443       * </ul>
3444       *
3445       * @param shared New property value.
3446       * @return This object.
3447       * @see HttpClientBuilder#setConnectionManagerShared(boolean)
3448       */
3449      @FluentSetter
3450      public Builder connectionManagerShared(boolean shared) {
3451         httpClientBuilder().setConnectionManagerShared(shared);
3452         return this;
3453      }
3454
3455      /**
3456       * Set up this client to use BASIC auth.
3457       *
3458       * <h5 class='section'>Example:</h5>
3459       * <p class='bjava'>
3460       *    <jc>// Construct a client that uses BASIC authentication.</jc>
3461       *    RestClient <jv>client</jv> = RestClient
3462       *       .<jsm>create</jsm>()
3463       *       .basicAuth(<js>"http://localhost"</js>, 80, <js>"me"</js>, <js>"mypassword"</js>)
3464       *       .build();
3465       * </p>
3466       *
3467       * @param host The auth scope hostname.
3468       * @param port The auth scope port.
3469       * @param user The username.
3470       * @param pw The password.
3471       * @return This object.
3472       */
3473      @FluentSetter
3474      public Builder basicAuth(String host, int port, String user, String pw) {
3475         AuthScope scope = new AuthScope(host, port);
3476         Credentials up = new UsernamePasswordCredentials(user, pw);
3477         CredentialsProvider p = new BasicCredentialsProvider();
3478         p.setCredentials(scope, up);
3479         defaultCredentialsProvider(p);
3480         return this;
3481      }
3482
3483      //-----------------------------------------------------------------------------------------------------------------
3484      // Properties
3485      //-----------------------------------------------------------------------------------------------------------------
3486
3487      /**
3488       * Console print stream
3489       *
3490       * <p>
3491       * Allows you to redirect the console output to a different print stream.
3492       *
3493       * @param value
3494       *    The new value for this setting.
3495       * @return This object.
3496       */
3497      @FluentSetter
3498      public Builder console(PrintStream value) {
3499         console = value;
3500         return this;
3501      }
3502
3503      /**
3504       * <i><l>RestClient</l> configuration property:&emsp;</i>  Executor service.
3505       *
3506       * <p>
3507       * Defines the executor service to use when calling future methods on the {@link RestRequest} class.
3508       *
3509       * <p>
3510       * This executor service is used to create {@link Future} objects on the following methods:
3511       * <ul>
3512       *    <li class='jm'>{@link RestRequest#runFuture()}
3513       *    <li class='jm'>{@link RestRequest#completeFuture()}
3514       *    <li class='jm'>{@link ResponseContent#asFuture(Class)} (and similar methods)
3515       * </ul>
3516       *
3517       * <p>
3518       * The default executor service is a single-threaded {@link ThreadPoolExecutor} with a 30 second timeout
3519       * and a queue size of 10.
3520       *
3521       * <h5 class='section'>Example:</h5>
3522       * <p class='bjava'>
3523       *    <jc>// Create a client with a customized executor service.</jc>
3524       *    RestClient <jv>client</jv> = RestClient
3525       *       .<jsm>create</jsm>()
3526       *       .executorService(<jk>new</jk> ThreadPoolExecutor(1, 1, 30, TimeUnit.<jsf>SECONDS</jsf>, <jk>new</jk> ArrayBlockingQueue&lt;Runnable&gt;(10)), <jk>true</jk>)
3527       *       .build();
3528       *
3529       *    <jc>// Use it to asynchronously run a request.</jc>
3530       *    Future&lt;RestResponse&gt; <jv>responseFuture</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).runFuture();
3531       *
3532       *    <jc>// Do some other stuff.</jc>
3533       *
3534       *    <jc>// Now read the response.</jc>
3535       *    String <jv>body</jv> = <jv>responseFuture</jv>.get().getContent().asString();
3536       *
3537       *    <jc>// Use it to asynchronously retrieve a response.</jc>
3538       *    Future&lt;MyBean&gt; <jv>myBeanFuture</jv> = <jv>client</jv>
3539       *       .get(<jsf>URI</jsf>)
3540       *       .run()
3541       *       .getContent().asFuture(MyBean.<jk>class</jk>);
3542       *
3543       *    <jc>// Do some other stuff.</jc>
3544       *
3545       *    <jc>// Now read the response.</jc>
3546       *    MyBean <jv>bean</jv> = <jv>myBeanFuture</jv>.get();
3547       * </p>
3548       *
3549       * @param executorService The executor service.
3550       * @param shutdownOnClose Call {@link ExecutorService#shutdown()} when {@link RestClient#close()} is called.
3551       * @return This object.
3552       */
3553      @FluentSetter
3554      public Builder executorService(ExecutorService executorService, boolean shutdownOnClose) {
3555         this.executorService = executorService;
3556         this.executorServiceShutdownOnClose = shutdownOnClose;
3557         return this;
3558      }
3559
3560      /**
3561       * <i><l>RestClient</l> configuration property:&emsp;</i>  Keep HttpClient open.
3562       *
3563       * <p>
3564       * Don't close this client when the {@link RestClient#close()} method is called.
3565       *
3566       * <h5 class='section'>Example:</h5>
3567       * <p class='bjava'>
3568       *    <jc>// Create a client with a customized client and don't close the client  service.</jc>
3569       *    RestClient <jv>client</jv> = RestClient
3570       *       .<jsm>create</jsm>()
3571       *       .httpClient(<jv>myHttpClient</jv>)
3572       *       .keepHttpClientOpen()
3573       *       .build();
3574       *
3575       *    <jv>client</jv>.closeQuietly();  <jc>// Customized HttpClient won't be closed.</jc>
3576       * </p>
3577       *
3578       * @return This object.
3579       */
3580      @FluentSetter
3581      public Builder keepHttpClientOpen() {
3582         keepHttpClientOpen = true;
3583         return this;
3584      }
3585
3586      /**
3587       * Ignore errors.
3588       *
3589       * <p>
3590       * When enabled, HTTP error response codes (e.g. <l>&gt;=400</l>) will not cause a {@link RestCallException} to
3591       * be thrown.
3592       * <p>
3593       * Note that this is equivalent to <c>builder.errorCodes(x -&gt; <jk>false</jk>);</c>
3594       *
3595       * <h5 class='section'>Example:</h5>
3596       * <p class='bjava'>
3597       *    <jc>// Create a client that doesn't throws a RestCallException when a 500 error occurs.</jc>
3598       *    RestClient
3599       *       .<jsm>create</jsm>()
3600       *       .ignoreErrors()
3601       *       .build()
3602       *       .get(<js>"/error"</js>)  <jc>// Throws a 500 error</jc>
3603       *       .run()
3604       *       .assertStatus().is(500);
3605       * </p>
3606       *
3607       * @return This object.
3608       */
3609      @FluentSetter
3610      public Builder ignoreErrors() {
3611         ignoreErrors = true;
3612         return this;
3613      }
3614
3615      /**
3616       * <i><l>RestClient</l> configuration property:&emsp;</i>  Call interceptors.
3617       *
3618       * <p>
3619       * Adds an interceptor that can be called to hook into specified events in the lifecycle of a single request.
3620       *
3621       * <h5 class='section'>Example:</h5>
3622       * <p class='bjava'>
3623       *   <jc>// Customized interceptor (note you can also extend from BasicRestCallInterceptor as well.</jc>
3624       *    <jk>public class</jk> MyRestCallInterceptor <jk>implements</jk> RestCallInterceptor {
3625       *
3626       *       <ja>@Override</ja>
3627       *       <jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
3628       *       <jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
3629       *       // set on the request from the client.</jc>
3630       *    }
3631       *
3632       *    <ja>@Override</ja>
3633       *    <jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3634       *       <jc>// Intercept immediately after an HTTP response has been received.</jc>
3635       *    }
3636       *
3637       *    <ja>@Override</ja>
3638       *    <jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3639       *          <jc>// Intercept when the response body is consumed.</jc>
3640       *       }
3641       *    }
3642       *
3643       *    <jc>// Create a client with a customized interceptor.</jc>
3644       *    RestClient <jv>client</jv> = RestClient
3645       *       .<jsm>create</jsm>()
3646       *       .interceptors(MyRestCallInterceptor.<jk>class</jk>)
3647       *       .build();
3648       * </p>
3649       *
3650       * <h5 class='section'>Notes:</h5><ul>
3651       *    <li class='note'>The {@link RestClient#onCallInit(RestRequest)}, {@link RestClient#onCallConnect(RestRequest,RestResponse)}, and
3652       * {@link RestClient#onCallClose(RestRequest,RestResponse)} methods can also be overridden to produce the same results.
3653       * </ul>
3654       *
3655       * @param values
3656       *    The values to add to this setting.
3657       *    <br>Can be implementations of any of the following:
3658       *    <ul>
3659       *       <li class='jic'>{@link RestCallInterceptor}
3660       *       <li class='jic'>{@link HttpRequestInterceptor}
3661       *       <li class='jic'>{@link HttpResponseInterceptor}
3662       *    </ul>
3663       * @return This object.
3664       * @throws Exception If one or more interceptors could not be created.
3665       */
3666      @FluentSetter
3667      public Builder interceptors(Class<?>...values) throws Exception {
3668         for (Class<?> c : values) {
3669            ClassInfo ci = ClassInfo.of(c);
3670            if (ci != null) {
3671               if (ci.isChildOfAny(RestCallInterceptor.class, HttpRequestInterceptor.class, HttpResponseInterceptor.class))
3672                  interceptors(ci.newInstance());
3673               else
3674                  throw new ConfigException("Invalid class of type ''{0}'' passed to interceptors().", ci.getName());
3675            }
3676         }
3677         return this;
3678      }
3679
3680      /**
3681       * Call interceptors.
3682       *
3683       * <p>
3684       * Adds an interceptor that gets called immediately after a connection is made.
3685       *
3686       * <h5 class='section'>Example:</h5>
3687       * <p class='bjava'>
3688       *    <jc>// Create a client with a customized interceptor.</jc>
3689       *    RestClient <jv>client</jv> = RestClient
3690       *       .<jsm>create</jsm>()
3691       *       .interceptors(
3692       *          <jk>new</jk> RestCallInterceptor() {
3693       *
3694       *             <ja>@Override</ja>
3695       *             <jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
3696       *             <jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
3697       *             // set on the request from the client.</jc>
3698       *          }
3699       *
3700       *          <ja>@Override</ja>
3701       *          <jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3702       *             <jc>// Intercept immediately after an HTTP response has been received.</jc>
3703       *          }
3704       *
3705       *          <ja>@Override</ja>
3706       *          <jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3707       *                <jc>// Intercept when the response body is consumed.</jc>
3708       *             }
3709       *          }
3710       *       )
3711       *       .build();
3712       * </p>
3713       *
3714       * <h5 class='section'>Notes:</h5><ul>
3715       *    <li class='note'>The {@link RestClient#onCallInit(RestRequest)}, {@link RestClient#onCallConnect(RestRequest,RestResponse)}, and
3716       * {@link RestClient#onCallClose(RestRequest,RestResponse)} methods can also be overridden to produce the same results.
3717       * </ul>
3718       *
3719       * @param value
3720       *    The values to add to this setting.
3721       *    <br>Can be implementations of any of the following:
3722       *    <ul>
3723       *       <li class='jic'>{@link RestCallInterceptor}
3724       *       <li class='jic'>{@link HttpRequestInterceptor}
3725       *       <li class='jic'>{@link HttpResponseInterceptor}
3726       *    </ul>
3727       * @return This object.
3728       */
3729      @FluentSetter
3730      public Builder interceptors(Object...value) {
3731         List<RestCallInterceptor> l = list();
3732         for (Object o : value) {
3733            ClassInfo ci = ClassInfo.of(o);
3734            if (ci != null) {
3735               if (! ci.isChildOfAny(HttpRequestInterceptor.class, HttpResponseInterceptor.class, RestCallInterceptor.class))
3736                  throw new ConfigException("Invalid object of type ''{0}'' passed to interceptors().", ci.getName());
3737               if (o instanceof HttpRequestInterceptor)
3738                  addInterceptorLast((HttpRequestInterceptor)o);
3739               if (o instanceof HttpResponseInterceptor)
3740                  addInterceptorLast((HttpResponseInterceptor)o);
3741               if (o instanceof RestCallInterceptor)
3742                  l.add((RestCallInterceptor)o);
3743            }
3744         }
3745         if (interceptors == null)
3746            interceptors = l;
3747         else
3748            interceptors.addAll(0, l);
3749         return this;
3750      }
3751
3752      /**
3753       * <i><l>RestClient</l> configuration property:&emsp;</i>  Enable leak detection.
3754       *
3755       * <p>
3756       * Enable client and request/response leak detection.
3757       *
3758       * <p>
3759       * Causes messages to be logged to the console if clients or request/response objects are not properly closed
3760       * when the <c>finalize</c> methods are invoked.
3761       *
3762       * <p>
3763       * Automatically enabled with {@link org.apache.juneau.Context.Builder#debug()}.
3764       *
3765       * <h5 class='section'>Example:</h5>
3766       * <p class='bjava'>
3767       *    <jc>// Create a client that logs a message if </jc>
3768       *    RestClient <jv>client</jv> = RestClient
3769       *       .<jsm>create</jsm>()
3770       *       .detectLeaks()
3771       *       .logToConsole()  <jc>// Also log the error message to System.err</jc>
3772       *       .build();
3773       *
3774       *    <jv>client</jv>.closeQuietly();  <jc>// Customized HttpClient won't be closed.</jc>
3775       * </p>
3776       *
3777       * @return This object.
3778       */
3779      @FluentSetter
3780      public Builder detectLeaks() {
3781         detectLeaks = true;
3782         return this;
3783      }
3784
3785      /**
3786       * <i><l>RestClient</l> configuration property:&emsp;</i>  Marshaller
3787       *
3788       * <p>
3789       * Shortcut for specifying the serializers and parsers
3790       * using the serializer and parser defined in a marshaller.
3791       *
3792       * <h5 class='section'>Notes:</h5><ul>
3793       *    <li class='note'>When using this method that takes in a pre-instantiated serializers and parsers, the serializer property setters (e.g. {@link #sortCollections()}),
3794       *    parser property setters (e.g. {@link #strict()}), or bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class have no effect.
3795       * </ul>
3796       *
3797       * <h5 class='section'>Example:</h5>
3798       * <p class='bjava'>
3799       *    <jc>// Create a client that uses Simplified-JSON transport using an existing marshaller.</jc>
3800       *    RestClient <jv>client</jv> = RestClient
3801       *       .<jsm>create</jsm>()
3802       *       .marshaller(Json5.<jsf>DEFAULT_READABLE</jsf>)
3803       *       .build();
3804       * </p>
3805       *
3806       * @param value The values to add to this setting.
3807       * @return This object.
3808       */
3809      @FluentSetter
3810      public Builder marshaller(Marshaller value) {
3811         if (value != null)
3812            serializer(value.getSerializer()).parser(value.getParser());
3813         return this;
3814      }
3815
3816      /**
3817       * <i><l>RestClient</l> configuration property:&emsp;</i>  Marshalls
3818       *
3819       * <p>
3820       * Shortcut for specifying the serializers and parsers
3821       * using the serializer and parser defined in a marshaller.
3822       *
3823       * <h5 class='section'>Notes:</h5><ul>
3824       *    <li class='note'>When using this method that takes in a pre-instantiated serializers and parsers, the serializer property setters (e.g. {@link #sortCollections()}),
3825       *    parser property setters (e.g. {@link #strict()}), or bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class have no effect.
3826       * </ul>
3827       *
3828       * <h5 class='section'>Example:</h5>
3829       * <p class='bjava'>
3830       *    <jc>// Create a client that uses JSON and XML transport using existing marshalls.</jc>
3831       *    RestClient <jv>client</jv> = RestClient
3832       *       .<jsm>create</jsm>()
3833       *       .marshaller(Json.<jsf>DEFAULT_READABLE</jsf>, Xml.<jsf>DEFAULT_READABLE</jsf>)
3834       *       .build();
3835       * </p>
3836       *
3837       * @param value The values to add to this setting.
3838       * @return This object.
3839       */
3840      @FluentSetter
3841      public Builder marshallers(Marshaller...value) {
3842         for (Marshaller m : value)
3843            if (m != null)
3844               serializer(m.getSerializer()).parser(m.getParser());
3845         return this;
3846      }
3847
3848      /**
3849       * <i><l>RestClient</l> configuration property:&emsp;</i>  Root URI.
3850       *
3851       * <p>
3852       * When set, relative URI strings passed in through the various rest call methods (e.g. {@link RestClient#get(Object)}
3853       * will be prefixed with the specified root.
3854       * <br>This root URI is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URI string.
3855       *
3856       * <h5 class='section'>Example:</h5>
3857       * <p class='bjava'>
3858       *    <jc>// Create a client that uses UON format by default for HTTP parts.</jc>
3859       *    RestClient <jv>client</jv> = RestClient
3860       *       .<jsm>create</jsm>()
3861       *       .rootUrl(<js>"http://localhost:10000/foo"</js>)
3862       *       .build();
3863       *
3864       *    Bar <jv>bar</jv> = <jv>client</jv>
3865       *       .get(<js>"/bar"</js>)  <jc>// Relative to http://localhost:10000/foo</jc>
3866       *       .run()
3867       *       .getContent().as(Bar.<jk>class</jk>);
3868       * </p>
3869       *
3870       * @param value
3871       *    The root URI to prefix to relative URI strings.
3872       *    <br>Trailing slashes are trimmed.
3873       *    <br>Usually a <c>String</c> but you can also pass in <c>URI</c> and <c>URL</c> objects as well.
3874       * @return This object.
3875       */
3876      @FluentSetter
3877      public Builder rootUrl(Object value) {
3878         String s = stringify(value);
3879         if (! isEmpty(s))
3880            s = s.replaceAll("\\/$", "");
3881         if (isEmpty(s))
3882            rootUrl = null;
3883         else if (s.indexOf("://") == -1)
3884            throw new BasicRuntimeException("Invalid rootUrl value: ''{0}''.  Must be a valid absolute URL.", value);
3885         else
3886            rootUrl = s;
3887         return this;
3888      }
3889
3890      /**
3891       * Returns the root URI defined for this client.
3892       *
3893       * <p>
3894       * Returns <jk>null</jk> in leu of an empty string.
3895       * Trailing slashes are trimmed.
3896       *
3897       * @return The root URI defined for this client.
3898       */
3899      public String getRootUri() {
3900         return rootUrl;
3901      }
3902
3903      /**
3904       * Skip empty form data.
3905       *
3906       * <p>
3907       * When enabled, form data consisting of empty strings will be skipped on requests.
3908       * Note that <jk>null</jk> values are already skipped.
3909       *
3910       * <p>
3911       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3912       *
3913       * @param value
3914       *    The new value for this setting.
3915       *    <br>The default is <jk>false</jk>.
3916       * @return This object.
3917       */
3918      @FluentSetter
3919      public Builder skipEmptyFormData(boolean value) {
3920         skipEmptyFormData = true;
3921         return this;
3922      }
3923
3924      /**
3925       * Skip empty form data.
3926       *
3927       * <p>
3928       * When enabled, form data consisting of empty strings will be skipped on requests.
3929       * Note that <jk>null</jk> values are already skipped.
3930       *
3931       * <p>
3932       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3933       *
3934       * @return This object.
3935       */
3936      @FluentSetter
3937      public Builder skipEmptyFormData() {
3938         return skipEmptyFormData(true);
3939      }
3940
3941      /**
3942       * Skip empty header data.
3943       *
3944       * <p>
3945       * When enabled, headers consisting of empty strings will be skipped on requests.
3946       * Note that <jk>null</jk> values are already skipped.
3947       *
3948       * <p>
3949       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3950       *
3951       * @param value
3952       *    The new value for this setting.
3953       *    <br>The default is <jk>false</jk>.
3954       * @return This object.
3955       */
3956      @FluentSetter
3957      public Builder skipEmptyHeaderData(boolean value) {
3958         skipEmptyHeaderData = true;
3959         return this;
3960      }
3961
3962      /**
3963       * Skip empty header data.
3964       *
3965       * <p>
3966       * When enabled, headers consisting of empty strings will be skipped on requests.
3967       * Note that <jk>null</jk> values are already skipped.
3968       *
3969       * <p>
3970       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3971       *
3972       * @return This object.
3973       */
3974      @FluentSetter
3975      public Builder skipEmptyHeaderData() {
3976         return skipEmptyHeaderData(true);
3977      }
3978
3979      /**
3980       * Skip empty query data.
3981       *
3982       * <p>
3983       * When enabled, query parameters consisting of empty strings will be skipped on requests.
3984       * Note that <jk>null</jk> values are already skipped.
3985       *
3986       * <p>
3987       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3988       *
3989       * @param value
3990       *    The new value for this setting.
3991       *    <br>The default is <jk>false</jk>.
3992       * @return This object.
3993       */
3994      @FluentSetter
3995      public Builder skipEmptyQueryData(boolean value) {
3996         skipEmptyQueryData = true;
3997         return this;
3998      }
3999
4000      /**
4001       * Skip empty query data.
4002       *
4003       * <p>
4004       * When enabled, query parameters consisting of empty strings will be skipped on requests.
4005       * Note that <jk>null</jk> values are already skipped.
4006       *
4007       * <p>
4008       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
4009       *
4010       * @return This object.
4011       */
4012      @FluentSetter
4013      public Builder skipEmptyQueryData() {
4014         return skipEmptyQueryData(true);
4015      }
4016
4017      //-----------------------------------------------------------------------------------------------------------------
4018      // BeanTraverse Properties
4019      //-----------------------------------------------------------------------------------------------------------------
4020
4021      /**
4022       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Automatically detect POJO recursions.
4023       *
4024       * <p>
4025       * When enabled, specifies that recursions should be checked for during traversal.
4026       *
4027       * <p>
4028       * Recursions can occur when traversing models that aren't true trees but rather contain loops.
4029       * <br>In general, unchecked recursions cause stack-overflow-errors.
4030       * <br>These show up as {@link BeanRecursionException BeanRecursionException} with the message <js>"Depth too deep.  Stack overflow occurred."</js>.
4031       *
4032       * <h5 class='section'>Notes:</h5><ul>
4033       *    <li class='note'>
4034       *       Checking for recursion can cause a small performance penalty.
4035       * </ul>
4036       *
4037       * <h5 class='section'>Example:</h5>
4038       * <p class='bjava'>
4039       *    <jc>// Create a JSON client that automatically checks for recursions.</jc>
4040       *    RestClient <jv>client</jv> = RestClient
4041       *       .<jsm>create</jsm>()
4042       *       .json()
4043       *       .detectRecursions()
4044       *       .build();
4045       *
4046       *    <jc>// Create a POJO model with a recursive loop.</jc>
4047       *    <jk>public class</jk> A {
4048       *       <jk>public</jk> Object <jf>f</jf>;
4049       *    }
4050       *    A <jv>a</jv> = <jk>new</jk> A();
4051       *    <jv>a</jv>.<jf>f</jf> = <jv>a</jv>;
4052       *
4053       * <jk>try</jk> {
4054       *       <jc>// Throws a RestCallException with an inner SerializeException and not a StackOverflowError</jc>
4055       *       <jv>client</jv>
4056       *          .post(<js>"http://localhost:10000/foo"</js>, <jv>a</jv>)
4057       *          .run();
4058       * } <jk>catch</jk> (RestCallException <jv>e</jv>} {
4059       *    <jc>// Handle exception.</jc>
4060       * }
4061       * </p>
4062       *
4063       * <h5 class='section'>See Also:</h5><ul>
4064       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#detectRecursions()}
4065       * </ul>
4066       *
4067       * @return This object.
4068       */
4069      @FluentSetter
4070      public Builder detectRecursions() {
4071         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::detectRecursions);
4072         return this;
4073      }
4074
4075      /**
4076       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Ignore recursion errors.
4077       *
4078       * <p>
4079       * When enabled, when we encounter the same object when traversing a tree, we set the value to <jk>null</jk>.
4080       *
4081       * <p>
4082       * For example, if a model contains the links A-&gt;B-&gt;C-&gt;A, then the JSON generated will look like
4083       *    the following when <jsf>BEANTRAVERSE_ignoreRecursions</jsf> is <jk>true</jk>...
4084       *
4085       * <p class='bjson'>
4086       *    {A:{B:{C:<jk>null</jk>}}}
4087       * </p>
4088       *
4089       * <h5 class='section'>Notes:</h5><ul>
4090       *    <li class='note'>
4091       *       Checking for recursion can cause a small performance penalty.
4092       * </ul>
4093       *
4094       * <h5 class='section'>Example:</h5>
4095       * <p class='bjava'>
4096       *    <jc>// Create a JSON client that ignores recursions.</jc>
4097       *    RestClient <jv>client</jv> = RestClient
4098       *       .<jsm>create</jsm>()
4099       *       .json()
4100       *       .ignoreRecursions()
4101       *       .build();
4102       *
4103       *    <jc>// Create a POJO model with a recursive loop.</jc>
4104       *    <jk>public class</jk> A {
4105       *       <jk>public</jk> Object <jf>f</jf>;
4106       *    }
4107       *    A <jv>a</jv> = <jk>new</jk> A();
4108       *    <jv>a</jv>.<jf>f</jf> = <jv>a</jv>;
4109       *
4110       *    <jc>// Produces request body "{f:null}"</jc>
4111       *    <jv>client</jv>
4112       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>a</jv>)
4113       *       .run();
4114       * </p>
4115       *
4116       * <h5 class='section'>See Also:</h5><ul>
4117       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#ignoreRecursions()}
4118       * </ul>
4119       *
4120       * @return This object.
4121       */
4122      @FluentSetter
4123      public Builder ignoreRecursions() {
4124         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::ignoreRecursions);
4125         return this;
4126      }
4127
4128      /**
4129       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Initial depth.
4130       *
4131       * <p>
4132       * The initial indentation level at the root.
4133       *
4134       * <p>
4135       * Useful when constructing document fragments that need to be indented at a certain level when whitespace is enabled.
4136       *
4137       * <h5 class='section'>Example:</h5>
4138       * <p class='bjava'>
4139       *    <jc>// Create a REST client with JSON serializer with whitespace enabled and an initial depth of 2.</jc>
4140       *    RestClient <jv>client</jv> = RestClient
4141       *       .<jsm>create</jsm>()
4142       *       .json()
4143       *       .ws()
4144       *       .initialDepth(2)
4145       *       .build();
4146       *
4147       *    <jc>// Our bean to serialize.</jc>
4148       *    <jk>public class</jk> MyBean {
4149       *       <jk>public</jk> String <jf>foo</jf> = <jk>null</jk>;
4150       *    }
4151       *
4152       *    <jc>// Produces request body "\t\t{\n\t\t\t'foo':'bar'\n\t\t}\n"</jc>
4153       *    <jv>client</jv>
4154       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4155       *       .run();
4156       * </p>
4157       *
4158       * <h5 class='section'>See Also:</h5><ul>
4159       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#initialDepth(int)}
4160       * </ul>
4161       *
4162       * @param value
4163       *    The new value for this property.
4164       *    <br>The default is <c>0</c>.
4165       * @return This object.
4166       */
4167      @FluentSetter
4168      public Builder initialDepth(int value) {
4169         serializers().forEach(x -> x.initialDepth(value));
4170         return this;
4171      }
4172
4173      /**
4174       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Max serialization depth.
4175       *
4176       * <p>
4177       * When enabled, abort traversal if specified depth is reached in the POJO tree.
4178       *
4179       * <p>
4180       * If this depth is exceeded, an exception is thrown.
4181       *
4182       * <p>
4183       * This prevents stack overflows from occurring when trying to traverse models with recursive references.
4184       *
4185       * <h5 class='section'>Example:</h5>
4186       * <p class='bjava'>
4187       *    <jc>// Create a REST client with JSON serializer that throws an exception if the depth reaches greater than 20.</jc>
4188       *    RestClient <jv>client</jv> = RestClient
4189       *       .<jsm>create</jsm>()
4190       *       .json()
4191       *       .maxDepth(20)
4192       *       .build();
4193       * </p>
4194       *
4195       * <h5 class='section'>See Also:</h5><ul>
4196       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#maxDepth(int)}
4197       * </ul>
4198       *
4199       * @param value
4200       *    The new value for this property.
4201       *    <br>The default is <c>100</c>.
4202       * @return This object.
4203       */
4204      @FluentSetter
4205      public Builder maxDepth(int value) {
4206         serializers().forEach(x -> x.maxDepth(value));
4207         return this;
4208      }
4209
4210      //-----------------------------------------------------------------------------------------------------------------
4211      // Serializer Properties
4212      //-----------------------------------------------------------------------------------------------------------------
4213
4214      /**
4215       * <i><l>Serializer</l> configuration property:&emsp;</i>  Add <js>"_type"</js> properties when needed.
4216       *
4217       * <p>
4218       * When enabled, <js>"_type"</js> properties will be added to beans if their type cannot be inferred
4219       * through reflection.
4220       *
4221       * <p>
4222       * This is used to recreate the correct objects during parsing if the object types cannot be inferred.
4223       * <br>For example, when serializing a <c>Map&lt;String,Object&gt;</c> field where the bean class cannot be determined from
4224       * the type of the values.
4225       *
4226       * <p>
4227       * Note the differences between the following settings:
4228       * <ul class='javatree'>
4229       *    <li class='jf'>{@link #addRootType()} - Affects whether <js>'_type'</js> is added to root node.
4230       *    <li class='jf'>{@link #addBeanTypes()} - Affects whether <js>'_type'</js> is added to any nodes.
4231       * </ul>
4232       *
4233       * <h5 class='section'>Example:</h5>
4234       * <p class='bjava'>
4235       *    <jc>// Create a JSON client that adds _type to nodes in the request body.</jc>
4236       *    RestClient <jv>client</jv> = RestClient
4237       *       .<jsm>create</jsm>()
4238       *       .json()
4239       *       .addBeanTypes()
4240       *       .build();
4241       *
4242       *    <jc>// Our map of beans to serialize.</jc>
4243       *    <ja>@Bean</ja>(typeName=<js>"mybean"</js>)
4244       *    <jk>public class</jk> MyBean {
4245       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4246       *    }
4247       *
4248       *    AMap <jv>map</jv> = AMap.of(<js>"foo"</js>, <jk>new</jk> MyBean());
4249       *
4250       *    <jc>// Request body will contain:  {"foo":{"_type":"mybean","foo":"bar"}}</jc>
4251       *    <jv>client</jv>
4252       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>map</jv>)
4253       *       .run();
4254       * </p>
4255       *
4256       * <h5 class='section'>See Also:</h5><ul>
4257       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#addBeanTypes()}
4258       * </ul>
4259       *
4260       * @return This object.
4261       */
4262      @FluentSetter
4263      public Builder addBeanTypes() {
4264         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::addBeanTypes);
4265         return this;
4266      }
4267
4268      /**
4269       * <i><l>Serializer</l> configuration property:&emsp;</i>  Add type attribute to root nodes.
4270       *
4271       * <p>
4272       * When enabled, <js>"_type"</js> properties will be added to top-level beans.
4273       *
4274       * <p>
4275       * When disabled, it is assumed that the parser knows the exact Java POJO type being parsed, and therefore top-level
4276       * type information that might normally be included to determine the data type will not be serialized.
4277       *
4278       * <p>
4279       * For example, when serializing a top-level POJO with a {@link Bean#typeName() @Bean(typeName)} value, a
4280       * <js>'_type'</js> attribute will only be added when this setting is enabled.
4281       *
4282       * <p>
4283       * Note the differences between the following settings:
4284       * <ul class='javatree'>
4285       *    <li class='jf'>{@link #addRootType()} - Affects whether <js>'_type'</js> is added to root node.
4286       *    <li class='jf'>{@link #addBeanTypes()} - Affects whether <js>'_type'</js> is added to any nodes.
4287       * </ul>
4288       *
4289       * <h5 class='section'>Example:</h5>
4290       * <p class='bjava'>
4291       *    <jc>// Create a JSON client that adds _type to root node.</jc>
4292       *    RestClient <jv>client</jv> = RestClient
4293       *       .<jsm>create</jsm>()
4294       *       .json()
4295       *       .addRootType()
4296       *       .build();
4297       *
4298       *    <jc>// Our bean to serialize.</jc>
4299       *    <ja>@Bean</ja>(typeName=<js>"mybean"</js>)
4300       *    <jk>public class</jk> MyBean {
4301       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4302       *    }
4303       *
4304       *    <jc>// Request body will contain:  {"_type":"mybean","foo":"bar"}</jc>
4305       *    <jv>client</jv>
4306       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4307       *       .run();
4308       * </p>
4309       *
4310       * <h5 class='section'>See Also:</h5><ul>
4311       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#addRootType()}
4312       * </ul>
4313       *
4314       * @return This object.
4315       */
4316      @FluentSetter
4317      public Builder addRootType() {
4318         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::addRootType);
4319         return this;
4320      }
4321
4322      /**
4323       * <i><l>Serializer</l> configuration property:&emsp;</i>  Don't trim null bean property values.
4324       *
4325       * <p>
4326       * When enabled, null bean values will be serialized to the output.
4327       *
4328       * <h5 class='section'>Notes:</h5><ul>
4329       *    <li class='note'>Not enabling this setting will cause <c>Map</c>s with <jk>null</jk> values to be lost during parsing.
4330       * </ul>
4331       *
4332       * <h5 class='section'>Example:</h5>
4333       * <p class='bjava'>
4334       *    <jc>// Create a REST client with JSON serializer that serializes null properties.</jc>
4335       *    RestClient <jv>client</jv> = RestClient
4336       *       .<jsm>create</jsm>()
4337       *       .json()
4338       *       .keepNullProperties()
4339       *       .build();
4340       *
4341       *    <jc>// Our bean to serialize.</jc>
4342       *    <jk>public class</jk> MyBean {
4343       *       <jk>public</jk> String <jf>foo</jf> = <jk>null</jk>;
4344       *    }
4345       *
4346       *    <jc>// Request body will contain:  {foo:null}</jc>
4347       *    <jv>client</jv>
4348       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4349       *       .run();
4350       * </p>
4351       *
4352       * <h5 class='section'>See Also:</h5><ul>
4353       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#keepNullProperties()}
4354       * </ul>
4355       *
4356       * @return This object.
4357       */
4358      @FluentSetter
4359      public Builder keepNullProperties() {
4360         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::keepNullProperties);
4361         return this;
4362      }
4363
4364      /**
4365       * <i><l>Serializer</l> configuration property:&emsp;</i>  Sort arrays and collections alphabetically.
4366       *
4367       * <p>
4368       * When enabled, copies and sorts the contents of arrays and collections before serializing them.
4369       *
4370       * <p>
4371       * Note that this introduces a performance penalty since it requires copying the existing collection.
4372       *
4373       * <h5 class='section'>Example:</h5>
4374       * <p class='bjava'>
4375       *    <jc>// Create a REST client with JSON serializer that sorts arrays and collections before serialization.</jc>
4376       *    RestClient <jv>client</jv> = RestClient
4377       *       .<jsm>create</jsm>()
4378       *       .json()
4379       *       .sortCollections()
4380       *       .build();
4381       *
4382       *    <jc>// An unsorted array</jc>
4383       *    String[] <jv>array</jv> = {<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>}
4384       *
4385       *    <jc>// Request body will contain:  ["bar","baz","foo"]</jc>
4386       *    <jv>client</jv>
4387       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>array</jv>)
4388       *       .run();
4389       * </p>
4390       *
4391       * <h5 class='section'>See Also:</h5><ul>
4392       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#sortCollections()}
4393       * </ul>
4394       *
4395       * @return This object.
4396       */
4397      @FluentSetter
4398      public Builder sortCollections() {
4399         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::sortCollections);
4400         return this;
4401      }
4402
4403      /**
4404       * <i><l>Serializer</l> configuration property:&emsp;</i>  Sort maps alphabetically.
4405       *
4406       * <p>
4407       * When enabled, copies and sorts the contents of maps by their keys before serializing them.
4408       *
4409       * <p>
4410       * Note that this introduces a performance penalty.
4411       *
4412       * <h5 class='section'>Example:</h5>
4413       * <p class='bjava'>
4414       *    <jc>// Create a REST client with JSON serializer that sorts maps before serialization.</jc>
4415       *    RestClient <jv>client</jv> = RestClient
4416       *       .<jsm>create</jsm>()
4417       *       .json()
4418       *       .sortMaps()
4419       *       .build();
4420       *
4421       *    <jc>// An unsorted map.</jc>
4422       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(<js>"foo"</js>,1,<js>"bar"</js>,2,<js>"baz"</js>,3);
4423       *
4424       *    <jc>// Request body will contain:  {"bar":2,"baz":3,"foo":1}</jc>
4425       *    <jv>client</jv>
4426       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>map</jv>)
4427       *       .run();
4428       * </p>
4429       *
4430       * <h5 class='section'>See Also:</h5><ul>
4431       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#sortMaps()}
4432       * </ul>
4433       *
4434       * @return This object.
4435       */
4436      @FluentSetter
4437      public Builder sortMaps() {
4438         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::sortMaps);
4439         return this;
4440      }
4441
4442      /**
4443       * <i><l>Serializer</l> configuration property:&emsp;</i>  Trim empty lists and arrays.
4444       *
4445       * <p>
4446       * When enabled, empty lists and arrays will not be serialized.
4447       *
4448       * <p>
4449       * Note that enabling this setting has the following effects on parsing:
4450       * <ul class='spaced-list'>
4451       *    <li>
4452       *       Map entries with empty list values will be lost.
4453       *    <li>
4454       *       Bean properties with empty list values will not be set.
4455       * </ul>
4456       *
4457       * <h5 class='section'>Example:</h5>
4458       * <p class='bjava'>
4459       *    <jc>// Create a serializer that skips empty arrays and collections.</jc>
4460       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
4461       *       .<jsm>create</jsm>()
4462       *       .trimEmptyCollections()
4463       *       .build();
4464       *
4465       *    <jc>// A bean with a field with an empty array.</jc>
4466       *    <jk>public class</jk> MyBean {
4467       *       <jk>public</jk> String[] <jf>foo</jf> = {};
4468       *    }
4469       *
4470       *    <jc>// Request body will contain:  {}</jc>
4471       *    <jv>client</jv>
4472       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4473       *       .run();
4474       * </p>
4475       *
4476       * <h5 class='section'>See Also:</h5><ul>
4477       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#trimEmptyCollections()}
4478       * </ul>
4479       *
4480       * @return This object.
4481       */
4482      @FluentSetter
4483      public Builder trimEmptyCollections() {
4484         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::trimEmptyCollections);
4485         return this;
4486      }
4487
4488      /**
4489       * <i><l>Serializer</l> configuration property:&emsp;</i>  Trim empty maps.
4490       *
4491       * <p>
4492       * When enabled, empty map values will not be serialized to the output.
4493       *
4494       * <p>
4495       * Note that enabling this setting has the following effects on parsing:
4496       * <ul class='spaced-list'>
4497       *    <li>
4498       *       Bean properties with empty map values will not be set.
4499       * </ul>
4500       *
4501       * <h5 class='section'>Example:</h5>
4502       * <p class='bjava'>
4503       *    <jc>// Create a REST client with JSON serializer that skips empty maps.</jc>
4504       *    RestClient <jv>client</jv> = RestClient
4505       *       .<jsm>create</jsm>()
4506       *       .json()
4507       *       .trimEmptyMaps()
4508       *       .build();
4509       *
4510       *    <jc>// A bean with a field with an empty map.</jc>
4511       *    <jk>public class</jk> MyBean {
4512       *       <jk>public</jk> AMap <jf>foo</jf> = AMap.<jsm>of</jsm>();
4513       *    }
4514       *
4515       *    <jc>// Request body will contain:  {}</jc>
4516       *    <jv>client</jv>
4517       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4518       *       .run();
4519       * </p>
4520       *
4521       * <h5 class='section'>See Also:</h5><ul>
4522       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#trimEmptyMaps()}
4523       * </ul>
4524       *
4525       * @return This object.
4526       */
4527      @FluentSetter
4528      public Builder trimEmptyMaps() {
4529         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::trimEmptyMaps);
4530         return this;
4531      }
4532
4533      /**
4534       * <i><l>Serializer</l> configuration property:&emsp;</i>  Trim strings.
4535       *
4536       * <p>
4537       * When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being serialized.
4538       *
4539       * <h5 class='section'>Example:</h5>
4540       * <p class='bjava'>
4541       *    <jc>// Create a REST client with JSON serializer that trims strings before serialization.</jc>
4542       *    RestClient <jv>client</jv> = RestClient
4543       *       .<jsm>create</jsm>()
4544       *       .json()
4545       *       .trimStrings()
4546       *       .build();
4547       *
4548       * <jc>// A map with space-padded keys/values</jc>
4549       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(<js>" foo "</js>, <js>" bar "</js>);
4550       *
4551       *    <jc>// Request body will contain:  {"foo":"bar"}</jc>
4552       *    <jv>client</jv>
4553       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>map</jv>)
4554       *       .run();
4555       * </p>
4556       *
4557       * <h5 class='section'>See Also:</h5><ul>
4558       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#trimStrings()}
4559       * </ul>
4560       *
4561       * @return This object.
4562       */
4563      @FluentSetter
4564      public Builder trimStringsOnWrite() {
4565         serializers().forEach(org.apache.juneau.serializer.Serializer.Builder::trimStrings);
4566         return this;
4567      }
4568
4569      /**
4570       * <i><l>Serializer</l> configuration property:&emsp;</i>  URI context bean.
4571       *
4572       * <p>
4573       * Bean used for resolution of URIs to absolute or root-relative form.
4574       *
4575       * <h5 class='section'>Example:</h5>
4576       * <p class='bjava'>
4577       *    <jc>// Our URI contextual information.</jc>
4578       *    String <jv>authority</jv> = <js>"http://localhost:10000"</js>;
4579       *    String <jv>contextRoot</jv> = <js>"/myContext"</js>;
4580       *    String <jv>servletPath</jv> = <js>"/myServlet"</js>;
4581       *    String <jv>pathInfo</jv> = <js>"/foo"</js>;
4582       *
4583       *    <jc>// Create a UriContext object.</jc>
4584       *    UriContext <jv>uriContext</jv> = <jk>new</jk> UriContext(<jv>authority</jv>, <jv>contextRoot</jv>, <jv>servletPath</jv>, <jv>pathInfo</jv>);
4585       *
4586       *    <jc>// Create a REST client with JSON serializer and associate our context.</jc>
4587       *    RestClient <jv>client</jv> = RestClient
4588       *       .<jsm>create</jsm>()
4589       *       .json()
4590       *       .uriContext(<jv>uriContext</jv>)
4591       *       .uriRelativity(<jsf>RESOURCE</jsf>)  <jc>// Assume relative paths are relative to servlet.</jc>
4592       *       .uriResolution(<jsf>ABSOLUTE</jsf>)  <jc>// Serialize URIs as absolute paths.</jc>
4593       *       .build();
4594       *
4595       *    <jc>// A relative URI</jc>
4596       *    URI <jv>uri</jv> = <jk>new</jk> URI(<js>"bar"</js>);
4597       *
4598       *    <jc>// Request body will contain:  "http://localhost:10000/myContext/myServlet/foo/bar"</jc>
4599       *    <jv>client</jv>
4600       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>uri</jv>)
4601       *       .run();
4602       * </p>
4603       *
4604       * <h5 class='section'>See Also:</h5><ul>
4605       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#uriContext(UriContext)}
4606       *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.MarshallingUris">URIs</a>
4607       * </ul>
4608       *
4609       * @param value The new value for this property.
4610       * @return This object.
4611       */
4612      @FluentSetter
4613      public Builder uriContext(UriContext value) {
4614         serializers().forEach(x -> x.uriContext(value));
4615         return this;
4616      }
4617
4618      /**
4619       * <i><l>Serializer</l> configuration property:&emsp;</i>  URI relativity.
4620       *
4621       * <p>
4622       * Defines what relative URIs are relative to when serializing any of the following:
4623       * <ul>
4624       *    <li>{@link java.net.URI}
4625       *    <li>{@link java.net.URL}
4626       *    <li>Properties and classes annotated with {@link Uri @Uri}
4627       * </ul>
4628       *
4629       * <p>
4630       * See {@link #uriContext(UriContext)} for examples.
4631       *
4632       * <ul class='values javatree'>
4633       *    <li class='jf'>{@link org.apache.juneau.UriRelativity#RESOURCE}
4634       *       - Relative URIs should be considered relative to the servlet URI.
4635       *    <li class='jf'>{@link org.apache.juneau.UriRelativity#PATH_INFO}
4636       *       - Relative URIs should be considered relative to the request URI.
4637       * </ul>
4638       *
4639       * <h5 class='section'>See Also:</h5><ul>
4640       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#uriRelativity(UriRelativity)}
4641       *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.MarshallingUris">URIs</a>
4642       * </ul>
4643       *
4644       * @param value
4645       *    The new value for this property.
4646       *    <br>The default is {@link UriRelativity#RESOURCE}
4647       * @return This object.
4648       */
4649      @FluentSetter
4650      public Builder uriRelativity(UriRelativity value) {
4651         serializers().forEach(x -> x.uriRelativity(value));
4652         return this;
4653      }
4654
4655      /**
4656       * <i><l>Serializer</l> configuration property:&emsp;</i>  URI resolution.
4657       *
4658       * <p>
4659       * Defines the resolution level for URIs when serializing any of the following:
4660       * <ul>
4661       *    <li>{@link java.net.URI}
4662       *    <li>{@link java.net.URL}
4663       *    <li>Properties and classes annotated with {@link Uri @Uri}
4664       * </ul>
4665       *
4666       * <p>
4667       * See {@link #uriContext(UriContext)} for examples.
4668       *
4669       * <ul class='values'>
4670       *    <li class='jf'>{@link UriResolution#ABSOLUTE}
4671       *       - Resolve to an absolute URI (e.g. <js>"http://host:port/context-root/servlet-path/path-info"</js>).
4672       *    <li class='jf'>{@link UriResolution#ROOT_RELATIVE}
4673       *       - Resolve to a root-relative URI (e.g. <js>"/context-root/servlet-path/path-info"</js>).
4674       *    <li class='jf'>{@link UriResolution#NONE}
4675       *       - Don't do any URI resolution.
4676       * </ul>
4677       *
4678       * <h5 class='section'>See Also:</h5><ul>
4679       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#uriResolution(UriResolution)}
4680       *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.MarshallingUris">URIs</a>
4681       * </ul>
4682       *
4683       * @param value
4684       *    The new value for this property.
4685       *    <br>The default is {@link UriResolution#NONE}
4686       * @return This object.
4687       */
4688      @FluentSetter
4689      public Builder uriResolution(UriResolution value) {
4690         serializers().forEach(x -> x.uriResolution(value));
4691         return this;
4692      }
4693
4694      //-----------------------------------------------------------------------------------------------------------------
4695      // WriterSerializer Properties
4696      //-----------------------------------------------------------------------------------------------------------------
4697
4698      /**
4699       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Maximum indentation.
4700       *
4701       * <p>
4702       * Specifies the maximum indentation level in the serialized document.
4703       *
4704       * <h5 class='section'>Notes:</h5><ul>
4705       *    <li class='note'>This setting does not apply to the RDF serializers.
4706       * </ul>
4707       *
4708       * <h5 class='section'>Example:</h5>
4709       * <p class='bjava'>
4710       *    <jc>// Create a REST client with JSON serializer that indents a maximum of 20 tabs.</jc>
4711       *    RestClient <jv>client</jv> = RestClient
4712       *       .<jsm>create</jsm>()
4713       *       .json()
4714       *       .ws()  <jc>// Enable whitespace</jc>
4715       *       .maxIndent(20)
4716       *       .build();
4717       * </p>
4718       *
4719       * <h5 class='section'>See Also:</h5><ul>
4720       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#maxIndent(int)}
4721       * </ul>
4722       *
4723       * @param value
4724       *    The new value for this property.
4725       *    <br>The default is <c>100</c>.
4726       * @return This object.
4727       */
4728      @FluentSetter
4729      public Builder maxIndent(int value) {
4730         serializers().forEachWS(x -> x.maxIndent(value));
4731         return this;
4732      }
4733
4734      /**
4735       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Quote character.
4736       *
4737       * <p>
4738       * Specifies the character to use for quoting attributes and values.
4739       *
4740       * <h5 class='section'>Notes:</h5><ul>
4741       *    <li class='note'>This setting does not apply to the RDF serializers.
4742       * </ul>
4743       *
4744       * <h5 class='section'>Example:</h5>
4745       * <p class='bjava'>
4746       *    <jc>// Create a REST client with JSON serializer that uses single quotes.</jc>
4747       *    RestClient <jv>client</jv> = RestClient
4748       *       .<jsm>create</jsm>()
4749       *       .json()
4750       *       .quoteChar(<js>'\''</js>)
4751       *       .build();
4752       *
4753       *    <jc>// A bean with a single property</jc>
4754       *    <jk>public class</jk> MyBean {
4755       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4756       *    }
4757       *
4758       *    <jc>// Request body will contain:  {'foo':'bar'}</jc>
4759       *    <jv>client</jv>
4760       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4761       *       .run();
4762       * </p>
4763       *
4764       * <h5 class='section'>See Also:</h5><ul>
4765       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#quoteChar(char)}
4766       * </ul>
4767       *
4768       * @param value
4769       *    The new value for this property.
4770       *    <br>The default is <js>'"'</js>.
4771       * @return This object.
4772       */
4773      @FluentSetter
4774      public Builder quoteChar(char value) {
4775         serializers().forEachWS(x -> x.quoteChar(value));
4776         return this;
4777      }
4778
4779      /**
4780       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Quote character.
4781       *
4782       * <p>
4783       * Specifies to use single quotes for quoting attributes and values.
4784       *
4785       * <h5 class='section'>Notes:</h5><ul>
4786       *    <li class='note'>This setting does not apply to the RDF serializers.
4787       * </ul>
4788       *
4789       * <h5 class='section'>Example:</h5>
4790       * <p class='bjava'>
4791       *    <jc>// Create a REST client with JSON serializer that uses single quotes.</jc>
4792       *    RestClient <jv>client</jv> = RestClient
4793       *       .<jsm>create</jsm>()
4794       *       .json()
4795       *       .sq()
4796       *       .build();
4797       *
4798       *    <jc>// A bean with a single property</jc>
4799       *    <jk>public class</jk> MyBean {
4800       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4801       *    }
4802       *
4803       *    <jc>// Request body will contain:  {'foo':'bar'}</jc>
4804       *    <jv>client</jv>
4805       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4806       *       .run();
4807       * </p>
4808       *
4809       * <h5 class='section'>See Also:</h5><ul>
4810       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#quoteChar(char)}
4811       * </ul>
4812       *
4813       * @return This object.
4814       */
4815      @FluentSetter
4816      public Builder sq() {
4817         serializers().forEachWS(org.apache.juneau.serializer.WriterSerializer.Builder::sq);
4818         return this;
4819      }
4820
4821      /**
4822       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Use whitespace.
4823       *
4824       * <p>
4825       * When enabled, whitespace is added to the output to improve readability.
4826       *
4827       * <h5 class='section'>Example:</h5>
4828       * <p class='bjava'>
4829       *    <jc>// Create a REST client with JSON serializer with whitespace enabled.</jc>
4830       *    RestClient <jv>client</jv> = RestClient
4831       *       .<jsm>create</jsm>()
4832       *       .json()
4833       *       .useWhitespace()
4834       *       .build();
4835       *
4836       *    <jc>// A bean with a single property</jc>
4837       *    <jk>public class</jk> MyBean {
4838       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4839       *    }
4840       *
4841       *    <jc>// Request body will contain:  {\n\t"foo": "bar"\n\}\n</jc>
4842       *    <jv>client</jv>
4843       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4844       *       .run();
4845       * </p>
4846       *
4847       * <h5 class='section'>See Also:</h5><ul>
4848       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#useWhitespace()}
4849       * </ul>
4850       * @return This object.
4851       */
4852      @FluentSetter
4853      public Builder useWhitespace() {
4854         serializers().forEachWS(org.apache.juneau.serializer.WriterSerializer.Builder::useWhitespace);
4855         return this;
4856      }
4857
4858      /**
4859       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Use whitespace.
4860       *
4861       * <p>
4862       * When enabled, whitespace is added to the output to improve readability.
4863       *
4864       * <h5 class='section'>Example:</h5>
4865       * <p class='bjava'>
4866       *    <jc>// Create a REST client with JSON serializer with whitespace enabled.</jc>
4867       *    RestClient <jv>client</jv> = RestClient
4868       *       .<jsm>create</jsm>()
4869       *       .json()
4870       *       .ws()
4871       *       .build();
4872       *
4873       *    <jc>// A bean with a single property</jc>
4874       *    <jk>public class</jk> MyBean {
4875       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4876       *    }
4877       *
4878       *    <jc>// Request body will contain:  {\n\t"foo": "bar"\n\}\n</jc>
4879       *    <jv>client</jv>
4880       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4881       *       .run();
4882       * </p>
4883       *
4884       * <h5 class='section'>See Also:</h5><ul>
4885       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#useWhitespace()}
4886       * </ul>
4887       *
4888       * @return This object.
4889       */
4890      @FluentSetter
4891      public Builder ws() {
4892         serializers().forEachWS(org.apache.juneau.serializer.WriterSerializer.Builder::ws);
4893         return this;
4894      }
4895
4896      //-----------------------------------------------------------------------------------------------------------------
4897      // OutputStreamSerializer Properties
4898      //-----------------------------------------------------------------------------------------------------------------
4899
4900      //-----------------------------------------------------------------------------------------------------------------
4901      // Parser Properties
4902      //-----------------------------------------------------------------------------------------------------------------
4903
4904      /**
4905       * <i><l>Parser</l> configuration property:&emsp;</i>  Debug output lines.
4906       *
4907       * <p>
4908       * When parse errors occur, this specifies the number of lines of input before and after the
4909       * error location to be printed as part of the exception message.
4910       *
4911       * <h5 class='section'>Example:</h5>
4912       * <p class='bjava'>
4913       *    <jc>// Create a parser whose exceptions print out 100 lines before and after the parse error location.</jc>
4914       *    RestClient <jv>client</jv> = RestClient
4915       *       .<jsm>create</jsm>()
4916       *       .json()
4917       *       .debug()  <jc>// Enable debug mode to capture Reader contents as strings.</jc>
4918       *       .debugOuputLines(100)
4919       *       .build();
4920       *
4921       *    <jc>// Try to parse some bad JSON.</jc>
4922       *    <jk>try</jk> {
4923       *       <jv>client</jv>
4924       *          .get(<js>"/pathToBadJson"</js>)
4925       *          .run()
4926       *          .getContent().as(Object.<jk>class</jk>);  <jc>// Try to parse it.</jc>
4927       *    } <jk>catch</jk> (RestCallException <jv>e</jv>) {
4928       *       System.<jsf>err</jsf>.println(<jv>e</jv>.getMessage());  <jc>// Will display 200 lines of the output.</jc>
4929       *    }
4930       * </p>
4931       *
4932       * <h5 class='section'>See Also:</h5><ul>
4933       *    <li class='jm'>{@link org.apache.juneau.parser.Parser.Builder#debugOutputLines(int)}
4934       * </ul>
4935       *
4936       * @param value
4937       *    The new value for this property.
4938       *    <br>The default value is <c>5</c>.
4939       * @return This object.
4940       */
4941      @FluentSetter
4942      public Builder debugOutputLines(int value) {
4943         parsers().forEach(x -> x.debugOutputLines(value));
4944         return this;
4945      }
4946
4947      /**
4948       * <i><l>Parser</l> configuration property:&emsp;</i>  Strict mode.
4949       *
4950       * <p>
4951       * When enabled, strict mode for the parser is enabled.
4952       *
4953       * <p>
4954       * Strict mode can mean different things for different parsers.
4955       *
4956       * <table class='styled'>
4957       *    <tr><th>Parser class</th><th>Strict behavior</th></tr>
4958       *    <tr>
4959       *       <td>All reader-based parsers</td>
4960       *       <td>
4961       *          When enabled, throws {@link ParseException ParseExceptions} on malformed charset input.
4962       *          Otherwise, malformed input is ignored.
4963       *       </td>
4964       *    </tr>
4965       *    <tr>
4966       *       <td>{@link JsonParser}</td>
4967       *       <td>
4968       *          When enabled, throws exceptions on the following invalid JSON syntax:
4969       *          <ul>
4970       *             <li>Unquoted attributes.
4971       *             <li>Missing attribute values.
4972       *             <li>Concatenated strings.
4973       *             <li>Javascript comments.
4974       *             <li>Numbers and booleans when Strings are expected.
4975       *             <li>Numbers valid in Java but not JSON (e.g. octal notation, etc...)
4976       *          </ul>
4977       *       </td>
4978       *    </tr>
4979       * </table>
4980       *
4981       * <h5 class='section'>Example:</h5>
4982       * <p class='bjava'>
4983       *    <jc>// Create a REST client with JSON parser using strict mode.</jc>
4984       *    RestClient <jv>client</jv> = RestClient
4985       *       .<jsm>create</jsm>()
4986       *       .json()
4987       *       .strict()
4988       *       .build();
4989       *
4990       *    <jc>// Try to parse some bad JSON.</jc>
4991       *    <jk>try</jk> {
4992       *       <jv>client</jv>
4993       *          .get(<js>"/pathToBadJson"</js>)
4994       *          .run()
4995       *          .getContent().as(Object.<jk>class</jk>);  <jc>// Try to parse it.</jc>
4996       *    } <jk>catch</jk> (RestCallException <jv>e</jv>) {
4997       *       <jc>// Handle exception.</jc>
4998       *    }
4999       * </p>
5000       *
5001       * <h5 class='section'>See Also:</h5><ul>
5002       *    <li class='jm'>{@link org.apache.juneau.parser.Parser.Builder#strict()}
5003       * </ul>
5004       *
5005       * @return This object.
5006       */
5007      @FluentSetter
5008      public Builder strict() {
5009         parsers().forEach(org.apache.juneau.parser.Parser.Builder::strict);
5010         return this;
5011      }
5012
5013      /**
5014       * <i><l>Parser</l> configuration property:&emsp;</i>  Trim parsed strings.
5015       *
5016       * <p>
5017       * When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being added to
5018       * the POJO.
5019       *
5020       * <h5 class='section'>Example:</h5>
5021       * <p class='bjava'>
5022       *    <jc>// Create a REST client with JSON parser with trim-strings enabled.</jc>
5023       *    RestClient <jv>client</jv> = RestClient
5024       *       .<jsm>create</jsm>()
5025       *       .json()
5026       *       .trimStringsOnRead()
5027       *       .build();
5028       *
5029       *    <jc>// Try to parse JSON containing {" foo ":" bar "}.</jc>
5030       *    Map&lt;String,String&gt; <jv>map</jv> = <jv>client</jv>
5031       *       .get(<js>"/pathToJson"</js>)
5032       *       .run()
5033       *       .getContent().as(HashMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
5034       *
5035       *    <jc>// Make sure strings are trimmed.</jc>
5036       *    <jsm>assertEquals</jsm>(<js>"bar"</js>, <jv>map</jv>.get(<js>"foo"</js>));
5037       * </p>
5038       *
5039       * <h5 class='section'>See Also:</h5><ul>
5040       *    <li class='jm'>{@link org.apache.juneau.parser.Parser.Builder#trimStrings()}
5041       * </ul>
5042       *
5043       * @return This object.
5044       */
5045      @FluentSetter
5046      public Builder trimStringsOnRead() {
5047         parsers().forEach(org.apache.juneau.parser.Parser.Builder::trimStrings);
5048         return this;
5049      }
5050
5051      //-----------------------------------------------------------------------------------------------------------------
5052      // ReaderParser Properties
5053      //-----------------------------------------------------------------------------------------------------------------
5054
5055      //-----------------------------------------------------------------------------------------------------------------
5056      // InputStreamParser Properties
5057      //-----------------------------------------------------------------------------------------------------------------
5058
5059      //-----------------------------------------------------------------------------------------------------------------
5060      // OpenApi Properties
5061      //-----------------------------------------------------------------------------------------------------------------
5062
5063      /**
5064       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default OpenAPI format for HTTP parts.
5065       *
5066       * <p>
5067       * Specifies the format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#format()} for
5068       * the OpenAPI serializer and parser on this client.
5069       *
5070       * <h5 class='section'>Example:</h5>
5071       * <p class='bjava'>
5072       *    <jc>// Create a REST client with UON part serialization and parsing.</jc>
5073       *    RestClient <jv>client</jv>  = RestClient
5074       *       .<jsm>create</jsm>()
5075       *       .oapiFormat(<jsf>UON</jsf>)
5076       *       .build();
5077       *
5078       *    <jc>// Set a header with a value in UON format.</jc>
5079       *    <jv>client</jv>
5080       *       .get(<js>"/uri"</js>)
5081       *       .header(<js>"Foo"</js>, <js>"bar baz"</js>)  <jc>// Will be serialized as:  'bar baz'</jc>
5082       *       .run();
5083       * </p>
5084       *
5085       * <ul class='values javatree'>
5086       *    <li class='jc'>{@link org.apache.juneau.httppart.HttpPartFormat}
5087       *    <ul>
5088       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#UON UON} - UON notation (e.g. <js>"'foo bar'"</js>).
5089       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT32 INT32} - Signed 32 bits.
5090       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT64 INT64} - Signed 64 bits.
5091       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#FLOAT FLOAT} - 32-bit floating point number.
5092       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DOUBLE DOUBLE} - 64-bit floating point number.
5093       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BYTE BYTE} - BASE-64 encoded characters.
5094       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY BINARY} - Hexadecimal encoded octets (e.g. <js>"00FF"</js>).
5095       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY_SPACED BINARY_SPACED} - Spaced-separated hexadecimal encoded octets (e.g. <js>"00 FF"</js>).
5096       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DATE DATE} - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 full-date</a>.
5097       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DATE_TIME DATE_TIME} - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 date-time</a>.
5098       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#PASSWORD PASSWORD} - Used to hint UIs the input needs to be obscured.
5099       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#NO_FORMAT NO_FORMAT} - (default) Not specified.
5100       *    </ul>
5101       * </ul>
5102       *
5103       * <h5 class='section'>See Also:</h5><ul>
5104       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiSerializer.Builder#format(HttpPartFormat)}
5105       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiParser.Builder#format(HttpPartFormat)}
5106       * </ul>
5107       *
5108       * @param value
5109       *    The new value for this property.
5110       *    <br>The default value is {@link HttpPartFormat#NO_FORMAT}.
5111       * @return This object.
5112       */
5113      @FluentSetter
5114      public Builder oapiFormat(HttpPartFormat value) {
5115         serializers().forEach(OpenApiSerializer.Builder.class, x -> x.format(value));
5116         parsers().forEach(OpenApiParser.Builder.class, x -> x.format(value));
5117         partSerializer().builder(OpenApiSerializer.Builder.class).ifPresent(x -> x.format(value));
5118         partParser().builder(OpenApiParser.Builder.class).ifPresent(x -> x.format(value));
5119         return this;
5120      }
5121
5122      /**
5123       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default collection format for HTTP parts.
5124       *
5125       * <p>
5126       * Specifies the collection format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#collectionFormat()} for the
5127       * OpenAPI serializer and parser on this client.
5128       *
5129       * <h5 class='section'>Example:</h5>
5130       * <p class='bjava'>
5131       *    <jc>// Create a REST client with CSV format for http parts.</jc>
5132       *    RestClient <jv>client</jv> = RestClient
5133       *       .<jsm>create</jsm>()
5134       *       .collectionFormat(<jsf>CSV</jsf>)
5135       *       .build();
5136       *
5137       *    <jc>// An arbitrary data structure.</jc>
5138       *    AList <jv>list</jv> = AList.<jsm>of</jsm>(
5139       *       <js>"foo"</js>,
5140       *       <js>"bar"</js>,
5141       *       AMap.<jsm>of</jsm>(
5142       *          <js>"baz"</js>, AList.<jsm>of</jsm>(<js>"qux"</js>,<js>"true"</js>,<js>"123"</js>)
5143       *    )
5144       * );
5145       *
5146       *    <jc>// Set a header with a comma-separated list.</jc>
5147       *    <jv>client</jv>
5148       *       .get(<js>"/uri"</js>)
5149       *       .header(<js>"Foo"</js>, <jv>list</jv>)  <jc>// Will be serialized as: foo=bar,baz=qux\,true\,123</jc>
5150       *       .run();
5151       * </p>
5152       *
5153       * <ul class='values javatree'>
5154       *    <li class='jc'>{@link HttpPartCollectionFormat}
5155       *    <ul>
5156       *       <li class='jf'>{@link HttpPartCollectionFormat#CSV CSV} - (default) Comma-separated values (e.g. <js>"foo,bar"</js>).
5157       *       <li class='jf'>{@link HttpPartCollectionFormat#SSV SSV} - Space-separated values (e.g. <js>"foo bar"</js>).
5158       *       <li class='jf'>{@link HttpPartCollectionFormat#TSV TSV} - Tab-separated values (e.g. <js>"foo\tbar"</js>).
5159       *       <li class='jf'>{@link HttpPartCollectionFormat#PIPES PIPES} - Pipe-separated values (e.g. <js>"foo|bar"</js>).
5160       *       <li class='jf'>{@link HttpPartCollectionFormat#MULTI MULTI} - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&amp;foo=baz"</js>).
5161       *       <li class='jf'>{@link HttpPartCollectionFormat#UONC UONC} - UON collection notation (e.g. <js>"@(foo,bar)"</js>).
5162       *    </ul>
5163       * </ul>
5164       *
5165       * <h5 class='section'>See Also:</h5><ul>
5166       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiSerializer.Builder#collectionFormat(HttpPartCollectionFormat)}
5167       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiParser.Builder#collectionFormat(HttpPartCollectionFormat)}
5168       * </ul>
5169       *
5170       * @param value
5171       *    The new value for this property.
5172       *    <br>The default value is {@link HttpPartCollectionFormat#NO_COLLECTION_FORMAT}.
5173       * @return This object.
5174       */
5175      @FluentSetter
5176      public Builder oapiCollectionFormat(HttpPartCollectionFormat value) {
5177         serializers().forEach(OpenApiSerializer.Builder.class, x -> x.collectionFormat(value));
5178         parsers().forEach(OpenApiParser.Builder.class, x -> x.collectionFormat(value));
5179         partSerializer().builder(OpenApiSerializer.Builder.class, x -> x.collectionFormat(value));
5180         partParser().builder(OpenApiParser.Builder.class, x -> x.collectionFormat(value));
5181         return this;
5182      }
5183
5184      //-----------------------------------------------------------------------------------------------------------------
5185      // UON Properties
5186      //-----------------------------------------------------------------------------------------------------------------
5187
5188      /**
5189       * <i><l>UonSerializer</l> configuration property:&emsp;</i>  Parameter format.
5190       *
5191       * <p>
5192       * Specifies the format of parameters when using the {@link UrlEncodingSerializer} to serialize Form Posts.
5193       *
5194       * <p>
5195       * Specifies the format to use for GET parameter keys and values.
5196       *
5197       * <h5 class='section'>Example:</h5>
5198       * <p class='bjava'>
5199       *    <jc>// Create a REST client with URL-Encoded serializer that serializes values in plain-text format.</jc>
5200       *    RestClient <jv>client</jv> = RestClient
5201       *       .<jsm>create</jsm>()
5202       *       .urlEnc()
5203       *       .paramFormat(<jsf>PLAINTEXT</jsf>)
5204       *       .build();
5205       *
5206       *    <jc>// An arbitrary data structure.</jc>
5207       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(
5208       *       <js>"foo"</js>, <js>"bar"</js>,
5209       *       <js>"baz"</js>, <jk>new</jk> String[]{<js>"qux"</js>, <js>"true"</js>, <js>"123"</js>}
5210       *    );
5211       *
5212       *    <jc>// Request body will be serialized as:  foo=bar,baz=qux,true,123</jc>
5213       *    <jv>client</jv>
5214       *       .post(<js>"/uri"</js>, <jv>map</jv>)
5215       *       .run();
5216       * </p>
5217       *
5218       * <ul class='values javatree'>
5219       *    <li class='jf'>{@link ParamFormat#UON} (default) - Use UON notation for parameters.
5220       *    <li class='jf'>{@link ParamFormat#PLAINTEXT} - Use plain text for parameters.
5221       * </ul>
5222       *
5223       * <h5 class='section'>See Also:</h5><ul>
5224       *    <li class='jm'>{@link org.apache.juneau.uon.UonSerializer.Builder#paramFormat(ParamFormat)}
5225       * </ul>
5226       *
5227       * @param value The new value for this property.
5228       * @return This object.
5229       */
5230      @FluentSetter
5231      public Builder paramFormat(ParamFormat value) {
5232         serializers().forEach(UonSerializer.Builder.class, x -> x.paramFormat(value));
5233         return this;
5234      }
5235
5236      /**
5237       * <i><l>UonSerializer</l> configuration property:&emsp;</i>  Parameter format.
5238       *
5239       * <p>
5240       * Specifies the format of parameters when using the {@link UrlEncodingSerializer} to serialize Form Posts.
5241       *
5242       * <p>
5243       * Specifies plaintext as the format to use for GET parameter keys and values.
5244       *
5245       * <h5 class='section'>Example:</h5>
5246       * <p class='bjava'>
5247       *    <jc>// Create a REST client with URL-Encoded serializer that serializes values in plain-text format.</jc>
5248       *    RestClient <jv>client</jv> = RestClient
5249       *       .<jsm>create</jsm>()
5250       *       .urlEnc()
5251       *       .build();
5252       *
5253       *    <jc>// An arbitrary data structure.</jc>
5254       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(
5255       *       <js>"foo"</js>, <js>"bar"</js>,
5256       *       <js>"baz"</js>, <jk>new</jk> String[]{<js>"qux"</js>, <js>"true"</js>, <js>"123"</js>}
5257       *    );
5258       *
5259       *    <jc>// Request body will be serialized as:  foo=bar,baz=qux,true,123</jc>
5260       *    <jv>client</jv>
5261       *       .post(<js>"/uri"</js>, <jv>map</jv>)
5262       *       .run();
5263       * </p>
5264       *
5265       * <h5 class='section'>See Also:</h5><ul>
5266       *    <li class='jm'>{@link org.apache.juneau.uon.UonSerializer.Builder#paramFormatPlain()}
5267       * </ul>
5268       *
5269       * @return This object.
5270       */
5271      @FluentSetter
5272      public Builder paramFormatPlain() {
5273         serializers().forEach(UonSerializer.Builder.class, org.apache.juneau.uon.UonSerializer.Builder::paramFormatPlain);
5274         return this;
5275      }
5276
5277      // <FluentSetters>
5278
5279      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5280      public Builder annotations(Annotation...values) {
5281         super.annotations(values);
5282         return this;
5283      }
5284
5285      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5286      public Builder apply(AnnotationWorkList work) {
5287         super.apply(work);
5288         return this;
5289      }
5290
5291      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5292      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
5293         super.applyAnnotations(fromClasses);
5294         return this;
5295      }
5296
5297      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5298      public Builder applyAnnotations(Method...fromMethods) {
5299         super.applyAnnotations(fromMethods);
5300         return this;
5301      }
5302
5303      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5304      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
5305         super.cache(value);
5306         return this;
5307      }
5308
5309      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5310      public Builder impl(Context value) {
5311         super.impl(value);
5312         return this;
5313      }
5314
5315      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5316      public Builder type(Class<? extends org.apache.juneau.Context> value) {
5317         super.type(value);
5318         return this;
5319      }
5320
5321      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5322      public Builder beanClassVisibility(Visibility value) {
5323         super.beanClassVisibility(value);
5324         return this;
5325      }
5326
5327      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5328      public Builder beanConstructorVisibility(Visibility value) {
5329         super.beanConstructorVisibility(value);
5330         return this;
5331      }
5332
5333      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5334      public Builder beanContext(BeanContext value) {
5335         super.beanContext(value);
5336         return this;
5337      }
5338
5339      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5340      public Builder beanContext(BeanContext.Builder value) {
5341         super.beanContext(value);
5342         return this;
5343      }
5344
5345      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5346      public Builder beanDictionary(java.lang.Class<?>...values) {
5347         super.beanDictionary(values);
5348         return this;
5349      }
5350
5351      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5352      public Builder beanFieldVisibility(Visibility value) {
5353         super.beanFieldVisibility(value);
5354         return this;
5355      }
5356
5357      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5358      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
5359         super.beanInterceptor(on, value);
5360         return this;
5361      }
5362
5363      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5364      public Builder beanMethodVisibility(Visibility value) {
5365         super.beanMethodVisibility(value);
5366         return this;
5367      }
5368
5369      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5370      public Builder beanProperties(Map<String,Object> values) {
5371         super.beanProperties(values);
5372         return this;
5373      }
5374
5375      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5376      public Builder beanProperties(Class<?> beanClass, String properties) {
5377         super.beanProperties(beanClass, properties);
5378         return this;
5379      }
5380
5381      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5382      public Builder beanProperties(String beanClassName, String properties) {
5383         super.beanProperties(beanClassName, properties);
5384         return this;
5385      }
5386
5387      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5388      public Builder beanPropertiesExcludes(Map<String,Object> values) {
5389         super.beanPropertiesExcludes(values);
5390         return this;
5391      }
5392
5393      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5394      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
5395         super.beanPropertiesExcludes(beanClass, properties);
5396         return this;
5397      }
5398
5399      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5400      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
5401         super.beanPropertiesExcludes(beanClassName, properties);
5402         return this;
5403      }
5404
5405      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5406      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
5407         super.beanPropertiesReadOnly(values);
5408         return this;
5409      }
5410
5411      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5412      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
5413         super.beanPropertiesReadOnly(beanClass, properties);
5414         return this;
5415      }
5416
5417      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5418      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
5419         super.beanPropertiesReadOnly(beanClassName, properties);
5420         return this;
5421      }
5422
5423      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5424      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
5425         super.beanPropertiesWriteOnly(values);
5426         return this;
5427      }
5428
5429      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5430      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
5431         super.beanPropertiesWriteOnly(beanClass, properties);
5432         return this;
5433      }
5434
5435      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5436      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
5437         super.beanPropertiesWriteOnly(beanClassName, properties);
5438         return this;
5439      }
5440
5441      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5442      public Builder beansRequireDefaultConstructor() {
5443         super.beansRequireDefaultConstructor();
5444         return this;
5445      }
5446
5447      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5448      public Builder beansRequireSerializable() {
5449         super.beansRequireSerializable();
5450         return this;
5451      }
5452
5453      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5454      public Builder beansRequireSettersForGetters() {
5455         super.beansRequireSettersForGetters();
5456         return this;
5457      }
5458
5459      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5460      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
5461         super.dictionaryOn(on, values);
5462         return this;
5463      }
5464
5465      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5466      public Builder disableBeansRequireSomeProperties() {
5467         super.disableBeansRequireSomeProperties();
5468         return this;
5469      }
5470
5471      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5472      public Builder disableIgnoreMissingSetters() {
5473         super.disableIgnoreMissingSetters();
5474         return this;
5475      }
5476
5477      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5478      public Builder disableIgnoreTransientFields() {
5479         super.disableIgnoreTransientFields();
5480         return this;
5481      }
5482
5483      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5484      public Builder disableIgnoreUnknownNullBeanProperties() {
5485         super.disableIgnoreUnknownNullBeanProperties();
5486         return this;
5487      }
5488
5489      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5490      public Builder disableInterfaceProxies() {
5491         super.disableInterfaceProxies();
5492         return this;
5493      }
5494
5495      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5496      public Builder findFluentSetters() {
5497         super.findFluentSetters();
5498         return this;
5499      }
5500
5501      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5502      public Builder findFluentSetters(Class<?> on) {
5503         super.findFluentSetters(on);
5504         return this;
5505      }
5506
5507      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5508      public Builder ignoreInvocationExceptionsOnGetters() {
5509         super.ignoreInvocationExceptionsOnGetters();
5510         return this;
5511      }
5512
5513      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5514      public Builder ignoreInvocationExceptionsOnSetters() {
5515         super.ignoreInvocationExceptionsOnSetters();
5516         return this;
5517      }
5518
5519      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5520      public Builder ignoreUnknownBeanProperties() {
5521         super.ignoreUnknownBeanProperties();
5522         return this;
5523      }
5524
5525      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5526      public Builder ignoreUnknownEnumValues() {
5527         super.ignoreUnknownEnumValues();
5528         return this;
5529      }
5530
5531      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5532      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
5533         super.implClass(interfaceClass, implClass);
5534         return this;
5535      }
5536
5537      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5538      public Builder implClasses(Map<Class<?>,Class<?>> values) {
5539         super.implClasses(values);
5540         return this;
5541      }
5542
5543      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5544      public Builder interfaceClass(Class<?> on, Class<?> value) {
5545         super.interfaceClass(on, value);
5546         return this;
5547      }
5548
5549      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5550      public Builder interfaces(java.lang.Class<?>...value) {
5551         super.interfaces(value);
5552         return this;
5553      }
5554
5555      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5556      public Builder locale(Locale value) {
5557         super.locale(value);
5558         return this;
5559      }
5560
5561      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5562      public Builder notBeanClasses(java.lang.Class<?>...values) {
5563         super.notBeanClasses(values);
5564         return this;
5565      }
5566
5567      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5568      public Builder notBeanPackages(String...values) {
5569         super.notBeanPackages(values);
5570         return this;
5571      }
5572
5573      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5574      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
5575         super.propertyNamer(value);
5576         return this;
5577      }
5578
5579      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5580      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
5581         super.propertyNamer(on, value);
5582         return this;
5583      }
5584
5585      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5586      public Builder sortProperties() {
5587         super.sortProperties();
5588         return this;
5589      }
5590
5591      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5592      public Builder sortProperties(java.lang.Class<?>...on) {
5593         super.sortProperties(on);
5594         return this;
5595      }
5596
5597      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5598      public Builder stopClass(Class<?> on, Class<?> value) {
5599         super.stopClass(on, value);
5600         return this;
5601      }
5602
5603      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5604      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
5605         super.swap(normalClass, swappedClass, swapFunction);
5606         return this;
5607      }
5608
5609      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5610      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
5611         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
5612         return this;
5613      }
5614
5615      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5616      public Builder swaps(java.lang.Class<?>...values) {
5617         super.swaps(values);
5618         return this;
5619      }
5620
5621      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5622      public Builder timeZone(TimeZone value) {
5623         super.timeZone(value);
5624         return this;
5625      }
5626
5627      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5628      public Builder typeName(Class<?> on, String value) {
5629         super.typeName(on, value);
5630         return this;
5631      }
5632
5633      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5634      public Builder typePropertyName(String value) {
5635         super.typePropertyName(value);
5636         return this;
5637      }
5638
5639      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5640      public Builder typePropertyName(Class<?> on, String value) {
5641         super.typePropertyName(on, value);
5642         return this;
5643      }
5644
5645      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5646      public Builder useEnumNames() {
5647         super.useEnumNames();
5648         return this;
5649      }
5650
5651      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5652      public Builder useJavaBeanIntrospector() {
5653         super.useJavaBeanIntrospector();
5654         return this;
5655      }
5656
5657      // </FluentSetters>
5658
5659      //------------------------------------------------------------------------------------------------
5660      // Passthrough methods for HttpClientBuilder.
5661      //------------------------------------------------------------------------------------------------
5662
5663      /**
5664       * Disables automatic redirect handling.
5665       *
5666       * @return This object.
5667       * @see HttpClientBuilder#disableRedirectHandling()
5668       */
5669      @FluentSetter
5670      public Builder disableRedirectHandling() {
5671         httpClientBuilder().disableRedirectHandling();
5672         return this;
5673      }
5674
5675      /**
5676       * Assigns {@link RedirectStrategy} instance.
5677       *
5678       * <h5 class='section'>Notes:</h5><ul>
5679       *    <li class='note'>This value can be overridden by the {@link #disableRedirectHandling()} method.
5680       * </ul>
5681       *
5682       * @param redirectStrategy New property value.
5683       * @return This object.
5684       * @see HttpClientBuilder#setRedirectStrategy(RedirectStrategy)
5685       */
5686      @FluentSetter
5687      public Builder redirectStrategy(RedirectStrategy redirectStrategy) {
5688         httpClientBuilder().setRedirectStrategy(redirectStrategy);
5689         return this;
5690      }
5691
5692      /**
5693       * Assigns default {@link CookieSpec} registry which will be used for request execution if not explicitly set in the client execution context.
5694       *
5695       * @param cookieSpecRegistry New property value.
5696       * @return This object.
5697       * @see HttpClientBuilder#setDefaultCookieSpecRegistry(Lookup)
5698       */
5699      @FluentSetter
5700      public Builder defaultCookieSpecRegistry(Lookup<CookieSpecProvider> cookieSpecRegistry) {
5701         httpClientBuilder().setDefaultCookieSpecRegistry(cookieSpecRegistry);
5702         return this;
5703      }
5704
5705      /**
5706       * Assigns {@link HttpRequestExecutor} instance.
5707       *
5708       * @param requestExec New property value.
5709       * @return This object.
5710       * @see HttpClientBuilder#setRequestExecutor(HttpRequestExecutor)
5711       */
5712      @FluentSetter
5713      public Builder requestExecutor(HttpRequestExecutor requestExec) {
5714         httpClientBuilder().setRequestExecutor(requestExec);
5715         return this;
5716      }
5717
5718      /**
5719       * Assigns {@link javax.net.ssl.HostnameVerifier} instance.
5720       *
5721       * <h5 class='section'>Notes:</h5><ul>
5722       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)}
5723       *       and the {@link #sslSocketFactory(LayeredConnectionSocketFactory)} methods.
5724       * </ul>
5725       *
5726       * @param hostnameVerifier New property value.
5727       * @return This object.
5728       * @see HttpClientBuilder#setSSLHostnameVerifier(HostnameVerifier)
5729       */
5730      @FluentSetter
5731      public Builder sslHostnameVerifier(HostnameVerifier hostnameVerifier) {
5732         httpClientBuilder().setSSLHostnameVerifier(hostnameVerifier);
5733         return this;
5734      }
5735
5736      /**
5737       * Assigns file containing public suffix matcher.
5738       *
5739       * <h5 class='section'>Notes:</h5><ul>
5740       *    <li class='note'>Instances of this class can be created with {@link PublicSuffixMatcherLoader}.
5741       * </ul>
5742       *
5743       * @param publicSuffixMatcher New property value.
5744       * @return This object.
5745       * @see HttpClientBuilder#setPublicSuffixMatcher(PublicSuffixMatcher)
5746       */
5747      @FluentSetter
5748      public Builder publicSuffixMatcher(PublicSuffixMatcher publicSuffixMatcher) {
5749         httpClientBuilder().setPublicSuffixMatcher(publicSuffixMatcher);
5750         return this;
5751      }
5752
5753      /**
5754       * Assigns {@link SSLContext} instance.
5755       *
5756       * <h5 class='section'>Notes:</h5><ul>
5757       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)}
5758       *    and the {@link #sslSocketFactory(LayeredConnectionSocketFactory)} methods.
5759       * </ul>
5760       *
5761       * @param sslContext New property value.
5762       * @return This object.
5763       * @see HttpClientBuilder#setSSLContext(SSLContext)
5764       */
5765      @FluentSetter
5766      public Builder sslContext(SSLContext sslContext) {
5767         httpClientBuilder().setSSLContext(sslContext);
5768         return this;
5769      }
5770
5771      /**
5772       * Assigns {@link LayeredConnectionSocketFactory} instance.
5773       *
5774       * <h5 class='section'>Notes:</h5><ul>
5775       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5776       * </ul>
5777       *
5778       * @param sslSocketFactory New property value.
5779       * @return This object.
5780       * @see HttpClientBuilder#setSSLSocketFactory(LayeredConnectionSocketFactory)
5781       */
5782      @FluentSetter
5783      public Builder sslSocketFactory(LayeredConnectionSocketFactory sslSocketFactory) {
5784         httpClientBuilder().setSSLSocketFactory(sslSocketFactory);
5785         return this;
5786      }
5787
5788      /**
5789       * Assigns maximum total connection value.
5790       *
5791       * <h5 class='section'>Notes:</h5><ul>
5792       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5793       * </ul>
5794       *
5795       * @param maxConnTotal New property value.
5796       * @return This object.
5797       * @see HttpClientBuilder#setMaxConnTotal(int)
5798       */
5799      @FluentSetter
5800      public Builder maxConnTotal(int maxConnTotal) {
5801         httpClientBuilder().setMaxConnTotal(maxConnTotal);
5802         return this;
5803      }
5804
5805      /**
5806       * Assigns maximum connection per route value.
5807       *
5808       * <h5 class='section'>Notes:</h5><ul>
5809       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5810       * </ul>
5811       *
5812       * @param maxConnPerRoute New property value.
5813       * @return This object.
5814       * @see HttpClientBuilder#setMaxConnPerRoute(int)
5815       */
5816      @FluentSetter
5817      public Builder maxConnPerRoute(int maxConnPerRoute) {
5818         httpClientBuilder().setMaxConnPerRoute(maxConnPerRoute);
5819         return this;
5820      }
5821
5822      /**
5823       * Assigns default {@link SocketConfig}.
5824       *
5825       * <h5 class='section'>Notes:</h5><ul>
5826       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5827       * </ul>
5828       *
5829       * @param config New property value.
5830       * @return This object.
5831       * @see HttpClientBuilder#setDefaultSocketConfig(SocketConfig)
5832       */
5833      @FluentSetter
5834      public Builder defaultSocketConfig(SocketConfig config) {
5835         httpClientBuilder().setDefaultSocketConfig(config);
5836         return this;
5837      }
5838
5839      /**
5840       * Assigns default {@link ConnectionConfig}.
5841       *
5842       * <h5 class='section'>Notes:</h5><ul>
5843       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5844       * </ul>
5845       *
5846       * @param config New property value.
5847       * @return This object.
5848       * @see HttpClientBuilder#setDefaultConnectionConfig(ConnectionConfig)
5849       */
5850      @FluentSetter
5851      public Builder defaultConnectionConfig(ConnectionConfig config) {
5852         httpClientBuilder().setDefaultConnectionConfig(config);
5853         return this;
5854      }
5855
5856      /**
5857       * Sets maximum time to live for persistent connections.
5858       *
5859       * <h5 class='section'>Notes:</h5><ul>
5860       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5861       * </ul>
5862       *
5863       * @param connTimeToLive New property value.
5864       * @param connTimeToLiveTimeUnit New property value.
5865       * @return This object.
5866       * @see HttpClientBuilder#setConnectionTimeToLive(long,TimeUnit)
5867       */
5868      @FluentSetter
5869      public Builder connectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) {
5870         httpClientBuilder().setConnectionTimeToLive(connTimeToLive, connTimeToLiveTimeUnit);
5871         return this;
5872      }
5873
5874      /**
5875       * Assigns {@link ConnectionReuseStrategy} instance.
5876       *
5877       * @param reuseStrategy New property value.
5878       * @return This object.
5879       * @see HttpClientBuilder#setConnectionReuseStrategy(ConnectionReuseStrategy)
5880       */
5881      @FluentSetter
5882      public Builder connectionReuseStrategy(ConnectionReuseStrategy reuseStrategy) {
5883         httpClientBuilder().setConnectionReuseStrategy(reuseStrategy);
5884         return this;
5885      }
5886
5887      /**
5888       * Assigns {@link ConnectionKeepAliveStrategy} instance.
5889       *
5890       * @param keepAliveStrategy New property value.
5891       * @return This object.
5892       * @see HttpClientBuilder#setKeepAliveStrategy(ConnectionKeepAliveStrategy)
5893       */
5894      @FluentSetter
5895      public Builder keepAliveStrategy(ConnectionKeepAliveStrategy keepAliveStrategy) {
5896         httpClientBuilder().setKeepAliveStrategy(keepAliveStrategy);
5897         return this;
5898      }
5899
5900      /**
5901       * Assigns {@link AuthenticationStrategy} instance for target host authentication.
5902       *
5903       * @param targetAuthStrategy New property value.
5904       * @return This object.
5905       * @see HttpClientBuilder#setTargetAuthenticationStrategy(AuthenticationStrategy)
5906       */
5907      @FluentSetter
5908      public Builder targetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
5909         httpClientBuilder().setTargetAuthenticationStrategy(targetAuthStrategy);
5910         return this;
5911      }
5912
5913      /**
5914       * Assigns {@link AuthenticationStrategy} instance for proxy authentication.
5915       *
5916       * @param proxyAuthStrategy New property value.
5917       * @return This object.
5918       * @see HttpClientBuilder#setProxyAuthenticationStrategy(AuthenticationStrategy)
5919       */
5920      @FluentSetter
5921      public Builder proxyAuthenticationStrategy(AuthenticationStrategy proxyAuthStrategy) {
5922         httpClientBuilder().setProxyAuthenticationStrategy(proxyAuthStrategy);
5923         return this;
5924      }
5925
5926      /**
5927       * Assigns {@link UserTokenHandler} instance.
5928       *
5929       * <h5 class='section'>Notes:</h5><ul>
5930       *    <li class='note'>This value can be overridden by the {@link #disableConnectionState()} method.
5931       * </ul>
5932       *
5933       * @param userTokenHandler New property value.
5934       * @return This object.
5935       * @see HttpClientBuilder#setUserTokenHandler(UserTokenHandler)
5936       */
5937      @FluentSetter
5938      public Builder userTokenHandler(UserTokenHandler userTokenHandler) {
5939         httpClientBuilder().setUserTokenHandler(userTokenHandler);
5940         return this;
5941      }
5942
5943      /**
5944       * Disables connection state tracking.
5945       *
5946       * @return This object.
5947       * @see HttpClientBuilder#disableConnectionState()
5948       */
5949      @FluentSetter
5950      public Builder disableConnectionState() {
5951         httpClientBuilder().disableConnectionState();
5952         return this;
5953      }
5954
5955      /**
5956       * Assigns {@link SchemePortResolver} instance.
5957       *
5958       * @param schemePortResolver New property value.
5959       * @return This object.
5960       * @see HttpClientBuilder#setSchemePortResolver(SchemePortResolver)
5961       */
5962      @FluentSetter
5963      public Builder schemePortResolver(SchemePortResolver schemePortResolver) {
5964         httpClientBuilder().setSchemePortResolver(schemePortResolver);
5965         return this;
5966      }
5967
5968      /**
5969       * Adds this protocol interceptor to the head of the protocol processing list.
5970       *
5971       * <h5 class='section'>Notes:</h5><ul>
5972       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
5973       * </ul>
5974       *
5975       * @param itcp New property value.
5976       * @return This object.
5977       * @see HttpClientBuilder#addInterceptorFirst(HttpResponseInterceptor)
5978       */
5979      @FluentSetter
5980      public Builder addInterceptorFirst(HttpResponseInterceptor itcp) {
5981         httpClientBuilder().addInterceptorFirst(itcp);
5982         return this;
5983      }
5984
5985      /**
5986       * Adds this protocol interceptor to the tail of the protocol processing list.
5987       *
5988       * <h5 class='section'>Notes:</h5><ul>
5989       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
5990       * </ul>
5991       *
5992       * @param itcp New property value.
5993       * @return This object.
5994       * @see HttpClientBuilder#addInterceptorLast(HttpResponseInterceptor)
5995       */
5996      @FluentSetter
5997      public Builder addInterceptorLast(HttpResponseInterceptor itcp) {
5998         httpClientBuilder().addInterceptorLast(itcp);
5999         return this;
6000      }
6001
6002      /**
6003       * Adds this protocol interceptor to the head of the protocol processing list.
6004       *
6005       * <h5 class='section'>Notes:</h5><ul>
6006       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6007       * </ul>
6008       *
6009       * @param itcp New property value.
6010       * @return This object.
6011       * @see HttpClientBuilder#addInterceptorFirst(HttpRequestInterceptor)
6012       */
6013      @FluentSetter
6014      public Builder addInterceptorFirst(HttpRequestInterceptor itcp) {
6015         httpClientBuilder().addInterceptorFirst(itcp);
6016         return this;
6017      }
6018
6019      /**
6020       * Adds this protocol interceptor to the tail of the protocol processing list.
6021       *
6022       * <h5 class='section'>Notes:</h5><ul>
6023       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6024       * </ul>
6025       *
6026       * @param itcp New property value.
6027       * @return This object.
6028       * @see HttpClientBuilder#addInterceptorLast(HttpRequestInterceptor)
6029       */
6030      @FluentSetter
6031      public Builder addInterceptorLast(HttpRequestInterceptor itcp) {
6032         httpClientBuilder().addInterceptorLast(itcp);
6033         return this;
6034      }
6035
6036      /**
6037       * Disables state (cookie) management.
6038       *
6039       * <h5 class='section'>Notes:</h5><ul>
6040       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6041       * </ul>
6042       *
6043       * @return This object.
6044       * @see HttpClientBuilder#disableCookieManagement()
6045       */
6046      @FluentSetter
6047      public Builder disableCookieManagement() {
6048         httpClientBuilder().disableCookieManagement();
6049         return this;
6050      }
6051
6052      /**
6053       * Disables automatic content decompression.
6054       *
6055       * <h5 class='section'>Notes:</h5><ul>
6056       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6057       * </ul>
6058       *
6059       * @return This object.
6060       * @see HttpClientBuilder#disableContentCompression()
6061       */
6062      @FluentSetter
6063      public Builder disableContentCompression() {
6064         httpClientBuilder().disableContentCompression();
6065         return this;
6066      }
6067
6068      /**
6069       * Disables authentication scheme caching.
6070       *
6071       * <h5 class='section'>Notes:</h5><ul>
6072       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6073       * </ul>
6074       *
6075       * @return This object.
6076       * @see HttpClientBuilder#disableAuthCaching()
6077       */
6078      @FluentSetter
6079      public Builder disableAuthCaching() {
6080         httpClientBuilder().disableAuthCaching();
6081         return this;
6082      }
6083
6084      /**
6085       * Assigns {@link HttpProcessor} instance.
6086       *
6087       * @param httpprocessor New property value.
6088       * @return This object.
6089       * @see HttpClientBuilder#setHttpProcessor(HttpProcessor)
6090       */
6091      @FluentSetter
6092      public Builder httpProcessor(HttpProcessor httpprocessor) {
6093         httpClientBuilder().setHttpProcessor(httpprocessor);
6094         return this;
6095      }
6096
6097      /**
6098       * Assigns {@link HttpRequestRetryHandler} instance.
6099       *
6100       * <h5 class='section'>Notes:</h5><ul>
6101       *    <li class='note'>This value can be overridden by the {@link #disableAutomaticRetries()} method.
6102       * </ul>
6103       *
6104       * @param retryHandler New property value.
6105       * @return This object.
6106       * @see HttpClientBuilder#setRetryHandler(HttpRequestRetryHandler)
6107       */
6108      @FluentSetter
6109      public Builder retryHandler(HttpRequestRetryHandler retryHandler) {
6110         httpClientBuilder().setRetryHandler(retryHandler);
6111         return this;
6112      }
6113
6114      /**
6115       * Disables automatic request recovery and re-execution.
6116       *
6117       * @return This object.
6118       * @see HttpClientBuilder#disableAutomaticRetries()
6119       */
6120      @FluentSetter
6121      public Builder disableAutomaticRetries() {
6122         httpClientBuilder().disableAutomaticRetries();
6123         return this;
6124      }
6125
6126      /**
6127       * Assigns default proxy value.
6128       *
6129       * <h5 class='section'>Notes:</h5><ul>
6130       *    <li class='note'>This value can be overridden by the {@link #routePlanner(HttpRoutePlanner)} method.
6131       * </ul>
6132       *
6133       * @param proxy New property value.
6134       * @return This object.
6135       * @see HttpClientBuilder#setProxy(HttpHost)
6136       */
6137      @FluentSetter
6138      public Builder proxy(HttpHost proxy) {
6139         httpClientBuilder().setProxy(proxy);
6140         return this;
6141      }
6142
6143      /**
6144       * Assigns {@link HttpRoutePlanner} instance.
6145       *
6146       * @param routePlanner New property value.
6147       * @return This object.
6148       * @see HttpClientBuilder#setRoutePlanner(HttpRoutePlanner)
6149       */
6150      @FluentSetter
6151      public Builder routePlanner(HttpRoutePlanner routePlanner) {
6152         httpClientBuilder().setRoutePlanner(routePlanner);
6153         return this;
6154      }
6155
6156      /**
6157       * Assigns {@link ConnectionBackoffStrategy} instance.
6158       *
6159       * @param connectionBackoffStrategy New property value.
6160       * @return This object.
6161       * @see HttpClientBuilder#setConnectionBackoffStrategy(ConnectionBackoffStrategy)
6162       */
6163      @FluentSetter
6164      public Builder connectionBackoffStrategy(ConnectionBackoffStrategy connectionBackoffStrategy) {
6165         httpClientBuilder().setConnectionBackoffStrategy(connectionBackoffStrategy);
6166         return this;
6167      }
6168
6169      /**
6170       * Assigns {@link BackoffManager} instance.
6171       *
6172       * @param backoffManager New property value.
6173       * @return This object.
6174       * @see HttpClientBuilder#setBackoffManager(BackoffManager)
6175       */
6176      @FluentSetter
6177      public Builder backoffManager(BackoffManager backoffManager) {
6178         httpClientBuilder().setBackoffManager(backoffManager);
6179         return this;
6180      }
6181
6182      /**
6183       * Assigns {@link ServiceUnavailableRetryStrategy} instance.
6184       *
6185       * @param serviceUnavailStrategy New property value.
6186       * @return This object.
6187       * @see HttpClientBuilder#setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)
6188       */
6189      @FluentSetter
6190      public Builder serviceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy serviceUnavailStrategy) {
6191         httpClientBuilder().setServiceUnavailableRetryStrategy(serviceUnavailStrategy);
6192         return this;
6193      }
6194
6195      /**
6196       * Assigns default {@link CookieStore} instance which will be used for request execution if not explicitly set in the client execution context.
6197       *
6198       * @param cookieStore New property value.
6199       * @return This object.
6200       * @see HttpClientBuilder#setDefaultCookieStore(CookieStore)
6201       */
6202      @FluentSetter
6203      public Builder defaultCookieStore(CookieStore cookieStore) {
6204         httpClientBuilder().setDefaultCookieStore(cookieStore);
6205         return this;
6206      }
6207
6208      /**
6209       * Assigns default {@link CredentialsProvider} instance which will be used for request execution if not explicitly set in the client execution context.
6210       *
6211       * @param credentialsProvider New property value.
6212       * @return This object.
6213       * @see HttpClientBuilder#setDefaultCredentialsProvider(CredentialsProvider)
6214       */
6215      @FluentSetter
6216      public Builder defaultCredentialsProvider(CredentialsProvider credentialsProvider) {
6217         httpClientBuilder().setDefaultCredentialsProvider(credentialsProvider);
6218         return this;
6219      }
6220
6221      /**
6222       * Assigns default {@link org.apache.http.auth.AuthScheme} registry which will be used for request execution if not explicitly set in the client execution context.
6223       *
6224       * @param authSchemeRegistry New property value.
6225       * @return This object.
6226       * @see HttpClientBuilder#setDefaultAuthSchemeRegistry(Lookup)
6227       */
6228      @FluentSetter
6229      public Builder defaultAuthSchemeRegistry(Lookup<AuthSchemeProvider> authSchemeRegistry) {
6230         httpClientBuilder().setDefaultAuthSchemeRegistry(authSchemeRegistry);
6231         return this;
6232      }
6233
6234      /**
6235       * Assigns a map of {@link org.apache.http.client.entity.InputStreamFactory InputStreamFactories} to be used for automatic content decompression.
6236       *
6237       * @param contentDecoderMap New property value.
6238       * @return This object.
6239       * @see HttpClientBuilder#setContentDecoderRegistry(Map)
6240       */
6241      @FluentSetter
6242      public Builder contentDecoderRegistry(Map<String,InputStreamFactory> contentDecoderMap) {
6243         httpClientBuilder().setContentDecoderRegistry(contentDecoderMap);
6244         return this;
6245      }
6246
6247      /**
6248       * Assigns default {@link RequestConfig} instance which will be used for request execution if not explicitly set in the client execution context.
6249       *
6250       * @param config New property value.
6251       * @return This object.
6252       * @see HttpClientBuilder#setDefaultRequestConfig(RequestConfig)
6253       */
6254      @FluentSetter
6255      public Builder defaultRequestConfig(RequestConfig config) {
6256         httpClientBuilder().setDefaultRequestConfig(config);
6257         return this;
6258      }
6259
6260      /**
6261       * Use system properties when creating and configuring default implementations.
6262       *
6263       * @return This object.
6264       * @see HttpClientBuilder#useSystemProperties()
6265       */
6266      @FluentSetter
6267      public Builder useSystemProperties() {
6268         httpClientBuilder().useSystemProperties();
6269         return this;
6270      }
6271
6272      /**
6273       * Makes this instance of {@link HttpClient} proactively evict expired connections from the connection pool using a background thread.
6274       *
6275       * <h5 class='section'>Notes:</h5><ul>
6276       *    <li class='note'>One MUST explicitly close HttpClient with {@link CloseableHttpClient#close()} in order to stop and release the background thread.
6277       *    <li class='note'>This method has no effect if the instance of {@link HttpClient} is configured to use a shared connection manager.
6278       *    <li class='note'>This method may not be used when the instance of {@link HttpClient} is created inside an EJB container.
6279       * </ul>
6280       *
6281       * @return This object.
6282       * @see HttpClientBuilder#evictExpiredConnections()
6283       */
6284      @FluentSetter
6285      public Builder evictExpiredConnections() {
6286         httpClientBuilder().evictExpiredConnections();
6287         return this;
6288      }
6289
6290      /**
6291       * Makes this instance of {@link HttpClient} proactively evict idle connections from the connection pool using a background thread.
6292       *
6293       * <h5 class='section'>Notes:</h5><ul>
6294       *    <li class='note'>One MUST explicitly close HttpClient with {@link CloseableHttpClient#close()} in order to stop and release the background thread.
6295       *    <li class='note'>This method has no effect if the instance of {@link HttpClient} is configured to use a shared connection manager.
6296       *    <li class='note'>This method may not be used when the instance of {@link HttpClient} is created inside an EJB container.
6297       * </ul>
6298       *
6299       * @param maxIdleTime New property value.
6300       * @param maxIdleTimeUnit New property value.
6301       * @return This object.
6302       * @see HttpClientBuilder#evictIdleConnections(long,TimeUnit)
6303       */
6304      @FluentSetter
6305      public Builder evictIdleConnections(long maxIdleTime, TimeUnit maxIdleTimeUnit) {
6306         httpClientBuilder().evictIdleConnections(maxIdleTime, maxIdleTimeUnit);
6307         return this;
6308      }
6309   }
6310
6311   //-------------------------------------------------------------------------------------------------------------------
6312   // Instance
6313   //-------------------------------------------------------------------------------------------------------------------
6314
6315   final HeaderList headerData;
6316   final PartList queryData, formData, pathData;
6317   final CloseableHttpClient httpClient;
6318
6319   private final HttpClientConnectionManager connectionManager;
6320   private final boolean keepHttpClientOpen, detectLeaks, skipEmptyHeaderData, skipEmptyQueryData, skipEmptyFormData;
6321   private final BeanStore beanStore;
6322   private final UrlEncodingSerializer urlEncodingSerializer;  // Used for form posts only.
6323   final HttpPartSerializer partSerializer;
6324   final HttpPartParser partParser;
6325   private final RestCallHandler callHandler;
6326   private final String rootUrl;
6327   private volatile boolean isClosed = false;
6328   private final StackTraceElement[] creationStack;
6329   private final Logger logger;
6330   final DetailLevel logRequests;
6331   final BiPredicate<RestRequest,RestResponse> logRequestsPredicate;
6332   final Level logRequestsLevel;
6333   final boolean ignoreErrors;
6334   private final boolean logToConsole;
6335   private final PrintStream console;
6336   private StackTraceElement[] closedStack;
6337   private static final ConcurrentHashMap<Class<?>,Context> requestContexts = new ConcurrentHashMap<>();
6338
6339   // These are read directly by RestCall.
6340   final SerializerSet serializers;
6341   final ParserSet parsers;
6342   Predicate<Integer> errorCodes;
6343
6344   final RestCallInterceptor[] interceptors;
6345
6346   private final Map<Class<?>, HttpPartParser> partParsers = new ConcurrentHashMap<>();
6347   private final Map<Class<?>, HttpPartSerializer> partSerializers = new ConcurrentHashMap<>();
6348
6349   // This is lazy-created.
6350   private volatile ExecutorService executorService;
6351   private final boolean executorServiceShutdownOnClose;
6352
6353   private static final
6354      BiPredicate<RestRequest,RestResponse> LOG_REQUESTS_PREDICATE_DEFAULT = (req,res) -> true;
6355
6356   /**
6357    * Constructor.
6358    *
6359    * @param builder The builder for this client.
6360    */
6361   public RestClient(Builder builder) {
6362      super(builder);
6363
6364      beanStore = builder.beanStore
6365         .addBean(RestClient.class, this);
6366
6367      httpClient = builder.getHttpClient();
6368      headerData = builder.headers().copy();
6369      queryData = builder.queryData().copy();
6370      formData = builder.formData().copy();
6371      pathData = builder.pathData().copy();
6372      callHandler = builder.callHandler().run();
6373      skipEmptyHeaderData = builder.skipEmptyHeaderData;
6374      skipEmptyQueryData = builder.skipEmptyQueryData;
6375      skipEmptyFormData = builder.skipEmptyFormData;
6376      rootUrl = builder.rootUrl;
6377      errorCodes = builder.errorCodes;
6378      connectionManager = builder.connectionManager;
6379      console = builder.console != null ? builder.console : System.err;
6380      executorService = builder.executorService;
6381      executorServiceShutdownOnClose = builder.executorServiceShutdownOnClose;
6382      ignoreErrors = builder.ignoreErrors;
6383      keepHttpClientOpen = builder.keepHttpClientOpen;
6384      detectLeaks = builder.detectLeaks;
6385      logger = builder.logger != null ? builder.logger : Logger.getLogger(RestClient.class.getName());
6386      logToConsole = builder.logToConsole || isDebug();
6387      logRequests = builder.logRequests != null ? builder.logRequests : isDebug() ? DetailLevel.FULL : DetailLevel.NONE;
6388      logRequestsLevel = builder.logRequestsLevel != null ? builder.logRequestsLevel : isDebug() ? Level.WARNING : Level.OFF;
6389      logRequestsPredicate = builder.logRequestsPredicate != null ? builder.logRequestsPredicate : LOG_REQUESTS_PREDICATE_DEFAULT;
6390      interceptors = builder.interceptors != null ? builder.interceptors.toArray(EMPTY_REST_CALL_INTERCEPTORS) : EMPTY_REST_CALL_INTERCEPTORS;
6391      serializers = builder.serializers().build();
6392      parsers = builder.parsers().build();
6393      partSerializer = builder.partSerializer().create();
6394      partParser = builder.partParser().create();
6395      urlEncodingSerializer = builder.urlEncodingSerializer().build();
6396      creationStack = isDebug() ? Thread.currentThread().getStackTrace() : null;
6397
6398      init();
6399   }
6400
6401   @Override /* Context */
6402   public Builder copy() {
6403      throw new NoSuchMethodError("Not implemented.");
6404   }
6405
6406   /**
6407    * Perform optional initialization on builder before it is used.
6408    *
6409    * <p>
6410    * Default behavior is a no-op.
6411    *
6412    * @param builder The builder to initialize.
6413    */
6414   protected void init(RestClient.Builder builder) {}
6415
6416   /**
6417    * Gets called add the end of the constructor call to perform any post-initialization.
6418    */
6419   protected void init() {
6420   }
6421
6422   /**
6423    * Calls {@link CloseableHttpClient#close()} on the underlying {@link CloseableHttpClient}.
6424    *
6425    * <p>
6426    * It's good practice to call this method after the client is no longer used.
6427    *
6428    * @throws IOException Thrown by underlying stream.
6429    */
6430   @Override
6431   public void close() throws IOException {
6432      isClosed = true;
6433      if (! keepHttpClientOpen)
6434         httpClient.close();
6435      if (executorService != null && executorServiceShutdownOnClose)
6436         executorService.shutdown();
6437      if (creationStack != null)
6438         closedStack = Thread.currentThread().getStackTrace();
6439   }
6440
6441   /**
6442    * Same as {@link #close()}, but ignores any exceptions.
6443    */
6444   public void closeQuietly() {
6445      isClosed = true;
6446      try {
6447         if (! keepHttpClientOpen)
6448            httpClient.close();
6449         if (executorService != null && executorServiceShutdownOnClose)
6450            executorService.shutdown();
6451      } catch (Throwable t) {}
6452      if (creationStack != null)
6453         closedStack = Thread.currentThread().getStackTrace();
6454   }
6455
6456   /**
6457    * Entrypoint for executing all requests and returning a response.
6458    *
6459    * <p>
6460    * Subclasses can override this method to provide specialized handling.
6461    *
6462    * <p>
6463    * The behavior of this method can also be modified by specifying a different {@link RestCallHandler}.
6464    *
6465    * <h5 class='section'>See Also:</h5><ul>
6466    *    <li class='jm'>{@link Builder#callHandler()}
6467    * </ul>
6468    *
6469    * @param target The target host for the request.
6470    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
6471    *       target or by inspecting the request.
6472    * @param request The request to execute.
6473    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
6474    * @return
6475    *    The response to the request.
6476    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
6477    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
6478    *       implementation and configuration of this client.
6479    * @throws IOException In case of a problem or the connection was aborted.
6480    * @throws ClientProtocolException In case of an http protocol error.
6481    */
6482   protected HttpResponse run(HttpHost target, HttpRequest request, HttpContext context) throws ClientProtocolException, IOException {
6483      return callHandler.run(target, request, context);
6484   }
6485
6486   /**
6487    * Perform a <c>GET</c> request against the specified URI.
6488    *
6489    * @param uri
6490    *    The URI of the remote REST resource.
6491    *    <br>Can be any of the following types:
6492    *    <ul>
6493    *       <li>{@link URIBuilder}
6494    *       <li>{@link URI}
6495    *       <li>{@link URL}
6496    *       <li>{@link String}
6497    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6498    *    </ul>
6499    * @return
6500    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6501    *    as a parsed object.
6502    * @throws RestCallException If any authentication errors occurred.
6503    */
6504   public RestRequest get(Object uri) throws RestCallException {
6505      return request(op("GET", uri, NO_BODY));
6506   }
6507
6508   /**
6509    * Perform a <c>GET</c> request against the root URI.
6510    *
6511    * @return
6512    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6513    *    as a parsed object.
6514    * @throws RestCallException If any authentication errors occurred.
6515    */
6516   public RestRequest get() throws RestCallException {
6517      return request(op("GET", null, NO_BODY));
6518   }
6519
6520   /**
6521    * Perform a <c>PUT</c> request against the specified URI.
6522    *
6523    * @param uri
6524    *    The URI of the remote REST resource.
6525    *    <br>Can be any of the following types:
6526    *    <ul>
6527    *       <li>{@link URIBuilder}
6528    *       <li>{@link URI}
6529    *       <li>{@link URL}
6530    *       <li>{@link String}
6531    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6532    *    </ul>
6533    * @param body
6534    *    The object to serialize and transmit to the URI as the body of the request.
6535    *    Can be of the following types:
6536    *    <ul class='spaced-list'>
6537    *       <li>
6538    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
6539    *       <li>
6540    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
6541    *       <li>
6542    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
6543    *          {@link RestClient}.
6544    *       <li>
6545    *          {@link HttpEntity} / {@link HttpResource} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6546    *       <li>
6547    *          {@link PartList} - Converted to a URL-encoded FORM post.
6548    *       <li>
6549    *          {@link Supplier} - A supplier of anything on this list.
6550    *    </ul>
6551    * @return
6552    *    A {@link RestRequest} object that can be further tailored before executing the request
6553    *    and getting the response as a parsed object.
6554    * @throws RestCallException If any authentication errors occurred.
6555    */
6556   public RestRequest put(Object uri, Object body) throws RestCallException {
6557      return request(op("PUT", uri, body));
6558   }
6559
6560   /**
6561    * Perform a <c>PUT</c> request against the specified URI using a plain text body bypassing the serializer.
6562    *
6563    * @param uri
6564    *    The URI of the remote REST resource.
6565    *    <br>Can be any of the following types:
6566    *    <ul>
6567    *       <li>{@link URIBuilder}
6568    *       <li>{@link URI}
6569    *       <li>{@link URL}
6570    *       <li>{@link String}
6571    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6572    *    </ul>
6573    * @param body
6574    *    The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
6575    * @param contentType The content type of the request.
6576    * @return
6577    *    A {@link RestRequest} object that can be further tailored before executing the request
6578    *    and getting the response as a parsed object.
6579    * @throws RestCallException If any authentication errors occurred.
6580    */
6581   public RestRequest put(Object uri, String body, ContentType contentType) throws RestCallException {
6582      return request(op("PUT", uri, stringBody(body))).header(contentType);
6583   }
6584
6585   /**
6586    * Same as {@link #put(Object, Object)} but don't specify the input yet.
6587    *
6588    * <p>
6589    * You must call either {@link RestRequest#content(Object)} or {@link RestRequest#formData(String, Object)}
6590    * to set the contents on the result object.
6591    *
6592    * @param uri
6593    *    The URI of the remote REST resource.
6594    *    <br>Can be any of the following types:
6595    *    <ul>
6596    *       <li>{@link URIBuilder}
6597    *       <li>{@link URI}
6598    *       <li>{@link URL}
6599    *       <li>{@link String}
6600    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6601    *    </ul>
6602    * @return
6603    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6604    *    as a parsed object.
6605    * @throws RestCallException REST call failed.
6606    */
6607   public RestRequest put(Object uri) throws RestCallException {
6608      return request(op("PUT", uri, NO_BODY));
6609   }
6610
6611   /**
6612    * Perform a <c>POST</c> request against the specified URI.
6613    *
6614    * <h5 class='section'>Notes:</h5><ul>
6615    *    <li class='note'>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
6616    * </ul>
6617    *
6618    * @param uri
6619    *    The URI of the remote REST resource.
6620    *    <br>Can be any of the following types:
6621    *    <ul>
6622    *       <li>{@link URIBuilder}
6623    *       <li>{@link URI}
6624    *       <li>{@link URL}
6625    *       <li>{@link String}
6626    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6627    *    </ul>
6628    * @param body
6629    *    The object to serialize and transmit to the URI as the body of the request.
6630    *    Can be of the following types:
6631    *    <ul class='spaced-list'>
6632    *       <li>
6633    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
6634    *       <li>
6635    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
6636    *       <li>
6637    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
6638    *          {@link RestClient}.
6639    *       <li>
6640    *          {@link HttpEntity} / {@link HttpResource} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6641    *       <li>
6642    *          {@link PartList} - Converted to a URL-encoded FORM post.
6643    *       <li>
6644    *          {@link Supplier} - A supplier of anything on this list.
6645    *    </ul>
6646    * @return
6647    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6648    *    as a parsed object.
6649    * @throws RestCallException If any authentication errors occurred.
6650    */
6651   public RestRequest post(Object uri, Object body) throws RestCallException {
6652      return request(op("POST", uri, body));
6653   }
6654
6655   /**
6656    * Perform a <c>POST</c> request against the specified URI as a plain text body bypassing the serializer.
6657    *
6658    * @param uri
6659    *    The URI of the remote REST resource.
6660    *    <br>Can be any of the following types:
6661    *    <ul>
6662    *       <li>{@link URIBuilder}
6663    *       <li>{@link URI}
6664    *       <li>{@link URL}
6665    *       <li>{@link String}
6666    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6667    *    </ul>
6668    * @param body
6669    *    The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
6670    * @param contentType
6671    *    The content type of the request.
6672    * @return
6673    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6674    *    as a parsed object.
6675    * @throws RestCallException If any authentication errors occurred.
6676    */
6677   public RestRequest post(Object uri, String body, ContentType contentType) throws RestCallException {
6678      return request(op("POST", uri, stringBody(body))).header(contentType);
6679   }
6680
6681   /**
6682    * Same as {@link #post(Object, Object)} but don't specify the input yet.
6683    *
6684    * <p>
6685    * You must call either {@link RestRequest#content(Object)} or {@link RestRequest#formData(String, Object)} to set the
6686    * contents on the result object.
6687    *
6688    * <h5 class='section'>Notes:</h5><ul>
6689    *    <li class='note'>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
6690    * </ul>
6691    *
6692    * @param uri
6693    *    The URI of the remote REST resource.
6694    *    <br>Can be any of the following types:
6695    *    <ul>
6696    *       <li>{@link URIBuilder}
6697    *       <li>{@link URI}
6698    *       <li>{@link URL}
6699    *       <li>{@link String}
6700    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6701    *    </ul>
6702    * @return
6703    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6704    *    as a parsed object.
6705    * @throws RestCallException REST call failed.
6706    */
6707   public RestRequest post(Object uri) throws RestCallException {
6708      return request(op("POST", uri, NO_BODY));
6709   }
6710
6711   /**
6712    * Perform a <c>DELETE</c> request against the specified URI.
6713    *
6714    * @param uri
6715    *    The URI of the remote REST resource.
6716    *    <br>Can be any of the following types:
6717    *    <ul>
6718    *       <li>{@link URIBuilder}
6719    *       <li>{@link URI}
6720    *       <li>{@link URL}
6721    *       <li>{@link String}
6722    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6723    *    </ul>
6724    * @return
6725    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6726    *    as a parsed object.
6727    * @throws RestCallException If any authentication errors occurred.
6728    */
6729   public RestRequest delete(Object uri) throws RestCallException {
6730      return request(op("DELETE", uri, NO_BODY));
6731   }
6732
6733   /**
6734    * Perform an <c>OPTIONS</c> request against the specified URI.
6735    *
6736    * @param uri
6737    *    The URI of the remote REST resource.
6738    *    <br>Can be any of the following types:
6739    *    <ul>
6740    *       <li>{@link URIBuilder}
6741    *       <li>{@link URI}
6742    *       <li>{@link URL}
6743    *       <li>{@link String}
6744    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6745    *    </ul>
6746    * @return
6747    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6748    *    as a parsed object.
6749    * @throws RestCallException If any authentication errors occurred.
6750    */
6751   public RestRequest options(Object uri) throws RestCallException {
6752      return request(op("OPTIONS", uri, NO_BODY));
6753   }
6754
6755   /**
6756    * Perform a <c>HEAD</c> request against the specified URI.
6757    *
6758    * @param uri
6759    *    The URI of the remote REST resource.
6760    *    <br>Can be any of the following types:
6761    *    <ul>
6762    *       <li>{@link URIBuilder}
6763    *       <li>{@link URI}
6764    *       <li>{@link URL}
6765    *       <li>{@link String}
6766    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6767    *    </ul>
6768    * @return
6769    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6770    *    as a parsed object.
6771    * @throws RestCallException If any authentication errors occurred.
6772    */
6773   public RestRequest head(Object uri) throws RestCallException {
6774      return request(op("HEAD", uri, NO_BODY));
6775   }
6776
6777   /**
6778    * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
6779    * against the specified URI.
6780    *
6781    * @param uri
6782    *    The URI of the remote REST resource.
6783    *    <br>Can be any of the following types:
6784    *    <ul>
6785    *       <li>{@link URIBuilder}
6786    *       <li>{@link URI}
6787    *       <li>{@link URL}
6788    *       <li>{@link String}
6789    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6790    *    </ul>
6791    * @param body
6792    *    The object to serialize and transmit to the URI as the body of the request.
6793    *    <ul class='spaced-list'>
6794    *       <li>{@link NameValuePair} - URL-encoded as a single name-value pair.
6795    *       <li>{@link NameValuePair} array - URL-encoded as name value pairs.
6796    *       <li>{@link PartList} - URL-encoded as name value pairs.
6797    *       <li>{@link Reader}/{@link InputStream}- Streamed directly and <l>Content-Type</l> set to <js>"application/x-www-form-urlencoded"</js>
6798    *       <li>{@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
6799    *       <li>{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6800    *       <li>{@link Object} - Converted to a {@link SerializedEntity} using {@link UrlEncodingSerializer} to serialize.
6801    *       <li>{@link Supplier} - A supplier of anything on this list.
6802    *    </ul>
6803    * @return
6804    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6805    *    as a parsed object.
6806    * @throws RestCallException If any authentication errors occurred.
6807    */
6808   public RestRequest formPost(Object uri, Object body) throws RestCallException {
6809      RestRequest req = request(op("POST", uri, NO_BODY));
6810      try {
6811         if (body instanceof Supplier)
6812            body = ((Supplier<?>)body).get();
6813         if (body instanceof NameValuePair)
6814            return req.content(new UrlEncodedFormEntity(alist((NameValuePair)body)));
6815         if (body instanceof NameValuePair[])
6816            return req.content(new UrlEncodedFormEntity(alist((NameValuePair[])body)));
6817         if (body instanceof PartList)
6818            return req.content(new UrlEncodedFormEntity(((PartList)body)));
6819         if (body instanceof HttpResource)
6820            ((HttpResource)body).getHeaders().forEach(x-> req.header(x));
6821         if (body instanceof HttpEntity) {
6822            HttpEntity e = (HttpEntity)body;
6823            if (e.getContentType() == null)
6824               req.header(ContentType.APPLICATION_FORM_URLENCODED);
6825            return req.content(e);
6826         }
6827         if (body instanceof Reader || body instanceof InputStream)
6828            return req.header(ContentType.APPLICATION_FORM_URLENCODED).content(body);
6829         return req.content(serializedEntity(body, urlEncodingSerializer, null));
6830      } catch (IOException e) {
6831         throw new RestCallException(null, e, "Could not read form post body.");
6832      }
6833   }
6834
6835   /**
6836    * Same as {@link #formPost(Object, Object)} but doesn't specify the input yet.
6837    *
6838    * @param uri
6839    *    The URI of the remote REST resource.
6840    *    <br>Can be any of the following types:
6841    *    <ul>
6842    *       <li>{@link URIBuilder}
6843    *       <li>{@link URI}
6844    *       <li>{@link URL}
6845    *       <li>{@link String}
6846    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6847    *    </ul>
6848    * @return
6849    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6850    *    as a parsed object.
6851    * @throws RestCallException If any authentication errors occurred.
6852    */
6853   public RestRequest formPost(Object uri) throws RestCallException {
6854      return request(op("POST", uri, NO_BODY));
6855   }
6856
6857   /**
6858    * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
6859    * against the specified URI.
6860    *
6861    * @param uri
6862    *    The URI of the remote REST resource.
6863    *    <br>Can be any of the following types:
6864    *    <ul>
6865    *       <li>{@link URIBuilder}
6866    *       <li>{@link URI}
6867    *       <li>{@link URL}
6868    *       <li>{@link String}
6869    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6870    *    </ul>
6871    * @param parameters
6872    *    The parameters of the form post.
6873    *    <br>The parameters represent name/value pairs and must be an even number of arguments.
6874    *    <br>Parameters are converted to {@link BasicPart} objects.
6875    * @return
6876    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6877    *    as a parsed object.
6878    * @throws RestCallException If any authentication errors occurred.
6879    */
6880   public RestRequest formPostPairs(Object uri, String...parameters) throws RestCallException {
6881      return formPost(uri, partList(parameters));
6882   }
6883
6884   /**
6885    * Perform a <c>PATCH</c> request against the specified URI.
6886    *
6887    * @param uri
6888    *    The URI of the remote REST resource.
6889    *    <br>Can be any of the following types:
6890    *    <ul>
6891    *       <li>{@link URIBuilder}
6892    *       <li>{@link URI}
6893    *       <li>{@link URL}
6894    *       <li>{@link String}
6895    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6896    *    </ul>
6897    * @param body
6898    *    The object to serialize and transmit to the URI as the body of the request.
6899    *    Can be of the following types:
6900    *    <ul class='spaced-list'>
6901    *       <li>
6902    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
6903    *       <li>
6904    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
6905    *       <li>
6906    *          {@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
6907    *       <li>
6908    *          {@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6909    *       <li>
6910    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
6911    *          {@link RestClient}.
6912    *       <li>
6913    *          {@link PartList} - Converted to a URL-encoded FORM post.
6914    *       <li>
6915    *          {@link Supplier} - A supplier of anything on this list.
6916    *    </ul>
6917    * @return
6918    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6919    *    as a parsed object.
6920    * @throws RestCallException If any authentication errors occurred.
6921    */
6922   public RestRequest patch(Object uri, Object body) throws RestCallException {
6923      return request(op("PATCH", uri, body));
6924   }
6925
6926   /**
6927    * Perform a <c>PATCH</c> request against the specified URI as a plain text body bypassing the serializer.
6928    *
6929    * @param uri
6930    *    The URI of the remote REST resource.
6931    *    <br>Can be any of the following types:
6932    *    <ul>
6933    *       <li>{@link URIBuilder}
6934    *       <li>{@link URI}
6935    *       <li>{@link URL}
6936    *       <li>{@link String}
6937    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6938    *    </ul>
6939    * @param body
6940    *    The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
6941    * @param contentType
6942    *    The content type of the request.
6943    * @return
6944    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6945    *    as a parsed object.
6946    * @throws RestCallException If any authentication errors occurred.
6947    */
6948   public RestRequest patch(Object uri, String body, ContentType contentType) throws RestCallException {
6949      return request(op("PATCH", uri, stringBody(body))).header(contentType);
6950   }
6951
6952   /**
6953    * Same as {@link #patch(Object, Object)} but don't specify the input yet.
6954    *
6955    * <p>
6956    * You must call {@link RestRequest#content(Object)} to set the contents on the result object.
6957    *
6958    * @param uri
6959    *    The URI of the remote REST resource.
6960    *    <br>Can be any of the following types:
6961    *    <ul>
6962    *       <li>{@link URIBuilder}
6963    *       <li>{@link URI}
6964    *       <li>{@link URL}
6965    *       <li>{@link String}
6966    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6967    *    </ul>
6968    * @return
6969    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6970    *    as a parsed object.
6971    * @throws RestCallException REST call failed.
6972    */
6973   public RestRequest patch(Object uri) throws RestCallException {
6974      return request(op("PATCH", uri, NO_BODY));
6975   }
6976
6977
6978   /**
6979    * Performs a REST call where the entire call is specified in a simple string.
6980    *
6981    * <p>
6982    * This method is useful for performing callbacks when the target of a callback is passed in
6983    * on an initial request, for example to signal when a long-running process has completed.
6984    *
6985    * <p>
6986    * The call string can be any of the following formats:
6987    * <ul class='spaced-list'>
6988    *    <li>
6989    *       <js>"[method] [uri]"</js> - e.g. <js>"GET http://localhost/callback"</js>
6990    *    <li>
6991    *       <js>"[method] [uri] [payload]"</js> - e.g. <js>"POST http://localhost/callback some text payload"</js>
6992    *    <li>
6993    *       <js>"[method] [headers] [uri] [payload]"</js> - e.g. <js>"POST {'Content-Type':'text/json'} http://localhost/callback {'some':'json'}"</js>
6994    * </ul>
6995    * <p>
6996    * The payload will always be sent using a simple {@link StringEntity}.
6997    *
6998    * @param callString The call string.
6999    * @return
7000    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7001    *    as a parsed object.
7002    * @throws RestCallException REST call failed.
7003    */
7004   public RestRequest callback(String callString) throws RestCallException {
7005      callString = emptyIfNull(callString);
7006
7007      // S01 - Looking for end of method.
7008      // S02 - Found end of method, looking for beginning of URI or headers.
7009      // S03 - Found beginning of headers, looking for end of headers.
7010      // S04 - Found end of headers, looking for beginning of URI.
7011      // S05 - Found beginning of URI, looking for end of URI.
7012
7013      StateMachineState state = S01;
7014
7015      int mark = 0;
7016      String method = null, headers = null, uri = null, content = null;
7017      for (int i = 0; i < callString.length(); i++) {
7018         char c = callString.charAt(i);
7019         if (state == S01) {
7020            if (isWhitespace(c)) {
7021               method = callString.substring(mark, i);
7022               state = S02;
7023            }
7024         } else if (state == S02) {
7025            if (! isWhitespace(c)) {
7026               mark = i;
7027               if (c == '{')
7028                  state = S03;
7029               else
7030                  state = S05;
7031            }
7032         } else if (state == S03) {
7033            if (c == '}') {
7034               headers = callString.substring(mark, i+1);
7035               state = S04;
7036            }
7037         } else if (state == S04) {
7038            if (! isWhitespace(c)) {
7039               mark = i;
7040               state = S05;
7041            }
7042         } else /* (state == S05) */ {
7043            if (isWhitespace(c)) {
7044               uri = callString.substring(mark, i);
7045               content = callString.substring(i).trim();
7046               break;
7047            }
7048         }
7049      }
7050
7051      if (state != S05)
7052         throw new RestCallException(null, null, "Invalid format for call string.  State={0}", state);
7053
7054      try {
7055         RestRequest req = request(method, uri, isNotEmpty(content));
7056         if (headers != null)
7057            JsonMap.ofJson(headers).forEach((k,v) -> req.header(stringHeader(k, stringify(v))));
7058         if (isNotEmpty(content))
7059            req.contentString(content);
7060         return req;
7061      } catch (ParseException e) {
7062         throw new RestCallException(null, e, "Invalid format for call string.");
7063      }
7064   }
7065
7066   /**
7067    * Perform a generic REST call.
7068    *
7069    * @param method The HTTP method.
7070    * @param uri
7071    *    The URI of the remote REST resource.
7072    *    <br>Can be any of the following types:
7073    *    <ul>
7074    *       <li>{@link URIBuilder}
7075    *       <li>{@link URI}
7076    *       <li>{@link URL}
7077    *       <li>{@link String}
7078    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
7079    *    </ul>
7080    * @param body
7081    *    The HTTP body content.
7082    *    Can be of the following types:
7083    *    <ul class='spaced-list'>
7084    *       <li>
7085    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
7086    *       <li>
7087    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
7088    *       <li>
7089    *          {@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
7090    *       <li>
7091    *          {@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
7092    *       <li>
7093    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
7094    *          {@link RestClient}.
7095    *       <li>
7096    *          {@link PartList} - Converted to a URL-encoded FORM post.
7097    *       <li>
7098    *          {@link Supplier} - A supplier of anything on this list.
7099    *    </ul>
7100    *    This parameter is IGNORED if the method type normally does not have content.
7101    * @return
7102    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7103    *    as a parsed object.
7104    * @throws RestCallException If any authentication errors occurred.
7105    */
7106   public RestRequest request(String method, Object uri, Object body) throws RestCallException {
7107      return request(op(method, uri, body));
7108   }
7109
7110   /**
7111    * Perform a generic REST call.
7112    *
7113    * @param method The HTTP method.
7114    * @param uri
7115    *    The URI of the remote REST resource.
7116    *    <br>Can be any of the following types:
7117    *    <ul>
7118    *       <li>{@link URIBuilder}
7119    *       <li>{@link URI}
7120    *       <li>{@link URL}
7121    *       <li>{@link String}
7122    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
7123    *    </ul>
7124    * @return
7125    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7126    *    as a parsed object.
7127    * @throws RestCallException If any authentication errors occurred.
7128    */
7129   public RestRequest request(String method, Object uri) throws RestCallException {
7130      return request(op(method, uri, NO_BODY));
7131   }
7132
7133   /**
7134    * Perform a generic REST call.
7135    *
7136    * <p>
7137    * Typically you're going to use {@link #request(String, Object)} or {@link #request(String, Object, Object)},
7138    * but this method is provided to allow you to perform non-standard HTTP methods (e.g. HTTP FOO).
7139    *
7140    * @param method The method name (e.g. <js>"GET"</js>, <js>"OPTIONS"</js>).
7141    * @param uri
7142    *    The URI of the remote REST resource.
7143    *    <br>Can be any of the following types:
7144    *    <ul>
7145    *       <li>{@link URIBuilder}
7146    *       <li>{@link URI}
7147    *       <li>{@link URL}
7148    *       <li>{@link String}
7149    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
7150    *    </ul>
7151    * @param hasBody Boolean flag indicating if the specified request has content associated with it.
7152    * @return
7153    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7154    *    as a parsed object.
7155    * @throws RestCallException If any authentication errors occurred.
7156    */
7157   public RestRequest request(String method, Object uri, boolean hasBody) throws RestCallException {
7158      return request(op(method, uri, NO_BODY).hasContent(hasBody));
7159   }
7160
7161   /**
7162    * Perform an arbitrary request against the specified URI.
7163    *
7164    * <p>
7165    * All requests feed through this method so it can be used to intercept request creations and make modifications
7166    * (such as add headers).
7167    *
7168    * @param op The operation that identifies the HTTP method, URL, and optional payload.
7169    * @return
7170    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7171    *    as a parsed object.
7172    * @throws RestCallException If any authentication errors occurred.
7173    */
7174   protected RestRequest request(RestOperation op) throws RestCallException {
7175      if (isClosed) {
7176         Exception e2 = null;
7177         if (closedStack != null) {
7178            e2 = new Exception("Creation stack:");
7179            e2.setStackTrace(closedStack);
7180            throw new RestCallException(null, e2, "RestClient.close() has already been called.  This client cannot be reused.");
7181         }
7182         throw new RestCallException(null, null, "RestClient.close() has already been called.  This client cannot be reused.  Closed location stack trace can be displayed by setting the system property 'org.apache.juneau.rest.client2.RestClient.trackCreation' to true.");
7183      }
7184
7185      RestRequest req = createRequest(toURI(op.getUri(), rootUrl), op.getMethod(), op.hasContent());
7186
7187      onCallInit(req);
7188
7189      req.content(op.getContent());
7190
7191      return req;
7192   }
7193
7194   /**
7195    * Creates a {@link RestRequest} object from the specified {@link HttpRequest} object.
7196    *
7197    * <p>
7198    * Subclasses can override this method to provide their own specialized {@link RestRequest} objects.
7199    *
7200    * @param uri The target.
7201    * @param method The HTTP method (uppercase).
7202    * @param hasBody Whether this method has a request entity.
7203    * @return A new {@link RestRequest} object.
7204    * @throws RestCallException If an exception or non-200 response code occurred during the connection attempt.
7205    */
7206   protected RestRequest createRequest(URI uri, String method, boolean hasBody) throws RestCallException {
7207      return new RestRequest(this, uri, method, hasBody);
7208   }
7209
7210   /**
7211    * Creates a {@link RestResponse} object from the specified {@link HttpResponse} object.
7212    *
7213    * <p>
7214    * Subclasses can override this method to provide their own specialized {@link RestResponse} objects.
7215    *
7216    * @param request The request creating this response.
7217    * @param httpResponse The response object to wrap.
7218    * @param parser The parser to use to parse the response.
7219    *
7220    * @return A new {@link RestResponse} object.
7221    * @throws RestCallException If an exception or non-200 response code occurred during the connection attempt.
7222    */
7223   protected RestResponse createResponse(RestRequest request, HttpResponse httpResponse, Parser parser) throws RestCallException {
7224      return new RestResponse(this, request, httpResponse, parser);
7225   }
7226
7227   /**
7228    * Create a new proxy interface against a 3rd-party REST interface.
7229    *
7230    * <p>
7231    * The URI to the REST interface is based on the following values:
7232    * <ul>
7233    *    <li>The {@link Remote#path() @Remote(path)} annotation on the interface (<c>remote-path</c>).
7234    *    <li>The {@link Builder#rootUrl(Object) rootUrl} on the client (<c>root-url</c>).
7235    *    <li>The fully-qualified class name of the interface (<c>class-name</c>).
7236    * </ul>
7237    *
7238    * <p>
7239    * The URI calculation is as follows:
7240    * <ul>
7241    *    <li><c>remote-path</c> - If remote path is absolute.
7242    *    <li><c>root-uri/remote-path</c> - If remote path is relative and root-uri has been specified.
7243    *    <li><c>root-uri/class-name</c> - If remote path is not specified.
7244    * </ul>
7245    *
7246    * <p>
7247    * If the information is not available to resolve to an absolute URI, a {@link RemoteMetadataException} is thrown.
7248    *
7249    * <h5 class='section'>Examples:</h5>
7250    * <p class='bjava'>
7251    *    <jk>package</jk> org.apache.foo;
7252    *
7253    *    <ja>@RemoteResource</ja>(path=<js>"http://hostname/resturi/myinterface1"</js>)
7254    *    <jk>public interface</jk> MyInterface1 { ... }
7255    *
7256    *    <ja>@RemoteResource</ja>(path=<js>"/myinterface2"</js>)
7257    *    <jk>public interface</jk> MyInterface2 { ... }
7258    *
7259    *    <jk>public interface</jk> MyInterface3 { ... }
7260    *
7261    *    <jc>// Resolves to "http://localhost/resturi/myinterface1"</jc>
7262    *    MyInterface1 <jv>interface1</jv> = RestClient
7263    *       .<jsm>create</jsm>()
7264    *       .build()
7265    *       .getRemote(MyInterface1.<jk>class</jk>);
7266    *
7267    *    <jc>// Resolves to "http://hostname/resturi/myinterface2"</jc>
7268    *    MyInterface2 <jv>interface2</jv> = RestClient
7269    *       .<jsm>create</jsm>()
7270    *       .rootUrl(<js>"http://hostname/resturi"</js>)
7271    *       .build()
7272    *       .getRemote(MyInterface2.<jk>class</jk>);
7273    *
7274    *    <jc>// Resolves to "http://hostname/resturi/org.apache.foo.MyInterface3"</jc>
7275    *    MyInterface3 <jv>interface3</jv> = RestClient
7276    *       .<jsm>create</jsm>()
7277    *       .rootUrl(<js>"http://hostname/resturi"</js>)
7278    *       .build()
7279    *       .getRemote(MyInterface3.<jk>class</jk>);
7280    * </p>
7281    *
7282    * <h5 class='section'>Notes:</h5><ul>
7283    *    <li class='note'>
7284    *       If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying
7285    *       pooling client connection manager.
7286    * </ul>
7287    *
7288    * <h5 class='section'>See Also:</h5><ul>
7289    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
7290    * </ul>
7291    *
7292    * @param <T> The interface to create a proxy for.
7293    * @param interfaceClass The interface to create a proxy for.
7294    * @return The new proxy interface.
7295    * @throws RemoteMetadataException If the REST URI cannot be determined based on the information given.
7296    */
7297   public <T> T getRemote(Class<T> interfaceClass) {
7298      return getRemote(interfaceClass, null);
7299   }
7300
7301   /**
7302    * Same as {@link #getRemote(Class)} except explicitly specifies the URI of the REST interface.
7303    *
7304    * <h5 class='section'>See Also:</h5><ul>
7305    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
7306    * </ul>
7307    *
7308    * @param <T> The interface to create a proxy for.
7309    * @param interfaceClass The interface to create a proxy for.
7310    * @param rootUrl The URI of the REST interface.
7311    * @return The new proxy interface.
7312    */
7313   public <T> T getRemote(Class<T> interfaceClass, Object rootUrl) {
7314      return getRemote(interfaceClass, rootUrl, null, null);
7315   }
7316
7317   /**
7318    * Same as {@link #getRemote(Class, Object)} but allows you to override the serializer and parser used.
7319    *
7320    * <h5 class='section'>See Also:</h5><ul>
7321    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
7322    * </ul>
7323
7324    * @param <T> The interface to create a proxy for.
7325    * @param interfaceClass The interface to create a proxy for.
7326    * @param rootUrl The URI of the REST interface.
7327    * @param serializer The serializer used to serialize POJOs to the body of the HTTP request.
7328    * @param parser The parser used to parse POJOs from the body of the HTTP response.
7329    * @return The new proxy interface.
7330    */
7331   @SuppressWarnings({ "unchecked" })
7332   public <T> T getRemote(final Class<T> interfaceClass, Object rootUrl, final Serializer serializer, final Parser parser) {
7333
7334      if (rootUrl == null)
7335         rootUrl = this.rootUrl;
7336
7337      final String restUrl2 = trimSlashes(emptyIfNull(rootUrl));
7338
7339      return (T)Proxy.newProxyInstance(
7340         interfaceClass.getClassLoader(),
7341         new Class[] { interfaceClass },
7342         new InvocationHandler() {
7343
7344            final RemoteMeta rm = new RemoteMeta(interfaceClass);
7345
7346            @Override /* InvocationHandler */
7347            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
7348               RemoteOperationMeta rom = rm.getOperationMeta(method);
7349
7350               String uri = rom.getFullPath();
7351               if (uri.indexOf("://") == -1)
7352                  uri = restUrl2 + '/' + uri;
7353               if (uri.indexOf("://") == -1)
7354                  throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote resource.");
7355
7356               String httpMethod = rom.getHttpMethod();
7357               RestRequest rc = request(httpMethod, uri, hasContent(httpMethod));
7358
7359               rc.serializer(serializer);
7360               rc.parser(parser);
7361
7362               rm.getHeaders().forEach(x -> rc.header(x));
7363               rom.forEachPathArg(a -> rc.pathArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer)));
7364               rom.forEachQueryArg(a -> rc.queryArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
7365               rom.forEachFormDataArg(a -> rc.formDataArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
7366               rom.forEachHeaderArg(a -> rc.headerArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
7367
7368               RemoteOperationArg ba = rom.getContentArg();
7369               if (ba != null)
7370                  rc.content(args[ba.getIndex()], ba.getSchema());
7371
7372               rom.forEachRequestArg(rmba -> {
7373                     RequestBeanMeta rbm = rmba.getMeta();
7374                     Object bean = args[rmba.getIndex()];
7375                     if (bean != null) {
7376                        for (RequestBeanPropertyMeta p : rbm.getProperties()) {
7377                           Object val = safeSupplier(()->p.getGetter().invoke(bean));
7378                           HttpPartType pt = p.getPartType();
7379                           String pn = p.getPartName();
7380                           HttpPartSchema schema = p.getSchema();
7381                           if (pt == PATH)
7382                              rc.pathArg(pn, val, schema, p.getSerializer().orElse(partSerializer));
7383                           else if (val != null) {
7384                              if (pt == QUERY)
7385                                 rc.queryArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
7386                              else if (pt == FORMDATA)
7387                                 rc.formDataArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
7388                              else if (pt == HEADER)
7389                                 rc.headerArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
7390                              else /* (pt == HttpPartType.BODY) */
7391                                 rc.content(val, schema);
7392                           }
7393                        }
7394                     }
7395               });
7396
7397               RemoteOperationReturn ror = rom.getReturns();
7398               if (ror.isFuture()) {
7399                  return getExecutorService().submit(() -> {
7400                           try {
7401                              return executeRemote(interfaceClass, rc, method, rom);
7402                           } catch (Exception e) {
7403                              throw e;
7404                           } catch (Throwable e) {
7405                              throw asRuntimeException(e);
7406                           }
7407                        });
7408               } else if (ror.isCompletableFuture()) {
7409                  CompletableFuture<Object> cf = new CompletableFuture<>();
7410                  getExecutorService().submit(() -> {
7411                           try {
7412                              cf.complete(executeRemote(interfaceClass, rc, method, rom));
7413                           } catch (Throwable e) {
7414                              cf.completeExceptionally(e);
7415                           }
7416                           return null;
7417                        });
7418                  return cf;
7419               }
7420
7421               return executeRemote(interfaceClass, rc, method, rom);
7422            }
7423      });
7424   }
7425
7426   Object executeRemote(Class<?> interfaceClass, RestRequest rc, Method method, RemoteOperationMeta rom) throws Throwable {
7427      RemoteOperationReturn ror = rom.getReturns();
7428
7429      try {
7430         Object ret = null;
7431         RestResponse res = null;
7432         rc.rethrow(RuntimeException.class);
7433         rom.forEachException(x -> rc.rethrow(x));
7434         if (ror.getReturnValue() == RemoteReturn.NONE) {
7435            res = rc.complete();
7436         } else if (ror.getReturnValue() == RemoteReturn.STATUS) {
7437            res = rc.complete();
7438            int returnCode = res.getStatusCode();
7439            Class<?> rt = method.getReturnType();
7440            if (rt == Integer.class || rt == int.class)
7441               ret = returnCode;
7442            else if (rt == Boolean.class || rt == boolean.class)
7443               ret = returnCode < 400;
7444            else
7445               throw new RestCallException(res, null, "Invalid return type on method annotated with @RemoteOp(returns=RemoteReturn.STATUS).  Only integer and booleans types are valid.");
7446         } else if (ror.getReturnValue() == RemoteReturn.BEAN) {
7447            rc.ignoreErrors();
7448            res = rc.run();
7449            ret = res.as(ror.getResponseBeanMeta());
7450         } else {
7451            Class<?> rt = method.getReturnType();
7452            if (Throwable.class.isAssignableFrom(rt))
7453               rc.ignoreErrors();
7454            res = rc.run();
7455            Object v = res.getContent().as(ror.getReturnType());
7456            if (v == null && rt.isPrimitive())
7457               v = ClassInfo.of(rt).getPrimitiveDefault();
7458            ret = v;
7459         }
7460         return ret;
7461      } catch (RestCallException e) {
7462         Throwable t = e.getCause();
7463         if (t instanceof RuntimeException)
7464            throw t;
7465         for (Class<?> t2 : method.getExceptionTypes())
7466            if (t2.isInstance(t))
7467               throw t;
7468         throw asRuntimeException(e);
7469      }
7470   }
7471
7472   /**
7473    * Create a new proxy interface against an RRPC-style service.
7474    *
7475    * <p>
7476    * Remote interfaces are interfaces exposed on the server side using either the <c>RrpcServlet</c>
7477    * or <c>RRPC</c> REST methods.
7478    *
7479    * <p>
7480    * The URI to the REST interface is based on the following values:
7481    * <ul>
7482    *    <li>The {@link Remote#path() @Remote(path)} annotation on the interface (<c>remote-path</c>).
7483    *    <li>The {@link Builder#rootUrl(Object) rootUrl} on the client (<c>root-url</c>).
7484    *    <li>The fully-qualified class name of the interface (<c>class-name</c>).
7485    * </ul>
7486    *
7487    * <p>
7488    * The URI calculation is as follows:
7489    * <ul>
7490    *    <li><c>remote-path</c> - If remote path is absolute.
7491    *    <li><c>root-url/remote-path</c> - If remote path is relative and root-url has been specified.
7492    *    <li><c>root-url/class-name</c> - If remote path is not specified.
7493    * </ul>
7494    *
7495    * <p>
7496    * If the information is not available to resolve to an absolute URI, a {@link RemoteMetadataException} is thrown.
7497    *
7498    * <h5 class='section'>Notes:</h5><ul>
7499    *    <li class='note'>
7500    *       If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying
7501    *       pooling client connection manager.
7502    * </ul>
7503    *
7504    * <h5 class='section'>See Also:</h5><ul>
7505    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
7506    * </ul>
7507    *
7508    * @param <T> The interface to create a proxy for.
7509    * @param interfaceClass The interface to create a proxy for.
7510    * @return The new proxy interface.
7511    * @throws RemoteMetadataException If the REST URI cannot be determined based on the information given.
7512    */
7513   public <T> T getRrpcInterface(final Class<T> interfaceClass) {
7514      return getRrpcInterface(interfaceClass, null);
7515   }
7516
7517   /**
7518    * Same as {@link #getRrpcInterface(Class)} except explicitly specifies the URI of the REST interface.
7519    *
7520    * <h5 class='section'>See Also:</h5><ul>
7521    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
7522    * </ul>
7523    *
7524    * @param <T> The interface to create a proxy for.
7525    * @param interfaceClass The interface to create a proxy for.
7526    * @param uri The URI of the REST interface.
7527    * @return The new proxy interface.
7528    */
7529   public <T> T getRrpcInterface(final Class<T> interfaceClass, final Object uri) {
7530      return getRrpcInterface(interfaceClass, uri, null, null);
7531   }
7532
7533   /**
7534    * Same as {@link #getRrpcInterface(Class, Object)} but allows you to override the serializer and parser used.
7535    *
7536    * <h5 class='section'>See Also:</h5><ul>
7537    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
7538    * </ul>
7539    *
7540    * @param <T> The interface to create a proxy for.
7541    * @param interfaceClass The interface to create a proxy for.
7542    * @param uri The URI of the REST interface.
7543    * @param serializer The serializer used to serialize POJOs to the body of the HTTP request.
7544    * @param parser The parser used to parse POJOs from the body of the HTTP response.
7545    * @return The new proxy interface.
7546    */
7547   @SuppressWarnings({ "unchecked" })
7548   public <T> T getRrpcInterface(final Class<T> interfaceClass, Object uri, final Serializer serializer, final Parser parser) {
7549
7550      if (uri == null) {
7551         RrpcInterfaceMeta rm = new RrpcInterfaceMeta(interfaceClass, "");
7552         String path = rm.getPath();
7553         if (path.indexOf("://") == -1) {
7554            if (isEmpty(rootUrl))
7555               throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote interface.");
7556            path = trimSlashes(rootUrl) + '/' + path;
7557         }
7558         uri = path;
7559      }
7560
7561      final String restUrl2 = stringify(uri);
7562
7563      return (T)Proxy.newProxyInstance(
7564         interfaceClass.getClassLoader(),
7565         new Class[] { interfaceClass },
7566         new InvocationHandler() {
7567
7568            final RrpcInterfaceMeta rm = new RrpcInterfaceMeta(interfaceClass, restUrl2);
7569
7570            @Override /* InvocationHandler */
7571            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
7572               RrpcInterfaceMethodMeta rim = rm.getMethodMeta(method);
7573
7574               String uri = rim.getUri();
7575               RestResponse res = null;
7576
7577               try {
7578                  RestRequest rc = request("POST", uri, true)
7579                     .serializer(serializer)
7580                     .content(args)
7581                     .rethrow(RuntimeException.class)
7582                     .rethrow(method.getExceptionTypes());
7583
7584                  res = rc.run();
7585
7586                  Object v = res.getContent().as(method.getGenericReturnType());
7587                  if (v == null && method.getReturnType().isPrimitive())
7588                     v = ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
7589                  return v;
7590
7591               } catch (Throwable e) {
7592                  if (e instanceof RestCallException) {
7593                     Throwable t = e.getCause();
7594                     if (t != null)
7595                        e = t;
7596                  }
7597                  if (e instanceof RuntimeException)
7598                     throw e;
7599                  for (Class<?> t2 : method.getExceptionTypes())
7600                     if (t2.isInstance(e))
7601                        throw e;
7602                  throw asRuntimeException(e);
7603               }
7604            }
7605      });
7606   }
7607
7608   @Override
7609   protected void finalize() throws Throwable {
7610      if (detectLeaks && ! isClosed && ! keepHttpClientOpen) {
7611         StringBuilder sb = new StringBuilder("WARNING:  RestClient garbage collected before it was finalized.");  // NOT DEBUG
7612         if (creationStack != null) {
7613            sb.append("\nCreation Stack:");  // NOT DEBUG
7614            for (StackTraceElement e : creationStack)
7615               sb.append("\n\t" + e);  // NOT DEBUG
7616         }
7617         log(WARNING, sb.toString());
7618      }
7619   }
7620
7621   /**
7622    * Logs a message.
7623    *
7624    * @param level The log level.
7625    * @param t Thrown exception.  Can be <jk>null</jk>.
7626    * @param msg The message.
7627    * @param args Optional message arguments.
7628    */
7629   protected void log(Level level, Throwable t, String msg, Object...args) {
7630      logger.log(level, t, msg(msg, args));
7631      if (logToConsole) {
7632         console.println(msg(msg, args).get());
7633         if (t != null)
7634            t.printStackTrace(console);
7635      }
7636   }
7637
7638   /**
7639    * Logs a message.
7640    *
7641    * @param level The log level.
7642    * @param msg The message with {@link MessageFormat}-style arguments.
7643    * @param args The arguments.
7644    */
7645   protected void log(Level level, String msg, Object...args) {
7646      logger.log(level, msg(msg, args));
7647      if (logToConsole)
7648         console.println(msg(msg, args).get());
7649   }
7650
7651   private Supplier<String> msg(String msg, Object...args) {
7652      return ()->args.length == 0 ? msg : MessageFormat.format(msg, args);
7653   }
7654
7655   /**
7656    * Returns the part serializer associated with this client.
7657    *
7658    * @return The part serializer associated with this client.
7659    */
7660   protected HttpPartSerializer getPartSerializer() {
7661      return partSerializer;
7662   }
7663
7664   /**
7665    * Returns the part parser associated with this client.
7666    *
7667    * @return The part parser associated with this client.
7668    */
7669   protected HttpPartParser getPartParser() {
7670      return partParser;
7671   }
7672
7673   /**
7674    * Returns the part serializer instance of the specified type.
7675    *
7676    * @param c The part serializer class.
7677    * @return The part serializer.
7678    */
7679   protected HttpPartSerializer getPartSerializer(Class<? extends HttpPartSerializer> c) {
7680      HttpPartSerializer x = partSerializers.get(c);
7681      if (x == null) {
7682         try {
7683            x = beanStore.createBean(c).run();
7684         } catch (ExecutableException e) {
7685            throw asRuntimeException(e);
7686         }
7687         partSerializers.put(c, x);
7688      }
7689      return x;
7690   }
7691
7692   /**
7693    * Returns the part parser instance of the specified type.
7694    *
7695    * @param c The part parser class.
7696    * @return The part parser.
7697    */
7698   protected HttpPartParser getPartParser(Class<? extends HttpPartParser> c) {
7699      HttpPartParser x = partParsers.get(c);
7700      if (x == null) {
7701         try {
7702            x = beanStore.createBean(c).run();
7703         } catch (ExecutableException e) {
7704            throw asRuntimeException(e);
7705         }
7706         partParsers.put(c, x);
7707      }
7708      return x;
7709   }
7710
7711   /**
7712    * Returns <jk>true</jk> if empty request header values should be ignored.
7713    *
7714    * @return <jk>true</jk> if empty request header values should be ignored.
7715    */
7716   protected boolean isSkipEmptyHeaderData() {
7717      return skipEmptyHeaderData;
7718   }
7719
7720   /**
7721    * Returns <jk>true</jk> if empty request query parameter values should be ignored.
7722    *
7723    * @return <jk>true</jk> if empty request query parameter values should be ignored.
7724    */
7725   protected boolean isSkipEmptyQueryData() {
7726      return skipEmptyQueryData;
7727   }
7728
7729   /**
7730    * Returns <jk>true</jk> if empty request form-data parameter values should be ignored.
7731    *
7732    * @return <jk>true</jk> if empty request form-data parameter values should be ignored.
7733    */
7734   protected boolean isSkipEmptyFormData() {
7735      return skipEmptyFormData;
7736   }
7737
7738   //-----------------------------------------------------------------------------------------------------------------
7739   // Part list builders methods
7740   //-----------------------------------------------------------------------------------------------------------------
7741
7742   /**
7743    * Creates a mutable copy of the header data defined on this client.
7744    *
7745    * <p>
7746    * Used during the construction of {@link RestRequest} objects.
7747    *
7748    * <p>
7749    * Subclasses can override this method to provide their own builder.
7750    *
7751    * @return A new builder.
7752    */
7753   public HeaderList createHeaderData() {
7754      return headerData.copy();
7755   }
7756
7757   /**
7758    * Creates a mutable copy of the query data defined on this client.
7759    *
7760    * <p>
7761    * Used during the construction of {@link RestRequest} objects.
7762    *
7763    * <p>
7764    * Subclasses can override this method to provide their own builder.
7765    *
7766    * @return A new builder.
7767    */
7768   public PartList createQueryData() {
7769      return queryData.copy();
7770   }
7771
7772   /**
7773    * Creates a mutable copy of the form data defined on this client.
7774    *
7775    * <p>
7776    * Used during the construction of {@link RestRequest} objects.
7777    *
7778    * <p>
7779    * Subclasses can override this method to provide their own builder.
7780    *
7781    * @return A new builder.
7782    */
7783   public PartList createFormData() {
7784      return formData.copy();
7785   }
7786
7787   /**
7788    * Creates a mutable copy of the path data defined on this client.
7789    *
7790    * <p>
7791    * Used during the construction of {@link RestRequest} objects.
7792    *
7793    * <p>
7794    * Subclasses can override this method to provide their own builder.
7795    *
7796    * @return A new builder.
7797    */
7798   public PartList createPathData() {
7799      return pathData.copy();
7800   }
7801
7802   //-----------------------------------------------------------------------------------------------------------------
7803   // RestCallInterceptor methods
7804   //-----------------------------------------------------------------------------------------------------------------
7805
7806   /**
7807    * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been copied from the client.
7808    *
7809    * <p>
7810    * Subclasses can override this method to intercept the request and perform special modifications.
7811    *
7812    * <h5 class='section'>See Also:</h5><ul>
7813    *    <li class='jm'>{@link Builder#interceptors(Object...)}
7814    * </ul>
7815    *
7816    * @param req The HTTP request.
7817    * @throws RestCallException If any of the interceptors threw an exception.
7818    */
7819   protected void onCallInit(RestRequest req) throws RestCallException {
7820      try {
7821         for (RestCallInterceptor rci : interceptors)
7822            rci.onInit(req);
7823      } catch (RuntimeException | RestCallException e) {
7824         throw e;
7825      } catch (Exception e) {
7826         throw new RestCallException(null, e, "Interceptor threw an exception on init.");
7827      }
7828   }
7829
7830   /**
7831    * Interceptor method called immediately after an HTTP response has been received.
7832    *
7833    * <p>
7834    * Subclasses can override this method to intercept the response and perform special modifications.
7835    *
7836    * <h5 class='section'>See Also:</h5><ul>
7837    *    <li class='jm'>{@link Builder#interceptors(Object...)}
7838    * </ul>
7839    *
7840    * @param req The HTTP request.
7841    * @param res The HTTP response.
7842    * @throws RestCallException If any of the interceptors threw an exception.
7843    */
7844   protected void onCallConnect(RestRequest req, RestResponse res) throws RestCallException {
7845      try {
7846         for (RestCallInterceptor rci : interceptors)
7847            rci.onConnect(req, res);
7848      } catch (RuntimeException | RestCallException e) {
7849         throw e;
7850      } catch (Exception e) {
7851         throw new RestCallException(res, e, "Interceptor threw an exception on connect.");
7852      }
7853   }
7854
7855   /**
7856    * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been set on the request from the client.
7857    *
7858    * <p>
7859    * Subclasses can override this method to handle any cleanup operations.
7860    *
7861    * <h5 class='section'>See Also:</h5><ul>
7862    *    <li class='jm'>{@link Builder#interceptors(Object...)}
7863    * </ul>
7864    *
7865    * @param req The HTTP request.
7866    * @param res The HTTP response.
7867    * @throws RestCallException If any of the interceptors threw an exception.
7868    */
7869   protected void onCallClose(RestRequest req, RestResponse res) throws RestCallException {
7870      try {
7871         for (RestCallInterceptor rci : interceptors)
7872            rci.onClose(req, res);
7873      } catch (RuntimeException | RestCallException e) {
7874         throw e;
7875      } catch (Exception e) {
7876         throw new RestCallException(res, e, "Interceptor threw an exception on close.");
7877      }
7878   }
7879
7880   //------------------------------------------------------------------------------------------------
7881   // Passthrough methods for HttpClient.
7882   //------------------------------------------------------------------------------------------------
7883
7884   /**
7885    * Obtains the parameters for this client.
7886    *
7887    * These parameters will become defaults for all requests being executed with this client, and for the parameters of dependent objects in this client.
7888    *
7889    * @return The default parameters.
7890    * @deprecated Use {@link RequestConfig}.
7891    */
7892   @Deprecated
7893   @Override /* HttpClient */
7894   public HttpParams getParams() {
7895      return httpClient.getParams();
7896   }
7897
7898   /**
7899    * Obtains the connection manager used by this client.
7900    *
7901    * @return The connection manager.
7902    * @deprecated Use {@link HttpClientBuilder}.
7903    */
7904   @Deprecated
7905   @Override /* HttpClient */
7906   public ClientConnectionManager getConnectionManager() {
7907      return httpClient.getConnectionManager();
7908   }
7909
7910   /**
7911    * Returns the connection manager if one was specified in the client builder.
7912    *
7913    * @return The connection manager.  May be <jk>null</jk>.
7914    */
7915   public HttpClientConnectionManager getHttpClientConnectionManager() {
7916      return connectionManager;
7917   }
7918
7919   /**
7920    * Executes HTTP request using the default context.
7921    *
7922    * <h5 class='section'>Notes:</h5><ul>
7923    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7924    * </ul>
7925    *
7926    * @param request The request to execute.
7927    * @return
7928    *    The response to the request.
7929    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
7930    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
7931    *       implementation and configuration of this client.
7932    * @throws IOException In case of a problem or the connection was aborted.
7933    * @throws ClientProtocolException In case of an http protocol error.
7934    */
7935   @Override /* HttpClient */
7936   public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
7937      return httpClient.execute(request);
7938   }
7939
7940   /**
7941    * Executes HTTP request using the given context.
7942    *
7943    * <h5 class='section'>Notes:</h5><ul>
7944    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7945    * </ul>
7946    *
7947    * @param request The request to execute.
7948    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
7949    * @return
7950    *    The response to the request.
7951    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
7952    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
7953    *       implementation and configuration of this client.
7954    * @throws IOException In case of a problem or the connection was aborted.
7955    * @throws ClientProtocolException In case of an http protocol error.
7956    */
7957   @Override /* HttpClient */
7958   public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
7959      return httpClient.execute(request, context);
7960   }
7961
7962   /**
7963    * Executes HTTP request using the default context.
7964    *
7965    * <h5 class='section'>Notes:</h5><ul>
7966    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7967    * </ul>
7968    *
7969    * @param target The target host for the request.
7970    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
7971    *       target or by inspecting the request.
7972    * @param request The request to execute.
7973    * @return The response to the request.
7974    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
7975    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
7976    *       implementation and configuration of this client.
7977    * @throws IOException In case of a problem or the connection was aborted.
7978    * @throws ClientProtocolException In case of an http protocol error.
7979    */
7980   @Override /* HttpClient */
7981   public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException {
7982      return httpClient.execute(target, request);
7983   }
7984
7985   /**
7986    * Executes HTTP request using the given context.
7987    *
7988    * <h5 class='section'>Notes:</h5><ul>
7989    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7990    *    <li class='note'>The {@link #run(HttpHost,HttpRequest,HttpContext)} method has been provided as a wrapper around this method.
7991    *       Subclasses can override these methods for handling requests with and without bodies separately.
7992    *    <li class='note'>The {@link RestCallHandler} interface can also be implemented to intercept this method.
7993    * </ul>
7994    *
7995    * @param target The target host for the request.
7996    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
7997    *       target or by inspecting the request.
7998    * @param request The request to execute.
7999    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
8000    * @return
8001    *    The response to the request.
8002    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
8003    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
8004    *       implementation and configuration of this client.
8005    * @throws IOException In case of a problem or the connection was aborted.
8006    * @throws ClientProtocolException In case of an http protocol error.
8007    */
8008   @Override /* HttpClient */
8009   public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException {
8010      return httpClient.execute(target, request, context);
8011   }
8012
8013   /**
8014    * Executes HTTP request using the default context and processes the response using the given response handler.
8015    *
8016    * <p>
8017    * The content entity associated with the response is fully consumed and the underlying connection is released back
8018    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8019    * from having to manage resource deallocation internally.
8020    *
8021    * <h5 class='section'>Notes:</h5><ul>
8022    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8023    * </ul>
8024    *
8025    * @param request The request to execute.
8026    * @param responseHandler The response handler.
8027    * @return Object returned by response handler.
8028    * @throws IOException In case of a problem or the connection was aborted.
8029    * @throws ClientProtocolException In case of an http protocol error.
8030    */
8031   @Override /* HttpClient */
8032   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
8033      return httpClient.execute(request, responseHandler);
8034   }
8035
8036   /**
8037    * Executes HTTP request using the given context and processes the response using the given response handler.
8038    *
8039    * <p>
8040    * The content entity associated with the response is fully consumed and the underlying connection is released back
8041    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8042    * from having to manage resource deallocation internally.
8043    *
8044    * <h5 class='section'>Notes:</h5><ul>
8045    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8046    * </ul>
8047    *
8048    * @param request The request to execute.
8049    * @param responseHandler The response handler.
8050    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
8051    * @return The response object as generated by the response handler.
8052    * @throws IOException In case of a problem or the connection was aborted.
8053    * @throws ClientProtocolException In case of an http protocol error.
8054    */
8055   @Override /* HttpClient */
8056   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
8057      return httpClient.execute(request, responseHandler, context);
8058   }
8059
8060   /**
8061    * Executes HTTP request to the target using the default context and processes the response using the given response handler.
8062    *
8063    * <p>
8064    * The content entity associated with the response is fully consumed and the underlying connection is released back
8065    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8066    * from having to manage resource deallocation internally.
8067    *
8068    * <h5 class='section'>Notes:</h5><ul>
8069    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8070    * </ul>
8071    *
8072    * @param target
8073    *    The target host for the request.
8074    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default target or by inspecting the request.
8075    * @param request The request to execute.
8076    * @param responseHandler The response handler.
8077    * @return The response object as generated by the response handler.
8078    * @throws IOException In case of a problem or the connection was aborted.
8079    * @throws ClientProtocolException In case of an http protocol error.
8080    */
8081   @Override /* HttpClient */
8082   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
8083      return httpClient.execute(target, request, responseHandler);
8084   }
8085
8086   /**
8087    * Executes a request using the default context and processes the response using the given response handler.
8088    *
8089    * <p>
8090    * The content entity associated with the response is fully consumed and the underlying connection is released back
8091    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8092    * from having to manage resource deallocation internally.
8093    *
8094    * <h5 class='section'>Notes:</h5><ul>
8095    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8096    * </ul>
8097    *
8098    * @param target
8099    *    The target host for the request.
8100    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default target or by inspecting the request.
8101    * @param request The request to execute.
8102    * @param responseHandler The response handler.
8103    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
8104    * @return The response object as generated by the response handler.
8105    * @throws IOException In case of a problem or the connection was aborted.
8106    * @throws ClientProtocolException In case of an http protocol error.
8107    */
8108   @Override /* HttpClient */
8109   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
8110      return httpClient.execute(target, request, responseHandler, context);
8111   }
8112
8113   //-----------------------------------------------------------------------------------------------------------------
8114   // Other methods
8115   //-----------------------------------------------------------------------------------------------------------------
8116
8117   private Pattern absUrlPattern = Pattern.compile("^\\w+\\:\\/\\/.*");
8118
8119   URI toURI(Object x, String rootUrl) throws RestCallException {
8120      try {
8121         if (x instanceof URI)
8122            return (URI)x;
8123         if (x instanceof URL)
8124            ((URL)x).toURI();
8125         if (x instanceof URIBuilder)
8126            return ((URIBuilder)x).build();
8127         String s = x == null ? "" : x.toString();
8128         if (rootUrl != null && ! absUrlPattern.matcher(s).matches()) {
8129            if (s.isEmpty())
8130               s = rootUrl;
8131            else {
8132               StringBuilder sb = new StringBuilder(rootUrl);
8133               if (! s.startsWith("/"))
8134                  sb.append('/');
8135               sb.append(s);
8136               s = sb.toString();
8137            }
8138         }
8139         s = fixUrl(s);
8140         return new URI(s);
8141      } catch (URISyntaxException e) {
8142         throw new RestCallException(null, e, "Invalid URI encountered:  {0}", x);  // Shouldn't happen.
8143      }
8144   }
8145
8146   ExecutorService getExecutorService() {
8147      if (executorService != null)
8148         return executorService;
8149      synchronized(this) {
8150         executorService = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
8151         return executorService;
8152      }
8153   }
8154
8155   /*
8156    * Returns the serializer that best matches the specified content type.
8157    * If no match found or the content type is null, returns the serializer in the list if it's a list of one.
8158    * Returns null if no serializers are defined.
8159    */
8160   Serializer getMatchingSerializer(String mediaType) {
8161      if (serializers.isEmpty())
8162         return null;
8163      if (mediaType != null) {
8164         Serializer s = serializers.getSerializer(mediaType);
8165         if (s != null)
8166            return s;
8167      }
8168      List<Serializer> l = serializers.getSerializers();
8169      return (l.size() == 1 ? l.get(0) : null);
8170   }
8171
8172   boolean hasSerializers() {
8173      return ! serializers.getSerializers().isEmpty();
8174   }
8175
8176   /*
8177    * Returns the parser that best matches the specified content type.
8178    * If no match found or the content type is null, returns the parser in the list if it's a list of one.
8179    * Returns null if no parsers are defined.
8180    */
8181   Parser getMatchingParser(String mediaType) {
8182      if (parsers.isEmpty())
8183         return null;
8184      if (mediaType != null) {
8185         Parser p = parsers.getParser(mediaType);
8186         if (p != null)
8187            return p;
8188      }
8189      List<Parser> l = parsers.getParsers();
8190      return (l.size() == 1 ? l.get(0) : null);
8191   }
8192
8193   boolean hasParsers() {
8194      return ! parsers.getParsers().isEmpty();
8195   }
8196
8197   @SuppressWarnings("unchecked")
8198   <T extends Context> T getInstance(Class<T> c) {
8199      Context o = requestContexts.get(c);
8200      if (o == null) {
8201         if (Serializer.class.isAssignableFrom(c)) {
8202            o = Serializer.createSerializerBuilder((Class<? extends Serializer>)c).beanContext(getBeanContext()).build();
8203         } else if (Parser.class.isAssignableFrom(c)) {
8204            o = Parser.createParserBuilder((Class<? extends Parser>)c).beanContext(getBeanContext()).build();
8205         }
8206         requestContexts.put(c, o);
8207      }
8208      return (T)o;
8209   }
8210
8211   private RestOperation op(String method, Object url, Object body) {
8212      return RestOperation.of(method, url, body);
8213   }
8214
8215   private Reader stringBody(String body) {
8216      return body == null ? null : new StringReader(stringify(body));
8217   }
8218
8219   @Override /* Context */
8220   protected JsonMap properties() {
8221      return filteredMap()
8222         .append("errorCodes", errorCodes)
8223         .append("executorService", executorService)
8224         .append("executorServiceShutdownOnClose", executorServiceShutdownOnClose)
8225         .append("headerData", headerData)
8226         .append("interceptors", interceptors)
8227         .append("keepHttpClientOpen", keepHttpClientOpen)
8228         .append("partParser", partParser)
8229         .append("partSerializer", partSerializer)
8230         .append("queryData", queryData)
8231         .append("rootUrl", rootUrl);
8232   }
8233}