Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 81 additions & 124 deletions jooby/src/main/java/io/jooby/StatusCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,27 @@ public final class StatusCode {

private final String reason;

private final transient boolean unknown;

private StatusCode(final int value, final String reason) {
this.value = value;
this.reason = reason;
this.unknown = false;
}

private StatusCode(final int value) {
this.value = value;
this.reason = Integer.toString(value);
this.unknown = true;
}

/**
* True for custom status code.
*
* @return True for custom status code.
*/
public boolean isUnknown() {
return unknown;
}

/**
Expand Down Expand Up @@ -971,129 +989,68 @@ public int hashCode() {
* @throws IllegalArgumentException if this enum has no constant for the specified numeric value
*/
public static StatusCode valueOf(final int statusCode) {
switch (statusCode) {
case CONTINUE_CODE:
return CONTINUE;
case SWITCHING_PROTOCOLS_CODE:
return SWITCHING_PROTOCOLS;
case PROCESSING_CODE:
return PROCESSING;
case CHECKPOINT_CODE:
return CHECKPOINT;
case OK_CODE:
return OK;
case CREATED_CODE:
return CREATED;
case ACCEPTED_CODE:
return ACCEPTED;
case NON_AUTHORITATIVE_INFORMATION_CODE:
return NON_AUTHORITATIVE_INFORMATION;
case NO_CONTENT_CODE:
return NO_CONTENT;
case RESET_CONTENT_CODE:
return RESET_CONTENT;
case PARTIAL_CONTENT_CODE:
return PARTIAL_CONTENT;
case MULTI_STATUS_CODE:
return MULTI_STATUS;
case ALREADY_REPORTED_CODE:
return ALREADY_REPORTED;
case IM_USED_CODE:
return IM_USED;
case MULTIPLE_CHOICES_CODE:
return MULTIPLE_CHOICES;
case MOVED_PERMANENTLY_CODE:
return MOVED_PERMANENTLY;
case FOUND_CODE:
return FOUND;
case SEE_OTHER_CODE:
return SEE_OTHER;
case NOT_MODIFIED_CODE:
return NOT_MODIFIED;
case USE_PROXY_CODE:
return USE_PROXY;
case TEMPORARY_REDIRECT_CODE:
return TEMPORARY_REDIRECT;
case RESUME_INCOMPLETE_CODE:
return RESUME_INCOMPLETE;
case BAD_REQUEST_CODE:
return BAD_REQUEST;
case UNAUTHORIZED_CODE:
return UNAUTHORIZED;
case PAYMENT_REQUIRED_CODE:
return PAYMENT_REQUIRED;
case FORBIDDEN_CODE:
return FORBIDDEN;
case NOT_FOUND_CODE:
return NOT_FOUND;
case METHOD_NOT_ALLOWED_CODE:
return METHOD_NOT_ALLOWED;
case NOT_ACCEPTABLE_CODE:
return NOT_ACCEPTABLE;
case PROXY_AUTHENTICATION_REQUIRED_CODE:
return PROXY_AUTHENTICATION_REQUIRED;
case REQUEST_TIMEOUT_CODE:
return REQUEST_TIMEOUT;
case CONFLICT_CODE:
return CONFLICT;
case GONE_CODE:
return GONE;
case LENGTH_REQUIRED_CODE:
return LENGTH_REQUIRED;
case PRECONDITION_FAILED_CODE:
return PRECONDITION_FAILED;
case REQUEST_ENTITY_TOO_LARGE_CODE:
return REQUEST_ENTITY_TOO_LARGE;
case REQUEST_URI_TOO_LONG_CODE:
return REQUEST_URI_TOO_LONG;
case UNSUPPORTED_MEDIA_TYPE_CODE:
return UNSUPPORTED_MEDIA_TYPE;
case REQUESTED_RANGE_NOT_SATISFIABLE_CODE:
return REQUESTED_RANGE_NOT_SATISFIABLE;
case EXPECTATION_FAILED_CODE:
return EXPECTATION_FAILED;
case I_AM_A_TEAPOT_CODE:
return I_AM_A_TEAPOT;
case UNPROCESSABLE_ENTITY_CODE:
return UNPROCESSABLE_ENTITY;
case LOCKED_CODE:
return LOCKED;
case FAILED_DEPENDENCY_CODE:
return FAILED_DEPENDENCY;
case UPGRADE_REQUIRED_CODE:
return UPGRADE_REQUIRED;
case PRECONDITION_REQUIRED_CODE:
return PRECONDITION_REQUIRED;
case TOO_MANY_REQUESTS_CODE:
return TOO_MANY_REQUESTS;
case REQUEST_HEADER_FIELDS_TOO_LARGE_CODE:
return REQUEST_HEADER_FIELDS_TOO_LARGE;
case SERVER_ERROR_CODE:
return SERVER_ERROR;
case NOT_IMPLEMENTED_CODE:
return NOT_IMPLEMENTED;
case BAD_GATEWAY_CODE:
return BAD_GATEWAY;
case SERVICE_UNAVAILABLE_CODE:
return SERVICE_UNAVAILABLE;
case GATEWAY_TIMEOUT_CODE:
return GATEWAY_TIMEOUT;
case HTTP_VERSION_NOT_SUPPORTED_CODE:
return HTTP_VERSION_NOT_SUPPORTED;
case VARIANT_ALSO_NEGOTIATES_CODE:
return VARIANT_ALSO_NEGOTIATES;
case INSUFFICIENT_STORAGE_CODE:
return INSUFFICIENT_STORAGE;
case LOOP_DETECTED_CODE:
return LOOP_DETECTED;
case BANDWIDTH_LIMIT_EXCEEDED_CODE:
return BANDWIDTH_LIMIT_EXCEEDED;
case NOT_EXTENDED_CODE:
return NOT_EXTENDED;
case NETWORK_AUTHENTICATION_REQUIRED_CODE:
return NETWORK_AUTHENTICATION_REQUIRED;
default:
return new StatusCode(statusCode, Integer.toString(statusCode));
}
return switch (statusCode) {
case CONTINUE_CODE -> CONTINUE;
case SWITCHING_PROTOCOLS_CODE -> SWITCHING_PROTOCOLS;
case PROCESSING_CODE -> PROCESSING;
case CHECKPOINT_CODE -> CHECKPOINT;
case OK_CODE -> OK;
case CREATED_CODE -> CREATED;
case ACCEPTED_CODE -> ACCEPTED;
case NON_AUTHORITATIVE_INFORMATION_CODE -> NON_AUTHORITATIVE_INFORMATION;
case NO_CONTENT_CODE -> NO_CONTENT;
case RESET_CONTENT_CODE -> RESET_CONTENT;
case PARTIAL_CONTENT_CODE -> PARTIAL_CONTENT;
case MULTI_STATUS_CODE -> MULTI_STATUS;
case ALREADY_REPORTED_CODE -> ALREADY_REPORTED;
case IM_USED_CODE -> IM_USED;
case MULTIPLE_CHOICES_CODE -> MULTIPLE_CHOICES;
case MOVED_PERMANENTLY_CODE -> MOVED_PERMANENTLY;
case FOUND_CODE -> FOUND;
case SEE_OTHER_CODE -> SEE_OTHER;
case NOT_MODIFIED_CODE -> NOT_MODIFIED;
case USE_PROXY_CODE -> USE_PROXY;
case TEMPORARY_REDIRECT_CODE -> TEMPORARY_REDIRECT;
case RESUME_INCOMPLETE_CODE -> RESUME_INCOMPLETE;
case BAD_REQUEST_CODE -> BAD_REQUEST;
case UNAUTHORIZED_CODE -> UNAUTHORIZED;
case PAYMENT_REQUIRED_CODE -> PAYMENT_REQUIRED;
case FORBIDDEN_CODE -> FORBIDDEN;
case NOT_FOUND_CODE -> NOT_FOUND;
case METHOD_NOT_ALLOWED_CODE -> METHOD_NOT_ALLOWED;
case NOT_ACCEPTABLE_CODE -> NOT_ACCEPTABLE;
case PROXY_AUTHENTICATION_REQUIRED_CODE -> PROXY_AUTHENTICATION_REQUIRED;
case REQUEST_TIMEOUT_CODE -> REQUEST_TIMEOUT;
case CONFLICT_CODE -> CONFLICT;
case GONE_CODE -> GONE;
case LENGTH_REQUIRED_CODE -> LENGTH_REQUIRED;
case PRECONDITION_FAILED_CODE -> PRECONDITION_FAILED;
case REQUEST_ENTITY_TOO_LARGE_CODE -> REQUEST_ENTITY_TOO_LARGE;
case REQUEST_URI_TOO_LONG_CODE -> REQUEST_URI_TOO_LONG;
case UNSUPPORTED_MEDIA_TYPE_CODE -> UNSUPPORTED_MEDIA_TYPE;
case REQUESTED_RANGE_NOT_SATISFIABLE_CODE -> REQUESTED_RANGE_NOT_SATISFIABLE;
case EXPECTATION_FAILED_CODE -> EXPECTATION_FAILED;
case I_AM_A_TEAPOT_CODE -> I_AM_A_TEAPOT;
case UNPROCESSABLE_ENTITY_CODE -> UNPROCESSABLE_ENTITY;
case LOCKED_CODE -> LOCKED;
case FAILED_DEPENDENCY_CODE -> FAILED_DEPENDENCY;
case UPGRADE_REQUIRED_CODE -> UPGRADE_REQUIRED;
case PRECONDITION_REQUIRED_CODE -> PRECONDITION_REQUIRED;
case TOO_MANY_REQUESTS_CODE -> TOO_MANY_REQUESTS;
case REQUEST_HEADER_FIELDS_TOO_LARGE_CODE -> REQUEST_HEADER_FIELDS_TOO_LARGE;
case SERVER_ERROR_CODE -> SERVER_ERROR;
case NOT_IMPLEMENTED_CODE -> NOT_IMPLEMENTED;
case BAD_GATEWAY_CODE -> BAD_GATEWAY;
case SERVICE_UNAVAILABLE_CODE -> SERVICE_UNAVAILABLE;
case GATEWAY_TIMEOUT_CODE -> GATEWAY_TIMEOUT;
case HTTP_VERSION_NOT_SUPPORTED_CODE -> HTTP_VERSION_NOT_SUPPORTED;
case VARIANT_ALSO_NEGOTIATES_CODE -> VARIANT_ALSO_NEGOTIATES;
case INSUFFICIENT_STORAGE_CODE -> INSUFFICIENT_STORAGE;
case LOOP_DETECTED_CODE -> LOOP_DETECTED;
case BANDWIDTH_LIMIT_EXCEEDED_CODE -> BANDWIDTH_LIMIT_EXCEEDED;
case NOT_EXTENDED_CODE -> NOT_EXTENDED;
case NETWORK_AUTHENTICATION_REQUIRED_CODE -> NETWORK_AUTHENTICATION_REQUIRED;
default -> new StatusCode(statusCode);
};
}
}
27 changes: 27 additions & 0 deletions modules/jooby-openapi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
<version>${jooby.version}</version>
</dependency>

