All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jooby.internal.apt.HttpMethod Maven / Gradle / Ivy

There is a newer version: 3.5.3
Show newest version
/*
 * Jooby https://jooby.io
 * Apache License Version 2.0 https://jooby.io/LICENSE.txt
 * Copyright 2014 Edgar Espina
 */
package io.jooby.internal.apt;

import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;

import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

/**
 * Parser for HTTP method comming from HTTP method annotations.
 *
 * @author edgar
 */
public enum HttpMethod implements AnnotationSupport {
  CONNECT("io.jooby.annotation"),
  TRACE("io.jooby.annotation"),
  DELETE,
  GET,
  HEAD,
  OPTIONS,
  PATCH,
  POST,
  PUT;
  private final List annotations;

  HttpMethod(String... packages) {
    var packageList =
        packages.length == 0 ? List.of("io.jooby.annotation", "jakarta.ws.rs") : List.of(packages);
    this.annotations = packageList.stream().map(it -> it + "." + name()).toList();
  }

  /**
   * Look at path attribute over HTTP method annotation (like io.jooby.annotation.GET) or fallback
   * to Path annotation.
   *
   * @param element Type or Method.
   * @return Path.
   */
  public List path(Element element) {
    var path =
        annotations.stream()
            .map(it -> AnnotationSupport.findAnnotationByName(element, it))
            .filter(Objects::nonNull)
            .findFirst()
            .map(it -> AnnotationSupport.findAnnotationValue(it, VALUE.or("path"::equals)))
            .orElseGet(List::of);
    return path.isEmpty() ? HttpPath.PATH.path(element) : path;
  }

  /**
   * Look at consumes attribute over HTTP method annotation (like io.jooby.annotation.GET) or
   * fallback to Consumes annotation.
   *
   * @param element Type or Method.
   * @return Consumes media type.
   */
  public List consumes(Element element) {
    return mediaType(element, HttpMediaType.Consumes, "consumes"::equals);
  }

  /**
   * Look at produces attribute over HTTP method annotation (like io.jooby.annotation.GET) or
   * fallback to Produces annotation.
   *
   * @param element Type or Method.
   * @return Produces media type.
   */
  public List produces(Element element) {
    return mediaType(element, HttpMediaType.Produces, "produces"::equals);
  }

  private List mediaType(
      Element element, HttpMediaType mediaType, Predicate filter) {
    var path =
        annotations.stream()
            .map(it -> AnnotationSupport.findAnnotationByName(element, it))
            .filter(Objects::nonNull)
            .findFirst()
            .map(it -> AnnotationSupport.findAnnotationValue(it, filter))
            .orElseGet(List::of);
    return Stream.concat(path.stream(), mediaType.mediaType(element).stream()).toList();
  }

  public static boolean hasAnnotation(TypeElement element) {
    if (element == null) {
      return false;
    }
    var names = Stream.of(element.toString(), element.asType().toString()).distinct().toList();
    return Stream.of(values()).anyMatch(it -> it.annotations.stream().anyMatch(names::contains));
  }

  public static HttpMethod findByAnnotationName(String name) {
    return Stream.of(values())
        .filter(it -> it.annotations.contains(name))
        .findFirst()
        .orElseThrow(() -> new IllegalArgumentException("Not found: " + name));
  }

  public static List annotations() {
    return Stream.of(values()).flatMap(it -> it.annotations.stream()).toList();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy