Page tree
Skip to end of metadata
Go to start of metadata
Summary: this page explains how to manage annotations.

Annotation group

Annotations defined in Java files and annotated objects are stored in the J2EE Analyzer memory and can be queried afterward through CAST Script.

Create an annotation group
To instruct the J2EE Analyzer to save these annotations, you must:

  1. Define an Environment Profile (if it doesn't already exist) for the framework you want to handle. For example, a profile to manage TestNG annotations (http://testng.org/).
  2. Define an annotation Group in the Environment Profile
  3. Define the list of annotations to handle
  4. Select the Analysis Method: the recommended method is CAST Script, the other one will be removed in a future version.

Which annotations to take into account?
This depends on:

  • The quality rules you want to create. If a quality rule depends on a specific property, then you must add this property to the object you will create.
  • Links between objects: to ensure navigation in CAST Enlighten and a correct Function Point result, you need to manage links from modules referenced through annotations. This is the case for example for links from Java classes to JPA entities and from JPA Entities to database tables.

Which annotation should be put in an annotation group?
An annotation group must:

  • Reference annotations that belong to the same semantic, for example: JPA annotations
  • If you use the new parsing method (CAST Script), you just have to reference annotation you want to manage. Independently of which annotation you add in this list, all annotations used in your code will still be queried by the CAST Script. The only consequence of missing one is a warning during the analysis to inform you that a specific annotation is not managed.

Note:
If you use the previous parsing method (CAST XML Query or XQuery) you must refer to the previous version of this CookBook that explains how to manage them. This parsing method as well as CAST XQuery method are kept for compatibility and will be removed in a future version.

Next
You will now need to customize the CAST Script.

Handling Annotations with CAST Script

The way to handle Java annotations with CAST Script is based on a new set of native functions:

  • native list(symbol) getSymbolsAnnotatedWith( symbol annotationType, string metatypeOrCategory );
  • native list(symbol) getSymbolsAnnotatedWith( symbol annotationType, list(string) metatypeOrCategories );
  • list(symbol) getSymbolsAnnotatedWith( string annotationFullName, string metatypeOrCategory )
  • list(symbol) getSymbolsAnnotatedWith( string annotationFullName, list(string) metatypeOrCategories )
  • symbol getAnnotationParameter( symbol annotation, string name )
  • native boolean hasAnnotation( symbol object,string annotation );
  • native list(symbol) getAnnotations( symbol object );
  • native boolean isDefaultParameter( symbol annotationParameter );
  • string getParameterStringFromAnnotation(symbol object,string annotationName,string parameterName)

with a set of string manipulation functions:

  • native string concat(string word_1,string word_2);
  • native string substring(string word, int index_begin, int length);
  • native string substring(string word, int index_begin);
  • native int getLength(string word);
  • native string toLower(string word);
  • native string toUpper(string word);
  • native int getFirstIndex(string word,string substring);
  • native string substringMatch(string word,string regexp);
  • native string toString(boolean value);
  • native string toString(int value);


Defining a CAST Script to manage a set of annotation would have the following body:

/* for all class of methods that have a specific annotation do... */
list(symbol) myClasses = getSymbolsAnnotatedWith( "myAnnotation" , JV_CLASS );
foreach( symbol class in myClasses) {
   /* create object and/or link and/or add properties */
   ...
}

Report to the Help to get the full description of native functions.
Sample:
Let's manage annotations from the following file Bid.java:

...
if you want to create an Hibernate Entity named Bid in the KB with associated links from the class and to the database table, we will use the following functions in a file located in:
<Custom CAST Script Library Path>\Custom\JEE\JPAAnnotations.castscript

/* module declaration */
module Custom.JEE.JPAAnnotations;

/* import declarations */
use Core.ConstantsMetamodel;
use Core.Log;
use Core.JEE.Annotations;
use Core.JEE.JEE;

/* creation of an Entity whose implementation class is entityClass and
 * the annotation fullname is entityAnnotation, create the link with the
 * class and the table and return the entity symbol that has been created
 */
symbol createEntity(symbol entityClass, string entityAnnotation) {
   /* 1. first we must find the name of the entity */
   /* 1.1 get the 'name' property value of @Entity annotation if exists */
   string entityName = getParameterStringFromAnnotation(entityClass,
                             entityAnnotation,"name");
   /* 1.2 if the annotation doesn't contains the entity name property,
      then the class name is used */
   if (entityName == "" || entityName == null) {
      entityName = getStringProperty(entityClass, identification_name );
   }

   /* 2. The entity parent in the object tree is the Java class file,
      so we must find this file */
   symbol entityFile = getSymbolUniqueParent(entityClass);

   /* 3. Creation of the entity */
   symbol jpaEntity = findOrCreateSymbol(entityName, JPA_ENTITY,
                          entityFile);

   /* 4. Creation of a link from the Java class
      to the Entity */
   createLink (entityClass, jpaEntity, useLink );

   /* 5. Creation of a link from the Entity to the table */
   /* 5.1 find the 'name' property value of @Table annotation if exists */
   string entityTable = getParameterStringFromAnnotation(entityClass,
                            "javax.persistence.Table","name");
   /* 5.2 if the annotation doesn't exist the entity table name,
      is the class name */
   if ((entityTable == "" || entityTable == null) {
      entityTable = entityName;
   }
   /* 5.3 get the symbol from the table name */
   symbol serverObject = findUniqueSymbol(entityTable, GROUP_SqlObject);
   /* 5.4 create the link */
   createLink (jpaEntity, serverObject, useLink );

   /* 6 return the entity */
   return jpaEntity;
}

void createAllEntities() {
    /* to manage Entities */
    list(symbol) myEntityClasses = getSymbolsAnnotatedWith(
                                "javax.persistence.Entity", JV_CLASS );
    foreach( symbol entityClass1 in myEntityClasses) {
       symbol entity = createEntity(entityClass1,
                       "javax.persistence.Entity");
    }

    /* to manage MappedSuperclass */
    myEntityClasses = getSymbolsAnnotatedWith(
                     "javax.persistence.MappedSuperClass" , JV_CLASS );
    foreach( symbol entityClass in myEntityClasses) {
       symbol entity = createEntity(entityClass,
                       "javax.persistence.MappedSuperClass");
    }
}

And we will reference the following file in the Environment Profile:
<Custom CAST Script Library Path>\Custom\JEE\JPA.castscript

/* module declaration */
module Custom.JEE.JPA;

/* import declarations */
use Custom.JEE.JPAAnnotations;

/* entities creation */
createAllEntities()

NOTE:

  • In this sample, only the interface 'javax.persistence.Entity' is required for the annotation @Entity.
  • javax.persistence.MappedSuperclass' has been added to manage the more general case where the annotation @MappedSuperclass is used.
  • <Custom CAST Script Library Path> directory is defined though the menu Technology > J2EE > Platform Setting > CAST Script Library Directory

Managing SQL Queries embedded in annotations

To manage SQL annotation embedded in Java annotations, you just have to create a CAST Script that get the annotation value (the same as explained in the sample Handling Annotations with CAST Script - see above) and then call the CAST Script function analyzeDBQuery as explained in Handling Annotations with CAST Script - see above. Write the CAST Script function that will create the Cast_SQL_NamedQuery object except that you have to use the analyzeDBQuery with the signature symbol analyzeDBQuery(string queryType, string queryName, string dbRequest, symbol queryParent) to set the parent of the query objet to the Java class, method or attribute depending on which is the object type the annotation is associated to.

Some CAST Script tips

Notion of parents: how to navigate in the memory representation of Java and JSP objects?
When using CAST Scripts functions that have a parameter "parent", how to know what is a parent of a specific object?

This notion of parent and children is the same that is displayed in Enlighten Object Tree. You can see for example, that a Java Class is the child of a Java File.

There is only one exception to this rule: the Java annotations. Java annotations applied on a class are not represented in Enlighten (there is only an annotation object type but not the annotation applied on the class, method, field...). So, what you must know is that if you want for example the list of annotations used on a class, method or field, you must use findUniqueSymbol with the annotation fullname, the type = CAST_Java_AnnotationType and use the class, method or field as the parent.

In the same way, annotation parameters are children of annotations.