javanna-gson

Library to convert between JSON and Java annotations at runtime.

License

License

Categories

Categories

Gson Data JSON
GroupId

GroupId

com.athaydes.javanna
ArtifactId

ArtifactId

javanna-gson
Last Version

Last Version

1.0
Release Date

Release Date

Type

Type

jar
Description

Description

javanna-gson
Library to convert between JSON and Java annotations at runtime.

Download javanna-gson

How to add to project

<!-- https://jarcasting.com/artifacts/com.athaydes.javanna/javanna-gson/ -->
<dependency>
    <groupId>com.athaydes.javanna</groupId>
    <artifactId>javanna-gson</artifactId>
    <version>1.0</version>
</dependency>
// https://jarcasting.com/artifacts/com.athaydes.javanna/javanna-gson/
implementation 'com.athaydes.javanna:javanna-gson:1.0'
// https://jarcasting.com/artifacts/com.athaydes.javanna/javanna-gson/
implementation ("com.athaydes.javanna:javanna-gson:1.0")
'com.athaydes.javanna:javanna-gson:jar:1.0'
<dependency org="com.athaydes.javanna" name="javanna-gson" rev="1.0">
  <artifact name="javanna-gson" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.athaydes.javanna', module='javanna-gson', version='1.0')
)
libraryDependencies += "com.athaydes.javanna" % "javanna-gson" % "1.0"
[com.athaydes.javanna/javanna-gson "1.0"]

Dependencies

compile (2)

Group / Artifact Type Version
com.athaydes.javanna : javanna jar 1.1
com.google.code.gson : gson jar 2.7

test (1)

Group / Artifact Type Version
junit : junit jar 4.12

Project Modules

There are no modules declared in this project.

Javanna

A Java library to create and introspect annotations at runtime.

The whole library is just one class: com.athaydes.javanna.Javanna.

To map between Java annotations and JSON, see Javanna-Gson.

Getting started

Javanna is on JCenter and Maven Central.

Gradle

dependencies {
    compile "com.athaydes.javanna:javanna:1.1"
}

Maven

<dependency>
  <groupId>com.athaydes.javanna</groupId>
  <artifactId>javanna</artifactId>
  <version>1.1</version>
</dependency>

Parse an annotation class

Given the following example definitions:

@Retention( RetentionPolicy.RUNTIME )
@interface Simple {
    String value();
}

enum Example {SMALL, MEDIUM, LARGE, XXX}

@Retention( RetentionPolicy.RUNTIME )
@interface Complex {
    String name() default "default-name";

    int count() default 2;

    Simple simple();

    Example example();
}

You can parse the annotations like this:

JavaAnnotation<Complex> annotation = Javanna.parseAnnotation( Complex.class );

And then, inspect its members types and defaults (from the unit tests):

// check the annotation actual type
assertEquals( Complex.class, annotation.getAnnotationType() );

// check the default values Map
assertEquals( new HashMap<String, Object>() {{
    put( "name", "default-name" );
    put( "count", 2 );
}}, annotation.getDefaultValueByMember() );

// check the annotation member types
assertEquals( new HashMap<String, Class<?>>() {{
    put( "name", String.class );
    put( "count", int.class );
    put( "simple", Simple.class );
    put( "example", Example.class );
}}, annotation.getTypeByMember() );

// check the annotation members
assertEquals( new HashSet<>( Arrays.asList( "name", "count", "simple", "example" ) ), annotation.getMembers() );

Create an annotation instance

An annotation instance can be created from a Class or JavaAnnotation:

final Simple simple = Javanna.createAnnotation( Simple.class, new HashMap<String, Object>() {{
    put( "value", "the-simple-one" );
}} );

Complex complex = Javanna.createAnnotation( Complex.class, new HashMap<String, Object>() {{
    put( "name", "hello" );
    put( "count", 6 );
    put( "simple", simple );
    put( "example", Example.LARGE );
}} );

// use the annotation as if it were a normal annotation instance
assertEquals( "hello", complex.name() );
assertEquals( 6, complex.count() );
assertEquals( "the-simple-one", complex.simple().value() );
assertEquals( Example.LARGE, complex.example() );

It is an error to not provide mandatory values, or to give invalid members or values of the wrong type. All errors cause an IllegalArgumentException to be thrown by the createAnnotation method.

Read the values of an annotation instance as a Map

To read all values of an annotation as a Map, use the getAnnotationValues method:

Map<String, Object> values = Javanna.getAnnotationValues( annotation );

Full example (from the unit tests):

@Simple( "hi" )
@Complex( name = "hello", count = 6, simple = @Simple( "hi" ), example = Example.SMALL )
public void canReadComplexAnnotationValues() throws Exception {
    // get the annotations on this method
    final Annotation simple = getClass().getMethod( "canReadComplexAnnotationValues" ).getAnnotation( Simple.class );
    final Annotation complex = getClass().getMethod( "canReadComplexAnnotationValues" ).getAnnotation( Complex.class );

    // expected values of the @Complex annotation
    Map<String, Object> expectedValues = new LinkedHashMap<String, Object>() {{
        put( "name", "hello" );
        put( "count", 6 );
        put( "simple", simple );
        put( "example", Example.SMALL );
    }};

    // read the annotation values as a Map
    Map<String, Object> actualValues = Javanna.getAnnotationValues( complex );

    assertEquals( expectedValues, actualValues );
}

To extract annotation values recursively (eg. get the value of the @Simple annotation as a Map in the example above), just use the getAnnotationValues(Annotation a, boolean recursive) method:

Map<String, Object> actualValues = Javanna.getAnnotationValues( complex, true );

In this case, the resulting Map would be:

Map<String, Object> expectedValues = new LinkedHashMap<String, Object>() {{
    put( "name", "hello" );
    put( "count", 6 );
    put( "simple", new LinkedHashMap<String, Object>() {{
        put( "value", "hi" );
    }} );
    put( "example", Example.SMALL );
}};

Versions

Version
1.0