Annotations

Olá, por acaso alguem tem alguem pequeno codigo que contenha 5 annotations?
pode ser qualquer coisinha simples, meu professor pediu, mas não explicou nada, li sobre o assunto mas não entendi mtu bem ): , de como usar uma annotation

se alguem puder me enviar um codigo ficaria muito agradecido

obrigado =D

Segue um trecho

@Validations(requiredStrings={
@RequiredStringValidator(fieldName=“tarefa.descricao”, message=“Valor obrigatorio”)
})
public class AdicionaTarefasAction extends ActionSupport {

private Tarefa tarefa;
private Calendar data;

@Action(value="adicionaTarefa", results = { 
		@Result(name="ok", location="lista-tarefas.jsp"),
		@Result(name="input", location="formulario-tarefas.jsp")
})

public String execute(){
	TarefaDAO tarefa = new TarefaDAO();
	tarefa.adiciona(this.tarefa);
	return "ok";
}

public Tarefa getTarefa() {
	return tarefa;
}

//@VisitorFieldValidator(key="tarefa")
public void setTarefa(Tarefa tarefa) {
	this.tarefa = tarefa;
}

}

Geralmente, nós usamos anotações, e não nos atentamos no que está acontecendo por tráz dos bastidores…

   //anotação          valor de um elemento
@ClassInfo(autor="James", dataDeCriacao="30/04/2011")
public class Foo {
...
}[/code]

Para criar a anotação você criaria como abaixo, lembre-se que a palavra interface, quando se cria uma anotação se refere ao tipo anotação!


[code]@interface ClassInfo {
String autor() default "Fulano";
String dataDeCriacao();
}[/code]


Bom vamos aos conceitos:


 :idea: Anotação é um Tipo
 :idea: Pode ser vista como uma espécie de interface,
declarada com auxílio do caractere @
 :idea: Tipos dos elementos: primitivos, String, enum,
anotação,Class ou array de um desses tipos
 :idea: Elementos podem ter valor default


Temos que considerar que se a antoação tiver apenas um elemento e ele for denominado value podemos omitir:
[code]
@interface ClassInfo { //codigo fonte da anotação
String value();
}

@ClassInfo("James")//uso da anotação em uma classe qualquer
public class Foo {
[/code]


Bom antes de continuar veja que você para criar sua própria anotação, apenas salvaria o arquivo "ClassInfo.java", e sendo assim sua anotação @ClassInfo estaria
disponível para o uso como foi o exemplo acima do uso na classe Foo.

Nós temos também as restrições que dizem onde uma anotação pode ser usada sendo algumas delas:


Restrições disponíveis:
[color=red]
ElementType.TYPE
ElementType.FIELD
ElementType.METHOD
ElementType.PARAMETER
...
 [/color]
[code]@Target(ElementType.METHOD)
@interface MetodoTestavel {
}

@ClassInfo("James")
public class Foo {
public void m1(String arg1) {
...
}
public void m2() {
...
}
@MetodoTestavel
public void m3() {
...
}
}[/code]


Acima foi criado uma anotação chamada MetodoTestavel que está sendo aplicada no método m3(), desta forma você pode definir em quais "tipos" poderá ser usada
sua interface!

Para acabar a história nos temos a política de retenção que definem quando a anotação pode ser usada sendo elas:

[color=red]RetentionPolicy.SOURCE[/color]
? Anotações existem somente no arquivo-fonte. São
descartadas pelo compilador ao produzir uma
representação binária
[color=red]RetentionPolicy.CLASS[/color]
? Anotação são preservadas na representação binária,
mas não necessitam estar disponíveis durante a execução
[color=red]RetentionPolicy.RUNTIME[/color]
? Anotações são preservadas na representação binária da
classe e devem estar disponíveis durante a execução
através do mecanismo de reflexão.

Exemplo:
[code]
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@interface ClassInfo {
String value();
}
[/code]

Desta forma podemos facilmente tirar proveito de nossas anotações com o uso da API de refexão veja abaixo o "pedaço" de código:

[code]Class <Foo> cls = Foo.class;
Annotation[] anots = cls.getAnnotations();
for (Annotation a: anots) {
Class ca = a.annotationType();
System.out.println( ca.getName() ); //ClassInfo
}[/code]

Veja que acima estamos "consultando" a classe e retornando as anotações que a Classe Foo possue....
Desta forma da para usar por exemplo chamada a métodos por meio de reflexion usando os proprios valores da anotação...

Para finalizar um exemplo prático, temos uma anotação chamada Teste, e uma classe Foo, vamos usar reflexion para chamar os métodos usando
os proprios valores da anotação, temos na classe Main.java três soluções possíveis para o caso. Abaixo o procedimento para você testar:

Salve anotação como Teste.java
Salve a classe Foo.java
E por fim temos uma classe de Teste que invoca os métodos passando como parâmetro os proprios valores da anotação:
Deixe a visibildade das classes transparente entre Si.



Teste.java
[code]import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Teste {
	String argumento() default "algum valor";

}

Foo.java



public class Foo {
	
