Esfinge Metadata


Overview

The EsfingeMETADATA is an extensible framework for metadata validation, which aims to simplify and mainly assist the development of frameworks based on metadata. In addition, it can also be used in applications based on custom annotations.

Dependencies of the framework

It is necessary to add the EsfingeMETADATA JAR files with the following dependencies: commons-beanutils-1.9.2.jar commons-collections-3.2.2.jar commons-logging-1.2.jar

Metadata Locator

To find the annotations use the methodAnnotationFinder.findAnnotation, this will return a list of Annotations.

Example:
List<Annotation> annotationList =AnnotationFinder.findAnnotation(container.getClass(), ContainerFor.class);

Validation configuration meta-annotations

@ToValidate

This annotation is used by validation annotations to identify which records must be validated by EsfingeMETADATA.

@ToValidateProperty

This meta-annotation is used by validation annotations to specify which attributes of the notes must be validated by EsfingeMETADATA.

@SearchOnEnclosingElements

This meta-annotation of configuration indicates that the retrieval of the annotation to be validated can be searched in the element that involves (levels above) the object informed as parameter, until reaching the extreme point of the search, in which there is no more where to look.

Metadata Validator

MetadataValidator in one minute

To run the validator metadata must perform the following steps:

  • Add the import net.sf.esfinge.metadata.AnnotationValidationException to call the EsfingeMetadata validation exceptions:
  • Add the import net.sf.esfinge.metadata.validate.MetadataValidator , to declare that you will use EsfingeMetadata to validate your code:
  • Initialize the method: MetadataValidator.validateMetadataOn(Class<?>); to search validations notes the EsfingeMetadata where the Class<?> is the class that you want to validate:

Example:

In order to validate the metadata, an annotation must first be created, in this example I am using the quantity with the annotation @unique, and the annotations @SearchOnEnclosingElements and @SearchInsideAnnotations are to go through the annotation internally:

@SearchOnEnclosingElements
@SearchInsideAnnotations
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PointsToUser {
@Unique
int quantity();
String name();
}

Class containing annotation to be validated by metadata validator:

public class Classe{ 
    @PointsToUser(name="ponto", quantity=10)  
    public void registrar(){ 

    }
}

Para validar o as anotações é necessário usar o método MetadataValidator.validateMetadataOn(Classe.class), se as anotações estiverem com alguma inconsistência vai ser executado a exceção AnnotationValidationException:

import net.sf.esfinge.metadata.AnnotationValidationException;
import net.sf.esfinge.metadata.validate.MetadataValidator; 
    public class ExemploMetadata { 
        
        public static void main(String[] args) 
        { 
            try { 
                MetadataValidator.validateMetadataOn 
                (Classe.class); 
                
            } catch  
            (AnnotationValidationException e) { 
            
                e.printStackTrace(); 
            }   
        }   

    }

Property Validation

@Unique

This annotation checks whether the method of a particular annotation is unique to a particular interface. That is, two methods of the same annotation can not be annotated with this type of annotation.

Example:

@SearchOnEnclosingElements
@SearchInsideAnnotations
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PointsToUser {
@Unique
int quantity();
String name();
}
@NotNull

This meta-annotation checks whether a given attribute value is not null / empty for a particular annotation.

Example:

@SearchOnEnclosingElements
@SearchInsideAnnotations
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PointsToUser {
int quantity();
@NotNull
String name();
}
@MinValue

This meta-annotation checks whether a given attribute value is not null / empty for a particular annotation. The validator defines the following attribute: value (): The minimum value of the annotation attribute it refers to.

Example:

@SearchOnEnclosingElements
@SearchInsideAnnotations
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PointsToUser {
@MinValue(value=0)
int quantity();
String name();
}
@MaxValue

This validator indicates that the attribute value of an annotation must be less than or equal to the value specified by the meta-annotation in question. The validator defines the following attribute: value (): The maximum value of the annotation attribute to which it refers.

Example:

