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

net.chestmc.common.annotations.Service.kt Maven / Gradle / Ivy

package net.chestmc.common.annotations

import com.google.auto.service.AutoService
import io.github.uinnn.serializer.DefaultJsonStrategyFormat
import kotlinx.serialization.encodeToString
import javax.annotation.processing.Processor
import javax.annotation.processing.RoundEnvironment
import javax.annotation.processing.SupportedAnnotationTypes
import javax.annotation.processing.SupportedSourceVersion
import javax.lang.model.SourceVersion
import javax.lang.model.element.TypeElement
import javax.tools.StandardLocation

/**
 * Represents a autommatically registered service. All objects and classes without constructors
 * annotated with this annotation, will be parsed as a service, and will be loaded when
 * the plugin enables.
 */
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class Service

/**
 * A annotation processor for processing [Service] annotations.
 * This processor is responsable to create the `services.json` and
 * inserts the values inside of them.
 */
@SupportedAnnotationTypes("net.chestmc.common.annotations.Service")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@AutoService(Processor::class)
class ServiceProcessor : StandardProcessor() {
  override fun process(annotations: MutableSet, roundEnv: RoundEnvironment): Boolean {
    val found = roundEnv.getElementsAnnotatedWith(Service::class.java)
    if (found.isNullOrEmpty())
      return false

    val values = found
      .map { it as TypeElement }
      .filter { it.isSupported() }
      .map { it.qualifiedName.toString() }

    create(values)
    return true
  }

  /**
   * Verify if a element is extending any of service interface.
   */
  fun TypeElement.isSupported(): Boolean {
    val serviceType = elements.getTypeElement("net.chestmc.common.service.ServiceRegistry").asType()
    return when {
      types.isAssignable(superclass, serviceType) -> true
      interfaces.contains(serviceType) -> true
      else -> error("The element annotated with @Service not extends any type of net.chestmc.common.service.ServiceRegistry")
    }
  }

  /**
   * Creates the services resouce file by the specified list.
   */
  fun create(values: List) {
    filer.createResource(StandardLocation.CLASS_OUTPUT, "", "services.json")
      .openWriter()
      .use {
        it.write(DefaultJsonStrategyFormat.encodeToString(values))
      }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy