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