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.swagger;
018
019import java.util.*;
020import java.util.function.*;
021
022import org.apache.juneau.bean.swagger.Swagger;
023import org.apache.juneau.common.utils.*;
024import org.apache.juneau.cp.*;
025import org.apache.juneau.http.response.*;
026import org.apache.juneau.jsonschema.*;
027import org.apache.juneau.rest.*;
028import org.apache.juneau.rest.annotation.*;
029import org.apache.juneau.svl.*;
030
031/**
032 * Interface for retrieving Swagger on a REST resource.
033 *
034 * <h5 class='section'>See Also:</h5><ul>
035 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>
036 * </ul>
037 */
038public interface SwaggerProvider {
039
040   //-----------------------------------------------------------------------------------------------------------------
041   // Static
042   //-----------------------------------------------------------------------------------------------------------------
043
044   /**
045    * Represents no SwaggerProvider.
046    *
047    * <p>
048    * Used on annotation to indicate that the value should be inherited from the parent class, and
049    * ultimately {@link BasicSwaggerProvider} if not specified at any level.
050    */
051   public abstract class Void implements SwaggerProvider {}
052
053   /**
054    * Static creator.
055    *
056    * @param beanStore The bean store to use for creating beans.
057    * @return A new builder for this object.
058    */
059   static Builder create(BeanStore beanStore) {
060      return new Builder(beanStore);
061   }
062
063   //-----------------------------------------------------------------------------------------------------------------
064   // Builder
065   //-----------------------------------------------------------------------------------------------------------------
066
067   /**
068    * Builder class.
069    */
070   public class Builder {
071
072      final BeanStore beanStore;
073      Class<?> resourceClass;
074      Supplier<VarResolver> varResolver;
075      Supplier<JsonSchemaGenerator> jsonSchemaGenerator;
076      Supplier<Messages> messages;
077      Supplier<FileFinder> fileFinder;
078      BeanCreator<SwaggerProvider> creator;
079
080      /**
081       * Constructor.
082       *
083       * @param beanStore The bean store to use for creating beans.
084       */
085      protected Builder(BeanStore beanStore) {
086         this.beanStore = beanStore;
087         this.creator = beanStore.createBean(SwaggerProvider.class).type(BasicSwaggerProvider.class).builder(Builder.class, this);
088      }
089
090      /**
091       * Creates a new {@link SwaggerProvider} object from this builder.
092       *
093       * <p>
094       * Instantiates an instance of the {@link #type(Class) implementation class} or
095       * else {@link BasicSwaggerProvider} if implementation class was not specified.
096       *
097       * @return A new {@link SwaggerProvider} object.
098       */
099      public SwaggerProvider build() {
100         try {
101            return creator.run();
102         } catch (Exception e) {
103            throw new InternalServerError(e);
104         }
105      }
106
107      /**
108       * Returns the var resolver in this builder if it's been specified.
109       *
110       * @return The var resolver.
111       */
112      public Optional<VarResolver> varResolver() {
113         return Utils.opt(varResolver).map(Supplier::get);
114      }
115
116      /**
117       * Returns the JSON schema generator in this builder if it's been specified.
118       *
119       * @return The JSON schema generator.
120       */
121      public Optional<JsonSchemaGenerator> jsonSchemaGenerator() {
122         return Utils.opt(jsonSchemaGenerator).map(Supplier::get);
123      }
124
125      /**
126       * Returns the messages in this builder if it's been specified.
127       *
128       * @return The messages.
129       */
130      public Optional<Messages> messages() {
131         return Utils.opt(messages).map(Supplier::get);
132      }
133
134      /**
135       * Returns the file finder in this builder if it's been specified.
136       *
137       * @return The file finder.
138       */
139      public Optional<FileFinder> fileFinder() {
140         return Utils.opt(fileFinder).map(Supplier::get);
141      }
142
143      /**
144       * Specifies the default implementation class if not specified via {@link #type(Class)}.
145       *
146       * @return The default implementation class if not specified via {@link #type(Class)}.
147       */
148      protected Class<? extends SwaggerProvider> getDefaultType() {
149         return BasicSwaggerProvider.class;
150      }
151
152      /**
153       * Specifies a subclass of {@link SwaggerProvider} to create when the {@link #build()} method is called.
154       *
155       * @param value The new value for this setting.
156       * @return  This object.
157       */
158      public Builder type(Class<? extends SwaggerProvider> value) {
159         creator.type(value == null ? BasicSwaggerProvider.class : value);
160         return this;
161      }
162
163      /**
164       * Specifies the variable resolver to use for the {@link SwaggerProvider} object.
165       *
166       * @param value The new value for this setting.
167       * @return  This object.
168       */
169      public Builder varResolver(Supplier<VarResolver> value) {
170         varResolver = value;
171         return this;
172      }
173
174      /**
175       * Specifies the JSON-schema generator to use for the {@link SwaggerProvider} object.
176       *
177       * @param value The new value for this setting.
178       * @return  This object.
179       */
180      public Builder jsonSchemaGenerator(Supplier<JsonSchemaGenerator> value) {
181         jsonSchemaGenerator = value;
182         return this;
183      }
184
185      /**
186       * Specifies the messages to use for the {@link SwaggerProvider} object.
187       *
188       * @param value The new value for this setting.
189       * @return  This object.
190       */
191      public Builder messages(Supplier<Messages> value) {
192         messages = value;
193         return this;
194      }
195
196      /**
197       * Specifies the file-finder to use for the {@link SwaggerProvider} object.
198       *
199       * @param value The new value for this setting.
200       * @return  This object.
201       */
202      public Builder fileFinder(Supplier<FileFinder> value) {
203         fileFinder = value;
204         return this;
205      }
206
207      /**
208       * Specifies an already-instantiated bean for the {@link #build()} method too return.
209       *
210       * @param value The new value for this setting.
211       * @return  This object.
212       */
213      public Builder impl(SwaggerProvider value) {
214         creator.impl(value);
215         return this;
216      }
217   }
218
219   //-----------------------------------------------------------------------------------------------------------------
220   // Instance
221   //-----------------------------------------------------------------------------------------------------------------
222
223   /**
224    * Returns the Swagger associated with the specified {@link Rest}-annotated class.
225    *
226    * @param context The context of the {@link Rest}-annotated class.
227    * @param locale The request locale.
228    * @return A new {@link Swagger} DTO object.
229    * @throws Exception If an error occurred producing the Swagger.
230    */
231   Swagger getSwagger(RestContext context, Locale locale) throws Exception;
232
233}