001package io.avaje.http.generator.core.openapi; 002 003import io.avaje.http.api.MediaType; 004import io.avaje.http.generator.core.MethodParam; 005import io.avaje.http.generator.core.MethodReader; 006import io.avaje.http.generator.core.javadoc.Javadoc; 007import io.swagger.v3.oas.annotations.Hidden; 008import io.swagger.v3.oas.models.Operation; 009import io.swagger.v3.oas.models.PathItem; 010import io.swagger.v3.oas.models.responses.ApiResponse; 011import io.swagger.v3.oas.models.responses.ApiResponses; 012 013/** 014 * Build the OpenAPI documentation for a method. 015 */ 016public class MethodDocBuilder { 017 018 private final Javadoc javadoc; 019 private final MethodReader methodReader; 020 private final DocContext ctx; 021 022 private final Operation operation = new Operation(); 023 024 public MethodDocBuilder(MethodReader methodReader, DocContext ctx) { 025 this.methodReader = methodReader; 026 this.ctx = ctx; 027 this.javadoc = methodReader.getJavadoc(); 028 } 029 030 public void build() { 031 032 if (ctx.isOpenApiAvailable() && methodReader.findAnnotation(Hidden.class) != null) { 033 return; 034 } 035 036 //operation.setOperationId(); 037 operation.setSummary(javadoc.getSummary()); 038 operation.setDescription(javadoc.getDescription()); 039 operation.setTags(methodReader.getTags()); 040 041 if (javadoc.isDeprecated()) { 042 operation.setDeprecated(true); 043 } else if (methodReader.findAnnotation(Deprecated.class) != null) { 044 operation.setDeprecated(true); 045 } 046 047 PathItem pathItem = ctx.pathItem(methodReader.getFullPath()); 048 switch (methodReader.getWebMethod()) { 049 case GET: 050 pathItem.setGet(operation); 051 break; 052 case PUT: 053 pathItem.setPut(operation); 054 break; 055 case POST: 056 pathItem.setPost(operation); 057 break; 058 case DELETE: 059 pathItem.setDelete(operation); 060 break; 061 case PATCH: 062 pathItem.setPatch(operation); 063 break; 064 } 065 066 for (MethodParam param : methodReader.getParams()) { 067 param.buildApiDocumentation(this); 068 } 069 070 ApiResponses responses = new ApiResponses(); 071 operation.setResponses(responses); 072 073 ApiResponse response = new ApiResponse(); 074 response.setDescription(javadoc.getReturnDescription()); 075 076 if (methodReader.isVoid()) { 077 if (isEmpty(response.getDescription())) { 078 response.setDescription("No content"); 079 } 080 } else { 081 final String produces = methodReader.getProduces(); 082 String contentMediaType = (produces == null) ? MediaType.APPLICATION_JSON : produces; 083 response.setContent(ctx.createContent(methodReader.getReturnType(), contentMediaType)); 084 } 085 responses.addApiResponse(methodReader.getStatusCode(), response); 086 } 087 088 DocContext getContext() { 089 return ctx; 090 } 091 092 Javadoc getJavadoc() { 093 return javadoc; 094 } 095 096 Operation getOperation() { 097 return operation; 098 } 099 100 private boolean isEmpty(String value) { 101 return value == null || value.isEmpty(); 102 } 103}