<dependency>
<groupId>net.datafaker</groupId>
<artifactId>datafaker</artifactId>
<version>2.5.3</version>
</dependency>

<!-- JAXRS -->
<dependency>
<groupId>jakarta.ws.rs</groupId>
Expand Down Expand Up @@ -51,6 +57,17 @@
<version>12.1.2</version>
</dependency>

<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj</artifactId>
<version>3.0.1</version>
</dependency>

<dependency>
<groupId>io.pebbletemplates</groupId>
<artifactId>pebble</artifactId>
</dependency>

<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
Expand All @@ -62,6 +79,11 @@
<artifactId>swagger-parser</artifactId>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down Expand Up @@ -128,6 +150,11 @@
<version>1.18.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,7 @@
import org.objectweb.asm.tree.*;

import io.jooby.*;
import io.jooby.annotation.ContextParam;
import io.jooby.annotation.CookieParam;
import io.jooby.annotation.FormParam;
import io.jooby.annotation.GET;
import io.jooby.annotation.HeaderParam;
import io.jooby.annotation.Path;
import io.jooby.annotation.PathParam;
import io.jooby.annotation.QueryParam;
import io.jooby.annotation.*;
import io.swagger.v3.oas.models.media.Content;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
Expand Down Expand Up @@ -314,6 +307,7 @@ private static Map<String, MethodNode> methods(ParserContext ctx, ClassNode node
return methods;
}

