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.mock2;
014
015import org.apache.juneau.marshall.*;
016import org.apache.juneau.parser.*;
017import org.apache.juneau.rest.annotation.*;
018import org.apache.juneau.rest.client.*;
019import org.apache.juneau.serializer.*;
020
021/**
022 * Mocked {@link RestClient}.
023 *
024 * <ul class='seealso'>
025 *    <li class='link'>{@doc juneau-rest-mock}
026 * </ul>
027 */
028public class MockRestClient extends RestClientBuilder {
029
030   private MockRest.Builder mrb;
031
032   /**
033    * Constructor.
034    *
035    * @param impl
036    *    The REST bean or bean class annotated with {@link Rest @Rest}.
037    *    <br>If a class, it must have a no-arg constructor.
038    */
039   protected MockRestClient(Object impl) {
040      super(null, null);
041      mrb = MockRest.create(impl);
042      rootUrl("http://localhost");
043   }
044
045   /**
046    * Creates a new RestClient builder configured with the specified REST implementation bean or bean class.
047    *
048    * @param impl
049    *    The REST bean or bean class annotated with {@link Rest @Rest}.
050    *    <br>If a class, it must have a no-arg constructor.
051    * @return A new builder.
052    */
053   public static MockRestClient create(Object impl) {
054      return new MockRestClient(impl);
055   }
056
057   /**
058    * Creates a new RestClient builder configured with the specified REST implementation bean or bean class.
059    *
060    * @param impl
061    *    The REST bean or bean class annotated with {@link Rest @Rest}.
062    *    <br>If a class, it must have a no-arg constructor.
063    * @param m
064    *    The marshall to use for serializing and parsing HTTP bodies.
065    *    <br>Can be <jk>null</jk> (will remove the existing serializer/parser).
066    * @return A new builder.
067    */
068   public static MockRestClient create(Object impl, Marshall m) {
069      return create(impl).marshall(m);
070   }
071
072   /**
073    * Creates a new RestClient builder configured with the specified REST implementation bean or bean class.
074    *
075    * @param impl
076    *    The REST bean or bean class annotated with {@link Rest @Rest}.
077    *    <br>If a class, it must have a no-arg constructor.
078    * @param s
079    *    The serializer to use for serializing HTTP bodies.
080    *    <br>Can be <jk>null</jk> (will remove the existing serializer).
081    * @param p
082    *    The parser to use for parsing HTTP bodies.
083    *    <br>Can be <jk>null</jk> (will remove the existing parser).
084    * @return A new builder.
085    */
086   public static MockRestClient create(Object impl, Serializer s, Parser p) {
087      return create(impl).serializer(s).parser(p);
088   }
089
090   /**
091    * Convenience method for creating a RestClient over the specified REST implementation bean or bean class.
092    *
093    * <p>
094    * Equivalent to calling:
095    * <p class='bpcode w800'>
096    *    MockRestClient.create(impl, m).build();
097    * </p>
098    *
099    * @param impl
100    *    The REST bean or bean class annotated with {@link Rest @Rest}.
101    *    <br>If a class, it must have a no-arg constructor.
102    * @param m
103    *    The marshall to use for specifying the <c>Accept</c> and <c>Content-Type</c> headers.
104    *    <br>If <jk>null</jk>, headers will be reset.
105    * @return A new {@link MockRest} object.
106    */
107   public static RestClient build(Object impl, Marshall m) {
108      return create(impl, m).build();
109   }
110
111   /**
112    * Convenience method for creating a RestClient over the specified REST implementation bean or bean class.
113    *
114    * <p>
115    * Equivalent to calling:
116    * <p class='bpcode w800'>
117    *    MockRestClient.create(impl, s, p).build();
118    * </p>
119    *
120    * @param impl
121    *    The REST bean or bean class annotated with {@link Rest @Rest}.
122    *    <br>If a class, it must have a no-arg constructor.
123    * @param s
124    *    The serializer to use for serializing HTTP bodies.
125    *    <br>Can be <jk>null</jk> (will remove the existing serializer).
126    * @param p
127    *    The parser to use for parsing HTTP bodies.
128    *    <br>Can be <jk>null</jk> (will remove the existing parser).
129    * @return A new {@link MockRest} object.
130    */
131   public static RestClient build(Object impl, Serializer s, Parser p) {
132      return create(impl, s, p).build();
133   }
134
135   @Override
136   public RestClient build() {
137      httpClientConnectionManager(new MockHttpClientConnectionManager(mrb.build()));
138      return super.build();
139   }
140
141   /**
142    * Enable debug mode.
143    *
144    * @return This object (for method chaining).
145    */
146   @Override
147   public MockRestClient debug() {
148      mrb.debug();
149      debug();
150      return this;
151   }
152
153   /**
154    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/json"</js>.
155    *
156    * @return This object (for method chaining).
157    */
158   @Override
159   public MockRestClient json() {
160      marshall(Json.DEFAULT);
161      return this;
162   }
163
164   /**
165    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/json+simple"</js>.
166    *
167    * @return This object (for method chaining).
168    */
169   @Override
170   public MockRestClient simpleJson() {
171      marshall(SimpleJson.DEFAULT);
172      return this;
173   }
174
175   /**
176    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/xml"</js>.
177    *
178    * @return This object (for method chaining).
179    */
180   @Override
181   public MockRestClient xml() {
182      marshall(Xml.DEFAULT);
183      return this;
184   }
185
186   /**
187    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/html"</js>.
188    *
189    * @return This object (for method chaining).
190    */
191   @Override
192   public MockRestClient html() {
193      marshall(Html.DEFAULT);
194      return this;
195   }
196
197   /**
198    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/plain"</js>.
199    *
200    * @return This object (for method chaining).
201    */
202   @Override
203   public MockRestClient plainText() {
204      marshall(PlainText.DEFAULT);
205      return this;
206   }
207
208   /**
209    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"octal/msgpack"</js>.
210    *
211    * @return This object (for method chaining).
212    */
213   @Override
214   public MockRestClient msgpack() {
215      marshall(MsgPack.DEFAULT);
216      return this;
217   }
218
219   /**
220    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/uon"</js>.
221    *
222    * @return This object (for method chaining).
223    */
224   @Override
225   public MockRestClient uon() {
226      marshall(Uon.DEFAULT);
227      return this;
228   }
229
230   /**
231    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/x-www-form-urlencoded"</js>.
232    *
233    * @return This object (for method chaining).
234    */
235   @Override
236   public MockRestClient urlEnc() {
237      marshall(UrlEncoding.DEFAULT);
238      return this;
239   }
240
241   /**
242    * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/openapi"</js>.
243    *
244    * @return This object (for method chaining).
245    */
246   @Override
247   public MockRestClient openapi() {
248      marshall(OpenApi.DEFAULT);
249      return this;
250   }
251
252   @Override
253   public MockRestClient marshall(Marshall value) {
254      super.marshall(value);
255      mrb.marshall(value);
256      return this;
257   }
258
259   @Override
260   public MockRestClient serializer(Serializer value) {
261      super.serializer(value);
262      mrb.serializer(value);
263      return this;
264   }
265
266   @Override
267   public MockRestClient parser(Parser value) {
268      super.parser(value);
269      mrb.parser(value);
270      return this;
271   }
272}