@SearchOnEnclosingElements
@SearchInsideAnnotations
@Target({ElementType.METHOD, ElementType.TYPE,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PointsToUser {
@MaxValue(value=10)
int quantity();
String name();
}
@RefersTo

This validator indicates that the value of the attribute of an annotation must refer (be equal) to the value of the attribute of another annotation somewhere in the program. The validator defines the following attributes: annotation(): Target annotation to which the current attribute refers. attributeValue():The value of the attribute of the target annotation to which the current attribute refers.

Context Validation

@Prohibits

This validator states that if a code element is annotated with the current annotation, then it will prohibit the use of another informed annotation. This validator is defined by a single value() attribute that tells the annotated class to be prohibited.

@NeedsToHave

This validator is the opposite of @Prohibits. It requires that the current meta-annotation should occur on elements that contain the annotation reported in value().

 

Field Validation

 

Validation by Modifiers
@FinalFieldOnly

This annotation indicates that the field using annotated annotation must have the final modifier.

Example:

@FinalFieldOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithFinalFieldOnly {
}
@StaticFieldOnly

This annotation indicates that the field using annotated annotation must have the static modifier.

Example:

@StaticFieldOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithStaticFieldOnly {
}
@TransientFieldOnly

This annotation indicates that the field using annotated annotation must have the transient modifier.

Example:

@TransientFieldOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithTransientFieldOnly {
}
@VolatileFieldOnly

This annotation indicates that the field using annotated annotation must have the volatile modifier.

Example:

@VolatileFieldOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithVolatileFieldOnly {
}
@InstanceFieldOnly

This annotation indicates that the field uses the annotation annotated may NOT have the modifier static.

Example:

@InstanceFieldOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithInstanceFieldOnly {
}

 

Validation by Visibility
@FieldVisibilityForbidden

This annotation indicates that the field that uses the annotated annotation may NOT have the visibility passed in the itCannotHaveThisVisibility parameter.

Example:

@FieldVisibilityForbidden(itCannotHaveThisVisibility = "public")
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithFieldVisibilityForbidden {
}
@FieldVisibilityRequired

This annotation indicates that the field that uses the annotated annotation needs have the visibility passed in the itNeedsToHaveThisVisibility parameter.

Example:

@FieldVisibilityRequired(itNeedsToHaveThisVisibility = "private")
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithFieldVisibilityRequired {
}

 

Validação por Tipo
@ValidFieldTypes

This annotation indicates that the field that uses the annotated annotation needs have a type passed in the listValidTypes parameter.

Example:

@ValidFieldTypes(listValidTypes = {String.class, List.class, int.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithValidFieldTypes {
}

 

Method Validation

 

Validation by Modifiers
@FinalMethodOnly

This annotation indicates that the method using annotated annotation must have the final modifier.

Example:

@FinalMethodOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithFinalMethodOnly {
}
@StaticMethodOnly

This annotation indicates that the method using annotated annotation must have the static modifier.

Example:

@StaticMethodOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithStaticMethodOnly {
}
@SynchronizedMethodOnly

This annotation indicates that the method using annotated annotation must have the synchronized modifier.

Example:

@SynchronizedMethodOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithSynchronizedMethodOnly {
}
@StrictfpMethodOnly

This annotation indicates that the method using annotated annotation must have the strictfp modifier.

Example:

@StrictfpMethodOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithStrictfpMethodOnly {
}
@InstanceMethodOnly

This annotation indicates that the method uses the annotation annotated may NOT have the modifier static.

Example:

@InstanceMethodOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithInstanceMethodOnly {
}

 

Validation by Visibility
@MethodVisibilityForbidden

This annotation indicates that the method that uses the annotated annotation may NOT have the visibility passed in the itCannotHaveThisVisibility parameter.

Example:

@MethodVisibilityForbidden(itCannotHaveThisVisibility = "private")
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithMethodVisibilityForbidden {
}
@MethodVisibilityRequired

This annotation indicates that the method that uses the annotated annotation needs have the visibility passed in the itNeedsToHaveThisVisibility parameter.

Example:

@MethodVisibilityRequired(itNeedsToHaveThisVisibility = "protected")
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithMethodVisibilityRequired {
}

 

Validation by Name Convention
@MethodNamingConvention

This annotation indicates that the method using the annotated annotation must have a method name according to the regular expression passed in the parameter regexNamingConvention.

Example:

@MethodNamingConvention(regexNamingConvencion = "^get")
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithMethodNamingConvention {
}

 

Validation by Parameters
@NoParametersMethodOnly

This annotation indicates that the method using annotated annotation can NOT have parameters.

Example:

@NoParametersMethodOnly
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithNoParametersMethodOnly {
}
@ValidNumberOfParameters

This annotation indicates that the method that uses the annotated annotation needs number of parameters passed in the numberOfParameters parameter.

Example:

@ValidNumberOfParameters(numberOfParameters = 2)
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithValidNumberOfParameters {
}
@ValidMethodParameterTypes

This annotation indicates that the method using the annotated annotation needs to have the parameters corresponding to what was passed in the validParameters parameter, where valid parameters are indicated by the @Parameters In the parameters parameter.

Example:

@ValidMethodParameterTypes(
		validParameters = {
			@Parameters( parameters = {String.class, Integer.class} ), 
			@Parameters( parameters = {String.class, int.class} )
		}
)
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithValidMethodParameterTypes {
}

 

Return Validation
@ForbiddenMethodReturn

This annotation indicates that the method that uses the annotated annotation CAN NOT have return passed in invalidTypesToReturn parameter.

Example:

@ForbiddenMethodReturn(invalidTypesToReturn = {void.class, float.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithForbiddenMethodReturn {
}
@ValidMethodReturn

This annotation indicates that the method that uses the annotated annotation needs have return passed in validTypesToReturn parameter.

Example:

@ValidMethodReturn(validTypesToReturn = {int.class, Integer.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotationWithValidMethodReturn {
}

 

Metadata Validator Extension

To create an extension for the metadata validator you must:

Create annotated annotation with:@ToValidateProperty()

Example:

@ToValidateProperty(validationClass = UniqueAnnotationValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Unique { 
}

Implement the AnnotationPropertyValidator, it has this structure:

public interface AnnotationPropertyValidator {
	public void initialize(Annotation self); 
    
	public void validate(Annotation annotationOnElement, AnnotatedElement annotatedWithMainAnnotation, Method annotatedWithValidation, 
	                      Object annotationPropertyValue) throws AnnotationValidationException;
}            
    

Where the initialize() method is responsible for initializing the validation class and validate() is responsible for validation;

Metadata Reader

MetadataReader in one minute

Import static method: import static net.sf.esfinge.metadata.AnnotationReader.readingAnnotationsTo;

Container container = readingAnnotationsTo(Dominio.class, Container.class); 

Where Domain.class is the class that will be captured the information and the Container.class is the class that will be stored the notes for future use.

Example: At first we created the target class of the metadata reader.

 @Entidade
@Tabela(nome="dominio")
public class Dominio {
	private String nomeField; 
        
         @FieldLista 
         private int fieldTrue; 
        
         public void entidadeFalse(){} 
        
         @Proces 
         public void entidadeTrue(){} 
         }

Next we create a container with the metadata read annotations we want.

In this case, I'm wanting to know class information, such as the name, if it contains the annotated class.

@ContainerFor(vaule = ContainerTarget.CLASS)
public class Container { 
      @ContainsAnnotation(Entidade.class) 
      private boolean entidade; 
        
      @ElementName 
      private String nomeClasse; 
                
      @ReflectionReference 
      private Class<?> classValue; 
        
      @AnnotationProperty(annotation = Tabela.class, property ="nome") 
      private String nomeTabela; 
        
      @ProcessMethods 
      private List<MethodContainer> listaMethod; 
        
       @ProcessFields 
       private List<FieldContainer> listaField; 
                
                //métodos gets e sets omitidos   
}

In the case of method and field annotations, you must create a container with the @ContainerFor annotation for METHODS or FIELDS. Exemplo for METHOD:

@ContainerFor(vaule = ContainerTarget.METHODS)
public class MethodContainer {
	@ContainsAnnotation(Proces.class)
	private boolean toProcess;
	@ElementName
	public String metodo;
}

 

Metadata Reader Annotations

@ContainsAnnotation

This Fields annotation checks to see if the selected annotation exists on the target element. It contains only the value () method that returns if the selected annotation exists, this annotation should be used in boolean primitive types or Boolean type classes.

@AnnotationProperty

This annotation checks if there is an annotation annotated in the target class, and also verifies if there is a property with a name described.

@ElementName

This field annotation takes the name of the element that has been annotated and passes to the container field.

@ReflectionReference

This field annotation takes the class of the element that has been annotated and passes to the field that was annotated with this element.

@ProcessMethods

This annotation takes the information from the methods, and places it in a container with the Methods information, it must be stored in the List, Set, Map container with information about the Methods.

@ProcessFields

This annotation takes Fields information, and places it in a container with Fields information, it must be stored in the List, Set, Map of Containers for the fields.

@AllMethodsWith

This annotation takes the information from the Methods, and places it in a container with the Methods information, it must be stored in the List, Set, Map container with information about the methods. It contains only the value () method and only takes the Methods with that annotation defined in it.

@AllFieldsWith

This annotation takes Fields information, and places it in a container with Fields information, it must be stored in the List, Set, Map of Containers for the fields.

Metadata Reader Extension

To create an extension for the Metadata Reader you must:

Create annotation with: @AnnotationReadingConfig() This annotation will tell which annotation is being passed;

Placing the @ValidFieldType() annotation, this annotation tells what types or classes annotations will be annotated. Example:


    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.FIELD) 
    @AnnotationReadingConfig(AllFieldsWithReadingProcessor.class) 
    @ValidFieldType({List.class, Set.class,Map.class}) 
     public @interface AllFieldsWith {
		Class<?  extends Annotation> value();
    }   

- Implement the AnnotationReadingProcessor interface, it has this structure:


            public interface AnnotationReadingProcessor { 
            
            void initAnnotation(Annotation an, Field field) throws AnnotationValidationException; 
            
            void read(AnnotatedElement classWithMetadata, Object container, ContainerTarget enumStr) throws AnnotationReadingException; 

            } 

Where the init Annotation () function is responsible for initializing the validation class and read() is responsible for reading the annotations:

 

 

 

 

Supported by

All rights reserved