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.mock;
014
015import static org.apache.juneau.internal.CollectionUtils.*;
016import static org.apache.juneau.rest.util.RestUtils.*;
017import static org.apache.juneau.Enablement.*;
018import static org.apache.juneau.common.internal.StringUtils.*;
019import static java.util.Collections.*;
020
021import java.io.*;
022import java.lang.annotation.*;
023import java.lang.reflect.Method;
024import java.net.*;
025import java.util.*;
026import java.util.concurrent.*;
027import java.util.function.*;
028import java.util.logging.*;
029import java.util.zip.*;
030
031import javax.net.ssl.*;
032import jakarta.servlet.http.*;
033
034import org.apache.http.*;
035import org.apache.http.auth.*;
036import org.apache.http.client.*;
037import org.apache.http.client.CookieStore;
038import org.apache.http.client.config.*;
039import org.apache.http.client.entity.*;
040import org.apache.http.client.methods.*;
041import org.apache.http.config.*;
042import org.apache.http.conn.*;
043import org.apache.http.conn.routing.*;
044import org.apache.http.conn.socket.*;
045import org.apache.http.conn.util.*;
046import org.apache.http.cookie.*;
047import org.apache.http.entity.*;
048import org.apache.http.impl.client.*;
049import org.apache.http.message.*;
050import org.apache.http.protocol.*;
051import org.apache.juneau.*;
052import org.apache.juneau.http.remote.*;
053import org.apache.juneau.httppart.*;
054import org.apache.juneau.internal.*;
055import org.apache.juneau.marshaller.*;
056import org.apache.juneau.parser.*;
057import org.apache.juneau.rest.*;
058import org.apache.juneau.rest.annotation.*;
059import org.apache.juneau.rest.client.*;
060import org.apache.juneau.rest.client.RestRequest;
061import org.apache.juneau.rest.client.RestResponse;
062import org.apache.juneau.rest.logger.*;
063import org.apache.juneau.http.header.ContentType;
064import org.apache.juneau.serializer.*;
065import org.apache.juneau.uon.*;
066import org.apache.juneau.utils.*;
067
068/**
069 * Mocked {@link RestClient}.
070 *
071 * <p>
072 *    This class is used for performing serverless unit testing of {@link Rest @Rest}-annotated and {@link Remote @Remote}-annotated classes.
073 *
074 * <p>
075 *    The class itself extends from {@link RestClient} providing it with the rich feature set of that API and combines
076 *    it with the Apache HttpClient {@link HttpClientConnection} interface for processing requests.
077 *  The class converts {@link HttpRequest} objects to instances of {@link MockServletRequest} and {@link MockServletResponse} which are passed directly
078 *  to the call handler on the resource class {@link RestContext#execute(Object,HttpServletRequest,HttpServletResponse)}.
079 *  In effect, you're fully testing your REST API as if it were running in a live servlet container, yet not
080 *  actually having to run in a servlet container.
081 *  All aspects of the client and server side code are tested, yet no servlet container is required.  The actual
082 *  over-the-wire transmission is the only aspect being bypassed.
083 *
084 * <p>
085 * The following shows a simple example of invoking a PUT method on a simple REST interface and asserting the correct status code and response body:
086 *
087 * <h5 class='figure'>Example:</h5>
088 * <p class='bjava'>
089 *    <jk>public class</jk> MockTest {
090 *
091 *       <jc>// A simple bean with one field.</jc>
092 *       <jk>public static class</jk> MyBean {
093 *          <jk>public int</jk> <jf>foo</jf> = 1;
094 *       }
095 *
096 *       <jc>// Our REST resource to test.</jc>
097 *       <jc>// Simply echos the response.</jc>
098 *       <ja>@Rest</ja>(
099 *          serializers=Json5Serializer.<jk>class</jk>,
100 *          parsers=JsonParser.<jk>class</jk>
101 *       )
102 *       <jk>public static class</jk> EchoRest {
103 *
104 *          <ja>@RestPut</ja>(
105 *             path=<js>"/echo"</js>
106 *          )
107 *          <jk>public</jk> MyBean echo(<ja>@Content</ja> MyBean <jv>bean</jv>) {
108 *             <jk>return</jk> <jv>bean</jv>;
109 *          }
110 *       }
111 *
112 *       <jc>// Our JUnit test.</jc>
113 *       <ja>@Test</ja>
114 *       <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
115 *
116 *          MyBean <jv>myBean</jv> = <jk>new</jk> MyBean();
117 *
118 *          <jc>// Do a round-trip on the bean through the REST interface</jc>
119 *          <jv>myBean</jv> = MockRestClient
120 *             .<jsm>create</jsm>(EchoRest.<jk>class</jk>)
121 *             .json5()
122 *             .build()
123 *             .put(<js>"/echo"</js>, <jv>myBean</jv>)
124 *             .run()
125 *             .assertStatus().is(200)
126 *             .assertContent().is(<js>"{foo:1}"</js>)
127 *             .getContent().as(MyBean.<jk>class</jk>);
128 *
129 *          <jsm>assertEquals</jsm>(1, <jv>myBean</jv>.<jf>foo</jf>);
130 *       }
131 *    }
132 * </p>
133 * <p>
134 *    Breaking apart the fluent method call above will help you understand how this works.
135 *
136 * <p class='bjava'>
137 *    <ja>@Test</ja>
138 *    <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
139 *
140 *       <jc>// Instantiate our mock client.</jc>
141 *       MockRestClient <jv>client</jv> = MockRestClient
142 *          .<jsm>create</jsm>(EchoRest.<jk>class</jk>)
143 *          .json5()
144 *          .build();
145 *
146 *       <jc>// Create a request.</jc>
147 *       RestRequest <jv>req</jv> = <jv>client</jv>.put(<js>"/echo"</js>, <jv>bean</jv>);
148 *
149 *       <jc>// Execute it (by calling RestCallHandler.service(...) and then returning the response object).</jc>
150 *       RestResponse <jv>res</jv> = <jv>req</jv>.run();
151 *
152 *       <jc>// Run assertion tests on the results.</jc>
153 *       <jv>res</jv>.assertStatus().is(200);
154 *       <jv>res</jv>.assertContent().is(<js>"'foo'"</js>);
155 *
156 *       <jc>// Convert the content of the response to a bean.</jc>
157 *       <jv>bean</jv> = <jv>res</jv>.getContent().as(MyBean.<jk>class</jk>);
158 *    }
159 * </p>
160 *
161 * <p>
162 *    The <c>create(Object)</c> method can take in either <c>Class</c> objects or pre-instantiated beans.
163 *    The latter is particularly useful for testing Spring beans.
164 *
165 * <p>
166 *    The {@link MockRestRequest} object has convenience methods provided to allow you to set any properties
167 *    directly on the underlying {@link HttpServletRequest} object.  The following example shows how
168 *    this can be used to directly set roles on the request object to perform security testing.
169 *
170 * <h5 class='figure'>Example:</h5>
171 * <p class='bjava'>
172 *    <ja>@Rest</ja>(roleGuard=<js>"ADMIN"</js>)
173 *    <jk>public class</jk> A {
174 *       <ja>@RestGet</ja>
175 *       <jk>public</jk> String get() {
176 *          <jk>return</jk> <js>"OK"</js>;
177 *       }
178 *    }
179 *
180 *    <ja>@Test</ja>
181 *    <jk>public void</jk> mytest() <jk>throws</jk> Exception {
182 *       MockRestClient <jv>client</jv> = MockRestClient.<jsm>build</jsm>(A.<jk>class</jk>);
183 *
184 *       <jc>// Admin user should get 200, but anyone else should get 403-Unauthorized.</jc>
185 *       <jv>client</jv>.get().roles(<js>"ADMIN"</js>).run().assertStatus().is(200);
186 *       <jv>client</jv>.get().roles(<js>"USER"</js>).run().assertStatus().is(403);
187 *    }
188 * </p>
189 *
190 * <p>
191 *    Debug mode is provided that will cause your HTTP requests and responses to be sent to the console:
192 *
193 * <h5 class='figure'>Example:</h5>
194 * <p class='bjava'>
195 *    MockRestClient <jv>client</jv> = MockRestClient
196 *       .<jsm>create</jsm>(MyRest.<jk>class</jk>)
197 *       .debug()
198 *       .json5()
199 *       .build();
200 * </p>
201 *
202 * <p>
203 *    The class can also be used for testing of {@link Remote @Remote}-annotated interfaces against {@link Rest @Rest}-annotated resources.
204 *
205 * <h5 class='figure'>Example:</h5>
206 * <p class='bjava'>
207 *    <jc>// Our remote resource to test.</jc>
208 *    <ja>@Remote</ja>
209 *    <jk>public interface</jk> MyRemoteInterface {
210 *
211 *       <ja>@RemoteGet</ja>(<js>"/echoQuery"</js>)
212 *       <jk>public int</jk> echoQuery(<ja>@Query</ja>(name=<js>"id"</js>) <jk>int</jk> <jv>id</jv>);
213 *    }
214 *
215 *    <jc>// Our mocked-up REST interface to test against.</jc>
216 *    <ja>@Rest</ja>
217 *    <jk>public class</jk> MyRest {
218 *
219 *       <ja>@RestGet</ja>(path=<js>"/echoQuery"</js>)
220 *       <jk>public int</jk> echoQuery(<ja>@Query</ja>(<js>"id"</js>) String <jv>id</jv>) {
221 *          <jk>return</jk> <jv>id</jv>;
222 *       }
223 *    }
224 *
225 *    <ja>@Test</ja>
226 *    <jk>public void</jk> testProxy() {
227 *       MyRemoteInterface <jv>client</jv> = MockRestClient
228 *          .create(MyRest.<jk>class</jk>)
229 *          .json()
230 *          .build()
231 *          .getRemote(MyRemoteInterface.<jk>class</jk>);
232 *
233 *       <jsm>assertEquals</jsm>(123, <jv>client</jv>.echoQuery(123));
234 *    }
235 * </p>
236 *
237 * <h5 class='section'>Notes:</h5><ul>
238 *    <li class='note'>This class is thread safe and reusable.
239 * </ul>
240 *
241 * <h5 class='section'>See Also:</h5><ul>
242 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-mock">juneau-rest-mock</a>
243 * </ul>
244 */
245public class MockRestClient extends RestClient implements HttpClientConnection {
246
247   //-------------------------------------------------------------------------------------------------------------------
248   // Static
249   //-------------------------------------------------------------------------------------------------------------------
250
251   private static Map<Class<?>,RestContext> REST_CONTEXTS = new ConcurrentHashMap<>();
252
253   /**
254    * Creates a new {@link org.apache.juneau.rest.client.RestClient.Builder} configured with the specified REST implementation bean or bean class.
255    *
256    * @param impl
257    *    The REST bean or bean class annotated with {@link Rest @Rest}.
258    *    <br>If a class, it must have a no-arg constructor.
259    * @return A new builder.
260    */
261   public static Builder create(Object impl) {
262      return new Builder().restBean(impl);
263   }
264
265   /**
266    * Creates a new {@link org.apache.juneau.rest.client.RestClient.Builder} configured with the specified REST implementation bean or bean class.
267    *
268    * <p>
269    * Same as {@link #create(Object)} but HTTP 400+ codes don't trigger {@link RestCallException RestCallExceptions}.
270    *
271    * @param impl
272    *    The REST bean or bean class annotated with {@link Rest @Rest}.
273    *    <br>If a class, it must have a no-arg constructor.
274    * @return A new builder.
275    */
276   public static Builder createLax(Object impl) {
277      return new Builder().restBean(impl).ignoreErrors().noTrace();
278   }
279
280   /**
281    * Creates a new {@link RestClient} with no registered serializer or parser.
282    *
283    * <p>
284    * Equivalent to calling:
285    * <p class='bjava'>
286    *    MockRestClient.<jsm>create</jsm>(<jv>impl</jv>).build();
287    * </p>
288    *
289    * @param impl
290    *    The REST bean or bean class annotated with {@link Rest @Rest}.
291    *    <br>If a class, it must have a no-arg constructor.
292    * @return A new builder.
293    */
294   public static MockRestClient build(Object impl) {
295      return create(impl).build();
296   }
297
298   /**
299    * Creates a new {@link RestClient} with no registered serializer or parser.
300    *
301    * <p>
302    * Same as {@link #build(Object)} but HTTP 400+ codes don't trigger {@link RestCallException RestCallExceptions}.
303    *
304    * <p>
305    * Equivalent to calling:
306    * <p class='bjava'>
307    *    MockRestClient.<jsm>create</jsm>(<jv>impl</jv>).ignoreErrors().noTrace().build();
308    * </p>
309    *
310    * @param impl
311    *    The REST bean or bean class annotated with {@link Rest @Rest}.
312    *    <br>If a class, it must have a no-arg constructor.
313    * @return A new builder.
314    */
315   public static MockRestClient buildLax(Object impl) {
316      return create(impl).ignoreErrors().noTrace().build();
317   }
318
319   /**
320    * Creates a new {@link RestClient} with JSON marshalling support.
321    *
322    * <p>
323    * Equivalent to calling:
324    * <p class='bjava'>
325    *    MockRestClient.<jsm>create</jsm>(<jv>impl</jv>).json().build();
326    * </p>
327    *
328    * @param impl
329    *    The REST bean or bean class annotated with {@link Rest @Rest}.
330    *    <br>If a class, it must have a no-arg constructor.
331    * @return A new builder.
332    */
333   public static MockRestClient buildJson(Object impl) {
334      return create(impl).json().build();
335   }
336
337   /**
338    * Creates a new {@link RestClient} with JSON marshalling support.
339    *
340    * <p>
341    * Same as {@link #buildJson(Object)} but HTTP 400+ codes don't trigger {@link RestCallException RestCallExceptions}.
342    *
343    * <p>
344    * Equivalent to calling:
345    * <p class='bjava'>
346    *    MockRestClient.<jsm>create</jsm>(<jv>impl</jv>).json().ignoreErrors().build();
347    * </p>
348    *
349    * @param impl
350    *    The REST bean or bean class annotated with {@link Rest @Rest}.
351    *    <br>If a class, it must have a no-arg constructor.
352    * @return A new builder.
353    */
354   public static MockRestClient buildJsonLax(Object impl) {
355      return create(impl).json().ignoreErrors().noTrace().build();
356   }
357
358   /**
359    * Creates a new {@link RestClient} with Simplified-JSON marshalling support.
360    *
361    * <p>
362    * Equivalent to calling:
363    * <p class='bjava'>
364    *    MockRestClient.<jsm>create</jsm>(<jv>impl</jv>).json().build();
365    * </p>
366    *
367    * @param impl
368    *    The REST bean or bean class annotated with {@link Rest @Rest}.
369    *    <br>If a class, it must have a no-arg constructor.
370    * @return A new builder.
371    */
372   public static MockRestClient buildJson5(Object impl) {
373      return create(impl).json5().build();
374   }
375
376   /**
377    * Creates a new {@link RestClient} with Simplified-JSON marshalling support.
378    *
379    * <p>
380    * Same as {@link #buildJson5(Object)} but HTTP 400+ codes don't trigger {@link RestCallException RestCallExceptions}.
381    *
382    * <p>
383    * Equivalent to calling:
384    * <p class='bjava'>
385    *    MockRestClient.<jsm>create</jsm>(<jv>impl</jv>).json().ignoreErrors().build();
386    * </p>
387    *
388    * @param impl
389    *    The REST bean or bean class annotated with {@link Rest @Rest}.
390    *    <br>If a class, it must have a no-arg constructor.
391    * @return A new builder.
392    */
393   public static MockRestClient buildJson5Lax(Object impl) {
394      return create(impl).json5().ignoreErrors().noTrace().build();
395   }
396
397   //-------------------------------------------------------------------------------------------------------------------
398   // Builder
399   //-------------------------------------------------------------------------------------------------------------------
400
401   /**
402    * Builder class.
403    */
404   @FluentSetters(ignore="debug")
405   public static class Builder extends RestClient.Builder {
406
407      Object restBean;
408      String contextPath, servletPath;
409      RestContext restContext;
410      Map<String,String> pathVars;
411
412      /**
413       * No-arg constructor.
414       *
415       * <p>
416       * Provided so that this class can be easily subclassed.
417       */
418      protected Builder() {
419         connectionManager(new MockHttpClientConnectionManager());
420      }
421
422      @Override /* Context.Builder */
423      public Builder copy() {
424         throw new NoSuchMethodError("Not implemented.");
425      }
426
427      /**
428       * Specifies the {@link Rest}-annotated bean class or instance to test against.
429       *
430       * @param value The {@link Rest}-annotated bean class or instance.
431       * @return This object.
432       */
433      public Builder restBean(Object value) {
434         restBean = value;
435         return this;
436      }
437
438      /**
439       * Specifies the {@link RestContext} created for the REST bean.
440       *
441       * @param value The {@link RestContext} created for the REST bean.
442       * @return This object.
443       */
444      public Builder restContext(RestContext value) {
445         restContext = value;
446         return this;
447      }
448
449      /**
450       * Identifies the context path for the REST resource.
451       *
452       * <p>
453       *    This value is used to deconstruct the request URL and set the appropriate URL getters on the {@link HttpServletRequest}
454       *    object correctly.
455       *
456       * <p>
457       *    Should either be a value such as <js>"/foo"</js> or an empty string.
458       *
459       * <p>
460       *    The following fixes are applied to non-conforming strings.
461       * <ul>
462       *    <li><jk>nulls</jk> and <js>"/"</js> are converted to empty strings.
463       *    <li>Trailing slashes are trimmed.
464       *    <li>Leading slash is added if needed.
465       * </ul>
466       *
467       * @param value The context path.
468       * @return This object.
469       */
470      public Builder contextPath(String value) {
471         contextPath = toValidContextPath(value);
472         return this;
473      }
474
475      /**
476       * Identifies the servlet path for the REST resource.
477       *
478       * <p>
479       *    This value is used to deconstruct the request URL and set the appropriate URL getters on the {@link HttpServletRequest}
480       *    object correctly.
481       *
482       * <p>
483       *    Should either be a value such as <js>"/foo"</js> or an empty string.
484       *
485       * <p>
486       *    The following fixes are applied to non-conforming strings.
487       * <ul>
488       *    <li><jk>nulls</jk> and <js>"/"</js> are converted to empty strings.
489       *    <li>Trailing slashes are trimmed.
490       *    <li>Leading slash is added if needed.
491       * </ul>
492       *
493       * @param value The context path.
494       * @return This object.
495       */
496      public Builder servletPath(String value) {
497         servletPath = toValidContextPath(value);
498         return this;
499      }
500
501      /**
502       * Add resolved path variables to this client.
503       *
504       * <p>
505       * Allows you to add resolved parent path variables when performing tests on child resource classes.
506       *
507       * <h5 class='section'>Example:</h5>
508       * <p class='bjava'>
509       *    <jc>// A parent class with a path variable.</jc>
510       *    <ja>@Rest</ja>(
511       *       path=<js>"/parent/{foo}"</js>,
512       *       children={
513       *          Child.<jk>class</jk>
514       *       }
515       *    )
516       *    <jk>public class</jk> Parent { ... }
517       *
518       *    <jc>// A child class that uses the parent path variable.</jc>
519       *    <ja>@Rest</ja>
520       *    <jk>public class</jk> Child {
521       *
522       *       <jk>@RestGet</jk>
523       *       <jk>public</jk> String get(<ja>@Path</ja>(<js>"foo"</js>) String <jv>foo</jv>) {
524       *          <jk>return</jk> <jv>foo</jv>;
525       *       }
526       *    }
527       * </p>
528       * <p class='bjava'>
529       *    <jc>// Test the method that uses the parent path variable.</jc>
530       *    MockRestClient
531       *       .<jsm>create</jsm>(Child.<jk>class</jk>)
532       *       .json5()
533       *       .pathVars(<js>"foo"</js>,<js>"bar"</js>)
534       *       .build()
535       *       .get(<js>"/"</js>)
536       *       .run()
537       *       .assertStatus().asCode().is(200)
538       *       .assertContent().is(<js>"bar"</js>);
539       * </p>
540       *
541       * <review>Needs review</review>
542       *
543       * @param value The path variables.
544       * @return This object.
545       * @see MockServletRequest#pathVars(Map)
546       */
547      public Builder pathVars(Map<String,String> value) {
548         pathVars = value;
549         return this;
550      }
551
552      /**
553       * Add resolved path variables to this client.
554       *
555       * <p>
556       * Identical to {@link #pathVars(Map)} but allows you to specify as a list of key/value pairs.
557       *
558       * @param pairs The key/value pairs.  Must be an even number of parameters.
559       * @return This object.
560       */
561      public Builder pathVars(String...pairs) {
562         return pathVars(mapBuilder(String.class,String.class).addPairs((Object[])pairs).build());
563      }
564
565      /**
566       * Suppress logging on this client.
567       *
568       * @return This object.
569       */
570      public Builder suppressLogging() {
571         return logRequests(DetailLevel.NONE, null, null);
572      }
573
574      @Override /* Context.Builder */
575      public Builder debug() {
576         header("Debug", "true");
577         super.debug();
578         return this;
579      }
580
581      @Override /* Context.Builder */
582      public MockRestClient build() {
583         return build(MockRestClient.class);
584      }
585
586      // <FluentSetters>
587
588      @Override /* GENERATED - org.apache.juneau.Context.Builder */
589      public Builder annotations(Annotation...values) {
590         super.annotations(values);
591         return this;
592      }
593
594      @Override /* GENERATED - org.apache.juneau.Context.Builder */
595      public Builder apply(AnnotationWorkList work) {
596         super.apply(work);
597         return this;
598      }
599
600      @Override /* GENERATED - org.apache.juneau.Context.Builder */
601      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
602         super.applyAnnotations(fromClasses);
603         return this;
604      }
605
606      @Override /* GENERATED - org.apache.juneau.Context.Builder */
607      public Builder applyAnnotations(Method...fromMethods) {
608         super.applyAnnotations(fromMethods);
609         return this;
610      }
611
612      @Override /* GENERATED - org.apache.juneau.Context.Builder */
613      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
614         super.cache(value);
615         return this;
616      }
617
618      @Override /* GENERATED - org.apache.juneau.Context.Builder */
619      public Builder impl(Context value) {
620         super.impl(value);
621         return this;
622      }
623
624      @Override /* GENERATED - org.apache.juneau.Context.Builder */
625      public Builder type(Class<? extends org.apache.juneau.Context> value) {
626         super.type(value);
627         return this;
628      }
629
630      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
631      public Builder beanClassVisibility(Visibility value) {
632         super.beanClassVisibility(value);
633         return this;
634      }
635
636      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
637      public Builder beanConstructorVisibility(Visibility value) {
638         super.beanConstructorVisibility(value);
639         return this;
640      }
641
642      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
643      public Builder beanContext(BeanContext value) {
644         super.beanContext(value);
645         return this;
646      }
647
648      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
649      public Builder beanContext(BeanContext.Builder value) {
650         super.beanContext(value);
651         return this;
652      }
653
654      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
655      public Builder beanDictionary(java.lang.Class<?>...values) {
656         super.beanDictionary(values);
657         return this;
658      }
659
660      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
661      public Builder beanFieldVisibility(Visibility value) {
662         super.beanFieldVisibility(value);
663         return this;
664      }
665
666      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
667      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
668         super.beanInterceptor(on, value);
669         return this;
670      }
671
672      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
673      public Builder beanMapPutReturnsOldValue() {
674         super.beanMapPutReturnsOldValue();
675         return this;
676      }
677
678      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
679      public Builder beanMethodVisibility(Visibility value) {
680         super.beanMethodVisibility(value);
681         return this;
682      }
683
684      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
685      public Builder beanProperties(Map<String,Object> values) {
686         super.beanProperties(values);
687         return this;
688      }
689
690      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
691      public Builder beanProperties(Class<?> beanClass, String properties) {
692         super.beanProperties(beanClass, properties);
693         return this;
694      }
695
696      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
697      public Builder beanProperties(String beanClassName, String properties) {
698         super.beanProperties(beanClassName, properties);
699         return this;
700      }
701
702      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
703      public Builder beanPropertiesExcludes(Map<String,Object> values) {
704         super.beanPropertiesExcludes(values);
705         return this;
706      }
707
708      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
709      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
710         super.beanPropertiesExcludes(beanClass, properties);
711         return this;
712      }
713
714      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
715      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
716         super.beanPropertiesExcludes(beanClassName, properties);
717         return this;
718      }
719
720      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
721      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
722         super.beanPropertiesReadOnly(values);
723         return this;
724      }
725
726      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
727      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
728         super.beanPropertiesReadOnly(beanClass, properties);
729         return this;
730      }
731
732      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
733      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
734         super.beanPropertiesReadOnly(beanClassName, properties);
735         return this;
736      }
737
738      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
739      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
740         super.beanPropertiesWriteOnly(values);
741         return this;
742      }
743
744      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
745      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
746         super.beanPropertiesWriteOnly(beanClass, properties);
747         return this;
748      }
749
750      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
751      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
752         super.beanPropertiesWriteOnly(beanClassName, properties);
753         return this;
754      }
755
756      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
757      public Builder beansRequireDefaultConstructor() {
758         super.beansRequireDefaultConstructor();
759         return this;
760      }
761
762      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
763      public Builder beansRequireSerializable() {
764         super.beansRequireSerializable();
765         return this;
766      }
767
768      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
769      public Builder beansRequireSettersForGetters() {
770         super.beansRequireSettersForGetters();
771         return this;
772      }
773
774      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
775      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
776         super.dictionaryOn(on, values);
777         return this;
778      }
779
780      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
781      public Builder disableBeansRequireSomeProperties() {
782         super.disableBeansRequireSomeProperties();
783         return this;
784      }
785
786      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
787      public Builder disableIgnoreMissingSetters() {
788         super.disableIgnoreMissingSetters();
789         return this;
790      }
791
792      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
793      public Builder disableIgnoreTransientFields() {
794         super.disableIgnoreTransientFields();
795         return this;
796      }
797
798      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
799      public Builder disableIgnoreUnknownNullBeanProperties() {
800         super.disableIgnoreUnknownNullBeanProperties();
801         return this;
802      }
803
804      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
805      public Builder disableInterfaceProxies() {
806         super.disableInterfaceProxies();
807         return this;
808      }
809
810      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
811      public <T> Builder example(Class<T> pojoClass, T o) {
812         super.example(pojoClass, o);
813         return this;
814      }
815
816      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
817      public <T> Builder example(Class<T> pojoClass, String json) {
818         super.example(pojoClass, json);
819         return this;
820      }
821
822      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
823      public Builder findFluentSetters() {
824         super.findFluentSetters();
825         return this;
826      }
827
828      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
829      public Builder findFluentSetters(Class<?> on) {
830         super.findFluentSetters(on);
831         return this;
832      }
833
834      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
835      public Builder ignoreInvocationExceptionsOnGetters() {
836         super.ignoreInvocationExceptionsOnGetters();
837         return this;
838      }
839
840      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
841      public Builder ignoreInvocationExceptionsOnSetters() {
842         super.ignoreInvocationExceptionsOnSetters();
843         return this;
844      }
845
846      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
847      public Builder ignoreUnknownBeanProperties() {
848         super.ignoreUnknownBeanProperties();
849         return this;
850      }
851
852      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
853      public Builder ignoreUnknownEnumValues() {
854         super.ignoreUnknownEnumValues();
855         return this;
856      }
857
858      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
859      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
860         super.implClass(interfaceClass, implClass);
861         return this;
862      }
863
864      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
865      public Builder implClasses(Map<Class<?>,Class<?>> values) {
866         super.implClasses(values);
867         return this;
868      }
869
870      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
871      public Builder interfaceClass(Class<?> on, Class<?> value) {
872         super.interfaceClass(on, value);
873         return this;
874      }
875
876      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
877      public Builder interfaces(java.lang.Class<?>...value) {
878         super.interfaces(value);
879         return this;
880      }
881
882      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
883      public Builder locale(Locale value) {
884         super.locale(value);
885         return this;
886      }
887
888      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
889      public Builder mediaType(MediaType value) {
890         super.mediaType(value);
891         return this;
892      }
893
894      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
895      public Builder notBeanClasses(java.lang.Class<?>...values) {
896         super.notBeanClasses(values);
897         return this;
898      }
899
900      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
901      public Builder notBeanPackages(String...values) {
902         super.notBeanPackages(values);
903         return this;
904      }
905
906      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
907      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
908         super.propertyNamer(value);
909         return this;
910      }
911
912      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
913      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
914         super.propertyNamer(on, value);
915         return this;
916      }
917
918      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
919      public Builder sortProperties() {
920         super.sortProperties();
921         return this;
922      }
923
924      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
925      public Builder sortProperties(java.lang.Class<?>...on) {
926         super.sortProperties(on);
927         return this;
928      }
929
930      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
931      public Builder stopClass(Class<?> on, Class<?> value) {
932         super.stopClass(on, value);
933         return this;
934      }
935
936      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
937      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
938         super.swap(normalClass, swappedClass, swapFunction);
939         return this;
940      }
941
942      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
943      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
944         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
945         return this;
946      }
947
948      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
949      public Builder swaps(java.lang.Class<?>...values) {
950         super.swaps(values);
951         return this;
952      }
953
954      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
955      public Builder timeZone(TimeZone value) {
956         super.timeZone(value);
957         return this;
958      }
959
960      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
961      public Builder typeName(Class<?> on, String value) {
962         super.typeName(on, value);
963         return this;
964      }
965
966      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
967      public Builder typePropertyName(String value) {
968         super.typePropertyName(value);
969         return this;
970      }
971
972      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
973      public Builder typePropertyName(Class<?> on, String value) {
974         super.typePropertyName(on, value);
975         return this;
976      }
977
978      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
979      public Builder useEnumNames() {
980         super.useEnumNames();
981         return this;
982      }
983
984      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
985      public Builder useJavaBeanIntrospector() {
986         super.useJavaBeanIntrospector();
987         return this;
988      }
989
990      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
991      public Builder accept(String value) {
992         super.accept(value);
993         return this;
994      }
995
996      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
997      public Builder acceptCharset(String value) {
998         super.acceptCharset(value);
999         return this;
1000      }
1001
1002      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1003      public Builder addBeanTypes() {
1004         super.addBeanTypes();
1005         return this;
1006      }
1007
1008      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1009      public Builder addInterceptorFirst(HttpRequestInterceptor itcp) {
1010         super.addInterceptorFirst(itcp);
1011         return this;
1012      }
1013
1014      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1015      public Builder addInterceptorFirst(HttpResponseInterceptor itcp) {
1016         super.addInterceptorFirst(itcp);
1017         return this;
1018      }
1019
1020      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1021      public Builder addInterceptorLast(HttpRequestInterceptor itcp) {
1022         super.addInterceptorLast(itcp);
1023         return this;
1024      }
1025
1026      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1027      public Builder addInterceptorLast(HttpResponseInterceptor itcp) {
1028         super.addInterceptorLast(itcp);
1029         return this;
1030      }
1031
1032      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1033      public Builder addRootType() {
1034         super.addRootType();
1035         return this;
1036      }
1037
1038      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1039      public Builder backoffManager(BackoffManager backoffManager) {
1040         super.backoffManager(backoffManager);
1041         return this;
1042      }
1043
1044      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1045      public Builder basicAuth(String host, int port, String user, String pw) {
1046         super.basicAuth(host, port, user, pw);
1047         return this;
1048      }
1049
1050      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1051      public Builder callHandler(Class<? extends org.apache.juneau.rest.client.RestCallHandler> value) {
1052         super.callHandler(value);
1053         return this;
1054      }
1055
1056      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1057      public Builder clientVersion(String value) {
1058         super.clientVersion(value);
1059         return this;
1060      }
1061
1062      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1063      public Builder connectionBackoffStrategy(ConnectionBackoffStrategy connectionBackoffStrategy) {
1064         super.connectionBackoffStrategy(connectionBackoffStrategy);
1065         return this;
1066      }
1067
1068      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1069      public Builder connectionManager(HttpClientConnectionManager value) {
1070         super.connectionManager(value);
1071         return this;
1072      }
1073
1074      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1075      public Builder connectionManagerShared(boolean shared) {
1076         super.connectionManagerShared(shared);
1077         return this;
1078      }
1079
1080      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1081      public Builder connectionReuseStrategy(ConnectionReuseStrategy reuseStrategy) {
1082         super.connectionReuseStrategy(reuseStrategy);
1083         return this;
1084      }
1085
1086      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1087      public Builder connectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) {
1088         super.connectionTimeToLive(connTimeToLive, connTimeToLiveTimeUnit);
1089         return this;
1090      }
1091
1092      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1093      public Builder console(PrintStream value) {
1094         super.console(value);
1095         return this;
1096      }
1097
1098      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1099      public Builder contentDecoderRegistry(Map<String,InputStreamFactory> contentDecoderMap) {
1100         super.contentDecoderRegistry(contentDecoderMap);
1101         return this;
1102      }
1103
1104      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1105      public Builder contentType(String value) {
1106         super.contentType(value);
1107         return this;
1108      }
1109
1110      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1111      public Builder debugOutputLines(int value) {
1112         super.debugOutputLines(value);
1113         return this;
1114      }
1115
1116      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1117      public Builder defaultAuthSchemeRegistry(Lookup<AuthSchemeProvider> authSchemeRegistry) {
1118         super.defaultAuthSchemeRegistry(authSchemeRegistry);
1119         return this;
1120      }
1121
1122      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1123      public Builder defaultConnectionConfig(ConnectionConfig config) {
1124         super.defaultConnectionConfig(config);
1125         return this;
1126      }
1127
1128      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1129      public Builder defaultCookieSpecRegistry(Lookup<CookieSpecProvider> cookieSpecRegistry) {
1130         super.defaultCookieSpecRegistry(cookieSpecRegistry);
1131         return this;
1132      }
1133
1134      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1135      public Builder defaultCookieStore(CookieStore cookieStore) {
1136         super.defaultCookieStore(cookieStore);
1137         return this;
1138      }
1139
1140      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1141      public Builder defaultCredentialsProvider(CredentialsProvider credentialsProvider) {
1142         super.defaultCredentialsProvider(credentialsProvider);
1143         return this;
1144      }
1145
1146      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1147      public Builder defaultRequestConfig(RequestConfig config) {
1148         super.defaultRequestConfig(config);
1149         return this;
1150      }
1151
1152      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1153      public Builder defaultSocketConfig(SocketConfig config) {
1154         super.defaultSocketConfig(config);
1155         return this;
1156      }
1157
1158      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1159      public Builder detectLeaks() {
1160         super.detectLeaks();
1161         return this;
1162      }
1163
1164      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1165      public Builder detectRecursions() {
1166         super.detectRecursions();
1167         return this;
1168      }
1169
1170      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1171      public Builder disableAuthCaching() {
1172         super.disableAuthCaching();
1173         return this;
1174      }
1175
1176      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1177      public Builder disableAutomaticRetries() {
1178         super.disableAutomaticRetries();
1179         return this;
1180      }
1181
1182      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1183      public Builder disableConnectionState() {
1184         super.disableConnectionState();
1185         return this;
1186      }
1187
1188      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1189      public Builder disableContentCompression() {
1190         super.disableContentCompression();
1191         return this;
1192      }
1193
1194      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1195      public Builder disableCookieManagement() {
1196         super.disableCookieManagement();
1197         return this;
1198      }
1199
1200      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1201      public Builder disableRedirectHandling() {
1202         super.disableRedirectHandling();
1203         return this;
1204      }
1205
1206      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1207      public Builder errorCodes(Predicate<Integer> value) {
1208         super.errorCodes(value);
1209         return this;
1210      }
1211
1212      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1213      public Builder evictExpiredConnections() {
1214         super.evictExpiredConnections();
1215         return this;
1216      }
1217
1218      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1219      public Builder evictIdleConnections(long maxIdleTime, TimeUnit maxIdleTimeUnit) {
1220         super.evictIdleConnections(maxIdleTime, maxIdleTimeUnit);
1221         return this;
1222      }
1223
1224      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1225      public Builder executorService(ExecutorService executorService, boolean shutdownOnClose) {
1226         super.executorService(executorService, shutdownOnClose);
1227         return this;
1228      }
1229
1230      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1231      public Builder formData(NameValuePair...parts) {
1232         super.formData(parts);
1233         return this;
1234      }
1235
1236      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1237      public Builder formData(String name, String value) {
1238         super.formData(name, value);
1239         return this;
1240      }
1241
1242      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1243      public Builder formData(String name, Supplier<String> value) {
1244         super.formData(name, value);
1245         return this;
1246      }
1247
1248      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1249      public Builder header(String name, String value) {
1250         super.header(name, value);
1251         return this;
1252      }
1253
1254      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1255      public Builder header(String name, Supplier<String> value) {
1256         super.header(name, value);
1257         return this;
1258      }
1259
1260      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1261      public Builder headers(Header...parts) {
1262         super.headers(parts);
1263         return this;
1264      }
1265
1266      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1267      public Builder html() {
1268         super.html();
1269         return this;
1270      }
1271
1272      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1273      public Builder htmlDoc() {
1274         super.htmlDoc();
1275         return this;
1276      }
1277
1278      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1279      public Builder htmlStrippedDoc() {
1280         super.htmlStrippedDoc();
1281         return this;
1282      }
1283
1284      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1285      public Builder httpClient(CloseableHttpClient value) {
1286         super.httpClient(value);
1287         return this;
1288      }
1289
1290      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1291      public Builder httpClientBuilder(HttpClientBuilder value) {
1292         super.httpClientBuilder(value);
1293         return this;
1294      }
1295
1296      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1297      public Builder httpProcessor(HttpProcessor httpprocessor) {
1298         super.httpProcessor(httpprocessor);
1299         return this;
1300      }
1301
1302      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1303      public Builder ignoreErrors() {
1304         super.ignoreErrors();
1305         return this;
1306      }
1307
1308      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1309      public Builder ignoreRecursions() {
1310         super.ignoreRecursions();
1311         return this;
1312      }
1313
1314      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1315      public Builder initialDepth(int value) {
1316         super.initialDepth(value);
1317         return this;
1318      }
1319
1320      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1321      public Builder interceptors(java.lang.Class<?>...values) throws Exception{
1322         super.interceptors(values);
1323         return this;
1324      }
1325
1326      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1327      public Builder interceptors(Object...value) {
1328         super.interceptors(value);
1329         return this;
1330      }
1331
1332      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1333      public Builder json() {
1334         super.json();
1335         return this;
1336      }
1337
1338      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1339      public Builder keepAliveStrategy(ConnectionKeepAliveStrategy keepAliveStrategy) {
1340         super.keepAliveStrategy(keepAliveStrategy);
1341         return this;
1342      }
1343
1344      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1345      public Builder keepHttpClientOpen() {
1346         super.keepHttpClientOpen();
1347         return this;
1348      }
1349
1350      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1351      public Builder keepNullProperties() {
1352         super.keepNullProperties();
1353         return this;
1354      }
1355
1356      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1357      public Builder logRequests(DetailLevel detail, Level level, BiPredicate<RestRequest,RestResponse> test) {
1358         super.logRequests(detail, level, test);
1359         return this;
1360      }
1361
1362      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1363      public Builder logToConsole() {
1364         super.logToConsole();
1365         return this;
1366      }
1367
1368      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1369      public Builder logger(Logger value) {
1370         super.logger(value);
1371         return this;
1372      }
1373
1374      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1375      public Builder marshaller(Marshaller value) {
1376         super.marshaller(value);
1377         return this;
1378      }
1379
1380      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1381      public Builder marshallers(Marshaller...value) {
1382         super.marshallers(value);
1383         return this;
1384      }
1385
1386      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1387      public Builder maxConnPerRoute(int maxConnPerRoute) {
1388         super.maxConnPerRoute(maxConnPerRoute);
1389         return this;
1390      }
1391
1392      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1393      public Builder maxConnTotal(int maxConnTotal) {
1394         super.maxConnTotal(maxConnTotal);
1395         return this;
1396      }
1397
1398      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1399      public Builder maxDepth(int value) {
1400         super.maxDepth(value);
1401         return this;
1402      }
1403
1404      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1405      public Builder maxIndent(int value) {
1406         super.maxIndent(value);
1407         return this;
1408      }
1409
1410      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1411      public Builder mediaType(String value) {
1412         super.mediaType(value);
1413         return this;
1414      }
1415
1416      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1417      public Builder msgPack() {
1418         super.msgPack();
1419         return this;
1420      }
1421
1422      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1423      public Builder noTrace() {
1424         super.noTrace();
1425         return this;
1426      }
1427
1428      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1429      public Builder oapiCollectionFormat(HttpPartCollectionFormat value) {
1430         super.oapiCollectionFormat(value);
1431         return this;
1432      }
1433
1434      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1435      public Builder oapiFormat(HttpPartFormat value) {
1436         super.oapiFormat(value);
1437         return this;
1438      }
1439
1440      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1441      public Builder openApi() {
1442         super.openApi();
1443         return this;
1444      }
1445
1446      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1447      public Builder paramFormat(ParamFormat value) {
1448         super.paramFormat(value);
1449         return this;
1450      }
1451
1452      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1453      public Builder paramFormatPlain() {
1454         super.paramFormatPlain();
1455         return this;
1456      }
1457
1458      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1459      public Builder parser(Class<? extends org.apache.juneau.parser.Parser> value) {
1460         super.parser(value);
1461         return this;
1462      }
1463
1464      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1465      public Builder parser(Parser value) {
1466         super.parser(value);
1467         return this;
1468      }
1469
1470      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1471      @SuppressWarnings("unchecked")
1472      public Builder parsers(java.lang.Class<? extends org.apache.juneau.parser.Parser>...value) {
1473         super.parsers(value);
1474         return this;
1475      }
1476
1477      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1478      public Builder parsers(Parser...value) {
1479         super.parsers(value);
1480         return this;
1481      }
1482
1483      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1484      public Builder partParser(Class<? extends org.apache.juneau.httppart.HttpPartParser> value) {
1485         super.partParser(value);
1486         return this;
1487      }
1488
1489      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1490      public Builder partParser(HttpPartParser value) {
1491         super.partParser(value);
1492         return this;
1493      }
1494
1495      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1496      public Builder partSerializer(Class<? extends org.apache.juneau.httppart.HttpPartSerializer> value) {
1497         super.partSerializer(value);
1498         return this;
1499      }
1500
1501      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1502      public Builder partSerializer(HttpPartSerializer value) {
1503         super.partSerializer(value);
1504         return this;
1505      }
1506
1507      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1508      public Builder pathData(NameValuePair...parts) {
1509         super.pathData(parts);
1510         return this;
1511      }
1512
1513      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1514      public Builder pathData(String name, String value) {
1515         super.pathData(name, value);
1516         return this;
1517      }
1518
1519      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1520      public Builder pathData(String name, Supplier<String> value) {
1521         super.pathData(name, value);
1522         return this;
1523      }
1524
1525      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1526      public Builder plainText() {
1527         super.plainText();
1528         return this;
1529      }
1530
1531      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1532      public Builder pooled() {
1533         super.pooled();
1534         return this;
1535      }
1536
1537      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1538      public Builder proxy(HttpHost proxy) {
1539         super.proxy(proxy);
1540         return this;
1541      }
1542
1543      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1544      public Builder proxyAuthenticationStrategy(AuthenticationStrategy proxyAuthStrategy) {
1545         super.proxyAuthenticationStrategy(proxyAuthStrategy);
1546         return this;
1547      }
1548
1549      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1550      public Builder publicSuffixMatcher(PublicSuffixMatcher publicSuffixMatcher) {
1551         super.publicSuffixMatcher(publicSuffixMatcher);
1552         return this;
1553      }
1554
1555      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1556      public Builder queryData(NameValuePair...parts) {
1557         super.queryData(parts);
1558         return this;
1559      }
1560
1561      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1562      public Builder queryData(String name, String value) {
1563         super.queryData(name, value);
1564         return this;
1565      }
1566
1567      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1568      public Builder queryData(String name, Supplier<String> value) {
1569         super.queryData(name, value);
1570         return this;
1571      }
1572
1573      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1574      public Builder quoteChar(char value) {
1575         super.quoteChar(value);
1576         return this;
1577      }
1578
1579      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1580      public Builder redirectStrategy(RedirectStrategy redirectStrategy) {
1581         super.redirectStrategy(redirectStrategy);
1582         return this;
1583      }
1584
1585      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1586      public Builder requestExecutor(HttpRequestExecutor requestExec) {
1587         super.requestExecutor(requestExec);
1588         return this;
1589      }
1590
1591      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1592      public Builder retryHandler(HttpRequestRetryHandler retryHandler) {
1593         super.retryHandler(retryHandler);
1594         return this;
1595      }
1596
1597      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1598      public Builder rootUrl(Object value) {
1599         super.rootUrl(value);
1600         return this;
1601      }
1602
1603      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1604      public Builder routePlanner(HttpRoutePlanner routePlanner) {
1605         super.routePlanner(routePlanner);
1606         return this;
1607      }
1608
1609      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1610      public Builder schemePortResolver(SchemePortResolver schemePortResolver) {
1611         super.schemePortResolver(schemePortResolver);
1612         return this;
1613      }
1614
1615      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1616      public Builder serializer(Class<? extends org.apache.juneau.serializer.Serializer> value) {
1617         super.serializer(value);
1618         return this;
1619      }
1620
1621      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1622      public Builder serializer(Serializer value) {
1623         super.serializer(value);
1624         return this;
1625      }
1626
1627      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1628      @SuppressWarnings("unchecked")
1629      public Builder serializers(java.lang.Class<? extends org.apache.juneau.serializer.Serializer>...value) {
1630         super.serializers(value);
1631         return this;
1632      }
1633
1634      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1635      public Builder serializers(Serializer...value) {
1636         super.serializers(value);
1637         return this;
1638      }
1639
1640      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1641      public Builder serviceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy serviceUnavailStrategy) {
1642         super.serviceUnavailableRetryStrategy(serviceUnavailStrategy);
1643         return this;
1644      }
1645
1646      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1647      public Builder json5() {
1648         super.json5();
1649         return this;
1650      }
1651
1652      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1653      public Builder skipEmptyFormData() {
1654         super.skipEmptyFormData();
1655         return this;
1656      }
1657
1658      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1659      public Builder skipEmptyFormData(boolean value) {
1660         super.skipEmptyFormData(value);
1661         return this;
1662      }
1663
1664      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1665      public Builder skipEmptyHeaderData() {
1666         super.skipEmptyHeaderData();
1667         return this;
1668      }
1669
1670      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1671      public Builder skipEmptyHeaderData(boolean value) {
1672         super.skipEmptyHeaderData(value);
1673         return this;
1674      }
1675
1676      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1677      public Builder skipEmptyQueryData() {
1678         super.skipEmptyQueryData();
1679         return this;
1680      }
1681
1682      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1683      public Builder skipEmptyQueryData(boolean value) {
1684         super.skipEmptyQueryData(value);
1685         return this;
1686      }
1687
1688      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1689      public Builder sortCollections() {
1690         super.sortCollections();
1691         return this;
1692      }
1693
1694      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1695      public Builder sortMaps() {
1696         super.sortMaps();
1697         return this;
1698      }
1699
1700      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1701      public Builder sq() {
1702         super.sq();
1703         return this;
1704      }
1705
1706      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1707      public Builder sslContext(SSLContext sslContext) {
1708         super.sslContext(sslContext);
1709         return this;
1710      }
1711
1712      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1713      public Builder sslHostnameVerifier(HostnameVerifier hostnameVerifier) {
1714         super.sslHostnameVerifier(hostnameVerifier);
1715         return this;
1716      }
1717
1718      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1719      public Builder sslSocketFactory(LayeredConnectionSocketFactory sslSocketFactory) {
1720         super.sslSocketFactory(sslSocketFactory);
1721         return this;
1722      }
1723
1724      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1725      public Builder strict() {
1726         super.strict();
1727         return this;
1728      }
1729
1730      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1731      public Builder targetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
1732         super.targetAuthenticationStrategy(targetAuthStrategy);
1733         return this;
1734      }
1735
1736      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1737      public Builder trimEmptyCollections() {
1738         super.trimEmptyCollections();
1739         return this;
1740      }
1741
1742      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1743      public Builder trimEmptyMaps() {
1744         super.trimEmptyMaps();
1745         return this;
1746      }
1747
1748      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1749      public Builder trimStringsOnRead() {
1750         super.trimStringsOnRead();
1751         return this;
1752      }
1753
1754      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1755      public Builder trimStringsOnWrite() {
1756         super.trimStringsOnWrite();
1757         return this;
1758      }
1759
1760      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1761      public Builder uon() {
1762         super.uon();
1763         return this;
1764      }
1765
1766      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1767      public Builder uriContext(UriContext value) {
1768         super.uriContext(value);
1769         return this;
1770      }
1771
1772      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1773      public Builder uriRelativity(UriRelativity value) {
1774         super.uriRelativity(value);
1775         return this;
1776      }
1777
1778      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1779      public Builder uriResolution(UriResolution value) {
1780         super.uriResolution(value);
1781         return this;
1782      }
1783
1784      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1785      public Builder urlEnc() {
1786         super.urlEnc();
1787         return this;
1788      }
1789
1790      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1791      public Builder useSystemProperties() {
1792         super.useSystemProperties();
1793         return this;
1794      }
1795
1796      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1797      public Builder useWhitespace() {
1798         super.useWhitespace();
1799         return this;
1800      }
1801
1802      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1803      public Builder userTokenHandler(UserTokenHandler userTokenHandler) {
1804         super.userTokenHandler(userTokenHandler);
1805         return this;
1806      }
1807
1808      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1809      public Builder ws() {
1810         super.ws();
1811         return this;
1812      }
1813
1814      @Override /* GENERATED - org.apache.juneau.rest.client.RestClient.Builder */
1815      public Builder xml() {
1816         super.xml();
1817         return this;
1818      }
1819
1820      // </FluentSetters>
1821   }
1822
1823   //-------------------------------------------------------------------------------------------------------------------
1824   // Instance
1825   //-------------------------------------------------------------------------------------------------------------------
1826
1827   private final RestContext restContext;
1828   private final Object restObject;
1829   private final String contextPath, servletPath;
1830   private final Map<String,String> pathVars;
1831
1832   private final ThreadLocal<HttpRequest> rreq = new ThreadLocal<>();
1833   private final ThreadLocal<MockRestResponse> rres = new ThreadLocal<>();
1834   private final ThreadLocal<MockServletRequest> sreq = new ThreadLocal<>();
1835   private final ThreadLocal<MockServletResponse> sres = new ThreadLocal<>();
1836
1837   /**
1838    * Constructor.
1839    *
1840    * @param builder
1841    *    The builder for this object.
1842    */
1843   public MockRestClient(Builder builder) {
1844      super(preInit(builder));
1845      restContext = builder.restContext;
1846      contextPath = builder.contextPath != null ? builder.contextPath : "";
1847      servletPath = builder.servletPath != null ? builder.servletPath : "";
1848      pathVars = builder.pathVars != null ? builder.pathVars : emptyMap();
1849      restObject = restContext.getResource();
1850
1851      HttpClientConnectionManager ccm = getHttpClientConnectionManager();
1852      if (ccm instanceof MockHttpClientConnectionManager)
1853         ((MockHttpClientConnectionManager)ccm).init(this);
1854   }
1855
1856   private static Builder preInit(Builder builder) {
1857      try {
1858         Object restBean = builder.restBean;
1859         String contextPath = builder.contextPath;
1860         String servletPath = builder.servletPath;
1861         String rootUrl = builder.getRootUri();
1862         if (rootUrl == null)
1863            rootUrl = "http://localhost";
1864
1865         Class<?> c = restBean instanceof Class ? (Class<?>)restBean : restBean.getClass();
1866         if (! REST_CONTEXTS.containsKey(c)) {
1867            boolean isClass = restBean instanceof Class;
1868            Object o = isClass ? ((Class<?>)restBean).getDeclaredConstructor().newInstance() : restBean;
1869            RestContext rc = RestContext
1870               .create(o.getClass(), null, null)
1871               .defaultClasses(BasicTestCallLogger.class)
1872               .debugDefault(CONDITIONAL)
1873               .init(()->o)
1874               .build()
1875               .postInit()
1876               .postInitChildFirst();
1877            REST_CONTEXTS.put(c, rc);
1878         }
1879         RestContext restBeanCtx = REST_CONTEXTS.get(c);
1880         builder.restContext(restBeanCtx);
1881
1882         if (servletPath == null)
1883            servletPath = toValidContextPath(restBeanCtx.getFullPath());
1884
1885         rootUrl = rootUrl + emptyIfNull(contextPath) + emptyIfNull(servletPath);
1886
1887         builder.servletPath = servletPath;
1888         builder.rootUrl(rootUrl);
1889         return builder;
1890      } catch (Exception e) {
1891         throw new ConfigException(e, "Could not initialize MockRestClient");
1892      }
1893   }
1894
1895   //------------------------------------------------------------------------------------------------------------------
1896   // Entry point methods.
1897   //------------------------------------------------------------------------------------------------------------------
1898
1899   @Override /* RestClient */
1900   public MockRestRequest request(RestOperation op) throws RestCallException {
1901      return (MockRestRequest)super.request(op);
1902   }
1903
1904   @Override /* RestClient */
1905   public MockRestRequest get(Object url) throws RestCallException {
1906      return (MockRestRequest)super.get(url);
1907   }
1908
1909   @Override /* RestClient */
1910   public MockRestRequest get() throws RestCallException {
1911      return (MockRestRequest)super.get();
1912   }
1913
1914   @Override /* RestClient */
1915   public MockRestRequest put(Object url, Object body) throws RestCallException {
1916      return (MockRestRequest)super.put(url, body);
1917   }
1918
1919   @Override /* RestClient */
1920   public MockRestRequest put(Object url, String body, ContentType contentType) throws RestCallException {
1921      return (MockRestRequest)super.put(url, body, contentType);
1922   }
1923
1924   @Override /* RestClient */
1925   public MockRestRequest put(Object url) throws RestCallException {
1926      return (MockRestRequest)super.put(url);
1927   }
1928
1929   @Override /* RestClient */
1930   public MockRestRequest post(Object url, Object body) throws RestCallException {
1931      return (MockRestRequest)super.post(url, body);
1932   }
1933
1934   @Override /* RestClient */
1935   public MockRestRequest post(Object url, String body, ContentType contentType) throws RestCallException {
1936      return (MockRestRequest)super.post(url, body, contentType);
1937   }
1938
1939   @Override /* RestClient */
1940   public MockRestRequest post(Object url) throws RestCallException {
1941      return (MockRestRequest)super.post(url);
1942   }
1943
1944   @Override /* RestClient */
1945   public MockRestRequest delete(Object url) throws RestCallException {
1946      return (MockRestRequest)super.delete(url);
1947   }
1948
1949   @Override /* RestClient */
1950   public MockRestRequest options(Object url) throws RestCallException {
1951      return (MockRestRequest)super.options(url);
1952   }
1953
1954   @Override /* RestClient */
1955   public MockRestRequest head(Object url) throws RestCallException {
1956      return (MockRestRequest)super.head(url);
1957   }
1958
1959   @Override /* RestClient */
1960   public MockRestRequest formPost(Object url, Object body) throws RestCallException {
1961      return (MockRestRequest)super.formPost(url, body);
1962   }
1963
1964   @Override /* RestClient */
1965   public MockRestRequest formPost(Object url) throws RestCallException {
1966      return (MockRestRequest)super.formPost(url);
1967   }
1968
1969   @Override /* RestClient */
1970   public MockRestRequest formPostPairs(Object url, String...parameters) throws RestCallException {
1971      return (MockRestRequest)super.formPostPairs(url, parameters);
1972   }
1973
1974   @Override /* RestClient */
1975   public MockRestRequest patch(Object url, Object body) throws RestCallException {
1976      return (MockRestRequest)super.patch(url, body);
1977   }
1978
1979   @Override /* RestClient */
1980   public MockRestRequest patch(Object url, String body, ContentType contentType) throws RestCallException {
1981      return (MockRestRequest)super.patch(url, body, contentType);
1982   }
1983
1984   @Override /* RestClient */
1985   public MockRestRequest patch(Object url) throws RestCallException {
1986      return (MockRestRequest)super.patch(url);
1987   }
1988
1989   @Override /* RestClient */
1990   public MockRestRequest callback(String callString) throws RestCallException {
1991      return (MockRestRequest)super.callback(callString);
1992   }
1993
1994   @Override /* RestClient */
1995   public MockRestRequest request(String method, Object url, Object body) throws RestCallException {
1996      return (MockRestRequest)super.request(method, url, body);
1997   }
1998
1999   @Override /* RestClient */
2000   public MockRestRequest request(String method, Object url) throws RestCallException {
2001      return (MockRestRequest)super.request(method, url);
2002   }
2003
2004   @Override /* RestClient */
2005   public MockRestRequest request(String method, Object url, boolean hasBody) throws RestCallException {
2006      return (MockRestRequest)super.request(method, url, hasBody);
2007   }
2008
2009   //------------------------------------------------------------------------------------------------------------------
2010   // Getters and setters.
2011   //------------------------------------------------------------------------------------------------------------------
2012
2013   /**
2014    * Returns the current client-side REST request.
2015    *
2016    * <p>
2017    * Note that this uses a {@link ThreadLocal} object for storage and so will not work on requests executed in
2018    * separate threads such as when using {@link Future Futures}.
2019    *
2020    * @return The current client-side REST request, or <jk>null</jk> if not set.
2021    */
2022   public HttpRequest getCurrentClientRequest() {
2023      return rreq.get();
2024   }
2025
2026   /**
2027    * Returns the current client-side REST response.
2028    *
2029    * <p>
2030    * Note that this uses a {@link ThreadLocal} object for storage and so will not work on requests executed in
2031    * separate threads such as when using {@link Future Futures}.
2032    *
2033    * @return The current client-side REST response, or <jk>null</jk> if not set.
2034    */
2035   public MockRestResponse getCurrentClientResponse() {
2036      return rres.get();
2037   }
2038
2039   /**
2040    * Returns the current server-side REST request.
2041    *
2042    * <p>
2043    * Note that this uses a {@link ThreadLocal} object for storage and so will not work on requests executed in
2044    * separate threads such as when using {@link Future Futures}.
2045    *
2046    * @return The current server-side REST request, or <jk>null</jk> if not set.
2047    */
2048   public MockServletRequest getCurrentServerRequest() {
2049      return sreq.get();
2050   }
2051
2052   /**
2053    * Returns the current server-side REST response.
2054    *
2055    * <p>
2056    * Note that this uses a {@link ThreadLocal} object for storage and so will not work on requests executed in
2057    * separate threads such as when using {@link Future Futures}.
2058    *
2059    * @return The current server-side REST response, or <jk>null</jk> if not set.
2060    */
2061   public MockServletResponse getCurrentServerResponse() {
2062      return sres.get();
2063   }
2064
2065   MockRestClient currentResponse(MockRestResponse value) {
2066      rres.set(value);
2067      return this;
2068   }
2069
2070   //------------------------------------------------------------------------------------------------------------------
2071   // RestClient methods.
2072   //------------------------------------------------------------------------------------------------------------------
2073
2074   @Override /* RestClient */
2075   protected MockRestRequest createRequest(URI uri, String method, boolean hasBody) throws RestCallException {
2076      return new MockRestRequest(this, uri, method, hasBody);
2077   }
2078
2079   @Override /* RestClient */
2080   protected MockRestResponse createResponse(RestRequest req, HttpResponse httpResponse, Parser parser) throws RestCallException {
2081      return new MockRestResponse(this, req, httpResponse, parser);
2082   }
2083
2084   //------------------------------------------------------------------------------------------------------------------
2085   // HttpClientConnection methods.
2086   //------------------------------------------------------------------------------------------------------------------
2087
2088   @Override /* HttpClientConnection */
2089   public void close() throws IOException {
2090      // Don't call super.close() because it will close the client.
2091      rreq.remove();
2092      rres.remove();
2093      sreq.remove();
2094      sres.remove();
2095   }
2096
2097   @Override /* HttpClientConnection */
2098   public boolean isOpen() {
2099      return true;
2100   }
2101
2102   @Override /* HttpClientConnection */
2103   public boolean isStale() {
2104      return false;
2105   }
2106
2107   @Override /* HttpClientConnection */
2108   public void setSocketTimeout(int timeout) {}
2109
2110   @Override /* HttpClientConnection */
2111   public int getSocketTimeout() {
2112      return Integer.MAX_VALUE;
2113   }
2114
2115   @Override /* HttpClientConnection */
2116   public void shutdown() throws IOException {}
2117
2118   @Override /* HttpClientConnection */
2119   public HttpConnectionMetrics getMetrics() {
2120      return null;
2121   }
2122
2123   @Override /* HttpClientConnection */
2124   public boolean isResponseAvailable(int timeout) throws IOException {
2125      return true;
2126   }
2127
2128   @Override /* HttpClientConnection */
2129   public void sendRequestHeader(HttpRequest request) throws HttpException, IOException {
2130      try {
2131         RequestLine rl = request.getRequestLine();
2132         String path = rl.getUri();
2133         String target = findTarget(request);
2134
2135         HttpRequest req = findRestRequest(request);
2136         rreq.set(req);
2137         rres.remove();
2138         sreq.remove();
2139         sres.remove();
2140
2141         path = target + path;
2142
2143         MockPathResolver pr = new MockPathResolver(target, contextPath, servletPath, path, null);
2144         if (pr.getError() != null)
2145            throw new IllegalStateException(pr.getError());
2146
2147         MockServletRequest r = MockServletRequest
2148            .create(request.getRequestLine().getMethod(), pr.getURI())
2149            .contextPath(pr.getContextPath())
2150            .servletPath(pr.getServletPath())
2151            .pathVars(pathVars)
2152            .debug(isDebug());
2153
2154         for (Header h : request.getAllHeaders())
2155            r.header(h.getName(), h.getValue());
2156
2157         sreq.set(r);
2158         sreq.get().applyOverrides(req);
2159      } catch (Exception e) {
2160         throw new HttpException(e.getMessage(), e);
2161      }
2162   }
2163
2164   /**
2165    * Attempts to unwrap the request to find the underlying RestRequest object.
2166    * Returns the same object if one of the low-level client methods are used (e.g. execute(HttpUriRequest)).
2167    */
2168   private HttpRequest findRestRequest(HttpRequest req) {
2169      if (req instanceof RestRequestCreated)
2170         return ((RestRequestCreated)req).getRestRequest();
2171      if (req instanceof HttpRequestWrapper)
2172         return findRestRequest(((HttpRequestWrapper) req).getOriginal());
2173      return req;
2174   }
2175
2176   private String findTarget(HttpRequest req) {
2177      if (req instanceof HttpRequestWrapper) {
2178         HttpHost httpHost = ((HttpRequestWrapper)req).getTarget();
2179         if (httpHost != null)
2180            return httpHost.toURI();
2181      }
2182      return "http://localhost";
2183   }
2184
2185   @Override /* HttpClientConnection */
2186   public void sendRequestEntity(HttpEntityEnclosingRequest request) throws HttpException, IOException {
2187      byte[] body = {};
2188      HttpEntity entity = request.getEntity();
2189      if (entity != null) {
2190         long length = entity.getContentLength();
2191         if (length < 0)
2192            length = 1024;
2193         ByteArrayOutputStream baos = new ByteArrayOutputStream((int)Math.min(length, 1024));
2194         entity.writeTo(baos);
2195         baos.flush();
2196         body = baos.toByteArray();
2197      }
2198      sreq.get().content(body);
2199   }
2200
2201   @Override /* HttpClientConnection */
2202   public HttpResponse receiveResponseHeader() throws HttpException, IOException {
2203      try {
2204         MockServletResponse res = MockServletResponse.create();
2205         restContext.execute(restObject, sreq.get(), res);
2206
2207         // If the status isn't set, something's broken.
2208         if (res.getStatus() == 0)
2209            throw new IllegalStateException("Response status was 0.");
2210
2211         // A bug in HttpClient causes an infinite loop if the response is less than 200.
2212         // As a workaround, just add 1000 to the status code (which is better than an infinite loop).
2213         if (res.getStatus() < 200)
2214            res.setStatus(1000 + res.getStatus());
2215
2216         sres.set(res);
2217
2218         HttpResponse response = new BasicHttpResponse(new BasicStatusLine(HttpVersion.HTTP_1_1, res.getStatus(), res.getMessage()));
2219         res.getHeaders().forEach((k,v) -> {
2220            for (String hv : v)
2221               response.addHeader(k, hv);
2222         });
2223
2224         return response;
2225      } catch (Exception e) {
2226         throw new HttpException(emptyIfNull(e.getMessage()), e);
2227      }
2228   }
2229
2230   @Override /* HttpClientConnection */
2231   public void receiveResponseEntity(HttpResponse response) throws HttpException, IOException {
2232      InputStream is = new ByteArrayInputStream(sres.get().getContent());
2233      Header contentEncoding = response.getLastHeader("Content-Encoding");
2234      if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip"))
2235         is = new GZIPInputStream(is);
2236      response.setEntity(new InputStreamEntity(is));
2237   }
2238
2239   @Override /* HttpClientConnection */
2240   public void flush() throws IOException {}
2241}