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