annotation-magic

Empower your Java annotations with magic.

Лицензия

Лицензия

Группа

Группа

com.github.blindpirate
Идентификатор

Идентификатор

annotation-magic
Последняя версия

Последняя версия

0.2.5
Дата

Дата

Тип

Тип

pom.sha512
Описание

Описание

annotation-magic
Empower your Java annotations with magic.
Ссылка на сайт

Ссылка на сайт

https://github.com/blindpirate/annotation-magic
Система контроля версий

Система контроля версий

https://github.com/blindpirate/annotation-magic

Скачать annotation-magic

Зависимости

Библиотека не имеет зависимостей. Это самодостаточное приложение, которое не зависит ни от каких других библиотек.

Модули Проекта

Данный проект не имеет модулей.

Annotation Magic - the magic of Java annotations

annotation-magic

Java annotation is a great feature, but it doesn't support inheritance or composition. This library enables annotation inheritance and composition for you, aka. "the magic way", which can greatly improve your API design.

Annotation Inheritance

In the following example, you can see how @Cat extends @Pet, which extends @Animal.

You declare the inheritance relationship via @Extends annotation.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@interface Animal {
    boolean fluffy() default false;

    String name() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Extends(Animal.class)
@Animal(fluffy = true)
@interface Pet {
    String name();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Extends(Pet.class)
@interface Cat {
    @AliasFor("name")
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Extends(Pet.class)
@interface Dog {
    String name();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Extends(Animal.class)
@interface Rat {
    @AliasFor(target = Animal.class, value = "name")
    String value();
}

@Cat("Tom")
class MyClass {
    @Dog(name = "Spike")
    @Rat("Jerry")
    public void foo() {
    }
}


public class ReadMeInheritanceSampleTest {
    @Test
    public void test() throws NoSuchMethodException {
        Pet petAnnotation = AnnotationMagic.getOneAnnotationOnClassOrNull(MyClass.class, Pet.class);
        assertEquals("Tom", petAnnotation.name());
        assertTrue(AnnotationMagic.instanceOf(petAnnotation, Animal.class));

        Animal animalAnnotation = AnnotationMagic.getOneAnnotationOnClassOrNull(MyClass.class, Animal.class);
        assertTrue(animalAnnotation.fluffy());

        Method fooMethod = MyClass.class.getMethod("foo");
        List<Animal> animalAnnotations = AnnotationMagic.getAnnotationsOnMethod(fooMethod, Animal.class);
        assertEquals(Arrays.asList("Spike", "Jerry"), animalAnnotations.stream().map(Animal::name).collect(toList()));
    }
}

Annotation composition

Annotation composition can simplify the annotation piling up, for example:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@interface GET {
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@interface Path {
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@interface Produces {
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@CompositeOf({GET.class, Path.class, Produces.class})
@interface GetResource {
    @AliasFor(target = Path.class, value = "value")
    String path();

    @AliasFor(target = Produces.class, value = "value")
    String produces();
}

class MyResource {
    @GET
    @Path("/{id}")
    @Produces("application/json")
    public String foo() {
        return "";
    }

    // Equivalent as above
    @GetResource(path = "/{id}", produces = "application/json")
    public String bar() {
        return "";
    }
}

public class ReadMeCompositionSampleTest {
    @Test
    public void test() throws NoSuchMethodException {
        assertTrue(AnnotationMagic.isAnnotationPresent(MyResource.class.getMethod("bar"), GET.class));

        Path pathAnnotation = AnnotationMagic.getOneAnnotationOnMethodOrNull(MyResource.class.getMethod("bar"), Path.class);
        assertEquals("/{id}", pathAnnotation.value());

        Produces producesAnnotation = AnnotationMagic.getOneAnnotationOnMethodOrNull(MyResource.class.getMethod("bar"), Produces.class);
        assertEquals("application/json", producesAnnotation.value());
    }
}

In this case, @GetResource is equivalent to @GET/@Path/@Produces present together. You can get any of them as if they exist.

Import

This library is published to maven central:

Gradle:

implementation("com.github.blindpirate:annotation-magic:0.2.5")

Maven:
<dependency>
    <groupId>com.github.blindpirate</groupId>
    <artifactId>annotation-magic</artifactId>
    <version>0.2.5</version>
</dependency>

Версии библиотеки

Версия
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2
0.1.2
0.1.1
0.1