Este post tem o objetivo de continuar o trabalho sobre a injeção de valores usando reflexão e anotações.
O código do projeto é encontrado em: http://iar.codeplex.com/
Alguns erros podem ocorrer durante o trabalho de injeção de valores. Além disso, problemas de validação das anotações podem ser necessárias. Sendo assim, são criadas algumas exceções para poder tratar tais cenários. São criadas as exceções FormatFieldException, InjectionException e MapFieldException. Também são definidas algumas mensagens de erro na classe ErrorMessages. A implementação destas classes é muito simples e é mostrado a seguir.
package br.com.wpattern.annotation.exception;
public class FormatFieldException extends Exception {
private static final long serialVersionUID = 8464144343246315472L;
public FormatFieldException() {
}
public FormatFieldException(String s) {
super(s);
}
public FormatFieldException(Throwable throwable) {
super(throwable);
}
public FormatFieldException(String s, Throwable throwable) {
super(s, throwable);
}
}
package br.com.wpattern.annotation.exception;
public class InjectionException extends Exception {
private static final long serialVersionUID = 810546994379030324L;
public InjectionException() {
}
public InjectionException(String s) {
super(s);
}
public InjectionException(Throwable throwable) {
super(throwable);
}
public InjectionException(String s, Throwable throwable) {
super(s, throwable);
}
}
package br.com.wpattern.annotation.exception;
public class MapFieldException extends Exception {
private static final long serialVersionUID = -8531171176826142401L;
public MapFieldException() {
}
public MapFieldException(String s) {
super(s);
}
public MapFieldException(Throwable throwable) {
super(throwable);
}
public MapFieldException(String s, Throwable throwable) {
super(s, throwable);
}
}
As mensagens de erros são colocadas na classe ErrorMessages.
package br.com.wpattern.annotation.util;
public class ErrorMessages {
public static final String FIELD_CAN_NOT_BE_NULL = "Field [%s] or value [%s] can't be null.";
public static final String FIELD_INVALID_FORMAT = "Invalid format [%s] of the field [%s].";
public static final String FIELD_NOT_FOUNDED = "Field [%s] not founded.";
public static final String FIELD_WITH_INVALID_TYPE = "Field [%s] with invalid type [%s].";
public static final String FIELD_WITH_INVALID_VALUE = "Field [%s] with invalid value [%s].";
}
Os valores que são injetados estão mapeadas em MapFields. Essa classe armazena um grupo de valores baseados em uma chave. Por exemplo, esta classe representa um um conjunto de valores presentes em um arquivo de configuração. A seguir é exibida a implementação desta classe.
package br.com.wpattern.annotation.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import br.com.wpattern.annotation.exception.FormatFieldException;
import br.com.wpattern.annotation.exception.MapFieldException;
public class MapFields {
private final Map<String, String> mapOfValues = new HashMap<String, String>();
public void AddField(String name, String value) throws MapFieldException {
if ((name == null) || (value == null)) {
throw new MapFieldException(String.format(ErrorMessages.FIELD_CAN_NOT_BE_NULL, name, value));
}
this.mapOfValues.put(name.toUpperCase(), value.toUpperCase());
}
public String getValue(String name) throws MapFieldException {
String value = this.mapOfValues.get(name);
if (value == null) {
throw new MapFieldException(String.format(ErrorMessages.FIELD_NOT_FOUNDED, name));
}
return value;
}
public Integer getIntValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
public Long getLongValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
try {
return Long.parseLong(value);
} catch(NumberFormatException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
public Double getDoubleValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
try {
return Double.parseDouble(value);
} catch(NumberFormatException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
public Float getFloatValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
try {
return Float.parseFloat(value);
} catch(NumberFormatException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
public Boolean getBooleanValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
try {
return Boolean.parseBoolean(value);
} catch(NumberFormatException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
public Character getCharacterValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
if (value.length() != 1) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name));
}
try {
return value.charAt(0);
} catch(NumberFormatException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
public Date getDateValue(String name) throws MapFieldException, FormatFieldException {
String value = getValue(name);
SimpleDateFormat formater = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
try {
return formater.parse(value);
} catch(ParseException e) {
throw new FormatFieldException(String.format(ErrorMessages.FIELD_INVALID_FORMAT, value, name), e);
}
}
}
Os métodos do MapFields são responsáveis por extrair os valores com os tipos específicos de acordo com o método chamado.
O vídeo a seguir mostra com detalhes os códigos apresentados neste post.
Com este vídeo finalizamos nosso trabalho das exceções.
Até o próximo post pessoal, abraços.

O objetivo deste post é de criar Annotations (Anotações) em java e usando Reflection (Reflexão) realizar a injeção de valores em variáveis.
O código do projeto é encontrado em: http://iar.codeplex.com/
As variáveis que terão os valores injetados estão estão todas anotadas. Serão criadas 3 anotações, sendo: @WPatternClass, @WPatternField e @WPatternValue.
@WPatternClass é usado apenas para anotar a classe, sendo apenas um exemplo de anotação. A anotação @WPatternField é aplicada sobre variáveis de escopo de classe. Por último, @WPatternValue é uma anotação usada dentro de @WPatternField e é responsável por determinar os valores aceitáveis pela variável anotada.
A figura exibida no início do post mostra as principais classes do projeto, incluindo as anotações.
O código responsável por criar as anotações é mostrado a seguir.
package br.com.wpattern.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WPatternClass {
String description() default "";
}
package br.com.wpattern.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface WPatternField {
String name();
boolean required() default true;
WPatternValue[] values() default { };
}
package br.com.wpattern.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface WPatternValue {
String value();
}
Os vídeos mostrado a seguir explicam com detalhes o projeto e as anotações.
Parte 01
Parte 02
Até o próximo post pessoal.
Abraços.