    public void m1(String s) {  
    	System.out.println("m1 invocado com argumento = " + s);
    }
    
    
    @Teste(argumento="Valor para o teste 2")
    public void m2(String s) {
    	System.out.println("m2 invocado com argumento = " + s);
    }

    //@Teste(argumento="Valor para o teste 3")
    public void m3(String s) {
    	System.out.println("m3 invocado com argumento = " + s);
    }
}

Main.java

[code]import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {

public static void main(String[] args) throws IllegalArgumentException,
		InstantiationException, IllegalAccessException,
		InvocationTargetException {

	solucao1();
	solucao2();
	solucao3(Teste.class, Foo.class);

}

private static void solucao1() throws InstantiationException,
		IllegalAccessException, IllegalArgumentException,
		InvocationTargetException {
	Class<Foo> c = Foo.class;
	Object o = c.newInstance();

	// Obtém os métodos da classe
	Method[] ms = c.getDeclaredMethods();

	for (Method m : ms) {

		Teste t = m.getAnnotation(Teste.class);
		if (t != null) {
			t.argumento();
			m.invoke(o, t.argumento());
		}
	}

}

private static void solucao2() throws InstantiationException,
		IllegalAccessException, IllegalArgumentException,
		InvocationTargetException {
	Class<Foo> c = Foo.class;
	Object o = c.newInstance();

	// Obtém os métodos da classe
	Method[] ms = c.getDeclaredMethods();

	for (Method m : ms) {

		Annotation[] ts = m.getAnnotations();
		for (Annotation t : ts) {
			if (t.annotationType().isAssignableFrom(Teste.class)) {
				m.invoke(o, ((Teste) t).argumento());
			}
		}

	}

}

private static <T extends Annotation, U> void solucao3(
		Class&lt;T&gt; tipoDaAnotacao, Class<U> c) throws InstantiationException,
		IllegalAccessException, IllegalArgumentException,
		InvocationTargetException {

	// Dos métodos declarados na anotação, verifica se existe um chamado
	// 'argumento'
	// Se não existir, retorna, pois a anotação informada como parâmetro
	// para esse método
	// não serve, pois não tem um elemento String chamado argumento.
	Method[] msa = tipoDaAnotacao.getDeclaredMethods();
	Method elemento = null;
	for (Method ma : msa) {
		if (ma.getName().equals("argumento")
				&& ma.getReturnType().equals(String.class)) {
			elemento = ma;
			break;
		}
	}
	if (elemento == null) {
		return;
	}

	U o = c.newInstance();

	// Obtém os métodos da classe
	Method[] ms = c.getDeclaredMethods();

	for (Method m : ms) {
		T t = m.getAnnotation(tipoDaAnotacao);
		if (t != null) {
			String valorArgumento = (String) elemento.invoke(t);
			m.invoke(o, valorArgumento);
		}
	}
}

}
[/code]

Espero ter ajudado!