At first when you asked, I immediately remembered my own experiences making notes, and how I was frustrated when trying to create a note that had a validation against its possible values, so my first answer, which is highlighted below, contemplates only the alternatives I myself adopted at the time, which would be to use a different version of the compiler and/or validate the values of the Runtime annotations with unchecked Exceptions. Investigating further I discovered a feature of the Java SE platform available from version 1.6 onwards
Annotation Processor - Java 1.6 or >
It is available as of version 1.6, an API that processes the annotations you define to be validated at compile time, through an interface Processor
and an Abstract class AbstractProcessor
How it works?
First of all, no third-party library, plugin or gimmick is required, just write your own teacher and use it when compiling/processing your classes that have the annotations. In it you define which annotations you want to process, and whatever happens, and you can even stop the compilation if you don’t agree with your contracts, issue warnings, or generate codes. It is possible to have more than one Processor. Using a project cycle control tool like Maven you will be able to apply your Processors.
So let’s get to your case
You want to validate the attribute values, you cannot have empty or null strings, you cannot have an empty array, with size(length) == 0
The class below does the work! It is in the package default(without package set) to facilitate understanding and testing
import java.util.Set;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes(value={"Ordem"})
public class MandatoryValuesAnnotationProcessor extends javax.annotation.processing.AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
System.out.println("/n/n Processing... /n Processing /n");
Messager messager = processingEnv.getMessager();
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Ordem.class)){
TypeElement typeElement = (TypeElement)annotatedElement;
Ordem ordemAnnotation = typeElement.getAnnotation(Ordem.class);
String valores[] = ordemAnnotation.valores();
if(valores == null || valores.lenght == 0){
messager.printMessage(Diagnostic.Kind.ERROR, "Annotation Ordem nao pode ter valores vazios, nao pode ser um array vazio");
return true;
}
for (String valor : valores) {
if(valor == null || valor.isEmpty()){
messager.printMessage(Diagnostic.Kind.ERROR, "Annotation Ordem nao pode ter strings vazias ou nulas");
return true;
}
}
}
return true;//because we don't want other processors to process this annotations
}
@Override
public SourceVersion getSupportedSourceVersion(){
return SourceVersion.latestSupported();
}
}
Above we are defining the Processor for your classes with your annotation, below we use it, already compiled to process your classes.
Compile your Order annotation first, if you sequence the Processor, and then use it to compile the other classes, as you can see, this is not the best way to manage your build clicks so I recommend you use Maven to build your project, or another solution. You can also create a jar with your teacher, here’s where I learned:
http://hannesdorfmann.com/annotation-processing/annotationprocessing101/
For teaching purposes, use this command line when compiling your classes (you can also use Maven)
javac -cp . -Xlint:processing -processor MandatoryValuesAnnotationProcessor -proc:only Foo2.java
Read this reference for a more complete understanding
Reference
--
Note: from the original answer, it is still valid to use a prepared compiler, which is not the best, because it gives you less flexibility and it is also possible to validate attribute values annotations in Runtime, which is common in the SE and EE platform in some Apis, such as JAX-WS, for example
Original Response
No, it is not possible to Geison, at least not only working with the Oracle Hotspot compiler, there are alternative ways, such as creating your own compiler, or customizing one of the Openjdk.
I’ve tried to do what you want to do, besides other things.
What you can do instead is write a unit test using Junit that Reflection, checks the values set for this annotation, not allowing arrays empty or Strings empty.
What I’ve always done is at the moment I need to read the notation values, if these are mandatory, I throw an exception - IllegalArgumentException
Where warning the programmer that the value set cannot be null or empty.
It is possible yes using Annotation Processors, but it is somewhat difficult to implement. I don’t have (yet) the knowledge necessary for this, so I leave the hint as a comment instead of a reply. If I can work something out, I’ll give you an answer.
– Victor Stafusa
Annotation Professor, a simple example. But I would not add this complexity in order to validate the content of a parameter. Instead, I would create an annotation with expressive name in context indicating clearly what should be passed, and validate at runtime when reading the annotations. Eventually, instead of waiting for a "donkey" array as a parameter you can also create a special type for this parameter that makes it more evident to the programmer which info is required for annotation.
– Caffé
Allow me to ask Voce @Victor Stafusa In case the Annotation Processor works only for Source Retention annotations, that is not available in Runtime, is that right? I believe that Geison Santos wants the values of the score in Runtime, right?
– Filipe Miranda
@Filipegonzagamiranda Works for Runtime too.
– Victor Stafusa
@Geisonsantos, updated the answer, I hope please send me your feedback, it is yes possible to solve using Java Platform features without third party libraries
– Filipe Miranda