quinta-feira, 3 de maio de 2007

Annotations

Olá, hoje vou falar um pouquinho das Annotations, que está disponibilizado desde a versão 5.0 do Java.

Annotation são meta-informações que guardam informações de dados dentro do proprio código-fonte, isso é muito util em frameworks por exemplo, porque não precisamos ter mais bilhões de arquivos xml guardando configurações e isso pode estar dentro do código, ficando mais facil e rapido de configurar o framework.

Bom para ilustrar melhor as annotations e o seu uso resolvi fazer um exemplo de validação de java beans utilizando elas.

Para começar, o código da Annotation:

/*
* Validation.java
*
* Created on 5 de Abril de 2007, 21:55
*
*/

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation para validar campos em beans.
* @author Emmanuel Silva
*/

@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.FIELD)
public @interface Validation {

/**
* Tipo da validação guardada em um Enum que será realizada, por padrão será
* checagem de not null
**/
ValidationType type() default ValidationType.NOT_NULL;

/**
* Se a validação for do tipo max_length, aqui eu guardo o tamanho maximo
**/
int maxlength() default 0;

}



Proximo passo é a criação do Enum que define os tipos de validações que serão validadas:


/**
*
* @author Emmanuel Silva
*/
public enum ValidationType {

MAX_LENGTH,

NOT_NULL;
}


Agora, temos o nosso Java Bean que será validado, repare que as annotations são chamadas através de um
@ e porque a Annotation é para field ela está em cima dos atributos:


/**
*
* @author Emmanuel Silva
*/
public class PessoaBean {

@Validation()
private String nome;
private String login;
@Validation(type=ValidationType.MAX_LENGTH, maxlength=6)
private String senha;

/** Creates a new instance of PessoaBean */
public PessoaBean() {
}

public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getSenha() {
return senha;
}

public void setSenha(String senha) {
this.senha = senha;
}
}


Agora temos a classe responsavel por validar os Java Beans, essa classe utiliza de um recurso muito poderoso presente no Java chamado Reflection, o reflection serve para que através de código Java eu consiga manipular uma classe como: Listar seus atributos, ler/modificar seus valores, entre outras coisas:


import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
*
* @author Emmanuel Silva
*/
public class ValidatorUtil {

private Object obj;

public void validate(Object obj) {
this.obj = obj;
Class classe = obj.getClass();
Field[] fields = classe.getDeclaredFields();

for(Field field : fields) {
if(field.isAnnotationPresent(Validation.class)) {
Validation validation = field.getAnnotation(Validation.class);
validateField(validation, field);
}
}
}

private void validateField(Validation v, Field field) {
field.setAccessible(true);
if(v.type() == ValidationType.NOT_NULL) {
boolean result = checkNotNull(field);
if(!result) {
System.out.println("Campo " + field.getName() + " nao foi preenchido corretamente.");
}
}

if(v.type() == ValidationType.MAX_LENGTH) {
boolean result = checkMaxLength(field, v.maxlength());
if(!result) {
System.out.println("Quantidade de caracteres permitido para o campo " + field.getName() + " é de "+ v.maxlength() +".");
}
}
}


private boolean checkNotNull(Field field) {
try {
if(field.get(this.obj) == null)
return false;
else
return true;
} catch(Exception ex) {
return false;
}
}

private boolean checkMaxLength(Field field, int max) {
try {
if(field.get(this.obj) != null && field.get(this.obj).toString().length() > max)
return false;
else
return true;
} catch(Exception ex) {
return false;
}
}

}


Por final, criei uma classe para testar as validações, criando 2 instancias do Java Bean "PessoaBean", uma instancia está com os dados incorretos e a outra instancia está com os dados corretos, assim que a instancia que estiver incorreta passar pelo validador será impressa os seus erros:


/**
*
* @author Emmanuel Silva
*/
public class Main {

/** Creates a new instance of Main */
public Main() {

System.out.println("Validando primeira pessoa");
//pessoa com cadastro invalido
PessoaBean pessoa = new PessoaBean();
pessoa.setLogin("login");
pessoa.setSenha("1234567");

ValidatorUtil valida = new ValidatorUtil();
valida.validate(pessoa);

//pessoa com cadastro correto
System.out.println("");
System.out.println("");
System.out.println("Validando segunda pessoa");
PessoaBean pessoaCorreta = new PessoaBean();
pessoaCorreta.setNome("Emmanuel Silva");
pessoaCorreta.setLogin("login");
pessoaCorreta.setSenha("123456");
valida.validate(pessoaCorreta);
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main();
}

}




Bom pessoal, acho que é isso espero que tenham gostado do material.

Até a proxíma!




2 comentários:

Anônimo disse...

Legal..funciona.
Mas, se o Bean tiver uma @Entity
não funciona não.
Abraço.

Anônimo disse...

excelente, me ajudou muito aqui no trabalho