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