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