@SuppressWarnings("unchecked")
private static List<OperationExt> routerMethod(
ParserContext ctx, String prefix, ClassNode classNode, MethodNode method) {

Expand All @@ -330,13 +324,35 @@ private static List<OperationExt> routerMethod(
operation.setOperationId(method.name);
Optional.ofNullable(requestBody.get()).ifPresent(operation::setRequestBody);

mediaType(classNode, method, produces(), operation::addProduces);
mediaType(classNode, method, consumes(), operation::addConsumes);

result.add(operation);
}
}

return result;
}

@SuppressWarnings("unchecked")
public static void mediaType(
ClassNode classNode, MethodNode method, List<String> types, Consumer<String> consumer) {
mediaType(classNode, method, types).stream()
.map(AsmUtils::toMap)
.map(it -> it.get("value"))
.filter(Objects::nonNull)
.map(List.class::cast)
.flatMap(List::stream)
.distinct()
.forEach(it -> consumer.accept(it.toString()));
}

public static List<AnnotationNode> mediaType(
ClassNode classNode, MethodNode method, List<String> types) {
var result = findAnnotationByType(method.visibleAnnotations, types);
return result.isEmpty() ? findAnnotationByType(classNode.visibleAnnotations, types) : result;
}

private static ResponseExt returnTypes(MethodNode method) {
Signature signature = Signature.create(method);
String desc = Optional.ofNullable(method.signature).orElse(method.desc);
Expand Down Expand Up @@ -604,6 +620,14 @@ private static List<String> httpMethods() {
return annotationTypes;
}

private static List<String> produces() {
return List.of(Produces.class.getName(), jakarta.ws.rs.Produces.class.getName());
}

private static List<String> consumes() {
return List.of(Consumes.class.getName(), jakarta.ws.rs.Consumes.class.getName());
}

private static List<String> httpMethod(String pkg, Class pathType) {
List<String> annotationTypes =
Router.METHODS.stream().map(m -> pkg + "." + m).collect(Collectors.toList());
Expand Down
Loading
Loading