Retired Project: Annotating Gen Objects (Part 2)

NOTE: This project has been retired and there will be no more updates. Other future projects may be reuse some concepts presented here.

Overview

Part 1 provided a general description of the concept behind annotating objects in the Gen Model. Now is time to be more specific about how to process annotations that have been attached to number objects stored in the CA Gen model.

The concept of annotations is very well-established in the world of Java programming language. This project uses a similar approach of processing the annotations in the Gen model to the one proposed in the Java world. I need to emphasize the word “similar”, but it is not the same.

At this point, it will be a largely simplified solution allowing just to experiment with the development of a variety of utilities and tools.

Annotation Worker

The provided classAnnotationWorker helps you in the process of extracting annotations from the Gen objects. Very much like in the Java world, developers have to implement a number of annotation processors and annotation workers will run them. A processor may be asked to process a subset of the annotations found in the number of objects. A user activating annotation worker provides a list of objects as an initial source for the processing. Java compiler processes annotations in the Java world. Here annotation worker plays the role of Java compiler in the processing annotations.

Processor

The processor is essentially a Java class provided by the developer which implements the interfaceProcessor. The class implementing Processor interface has to follow strict rules. This project provides an abstract classAbstractProcessor implementing initial logic.

package eu.jgen.notes.annot.processor.base;

import java.util.Set;

import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation;

public interface ć {

   public Set<String> getSupportedAnnotationTypes();

   public void init(ProcessingEnvironment processingEnv);

   public boolean process(Set<XAnnotation> annotations, ScanEnvironment scanEnv);

}

Here is an example of the classProcessor doing some simple reporting.

package eu.jgen.notes.annot.processor.tests.sample;

import java.util.Set;

import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation;

import eu.jgen.notes.annot.processor.base.ScanEnvironment;
import eu.jgen.notes.annot.processor.base.SupportedAnnotationTypes;
import eu.jgen.notes.annot.processor.impl.AbstractProcessor;
import eu.jgen.notes.annot.processor.impl.AnnotationObject;
import eu.jgen.notes.annot.processor.impl.DiagnosticKind;

@javax.annotation.processing.SupportedAnnotationTypes(value = { "" })
@SupportedAnnotationTypes(value = { "eu.jgen.notes.annot.processor.tests.sample.Author",
		"eu.jgen.notes.annot.processor.tests.sample.Function" })
public class SampleProcessor extends AbstractProcessor {

	public SampleProcessor() {
		super();
	}

	@Override
	public boolean process(Set<XAnnotation> annotations, ScanEnvironment scanEnv) {
		System.out.println("\nSupported Annotations:");
		for (XAnnotation annotation : annotations) {
			System.out.println(annotation.getAnnotationType().getQualifiedName());
		}
		System.out.println("\n\nAnnotation Objects Found:");
		for (AnnotationObject annotationObject : scanEnv.getScanResult()) {
			System.out.println("\n" + annotationObject);
		}
		
		Set<AnnotationObject>  selection = scanEnv.getElementsAnnotatedWith(eu.jgen.notes.annot.processor.tests.sample.Function.class);
		for (AnnotationObject annotationObject : selection) {
			System.out.println("Selection: \n" + annotationObject);
			processingEnv.getMessager().printMessage(DiagnosticKind.INFO, "Done.");
		}
		return true;
	}

}

Here is a sample code showing how simple is to invoke annotation worker. Please do not be confused by the syntax. This bit is written using Xtend language but is similarly easy when in Java.

package eu.jgen.notes.annot.processor.tests.sample

import com.ca.gen.jmmi.schema.ObjTypeCode
import com.ca.gen.jmmi.schema.ObjTypeHelper
import com.google.inject.Inject
import eu.jgen.notes.annot.desc.annotation.Metadata
import eu.jgen.notes.annot.desc.tests.AnnotationInjectorProvider
import eu.jgen.notes.annot.processor.impl.AnnotationWorker
import eu.jgen.notes.automation.wrapper.JGenEncyclopedia
import eu.jgen.notes.automation.wrapper.JGenFactory
import eu.jgen.notes.automation.wrapper.JGenModel
import org.eclipse.xtext.resource.XtextResourceSet
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.testing.validation.ValidationTestHelper
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(XtextRunner)
@InjectWith(AnnotationInjectorProvider)
class ProcessorTest {

	static JGenEncyclopedia ency 
	static JGenModel genModel  

	@Inject
	ParseHelper<Metadata> parseHelper
	@Inject extension ParseHelper<Metadata>
	@Inject extension ValidationTestHelper
	@Inject XtextResourceSet resourceSet
	@Inject AnnotationWorker worker

	@Test
	def void loadModel() {

		var JGenFactory factory = JGenFactory::eINSTANCE
		ency = factory.createEncyclopedia()
		ency.connect()
		genModel = ency.findModels().get(0)
		var objects = genModel.findTypeObjects(ObjTypeHelper.getCode(ObjTypeCode.ACBLKBSD))
		worker.initProcessor(new SampleProcessor()).setSources(objects).activate

	}
}

Summary

All sources including examples are published here. This project will need more refining and some more functionality and new features coming soon together with better documentation.