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