<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Java for Dinner</title>
	<atom:link href="http://javafordinner.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://javafordinner.wordpress.com</link>
	<description>Um repositório sobre Java e tudo que gira ao redor dele.</description>
	<lastBuildDate>Thu, 23 Oct 2008 22:37:09 +0000</lastBuildDate>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='javafordinner.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Java for Dinner</title>
		<link>http://javafordinner.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://javafordinner.wordpress.com/osd.xml" title="Java for Dinner" />
	<atom:link rel='hub' href='http://javafordinner.wordpress.com/?pushpress=hub'/>
		<item>
		<title>O poder das annotations em sistemas legados</title>
		<link>http://javafordinner.wordpress.com/2008/03/09/o-poder-das-annotations-em-sistemas-legados/</link>
		<comments>http://javafordinner.wordpress.com/2008/03/09/o-poder-das-annotations-em-sistemas-legados/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 17:08:17 +0000</pubDate>
		<dc:creator>Danilo Barsotti</dc:creator>
				<category><![CDATA[Annotation]]></category>

		<guid isPermaLink="false">http://javafordinner.wordpress.com/2008/03/09/o-poder-das-annotations-em-sistemas-legados/</guid>
		<description><![CDATA[odos sabem como é complicado mexer com sistemas legados, ainda mais quando esse sistema é um dos principais de um grande banco brasileiro e com isso todo cuidado é pouco para não ultrapassar os prazos. As Annotations: Dentre várias novidades do java 1.5 uma delas foi as Annotations, elas nos dão a possibilidade de se [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=9&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>odos sabem como é complicado mexer com sistemas legados, ainda mais quando esse sistema é um dos principais de um grande banco brasileiro e com isso todo cuidado é pouco para não ultrapassar os prazos.</p>
<h2>As Annotations:</h2>
<p>Dentre várias novidades do java 1.5 uma delas foi as Annotations, elas nos dão a possibilidade de se trabalhar com meta-dados muito facilmente, com pouco esforço podemos fazer varias coisas que antes não poderiamos ou então era muito trabalhoso.</p>
<p>No projeto atual, dentre várias tarefas que tenho, uma delas era de incluir algumas validações ( + ou &#8211; 400 ) no sistema, pela quantidade de validações e pelo curto prazo para cumprir a tarefa, tive que analisar o impacto que isso poderia acarretar.</p>
<p>Conclusão, era inviavel colocar um monte de código novo para fazer essas validações, primeiro porque ia ser muito trabalhoso e segundo que era muito arriscado.</p>
<p>Então fiz algumas classes ( que alguns chamam de framework, rsrs ) que gerenciam anotações para fazer todo meu trabalho de validação de variaveis, entrada de parametros em métodos, retorno de métodos ( ai usei AOP ) e por ai vai.</p>
<p>Então, vamos ao que interessa!</p>
<p>Obs.: Como esse projeto já é usado pelo banco e por motivos de segurança, vou mostrar simples validações e não as que foram usadas no banco, mas o motor é o mesmo, somente a logica das validações foram retiradas.</p>
<h2>Mão na massa</h2>
<p>Quando comecei a programar essa framework, umas das coisas que eu tinha em mente era ela ser rápida e flexivel na programação das anotações.</p>
<p>Comecei programando o motor de gerenciamento das anotações, a classe esta muito bem comentada sendo assim, acho q dispensa maiores explicações:</p>
<blockquote><p>/**<br />
* Classe responsavel por gerenciar o funcionamento de todas as annotations<br />
* usadas pela framework.<br />
*<br />
* Para cada anotação encontrada, é pego o valor do atributo onde a anotação<br />
* foi encontrada e esse valor é guardado em um HashMap, quando todos os<br />
* atributos forem lidos e todas as annotations também, são disparadas as<br />
* Threads para cada anotação ou conforme configuração do framework.<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public class Validators extends Control {</p>
<p>private Configuration mainConf;</p>
<p>public Validators(Configuration conf){<br />
if(conf.getMapConf() == null){<br />
mainConf = conf.initDefaultConfiguration();<br />
}else{<br />
mainConf = conf.getInstance();<br />
}<br />
}</p>
<p>/**<br />
* Inicia o gerenciamento dos validadores ( threads )<br />
* disparando uma thread para cada annotation ou 1 thread<br />
* para todas as annotations ou um numero especifico de threads<br />
* conforme a configuração do framework.<br />
*<br />
* @author Danilo Barsotti<br />
*/<br />
public void initValidators(Object annotedObject) {<br />
ArrayList&lt;ValidatorException&gt; exceptions = new ArrayList&lt;ValidatorException&gt;();<br />
// Map&lt;nomeDaAnotação, HashMap&lt;nomeDoAtributo, valorDoAtributo&gt;&gt;<br />
Map&lt;String, HashMap&lt;String, Object&gt;&gt; mapFieldUsedAnnotation = new HashMap&lt;String, HashMap&lt;String, Object&gt;&gt;();</p>
<p>Map&lt;String, HashMap&lt;String, Annotation[]&gt;&gt; mapFieldColAnnotation = new HashMap&lt;String, HashMap&lt;String, Annotation[]&gt;&gt;();</p>
<p>List&lt;String&gt; nameAnnotations = new ArrayList&lt;String&gt;();<br />
// pool de threads<br />
ExecutorService pool = Executors.newCachedThreadPool();<br />
Validator validator = null;</p>
<p>Class&lt;Annotation&gt; anottation = null;</p>
<p>Field[] fields = annotedObject.getClass().getDeclaredFields();</p>
<p>Annotation[] colAnnotations = null;</p>
<p>for (Field field : fields) {<br />
colAnnotations = field.getDeclaredAnnotations();<br />
// Separa os atributos para cada anotação que esta sendo usado<br />
for (Annotation annotation : colAnnotations) {<br />
// Verifica se já existe no map algum atributo que já tenha<br />
// usado a anotação<br />
if (mapFieldUsedAnnotation.containsKey(annotation<br />
.annotationType().getSimpleName())) {<br />
mapFieldUsedAnnotation.get(<br />
annotation.annotationType().getSimpleName()).put(<br />
field.getName(),<br />
super.getValueAtribute(super.getMethodName(field<br />
.getName()), annotedObject.getClass()));<br />
// acrescenta no map todas as anotações usadas pelo<br />
// atributo.<br />
mapFieldColAnnotation.get(<br />
annotation.annotationType().getSimpleName()).put(<br />
field.getName(), colAnnotations);<br />
// Nenhum atributo usou a anotação até agora, cria um novo<br />
// map e adiciona o valor<br />
} else {<br />
mapFieldUsedAnnotation.put(annotation.annotationType()<br />
.getSimpleName(), new HashMap&lt;String, Object&gt;());<br />
mapFieldUsedAnnotation.get(<br />
annotation.annotationType().getSimpleName()).put(<br />
field.getName(),<br />
super.getValueAtribute(super.getMethodName(field<br />
.getName()), annotedObject.getClass()));<br />
nameAnnotations.add(annotation.annotationType()<br />
.getSimpleName());<br />
// Todas as anotações usadas pelo atributo.<br />
mapFieldColAnnotation.put(annotation.annotationType()<br />
.getSimpleName(),<br />
new HashMap&lt;String, Annotation[]&gt;());<br />
mapFieldColAnnotation.get(<br />
annotation.annotationType().getSimpleName()).put(<br />
field.getName(), colAnnotations);<br />
}<br />
}<br />
}<br />
// Inicia as Threads<br />
try {<br />
for (String annotationTemp : nameAnnotations) {<br />
// TODO mudar o valor default de onde se encontram os validator, talvez pegar de um .properties<br />
// pega a thread com base no nome da annotation<br />
validator = (Validator) Class.forName(<br />
&#8220;control.validator.validators.Validator&#8221;<br />
+ annotationTemp).newInstance();<br />
// pega uma instancia da classe que representa a anotação<br />
anottation =  (Class&lt;Annotation&gt;) Class.forName(&#8220;annotations.&#8221; + annotationTemp);<br />
// seta um map com os valores dos atributos a serem validados<br />
validator.setObjToValidade(mapFieldUsedAnnotation<br />
.get(annotationTemp));<br />
// seta um map com uma coleção de anotações usadas pelo field<br />
validator.setMapFieldColAnnotation(mapFieldColAnnotation<br />
.get(annotationTemp));<br />
// seta uma instancia da anotação<br />
validator.setClazz(anottation);<br />
// seta onde as exceptions serão armazenadas<br />
validator.setExceptions(exceptions);<br />
// seta quais são os campos a serem validados<br />
validator.setFieldsToValidade();<br />
// inicia um validador pegando uma Thread do pool<br />
pool.execute(validator);<br />
}<br />
pool.shutdown();</p>
<p>while(true){<br />
if(pool.isTerminated()){<br />
System.out.println(&#8220;acabou!!!&#8221;);<br />
break;<br />
}<br />
}<br />
} catch (ClassNotFoundException e) {<br />
// TODO Lançar a exeção correta<br />
e.printStackTrace();<br />
} catch (InstantiationException e) {<br />
// TODO Lançar a exeção correta<br />
e.printStackTrace();<br />
} catch (IllegalAccessException e) {<br />
// TODO Lançar a exeção correta<br />
e.printStackTrace();<br />
}<br />
}</p>
<p>}</p>
<p>/**<br />
* Classe responsavel por métodos utilitarios em que todas<br />
* as classes que controlam as annotations devem usar.<br />
*<br />
* @author Danilo Barsotti<br />
*/<br />
public abstract class Control {</p>
<p>public abstract void initValidators(Object annotedObject);</p>
<p>/**<br />
* Retorna o nome do método acessor do atributo seguindo o<br />
* padrão JavaBean ( getCamelCase ).<br />
*<br />
* @param atributeName &#8211; nome do atributo<br />
* @return nomenclatura do método acessor do atributo, seguindo o padrão JavaBean<br />
*<br />
* @author Danilo Barsotti<br />
*/<br />
protected String getMethodName(String atributeName) {<br />
return &#8220;get&#8221;+atributeName.replaceFirst(atributeName.substring(0,1), atributeName.substring(0,1).toUpperCase());<br />
}</p>
<p>/**<br />
* Invoca o método usando reflection para pegar o valor de<br />
* retorno.<br />
*<br />
* @param methodName &#8211; nome do método a ser invocado<br />
* @param clazz &#8211; a qual classe o método pertence<br />
* @return return do método acessor.<br />
*<br />
* @author Danilo Barsotti          */<br />
protected Object getValueAtribute(String methodName, Class clazz) {<br />
Object objReturn = null;<br />
try {<br />
if(!clazz.getMethod(methodName).isAccessible()){<br />
clazz.getMethod(methodName).setAccessible(true);<br />
}<br />
Method method = clazz.getMethod(methodName);<br />
objReturn = method.invoke(clazz.newInstance());<br />
} catch (SecurityException e) {<br />
e.printStackTrace();<br />
} catch (NoSuchMethodException e) {<br />
e.printStackTrace();<br />
} catch (IllegalArgumentException e) {<br />
e.printStackTrace();<br />
} catch (IllegalAccessException e) {<br />
e.printStackTrace();<br />
} catch (InvocationTargetException e) {<br />
e.printStackTrace();<br />
} catch (InstantiationException e) {<br />
e.printStackTrace();<br />
}<br />
return objReturn;<br />
}<br />
}</p></blockquote>
<p>Pronto, o motor de gerenciamento já está pronto, como podem ver é bem simples, ele dispara uma thread para cada anotação diferente encontrada nas classes anotadas.</p>
<p><strong>Agora vamos ver uma anotação.</strong></p>
<blockquote><p>/**<br />
* Verifica se o atributo anotado está nulo.<br />
* Caso o parametro &lt;b&gt;acceptEmpty&lt;/b&gt; seja false, não aceita<br />
* uma String vazia &#8220;&#8221;, &lt;b&gt;valor default é true&lt;/&gt;<br />
*<br />
* @param acceptEmpty &#8211; &lt;b&gt;Opcional&lt;/b&gt;<br />
* @param message &#8211; a mensagem que sera exibida caso a validação<br />
* seja incorreta.<br />
*<br />
* @author danilo barsotti<br />
*/<br />
@Target(ElementType.FIELD)<br />
@Retention(RetentionPolicy.RUNTIME)<br />
public @interface NotNull {</p>
<p>boolean acceptEmpty() default true;<br />
String message() default &#8220;&#8221;;</p>
<p>}</p></blockquote>
<p>Essa anotação verifica se a variavel ( field ) está nula e se for uma String pergunta se aceita vazio (&#8220;&#8221;) ou não.</p>
<p>Usando convenção ao invez de configuração, a classe que representa a lógica dessa anotação deve ter o nome no seguinte padrão: <strong>Validator + O nome da anotação,</strong> então ficaria <strong>ValidatorNotNull</strong>, com isso conseguimos fazer varias anotações sem precisar configurar nada, somente precisamos fazer 1 annotation e 1 classe que representa sua lógica de validação e então o framework já vai conseguir usa-la.</p>
<p><strong>A classe que representa a regra de validação da anotação:</strong></p>
<blockquote><p>/**<br />
* Verifica se o atributo é Null<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public class ValidatorNotNull extends Validator{</p>
<p>@Override<br />
public void startValidation() throws ValidatorException  {<br />
for(String fieldName : fields){<br />
super.setFieldName(fieldName);<br />
if(isNull(fieldValue)){<br />
System.out.println(&#8220;O atributo &#8221; + fieldName + &#8221; é nulo!&#8221;);<br />
}else{<br />
if(getBooleanValueMethodAnnotation(fieldName, &#8220;acceptEmpty&#8221;)){<br />
System.out.println(&#8220;O atributo &#8221; + fieldName + &#8221; Não é nulo! o valor dele é = &#8221; + getValueToValidade(fieldName));<br />
}else{<br />
if(fieldValue.equals(&#8220;&#8221;)){<br />
System.out.println(&#8220;O atributo &#8221; + fieldName + &#8221; Não é nulo mas é uma String vazia&#8221;);<br />
addValidationError(fieldName);<br />
}<br />
}<br />
}<br />
}<br />
}</p>
<p>/**<br />
* Verifica se o objeto é nulo<br />
*<br />
* @param objeto a ser verificado<br />
* @return boolean<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public boolean isNull(Object obj){<br />
return obj == null;<br />
}<br />
}</p></blockquote>
<p>Como podem ver, toda classe que representa uma anotação deve estender a classe Validator, ela é uma classe que implementa Runnable e também disponibiliza alguns métodos utilitarios.</p>
<p><strong>Classe Validator</strong></p>
<blockquote><p>/**<br />
* Classe que todos os outros validadores devem estender<br />
* pois é por ele que a thread acessa os atributos a serem<br />
* validados de acordo com a annotation que a thread representa.<br />
*<br />
* @author danilo barsotti<br />
*<br />
*/<br />
public abstract class Validator implements Runnable{<br />
//Logger logger;<br />
Object lock1 = new Object();<br />
private String fieldName;<br />
public Object fieldValue;<br />
public String[] fields;<br />
/**<br />
* Classe que representa uma anotação.<br />
*/<br />
private Class&lt;Annotation&gt; clazz;<br />
/**<br />
* Onde todas as exceptions de validação são guardadas<br />
*/<br />
ArrayList&lt;ValidatorException&gt; exceptions;<br />
/**<br />
* Guarda os valores dos atributos a serem validados<br />
*/<br />
private HashMap&lt;String, Object&gt; objToValidade;</p>
<p>/**<br />
* Guarda todas as anotações usadas pelo atributo<br />
*/<br />
private HashMap&lt;String, Annotation[]&gt; mapFieldColAnnotation;<br />
/**<br />
* Método que inicia a validação<br />
*<br />
* @author danilo barsotti<br />
* @throws ValidatorException<br />
* @throws ValidatorException<br />
*/<br />
public abstract void startValidation() throws ValidatorException;</p>
<p>/**<br />
* Seta a anotação que é usada pelo validador.<br />
*<br />
* @param clazz &#8211; Classe que representa a anotação<br />
*/<br />
public void setClazz(Class&lt;Annotation&gt; clazz) {<br />
this.clazz = clazz;<br />
}</p>
<p>/**<br />
* Retorna os nomes dos campos que foram anotados.<br />
*<br />
* @return keys<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public String[] getFieldsToValidade(){<br />
String[] keys = new String[objToValidade.keySet().size()];<br />
Iterator&lt;String&gt; iter = objToValidade.keySet().iterator();<br />
int cont = 0;<br />
while(iter.hasNext()){<br />
keys[cont] = iter.next().toString();<br />
cont++;<br />
}<br />
return keys;<br />
}<br />
/**<br />
* ESSE MÉTODO NÃO DEVE SER SOBRESCRITO E NÃO DEVE SER USADO.<br />
* É USADO SOMENTE PELO FRAMEWORK.<br />
* &lt;br&gt;<br />
* Seta os nomes dos atributos a serem validados.<br />
*/<br />
public void setFieldsToValidade(){<br />
this.fields = getFieldsToValidade();<br />
}<br />
public void addValidationError(String fieldName){<br />
synchronized (lock1) {<br />
exceptions.add(new ValidatorException(fieldName));<br />
}<br />
}<br />
/**<br />
* Retorna um HashMap que contem os objetos a serem validados<br />
*<br />
* @return HashMap com os objetos<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public HashMap&lt;String, Object&gt; getObjToValidade() {<br />
return objToValidade;<br />
}<br />
/**<br />
* Retorna o valor do atributo a ser validado<br />
*<br />
* @param key &#8211; Nome do atributo (field)<br />
*<br />
* @return object &#8211; valor retornado pelo método<br />
*/<br />
public Object getValueToValidade(String key) {<br />
return getObjToValidade().get(key);<br />
}<br />
/**<br />
* ESSE MÉTODO NÃO DEVE SER SOBRESCRITO E NÃO DEVE SER USADO.<br />
* É USADO SOMENTE PELO FRAMEWORK.<br />
*<br />
* Seta os objetos a serem validados<br />
*<br />
* @param objToValidade &#8211; map com os objetos a serem validados<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public void setObjToValidade(HashMap&lt;String, Object&gt; objToValidade) {<br />
this.objToValidade = objToValidade;<br />
}</p>
<p>/**<br />
* ESSE MÉTODO NÃO DEVE SER SOBRESCRITO E NÃO DEVE SER USADO.<br />
* É USADO SOMENTE PELO FRAMEWORK.<br />
*<br />
* Da inicio a Thread de validação conforme a implementação do validador.<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public void run(){<br />
try{<br />
startValidation();<br />
}catch(ValidatorException ex){<br />
synchronized (lock1) {<br />
exceptions.add(ex);<br />
}<br />
}<br />
}</p>
<p>/**<br />
* Retorna a anotações que foi usada pelo field.<br />
*<br />
* @param fieldName &#8211; nome do field<br />
*<br />
* @return Annotation<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public Annotation getAnnotation(String fieldName) {<br />
Annotation[] annotations = mapFieldColAnnotation.get(fieldName);<br />
for(Annotation annotation : annotations){<br />
if(annotation.annotationType().getSimpleName().equals(clazz.getSimpleName())){<br />
return annotation;<br />
}<br />
}<br />
// TODO lançar uma excessão aqui, pois não encontrou a anotação!<br />
//logger.log(Level.WARNING, &#8220;asdf&#8221;);<br />
return null;<br />
}<br />
/**<br />
* Usado para pegar o valor (Integer) de retorno do método que foi declarado<br />
* na anotação<br />
*<br />
* @param fieldName &#8211; nome do atributo anotado<br />
* @param nameMethod &#8211; nome do método na anotação<br />
*<br />
* @return Integer com o valor retornado pelo método na anotação<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public Integer getIntegerValueMethodAnnotation(String fieldName, String nameMethod){<br />
// TODO verificar se o clazz é uma instancia de Annotation.class<br />
return  (Integer) getMethodValue(fieldName, nameMethod);<br />
}</p>
<p>/**<br />
* Usado para pegar o valor (boolean) de retorno do método que foi declarado<br />
* na anotação<br />
*<br />
* @param fieldName &#8211; nome do atributo anotado<br />
* @param nameMethod &#8211; nome do método na anotação<br />
*<br />
* @return boolean com o valor retornado pelo método na anotação<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public boolean getBooleanValueMethodAnnotation(String fieldName, String nameMethod){<br />
return (Boolean) getMethodValue(fieldName, nameMethod);<br />
}<br />
/**<br />
* Usado para pegar o valor (boolean) de retorno do método que foi declarado<br />
* na anotação<br />
*<br />
* @param fieldName &#8211; nome do atributo anotado<br />
* @param nameMethod &#8211; nome do método na anotação<br />
*<br />
* @return boolean com o valor retornado pelo método na anotação<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public String getStringValueMethodAnnotation(String fieldName, String nameMethod){<br />
return (String) getMethodValue(fieldName, nameMethod);<br />
}<br />
/**<br />
* Usado para pegar um valor de retorno de um método que foi declarado<br />
* na anotação, pega qualquer valor de retorno mas necessita de cast<br />
* pois retorna um object.<br />
*<br />
* @param fieldName &#8211; nome do atributo anotado<br />
* @param nameMethod &#8211; nome do método na anotação<br />
*<br />
* @return object &#8211; valor retornado pelo método<br />
*/<br />
private Object getMethodValue(String fieldName, String nameMethod){<br />
// TODO verificar se o clazz é uma instancia de Annotation.class<br />
Object obj = null;<br />
try {<br />
Annotation annotation = getAnnotation(fieldName);<br />
obj = annotation.getClass().getMethod(nameMethod).invoke(annotation);<br />
} catch (IllegalArgumentException e) {<br />
e.printStackTrace();<br />
} catch (SecurityException e) {<br />
e.printStackTrace();<br />
} catch (NoSuchMethodException e) {<br />
e.printStackTrace();<br />
} catch (IllegalAccessException e) {<br />
e.printStackTrace();<br />
} catch (InvocationTargetException e) {<br />
e.printStackTrace();<br />
}<br />
return obj;<br />
}</p>
<p>/**<br />
* ESSE MÉTODO NÃO DEVE SER SOBRESCRITO E NÃO DEVE SER USADO.<br />
* É USADO SOMENTE PELO FRAMEWORK.<br />
*<br />
* Seta um map que contem as anotações usadas pelos fields.<br />
*<br />
* @param objToValidade &#8211; map com as anotações<br />
*<br />
* @author danilo barsotti<br />
*/<br />
public void setMapFieldColAnnotation(<br />
HashMap&lt;String, Annotation[]&gt; mapFieldColAnnotation) {<br />
this.mapFieldColAnnotation = mapFieldColAnnotation;<br />
}</p>
<p>public ArrayList&lt;ValidatorException&gt; getExceptions() {<br />
return exceptions;<br />
}</p>
<p>public void setExceptions(ArrayList&lt;ValidatorException&gt; exceptions) {<br />
this.exceptions = exceptions;<br />
}</p>
<p>public void setFieldName(String fieldName) {<br />
this.fieldName = fieldName;<br />
this.fieldValue = getValueToValidade(fieldName);<br />
//this.fields = getFieldsToValidade();<br />
}<br />
}</p></blockquote>
<p>Quando o validador encontra algo que não é aceito, ele lança uma exeção e coloca ela dentro de um array.</p>
<p><strong>Segue a classe que representa uma exeção de validação:</strong></p>
<blockquote><p>public class ValidatorException extends Exception{</p>
<p>String field;<br />
public ValidatorException(String field){<br />
System.out.println(&#8220;&#8212;&#8211; rolou uma exception no campo = &#8221; + field + &#8221; &#8212;&#8211;&#8221;);<br />
this.field = field;<br />
}<br />
public void teste(){<br />
}<br />
}</p></blockquote>
<p>Também foi feito uma classe para fazer algumas configurações na framework, também não posso mostrar muito dela então tirei varias coisas bacanas, mas vamos talvez no proximo artigo focar nela e também em AOP, para deixar nossa framework mais interessante.</p>
<p><strong>Classe de configuração:</strong></p>
<blockquote><p>public class Configuration {</p>
<p>private static Configuration config;<br />
private static Map&lt;String, String&gt; mapConf;<br />
private Configuration(){}<br />
public static Configuration getInstance(){<br />
if(config == null){<br />
config = new Configuration();<br />
mapConf = new HashMap&lt;String, String&gt;();<br />
}<br />
return config;<br />
}<br />
public static Configuration setConfig(PropertiesConfiguration conf, String value){<br />
getInstance();<br />
mapConf.put(conf.toString(), value);<br />
return config;<br />
}<br />
public static String getConf(PropertiesConfiguration key){<br />
return mapConf.get(&#8220;&#8221;);<br />
}<br />
public static Map getMapConf(){<br />
return mapConf;<br />
}<br />
public static Configuration initDefaultConfiguration(){<br />
getInstance().getMapConf().put(PropertiesConfiguration.Threads, &#8220;&#8221;);<br />
return getInstance();<br />
}<br />
}</p></blockquote>
<p>E uma enum com as propriedades da configuração, só tem uma configuração pelo mesmo motivo já citado diversas vezes.</p>
<p><strong>Classe PropertiesConfiguration:</strong></p>
<blockquote><p>public enum PropertiesConfiguration {</p>
<p>Threads;</p>
<p>}</p></blockquote>
<p>Com isso finalizamos nossa framework, agora para testar basta anotar alguma classe e chamar o método de validação, no banco fiz isso ficar automatico, sem precisar chamar nenhum método a framework já verifica se tem algo de errado, lança suas exeções, joga tudo na request e exibe em uma pagina que também é configuravel, mas isso é para um próximo artigo.</p>
<p><strong>Para testar vamos anotar um VO:</strong></p>
<blockquote><p>public class TesteVo {</p>
<p>@NotNull(acceptEmpty=false)<br />
public String testeNotNull = &#8220;&#8221;;<br />
@NotNull<br />
public String testeNotNull2 = null;<br />
public String testeNotNull3 = &#8220;valorTesteNotNull3&#8243;;<br />
@NotNull<br />
public String range = &#8220;valorRange&#8221;;<br />
@NotNull<br />
public Integer testeNotNull4;<br />
@NotNull<br />
public Integer testeNotNull5 = 0;<br />
@NotNull<br />
public Integer testeNotNull6 = 211;<br />
@NotNull<br />
public int testeNotNull7 = 1;<br />
@NotNull<br />
public Object testeNotNull8 = null;</p>
<p>public String getTesteNotNull() {<br />
return testeNotNull;<br />
}</p>
<p>public void setTesteNotNull(String testeNotNull) {<br />
this.testeNotNull = testeNotNull;<br />
}</p>
<p>public String getRange() {<br />
return range;<br />
}</p>
<p>public void setRange(String range) {<br />
this.range = range;<br />
}</p>
<p>public String getTesteNotNull2() {<br />
return testeNotNull2;<br />
}</p>
<p>public void setTesteNotNull2(String testeNotNull2) {<br />
this.testeNotNull2 = testeNotNull2;<br />
}</p>
<p>public String getTesteNotNull3() {<br />
return testeNotNull3;<br />
}</p>
<p>public void setTesteNotNull3(String testeNotNull3) {<br />
this.testeNotNull3 = testeNotNull3;<br />
}</p>
<p>public Integer getTesteNotNull4() {<br />
return testeNotNull4;<br />
}</p>
<p>public void setTesteNotNull4(Integer testeNotNull4) {<br />
this.testeNotNull4 = testeNotNull4;<br />
}</p>
<p>public Integer getTesteNotNull5() {<br />
return testeNotNull5;<br />
}</p>
<p>public void setTesteNotNull5(Integer testeNotNull5) {<br />
this.testeNotNull5 = testeNotNull5;<br />
}</p>
<p>public Integer getTesteNotNull6() {<br />
return testeNotNull6;<br />
}</p>
<p>public void setTesteNotNull6(Integer testeNotNull6) {<br />
this.testeNotNull6 = testeNotNull6;<br />
}</p>
<p>public int getTesteNotNull7() {<br />
return testeNotNull7;<br />
}</p>
<p>public void setTesteNotNull7(int testeNotNull7) {<br />
this.testeNotNull7 = testeNotNull7;<br />
}</p>
<p>public Object getTesteNotNull8() {<br />
return testeNotNull8;<br />
}</p>
<p>public void setTesteNotNull8(Object testeNotNull8) {<br />
this.testeNotNull8 = testeNotNull8;<br />
}<br />
}</p></blockquote>
<p>E chamar a validação para testar o resultado:</p>
<blockquote><p>public class AnnotationsTestMain {</p>
<p>public static void main(String args[]){<br />
Control teste = new Validators(Configuration.setConfig(PropertiesConfiguration.Threads, &#8220;1&#8243;));<br />
TesteVo t = new TesteVo();<br />
teste.initValidators(t);<br />
}</p>
<p>}</p></blockquote>
<p><strong>A saida no console foi:</strong></p>
<blockquote><p>O atributo testeNotNull4 é nulo!<br />
O atributo testeNotNull6 Não é nulo! o valor dele é = 211<br />
O atributo testeNotNull Não é nulo mas é uma String vazia<br />
&#8212;&#8211; rolou uma exception no campo = testeNotNull &#8212;&#8211;<br />
O atributo testeNotNull5 Não é nulo! o valor dele é = 0<br />
O atributo range Não é nulo! o valor dele é = valorRange<br />
O atributo testeNotNull2 é nulo!<br />
O atributo testeNotNull7 Não é nulo! o valor dele é = 1<br />
O atributo testeNotNull8 é nulo!<br />
acabou!!!</p></blockquote>
<p>Com isso chegamos ao fim da nossa pequena mas pratica framework de validação, os proximos passos são, torna-la mais configuravel, fazer mais validadores, usar AOP, colocar as exeções na request para ser exibidas em um jsp e por ultimo junta-la com a framework Apache Wicket.</p>
<p>Não estou tendo tempo de postar, esta muito corrido meu projeto, mas vou ver se consigo arrumar tempo.</p>
<p>Um grande abraço a todos, e até a proxima!!! :- )</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/javafordinner.wordpress.com/9/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/javafordinner.wordpress.com/9/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/javafordinner.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/javafordinner.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/javafordinner.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/javafordinner.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/javafordinner.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/javafordinner.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/javafordinner.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/javafordinner.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=9&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://javafordinner.wordpress.com/2008/03/09/o-poder-das-annotations-em-sistemas-legados/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0ddc0192ae3b516c0055b270e026bcc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Barsotti</media:title>
		</media:content>
	</item>
		<item>
		<title>Mudando o local default dos arquivos no Apache Wicket</title>
		<link>http://javafordinner.wordpress.com/2008/01/28/mudando-o-local-default-dos-arquivos-no-apache-wicket/</link>
		<comments>http://javafordinner.wordpress.com/2008/01/28/mudando-o-local-default-dos-arquivos-no-apache-wicket/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 01:43:32 +0000</pubDate>
		<dc:creator>Danilo Barsotti</dc:creator>
				<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://javafordinner.wordpress.com/2008/01/28/mudando-o-local-default-dos-arquivos-no-apache-wicket/</guid>
		<description><![CDATA[Como foi falado no artigo anterior, quando criamos uma classe que representa uma pagina ( estende WebPage ) o arquivo .html deve estar no mesmo package da classe por default, mas isso nem sempre ( na maioria das vezes ) é algo muito bom de se fazer, pois um projeto pode ter diversos packages, imagine [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=8&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><font face="Arial">Como foi falado no artigo anterior, quando criamos uma classe que representa uma pagina ( <strong>estende WebPage</strong> ) o arquivo .html deve estar no mesmo package da classe por default, mas isso nem sempre ( na maioria das vezes ) é algo muito bom de se fazer, pois um projeto pode ter diversos packages, imagine varios deles com arquivos .html, imagens, .js entre outros, não ficaria algo muito agradavel de se trabalhar e organizar.</font></p>
<p><font face="Arial">Como não gostava disso fui dar uma pesquisada e descobri que quando se quer configurar como o wicket usa os recursos ( .html, .css, .js entre outros ) basta estender a classe <strong>ResourceStreamLocator,</strong> vejam como essa classe é feita:</font></p>
<p><font face="Arial">import org.apache.wicket.util.resource.IResourceStream;<br />import org.apache.wicket.util.resource.locator.ResourceStreamLocator; </font></p>
<p><font face="Arial">public class PathStripperLocator extends ResourceStreamLocator{ </font>
<p><font face="Arial">&nbsp;&nbsp;&nbsp; public PathStripperLocator() {<br />&nbsp;&nbsp;&nbsp; } </font>
<p><font face="Arial">&nbsp;&nbsp;&nbsp; public IResourceStream locate(final Class clazz, final String path) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IResourceStream located = super.locate(clazz, trimFolders(path));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (located != null) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return located;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return super.locate(clazz, path);<br />&nbsp;&nbsp;&nbsp; } </font>
<p><font face="Arial">&nbsp;&nbsp;&nbsp; private String trimFolders(String path) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return path.substring(path.lastIndexOf(&#8220;/&#8221;) + 1);<br />&nbsp;&nbsp;&nbsp; }<br />} </font>
<p><font face="Arial">E para usala, é só chamar no método <strong>init()</strong> da classe que estende <strong>WebApplication</strong> que no nosso caso é a classe <strong>JavaForDinnerApplication</strong> ( caso você não esteja acompanhado os artigos, recomendo a leitura do artigo </font><a href="http://javafordinner.wordpress.com/2008/01/26/comecando-com-o-apache-wicket/" target="_blank"><font face="Arial">Começando com o Apache Wicket</font></a><font face="Arial"> ) como é mostrado abaixo:</font>
<p><font face="Arial">&nbsp;&nbsp;&nbsp; @Override<br />&nbsp;&nbsp;&nbsp; protected void init() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.init();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.configResourceFolder();<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; private void configResourceFolder(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IResourceSettings resourceSettings = getResourceSettings();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resourceSettings.addResourceFolder(&#8220;/WEB-INF/&#8221;); // O local onde os arquivos .html,imagens e todo o restante vão estar.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resourceSettings.setResourceStreamLocator(new PathStripperLocator());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; } </font></p>
<p><code><font face="Arial">Como podem ver, configurei para os arquivos .html, .css, .js e todos os outros necessarios vão ser encontrados na pasta WEB-INF.</font></code></p>
<p><code><font face="Arial">Até a proxima!!!</font></p>
<p></code></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/javafordinner.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/javafordinner.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/javafordinner.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/javafordinner.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/javafordinner.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/javafordinner.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/javafordinner.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/javafordinner.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/javafordinner.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/javafordinner.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=8&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://javafordinner.wordpress.com/2008/01/28/mudando-o-local-default-dos-arquivos-no-apache-wicket/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0ddc0192ae3b516c0055b270e026bcc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Barsotti</media:title>
		</media:content>
	</item>
		<item>
		<title>Começando com o Apache Wicket.</title>
		<link>http://javafordinner.wordpress.com/2008/01/26/comecando-com-o-apache-wicket/</link>
		<comments>http://javafordinner.wordpress.com/2008/01/26/comecando-com-o-apache-wicket/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 16:33:52 +0000</pubDate>
		<dc:creator>Danilo Barsotti</dc:creator>
				<category><![CDATA[Wicket]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://javafordinner.wordpress.com/?p=5</guid>
		<description><![CDATA[Bom pessoal, hoje vou dar inicio a uma serie de posts sobre essa framework, o Apache Wicket. Wicket é uma framework web ( como o Struts, JSF, Mentawai entre outros 859664 milhões de frameworks ) que possui um estilo de programação &#8220;ala&#8221; Swing, possui uma curva de aprendizado bem pequena, é prazeroso e usa pouca [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=5&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Bom pessoal, hoje vou dar inicio a uma serie de posts sobre essa framework, o Apache Wicket.<br />
Wicket é uma framework web ( como o Struts, JSF, Mentawai entre outros 859664 milhões de frameworks ) que possui um estilo de programação &#8220;ala&#8221; Swing, possui uma curva de aprendizado bem pequena, é prazeroso e usa pouca configuração em .xml para que o programa funcione perfeitamente.<br />
Aqui segue um lista dos pontos principais do Wicket:</p>
<p>1. Utiliza POJO ( http://pt.wikipedia.org/wiki/Plain_Old_Java_Objects ).<br />
2. O código é escrito de uma forma &#8220;ala&#8221; Swing.<br />
3. Resolve os problemas do botão voltar do navegador automaticamente.<br />
4. Mensagens de erros fáceis de se entender e corrigir.<br />
5. Os componentes escritos utilizando o Wicket são totalmente reutilizáveis e podem ser distribuídos em um .jar .<br />
6. Não é intrusivo<br />
7. Compatível com qualquer editor HTML.<br />
8. Entre outras coisas&#8230; ( http://wicket.apache.org/introduction.html )</p>
<p>Agora depois de tantas apresentações, vou começar a demonstrar o poder dessa framework.<br />
Eu sei que todo site e blog mostra como iniciar um projeto do zero utilizando o wicket, e eu não vou ser diferente pois acho que apesar de se encontrar essa informação em todo lugar, no javaForDinner não existe, sendo assim:<br />
Você pode criar o seu projeto de 2 maneiras, a primeira é utilizando o Maven e a segunda é fazer na unha, vamos na unha mesmo.</p>
<p>O primeiro passo é fazer o download do <a href="http://www.apache.org/dyn/closer.cgi/wicket/1.3.0" target="_blank">wicket </a>, <a href="http://www.slf4j.org/dist/slf4j-1.4.3.zip">SLF4J </a>e do <a href="http://logging.apache.org/log4j/1.2/download.html" target="_blank">Log4j</a>. E caso você ainda não tenha um container sugiro o tomcat ou jetty, nesse artigo eu uso o tomcat.<br />
Depois que os downloads foram concluídos, abra o .zip do wicket, entre na pasta lib e adicione o arquivo wicket-1.3.0.jar em seu projeto, ele é a lib principal, onde se encontra todo o core do wicket e todo o mínimo necessário para que se consiga fazer um sistema.<br />
Abra o .zip do SLF4J e copie os arquivos slf4j-log4j12-1.4.2.jar e slf4j-api-1.4.2.jar para o seu projeto.<br />
Abra o .zip do Log4j e copie o arquivo log4j-1.2.15.jar para o seu projeto também.<br />
Pronto, todos as libs necessárias para iniciarmos nosso projeto já estão prontas. Não vou mostrar como adicionar essas libs em seu projeto web pois isso é uma coisa comum que a maioria das pessoas conhecem e também para não sairmos do foco do artigo.<br />
Dentro da pasta WebContent /WEB-INF crie/edite o arquivo web.xml com as seguintes informações:</p>
<pre><code>
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"&gt;&lt;display-name&gt;JavaForDinner&lt;/display-name&gt;
&lt;context-param&gt;
&lt;param-name&gt;configuration&lt;/param-name&gt;
&lt;param-value&gt;development&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;filter&gt;&lt;filter-name&gt;javafordinner&lt;/filter-name&gt;
&lt;filter-class&gt;org.apache.wicket.protocol.http.WicketFilter&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;applicationClassName&lt;/param-name&gt;
&lt;param-value&gt;br.com.javafordinner.JavaForDinnerApplication&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;javafordinner&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
&lt;welcome-file-list&gt;
&lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
&lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</code></pre>
<p>Pronto, essa é a unica configuração que é feita atravéz de um xml, o restante agora é só java <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Crie uma classe com o nome de JavaForDinnerApplication no pacote br.com.javafordinner e escreva o código a seguir nela:</p>
<pre><code>
public class JavaForDinnerApplication extends WebApplication
{
/**
* Constructor
*/
public JavaForDinnerApplication()
{
   super();
}

public Class getHomePage()
{
   return Index.class;
}

@Override
protected void init() {
   super.init();
}

}
</code></pre>
<p>Essa classe representa a sua aplicação como se fosse um &#8220;public static void main(String args[]) em uma aplicação desktop, é ela que da o start e configura a aplicação.<br />
Vou explicala em detalhes:</p>
<p><b>WebApplication</b><br />
A classe que representa a aplicação tem que estender a WebApplication, pois quando iniciamos o servidor, ele vai procurar pela classe que declaramos no web.xml, a classe que representa a aplicação.</p>
<p><b>public Class getHomePage()</b><br />
Vou mostrar o codigo da classe Index a seguir, mas por hora, essa classe representa a pagina principal da aplicação, que no caso, é a Index.html.</p>
<p><b>protected void init()</b><br />
Aqui setamos todas as configurações necessarias em nossa apliacação, como setar o local padrão dos arquivos css, html entre outras coisas. No momento não existe nenhuma configuração especial, então<br />
só é chamado o super.init() para gerar a configuração default.</p>
<p>Agora vamos criar a classe que representa nossa pagina inicial, crie uma classe chamada Index no pacote br.com.javafordinner.view.pages.Index e escreva o código a seguir:</p>
<pre><code>
/**
* Homepage
*/
public class Index extends WebPage {

private static final long serialVersionUID = 1L;

public Index(final PageParameters parameters) {
   add(new Label("label", "Olá Java for Dinner!!!"));
}

}
</code></pre>
<p>Explicando:</p>
<p>Toda classe que representa uma pagina da web deve extender a classe WebPage.<br />
Quando seu construtor é criado recebendo paramentros, isso indica ao Wicket que essa pagina não usa a session do servidor por default.</p>
<p>Agora crie um html no mesmo pacote da classe Index ( br.com.javafordinner.view.pages ) com o nome de Index.html e escreva o código a seguir:</p>
<pre><code>
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;span wicket:id="label"&gt;&lt;/span&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Reparem que exite um span com uma marcação &#8220;wicket:id=&#8221;label&#8221;, esse id=&#8221;label&#8221; representa o Label da classe Index.</p>
<p>Veja a imagem abaixo o resumo:</p>
<p><a href="http://javafordinner.files.wordpress.com/2008/01/fluxo_wicket1.jpg" title="Clique aqui e veja uma imagem resumindo o fluxo que seguimos."><img src="http://javafordinner.files.wordpress.com/2008/01/fluxo_wicket1.jpg" alt="Clique aqui e veja uma imagem resumindo o fluxo que seguimos." /></a></p>
<p><code></code>O label no html vai ser substituído pelo &#8220;Olá Java for Dinner!!!&#8221; da classe Index.Agora é só iniciar o servidor e acessar o endereço http://localhost:8080/javafordinner/ e pronto, você ira ver a mensagem .</p>
<p>Nos próximos artigos vamos nos aprofundar mais montando nossos componentes customizados, mudar o comportamento do Wicket entre outras coisas.</p>
<p>Até a próxima!!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/javafordinner.wordpress.com/5/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/javafordinner.wordpress.com/5/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/javafordinner.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/javafordinner.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/javafordinner.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/javafordinner.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/javafordinner.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/javafordinner.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/javafordinner.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/javafordinner.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=5&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://javafordinner.wordpress.com/2008/01/26/comecando-com-o-apache-wicket/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0ddc0192ae3b516c0055b270e026bcc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Barsotti</media:title>
		</media:content>

		<media:content url="http://javafordinner.files.wordpress.com/2008/01/fluxo_wicket1.jpg" medium="image">
			<media:title type="html">Clique aqui e veja uma imagem resumindo o fluxo que seguimos.</media:title>
		</media:content>
	</item>
		<item>
		<title>Sobre</title>
		<link>http://javafordinner.wordpress.com/2007/11/25/sobre/</link>
		<comments>http://javafordinner.wordpress.com/2007/11/25/sobre/#comments</comments>
		<pubDate>Sun, 25 Nov 2007 04:58:59 +0000</pubDate>
		<dc:creator>Danilo Barsotti</dc:creator>
				<category><![CDATA[Não classificado]]></category>

		<guid isPermaLink="false">http://javafordinner.wordpress.com/2007/11/25/sobre/</guid>
		<description><![CDATA[Esse blog tem o objetivo de dar dicas, idéias e soluções usando a linguagem Java e tudo oque ela pode oferecer.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=3&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Esse blog tem o objetivo de dar dicas, idéias e soluções usando a linguagem Java e tudo oque ela pode oferecer.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/javafordinner.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/javafordinner.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/javafordinner.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/javafordinner.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/javafordinner.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/javafordinner.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/javafordinner.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/javafordinner.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/javafordinner.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/javafordinner.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=javafordinner.wordpress.com&amp;blog=2196186&amp;post=3&amp;subd=javafordinner&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://javafordinner.wordpress.com/2007/11/25/sobre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a0ddc0192ae3b516c0055b270e026bcc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Barsotti</media:title>
		</media:content>
	</item>
	</channel>
</rss>
