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}