<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>JBlog</title>
	
	<link>http://blogs.dextra.com.br/jblog</link>
	<description>Just another WordPress weblog</description>
	<pubDate>Mon, 27 Jul 2009 13:55:26 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/dextra-jblog" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Curiosidade do Magic Number</title>
		<link>http://feedproxy.google.com/~r/dextra-jblog/~3/pzNMFg2HVJc/</link>
		<comments>http://blogs.dextra.com.br/jblog/?p=68#comments</comments>
		<pubDate>Mon, 27 Jul 2009 13:51:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Magic number]]></category>

		<guid isPermaLink="false">http://blogs.dextra.com.br/jblog/?p=68</guid>
		<description><![CDATA[pre{font-family:"Courier New", Courier, monospace;font-size:12px;background:#ccc;border:1px dashed #666;	display:block;padding:20px; overflow:auto}
Olá Pessoal,
Hoje nosso post será apenas uma curiosidade.
Segundo a spec da VM, a estrutura de um arquivo .class deve ser:

    ClassFile {
   	u4 magic;
    	u2 minor_version;
    	u2 major_version;
    	u2 constant_pool_count;
    	cp_info constant_pool[constant_pool_count-1];
 [...]]]></description>
			<content:encoded><![CDATA[<style>pre{font-family:"Courier New", Courier, monospace;font-size:12px;background:#ccc;border:1px dashed #666;	display:block;padding:20px; overflow:auto}</style>
<p>Olá Pessoal,</p>
<p>Hoje nosso post será apenas uma curiosidade.<br />
Segundo a <code>spec</code> da VM, a estrutura de um arquivo <code>.class</code> deve ser:</p>
<pre>
    <code>ClassFile {
   	u4 magic;
    	u2 minor_version;
    	u2 major_version;
    	u2 constant_pool_count;
    	cp_info constant_pool[constant_pool_count-1];
    	u2 access_flags;
    	u2 this_class;
    	u2 super_class;
    	u2 interfaces_count;
    	u2 interfaces[interfaces_count];
    	u2 fields_count;
    	field_info fields[fields_count];
    	u2 methods_count;
    	method_info methods[methods_count];
    	u2 attributes_count;
    	attribute_info attributes[attributes_count];
    }    </code>
</pre>
<p>Os 4 primeiros <code>bytes</code> desse arquivo, chamado de magic, idenfica que um arquivo é um <code>class</code> (<strong>&#8220;The magic item supplies the magic number identifying the class file format;&#8221;</strong>).</p>
<p>Ou seja, qualquer arquivo <code>.class</code> terá esse magic number que, em hexadecimal é nada mais do que <code>0xCAFEBABE</code> ou simplesmente <strong>Cafe Babe</strong>.</p>
<p>Faça o teste! abra qualquer <code>.class</code> em um editor hexadecimal e veja o resultado&#8230;</p>
<p><strong>Na linha de comando do Linux:</strong></p>
<pre>
<code>hexdump -C arquivo.class</code>
</pre>
<p><strong>Saída</strong></p>
<pre>
<code>00000000  ca fe ba be 00 00 00 32  00 81 0a 00 21 00 4a 0a  |Êþº¾...2....!.J.|
00000010  00 0f 00 4b 09 00 0f 00  4c 07 00 4d 0a 00 04 00  |...K....L..M....|
00000020  4a 0a 00 04 00 4e 0a 00  04 00 4f 07 00 50 09 00  |J....N....O..P..|
00000030  0f 00 51 08 00 52 0b 00  53 00 54 07 00 55 0a 00  |..Q..R..S.T..U..|</code>
</pre>
<p><strong>No emacs:</strong></p>
<pre>
  <code>emacs -nw arquivo.class</code>
</pre>
<p><strong>Mudar para modo hexadecimal</strong>:</p>
<p>- aperte Esc</p>
<p>- aperte x</p>
<p>- Digite: hexl-mode</p>
<p><strong>Para sair</strong>:</p>
<p>- Crtl+X</p>
<p>- Crtl + C </p>
<p>Enviado por: <strong>Raoni Fortes Normanton</strong><br />
Desenvolvedor Java, Dextra Sistemas</p>
<img src="http://feeds.feedburner.com/~r/dextra-jblog/~4/pzNMFg2HVJc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.dextra.com.br/jblog/?feed=rss2&amp;p=68</wfw:commentRss>
		<feedburner:origLink>http://blogs.dextra.com.br/jblog/?p=68</feedburner:origLink></item>
		<item>
		<title>Introdução a Programação Orientada a Aspectos com JBoss AOP</title>
		<link>http://feedproxy.google.com/~r/dextra-jblog/~3/9llELPfPVFY/</link>
		<comments>http://blogs.dextra.com.br/jblog/?p=38#comments</comments>
		<pubDate>Fri, 10 Jul 2009 16:53:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[AOP]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[JBoss]]></category>

		<category><![CDATA[Programação Orientada a Aspectos]]></category>

		<guid isPermaLink="false">http://blogs.dextra.com.br/jblog/?p=38</guid>
		<description><![CDATA[pre{font-family:"Courier New", Courier, monospace;font-size:12px;background:#ccc;border:1px dashed #666;	display:block;padding:20px; overflow:auto}
Olá pessoal! 
Este artigo, através de um exemplo simples de código, utiliza JBoss AOP para aprimorar seu comportamento, enquanto demonstra algumas das principais funcionalidades do framework. Vamos encapsular os interesses transversais da aplicação em aspectos, dar uma olhada em advices e nos novos advices leves que acompanham a versão [...]]]></description>
			<content:encoded><![CDATA[<style>pre{font-family:"Courier New", Courier, monospace;font-size:12px;background:#ccc;border:1px dashed #666;	display:block;padding:20px; overflow:auto}</style>
<p>Olá pessoal! </p>
<p>Este artigo, através de um exemplo simples de código, utiliza JBoss AOP para aprimorar seu comportamento, enquanto demonstra algumas das principais funcionalidades do framework. Vamos encapsular os interesses transversais da aplicação em aspectos, dar uma olhada em advices e nos novos advices leves que acompanham a versão 2.0 do JBoss AOP. Também estudaremos formas de adicionar interfaces às suas classes.</p>
<p>Baseado no texto original de <a href="http://java.dzone.com/news/an-introduction-aspect-oriente?page=0,0">Kabir Khan</a>.</p>
<p>&#8212;&#8212;&#8212;-</p>
<p>O Servidor de aplicações JBoss possui suporte nativo à programação orientada a aspectos (Aspect-Oriented Programming ou AOP) em sua versão 5. Entretanto, o JBoss AOP também está disponível como um framework independente para uso use em aplicações executadas em JBoss.</p>
<p>Este artigo, aplica os conceitos de programação orientada a aspectos a um exemplo simples de código, aperfeiçoando o comportamento do código e ao mesmo tempo demonstrando algumas das principais funcionalidades do framework. O encapsulamento dos interesses transversais da aplicação em aspectos através de advices e nos novos advices leves que acompanham a versão 2.0 do framework JBoss AOP serãoo foco principal deste estudo.</p>
<p><strong>Aplicação exemplo</strong></p>
<p>O exemplo utilizado para a demonstração dos conceitos básicos de JBoss AOP é um simples aplicativo bancário. Ele possui uma classe BankAccount:</p>
<pre>
package bank;
public class BankAccount{

   private int accountNumber;
   private int balance;

   public BankAccount(int accountNumber){
      System.out.println("*** Bank Account constructor");
      this.accountNumber = accountNumber;
   }

   public int getAccountNumber(){
      return accountNumber;
   }

   public int getBalance(){
      return balance;
   }

   public void debit(int amount){
      System.out.println("*** BankAccount.debit()");
      balance -= amount;
   }

   public void credit(int amount){
      System.out.println("*** BankAccount.credit()");
      balance += amount;
   }
}
</pre>
<p>E adicionalmente, possui uma classe Bank:</p>
<pre>
package bank;

import java.util.HashMap;
import java.util.Map;

public class Bank{

   private static Map bankAccounts = new HashMap();

   public static void transfer(BankAccount from, BankAccount to, int amount){
      from.debit(amount);
      to.credit(amount);
   }

   public static void main(String[] args){
      System.out.println("*** Creating account 1");
      BankAccount acc1 = new BankAccount(1);
      acc1.credit(150);
      bankAccounts.put(acc1.getAccountNumber(), acc1);

      System.out.println("*** Creating account 2");
      BankAccount acc2 = new BankAccount(2);
      acc2.credit(230);
      bankAccounts.put(acc2.getAccountNumber(), acc2);

      System.out.println("*** Balance acount 1: " + acc1.getBalance());
      System.out.println("*** Balance acount 2: " + acc2.getBalance());

      //Transfer some money
      System.out.println("*** Transfer 50 from account 1 to account 2");
      transfer(acc1, acc2, 50);

      System.out.println("*** Balance acount 1: " + acc1.getBalance());
      System.out.println("*** Balance acount 2: " + acc2.getBalance());
   }
}
</pre>
<p>Como se observa, foram criadas duas contas de banco com seus números de conta, definidos os saldos iniciais de cada conta, e então foram transfedos $50 da contra 1 para a conta 2.</p>
<p>Quando este código é executado, a saída esperada é a apresentada abaixo:</p>
<pre>
*** Creating account 1
*** Bank Account constructor
*** BankAccount.credit()
*** Creating account 2
*** Bank Account constructor
*** BankAccount.credit()
*** Balance acount 1: 150
*** Balance acount 2: 230
*** Transfer 50 from account 1 to account 2
*** BankAccount.debit()
*** BankAccount.credit()
*** Balance acount 1: 100
*** Balance acount 2: 280
</pre>
<p><strong>Logging: um interesse transversal à aplicação</strong></p>
<p>Uma das principais motivações para o uso de programação orientada a aspectos é extrair do código de negócio da aplicação interesses transversais, geralmente não-funcionais. Supondo que seja necessário auditar a aplicação através de logging toda vez que um objeto for criado, quando valores forem atribuídos a seus campos, e quando seus métodos forem invocados. A maneira mais óbvia para este fim, e que foi utilizada no exemplo acima, consiste em acrescentar código de logging em diversos pontos do código da aplicação.</p>
<p>O problema desta abordagem é que pode ser necessário editar muitos pontos do código da aplicação, espalhados por todo o sistema, os quais deveria ser identificados, modificados para o acréscimo do código de logging, e posteriormente uma recompilação da aplicação seria necessária. Além disso, para este comportamento seja desligado, pode ser necessário remover todo o código de logging novamente e recompilar a aplicação uma vez mais. Assim, a maneira óbvia também é tediosa e difícil de ser mantida.</p>
<p>Utilizando AOP, é possível encapsular este interesse transversal no código de um aspecto. O aspecto em si é apenas mais uma classe Java, que pode manter estado, estender outras classes e tudo o que se pode fazer com uma classe Java.</p>
<pre>
package bank;

import org.jboss.aop.joinpoint.ConstructorInvocation;
import org.jboss.aop.joinpoint.FieldWriteInvocation;
import org.jboss.aop.joinpoint.MethodInvocation;

public class LoggingAspect{

   public Object log(ConstructorInvocation invocation) throws Throwable{
      try
         System.out.println("C: Creating BankAccount using constructor " + invocation.getConstructor());
         System.out.println("C: Account number: " + invocation.getArguments()[0]);
         return invocation.invokeNext();
      finally
         System.out.println("C: Done");
   }

   public Object log(MethodInvocation invocation) throws Throwable{
      try
         System.out.println("M: Calling method " + invocation.getMethod().getName());
         System.out.println("M: Amount " + invocation.getArguments()[0]);
         return invocation.invokeNext();
      finally
         System.out.println("M: Done");
   }

   public Object log(FieldWriteInvocation invocation) throws Throwable{
      BankAccount account = (BankAccount)invocation.getTargetObject();
      System.out.println("F: setting field " + invocation.getField().getName() + " for BankAccount " + account.getAccountNumber());
      System.out.println("F: Field old value " + account.getBalance());
      System.out.println("F: New value will be " + invocation.getValue());
      try
         return invocation.invokeNext();
      finally
         System.out.println("F: Field new value " + account.getBalance());
         System.out.println("F: Done");
   }
}
</pre>
<p>O código que implementa os interesses transversais é encapsulado em métodos do aspecto denominados advice. Os advice apresentados nesta sessão são do tipo around advice, e sua assinatura e formato são os seguintes:</p>
<pre>
public Object (org.jboss.aop.joinpoint.Invocation invocation) throws Throwable{

   //Faça alguma coisa antes

   try

      return invocation.invokeNext();

   finally

      //Faça alguma coisa depois

}
</pre>
<p>O parâmetro invocation pode ser do tipo org.jboss.aop.joinpoint.Invocation, ou alguma de suas subclasses. Algumas destas subclasses são apresentadas no aspecto LoggingAspect, e o método log sobrecarregado a ser chamado depende do que estiver sendo chamado no código de negócio quando o aspecto for aplicado. Em LoggingAspect é possível tratar chamadas a um construtor de objeto, (como é feito pelo primeiro método log() do aspecto), chamadas a um método de objeto (como é feito pelo segundo método log() do aspecto), e chamadas a métodos setXX() de um campo de objeto (como é feito pelo terceiro método log() do aspecto).</p>
<p>Estes eventos, ou pontos de entrada para a aplicação do aspecto, são chamados joinpoints na terminologia AOP. O parâmetro invocation contém informação sobre qual campo/método/construtor sendo invocado. Métodos advice do tipo around também devem conter uma chamada a Invocation.invokeNext(), que realiza a propagação da cadeia de chamadas. Se houver diversos métodos advice aplicados a um mesmo joinpoint, esta chamada invoca o próximo advice da cadeia. Se este for o último advice a cadeia, ou como no exemplo acima, se houver apenas um advice na cadeia, o código do joinpoint (ou seja o código executado no objeto de negócio) é chamado quando Invocation.invokeNext() é executado.</p>
<p>Para aplicar o aspecto de logging ao código de negócio, é preciso definir alguma configuração para declarar o aspecto, e selecionar os joinpoints na aplicação de exemplo, a partir de onde os métodos advice serão invocados. No JBoss AOP, ma maneira mais simples de se fazer esta configuração é através de um arquivo XML, tipicamente chamado jboss-aop.xml. Em primeiro lugar, o aspecto é declarado:</p>
<pre>
&lt;aop&gt;
&lt;aspect class="bank.LoggingAspect"/&gt;
</pre>
<p>Em uma tag bind é definida uma amarração, utilizando o atributo pointcut da tag para selecionar os métodos de negócio aos quais um dos métodos advice do aspecto devem ser aplicados. Neste caso, tem-se uma expressão de construtor, que seleciona o construtor da classe bank.BankAccount que possua um parâmetro int. É importante notar que todos os nomes de classes utilizados em uma expressão de pointcut devem ser completamente qualificados.</p>
<p>A palavra new é um identificador especial dentro da linguagem de definição de pointcuts, utilizada para selecionar um construtor. Em seguida, a parte around da amarração indica que o advice log do aspecto bank.LoggingAspect deve ser aplicado a todos os joinpoints do código de negócio aos quais a definição deste pointcut se aplica. Em outras palavras, quando o construtor da classe BankAccount for invocado, o primeiro método LoggingAspect.log(), que recebe como parâmetro um ConstructorInvocation, é invocado.</p>
<pre>
   &lt;bind pointcut="execution(bank.BankAccount->new(int))"&gt;
     &lt;around aspect="bank.LoggingAspect" name="log"&gt;
   &lt;/bind&gt;
</pre>
<p>A amarração de pointcut anterior captura apenas um joinpoint. A próxima utiliza um coringa no lugar do nome do método, de forma que selecionamos todos os métodos que retornem void e que recebem um int como parâmetro, não obstante seu nome. Ela se parece muito com a expressão de construtor da amarração anterior, mas inclui o tipo de retorno dos métodos de interesse para logging. Este pointcut seleciona BankAccount.debit() e BankAccount.credit(), e invoca o segundo método LoginAspect.log() passando um MethodInvocation como parâmetro quando esses métodos são chamados.</p>
<pre>
&lt;bind pointcut="execution(void bank.BankAccount->*(int))"&gt;
      &lt;around aspect="bank.LoggingAspect" name="log"/&gt;
&lt;/bind&gt;
</pre>
<p>Finalmente, há uma amarração que captura as atribuições feitas ao campo de saldo (balance) da classe BankAccount. Neste caso, utiliza-se um coringa no lugar no nome do tipo, e o terceiro método LoggingAspect.log(), que recebe um FieldWriteInvocation, será invocado quando o campo tiver seu valor modificado.</p>
<pre>
&lt;bind pointcut="set(* bank.BankAccount->balance)"&gt;
   &lt;around aspect="bank.LoggingAspect" name="log"/&gt;
&lt;/bind&gt;
</pre>
<p>Além de coringas, também é possível capturar hierarquias de herança inteiras de classes, utilizando typedefs para expressões de classe complexas, capturar todas as classes pertencentes a um determinado pacote, e como será apresentado posteriormente, utilizar anotações para capturar uma ampla gama de joinpoints.</p>
<p>Para executar esta aplicação com AOP habilitada, é necessário passar alguns parâmetros extras para a JVM quando a aplicação for iniciada, como pode ser visto no build.xml do exemplo.</p>
<pre>
   &lt;target name="run-load-time" depends="compile"&gt;
      &lt;java fork="yes" failOnError="true" className="bank.Bank"&gt;
         &lt;sysproperty key="jboss.aop.path" value="jboss-aop.xml"/&gt;
         &lt;jvmarg value="-javaagent:../libraries/jboss-aop-jdk50-single.jar"/&gt;
         &lt;classpath refid="classpath"/&gt;
      &lt;/java&gt;
   &lt;/target&gt;
</pre>
<p>O parâmetro jboss.aop.path contém o caminho do arquivo jboss-aop.xml que declara os aspectos e amarra os métodos advice aos joinpoints. O argumento –javaagent aponta para a biblioteca do JBoss AOP, que liga o processo de weaving em tempo de carga (load-time weaving). Quando uma classe é carregada pela primeira vez, o JBoss AOP intercepta este evento e modifica o bytecode da classe para acrescentar os pontos de chamada requeridos à invocação dos aspectos relacionados aos joipoints selecionados.</p>
<p>Além de realizar o processo combinação (weaving) de código em tempo de carga das classes, você também pode combinar o código dos aspectos utilizando aopc post-processor. Um exemplo disso é mostrado no build.xml da aplicação exemplo. Ao executar o exemplo com load-time weaving, a seguinte saída é produzida, agora com muita informação extra vinda do aspecto de logging:</p>
<pre>
*** Creating account 1
C: Creating BankAccount using constructor public bank.BankAccount(int)
C: Account number: 1
*** Bank Account constructor
C: Done
M: Calling method credit
M: Amount 150
*** BankAccount.credit()
F: setting field balance for BankAccount 1
F: Field old value 0
F: New value will be 150
F: Field new value 150
F: Done
M: Done
*** Creating account 2
C: Creating BankAccount using constructor public bank.BankAccount(int)
C: Account number: 2
*** Bank Account constructor
C: Done
M: Calling method credit
M: Amount 230
*** BankAccount.credit()
F: setting field balance for BankAccount 2
F: Field old value 0
F: New value will be 230
F: Field new value 230
F: Done
M: Done
*** Balance acount 1: 150
*** Balance acount 2: 230
*** Transfer 50 from account 1 to account 2
M: Calling method debit
M: Amount 50
*** BankAccount.debit()
F: setting field balance for BankAccount 1
F: Field old value 150
F: New value will be 100
F: Field new value 100
F: Done
M: Done
M: Calling method credit
M: Amount 50
*** BankAccount.credit()
F: setting field balance for BankAccount 2
F: Field old value 230
F: New value will be 280
F: Field new value 280
F: Done
M: Done
*** Balance acount 1: 100
*** Balance acount 2: 280
</pre>
<p><strong>Externalizando Verificações de Segurança</strong></p>
<p>Logging é o exemplo mais comumente utilizado para uma introdução a AOP, mas é possível fazer algo mais interessante. Supondo que seja necessário ter certeza de que apenas usuários com determinadas permissões possam chamar um método. Seria necessário anotar os métodos de BankAccount da seguinte maneira:</p>
<pre>
package bank;

public class BankAccount{

   private int accountNumber;
   private int balance;

   @Roles(roles= "admin")
   public BankAccount(int accountNumber){
      System.out.println("*** Bank Account constructor");
      this.accountNumber = accountNumber;
   }
   ...

   @Roles(roles= "admin")
   public void debit(int amount){
      System.out.println("*** BankAccount.debit()");
      balance -= amount;
   }

   @Roles(roles= "admin", "user")
   public void credit(int amount){
      System.out.println("*** BankAccount.credit()");
      balance += amount;
   }
}
</pre>
<p>De forma que apenas usuários com o perfil <strong>admin</strong> possam criar instâncias de BankAccount e debitar contas, enquanto que tanto o perfil <strong>admin</strong> quando o perfil <strong>user</strong> possam creditar contas. Para simular usuários com acesso ao sistema, suponha a existência de um arquivo security.properties contendo tais informações:</p>
<pre>
admin=password;admin,user
guest=password;user
</pre>
<p>Há um usuário chamado <strong>admin</strong> cuja senha é <strong>password</strong> e que tem os perfis <strong>admim</strong> e <strong>user</strong>, e um usuário chamado <strong>guest</strong> cuja senha é <strong>password</strong> e que possui apenas o perfil <strong>user</strong>.</p>
<p>É possível então aplicar um SecurityAspect aos métodos anotados com a anotação @Roles. Assim como tudo o mais na linguagem de pointcut, as anotações precisam ser completamente qualificadas. O símbolo “..” no lugar dos parâmetros na expressão de pointcut significa que se deseja que este aspecto seja aplicado a todos os construtores e métodos anotados com @Roles, a despeito dos parâmetros que recebam.</p>
<pre>
&lt;aop&gt;
   &lt;aspect class="bank.SecurityAspect"/&gt;

   &lt;bind pointcut="execution(bank.BankAccount-&gt;@bank.Roles(..))"&gt;
      &lt;around aspect="bank.SecurityAspect" name="checkSecurity"/&gt;
   &lt;/bind&gt;

   &lt;bind pointcut="execution(* bank.BankAccount-&gt;@bank.Roles(..))"&gt;
      &lt;around aspect="bank.SecurityAspect" name="checkSecurity"/&gt;
   &lt;/bind&gt;
&lt;/aop&gt;
</pre>
<p>O aspecto SecurityAspect verifica que o usuário correto esteja sendo utilizado:</p>
<pre>package bank;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.jboss.aop.joinpoint.Invocation;

public class SecurityAspect{

   private Map&lt;String, String&gt; usernamePassword = new HashMap&lt;String, String&gt;();
   private Map&lt;String, List&lt;String&gt;&gt; userRoles = new HashMap&lt;String, List&lt;String&gt;&gt;();

   public SecurityAspect() throws FileNotFoundException, IOException, URISyntaxException{
      //Inicializa o usernamePassword e o mapa userRoles
      //com informação do security.properties
   }   

   public Object checkSecurity(Invocation invocation) throws Throwable{
      String username = LoginInfo.getUsername();
      String password = usernamePassword.get(username);
      if (password == null)
         throw new SecurityException("Unknown user");
      if (!password.equals(LoginInfo.getPassword()))
         throw new SecurityException("Wrong password");
      Roles rolesAnnotaton = (Roles)invocation.resolveAnnotation(Roles.class);
      List&lt;String&gt; hasRoles = userRoles.get(username);
      boolean hasRole = false;
      if (hasRoles != null)
         for (String role : rolesAnnotaton.roles())
            if (hasRoles.contains(role))
               hasRole = true;
               break;
      if (!hasRole)
         throw new SecurityException("Wrong roles for user");
      return invocation.invokeNext();
   }
</pre>
<p>Os perfis necessários para a invocação do joinpoint alvo são obtidas do parâmetro invocation utilizando esta chamada:</p>
<pre>
Roles rolesAnnotaton = (Roles)invocation.resolveAnnotation(Roles.class);
</pre>
<p>Este código tem o mesmo efeito que a chamada java.lang.reflect.Method.getAnnotation() ou java.lang.reflect.Constructor.getAnnotation() para um método ou construtor, mas também permite redefinição de anotações como parte da configuração AOP, que está além do escopo deste artigo. Apesar do tipo de invocação utilizada neste exemplo ser Invocation, o tipo específico criado pelo JBoss AOP será ConstructorInvocation ou MethodInvocation, dependendo do que estiver sendo chamando. A classe LoginInfo é apenas um wrapper para alguns campos estáticos contendo <strong>username</strong> e <strong>senha</strong>.</p>
<pre>
package bank;

public class LoginInfo{

   private static String username;
   private static String password;

   public static void setUsernameAndPassword(String username, String password){
      LoginInfo.username = username;
      LoginInfo.password = password;
   }   

   public static String getUsername(){
      return username;
   }   

   public static String getPassword(){
      return password;
   }
}
</pre>
<p>Agora, o método Bank.main() será modificado para popular os campos de LoginInfo:</p>
<pre>
public static void main(String[] args){
      System.out.println("*** Log in as 'guest' - it does not have the correct roles to create an account");
      LoginInfo.setUsernameAndPassword("guest", "password");
      System.out.println("*** Attempting to create account 1");
      try
         BankAccount acc1 = new BankAccount(1);
         acc1.credit(150);
         bankAccounts.put(acc1.getAccountNumber(), acc1);
      catch(SecurityException e)
         System.out.println("!!! Expected SecurityException " + e.getMessage());
      System.out.println("*** Log in as 'admin' - the roles are fine for the rest now");
      LoginInfo.setUsernameAndPassword("admin", "password");
      System.out.println("*** Creating account 1");
      BankAccount acc1 = new BankAccount(1);
      acc1.credit(150);
      bankAccounts.put(acc1.getAccountNumber(), acc1);
      System.out.println("*** Creating account 2");
      BankAccount acc2 = new BankAccount(2);
      acc2.credit(230);
      bankAccounts.put(acc2.getAccountNumber(), acc2);
      System.out.println("*** Balance acount 1: " + acc1.getBalance());
      System.out.println("*** Balance acount 2: " + acc2.getBalance());
      //Transfer some money
      System.out.println("*** Transfer 50 from account 1 to account 2");
      transfer(acc1, acc2, 50);
      System.out.println("*** Balance acount 1: " + acc1.getBalance());
      System.out.println("*** Balance acount 2: " + acc2.getBalance());
}
</pre>
<p>Primeiro o método tenta criar uma BankAccount com um usuário que não possui o perfil admim requerido, e então o processo é repetido com um usuário que possui o perfil requerido. Quando a aplicação é executada, a seguinte saída é apresentada:</p>
<pre>
*** Log in as 'guest' - it does not have the correct roles to create an account
*** Attempting to create account 1
!!! Expected SecurityException Wrong roles for user
*** Log in as 'admin' - the roles are fine for the rest now
*** Creating account 1
*** Bank Account constructor
*** BankAccount.credit()
*** Creating account 2
*** Bank Account constructor
*** BankAccount.credit()
*** Balance acount 1: 150
*** Balance acount 2: 230
*** Transfer 50 from account 1 to account 2
*** BankAccount.debit()
*** BankAccount.credit()
*** Balance acount 1: 100
*** Balance acount 2: 280
</pre>
<p>Ao utilizar AOP para controle de segurança, as verificações de segurança foram extraídas para um local centralizado na aplicação e foram utilizadas anotações para configurar sinalizar os aspectos sobre onde aplicar a segurança. Se for desejável utilizar um mecanismo diferente de configuração de usuários, é possível manter o núcleo de negócio da aplicação intacto, escrever um outro aspecto e modificar facilmente a maneira como a segurança é aplicada em toda a parte do sistema modificando o arquivo jboss-aop.xml.</p>
<p><strong>Métodos Advice Leves</strong></p>
<p>Os méodos advice vistos até o momento são do tipo around, que tem sido parte do framework JBoss AOP desde seu início. Eles permitem adicionar comportamento antes e depois da invocação do joinpoint alvo. Como visto, estes advice recebem como argumento um parâmetro do tipo Invocation, ou uma subclasse desta. Em uma aplicação com muitos pontos de aplicação de aspectos, toda vez que for necessário invocar um joinpoint que possua métodos advice aplicados a ele, o framework AOP precisará instanciar o objeto Invocation, e isto pode causar algum reflexo no desempenho da aplicação.</p>
<p>Para alinhar o framework ao que é oferecido por outros frameworks de AOP, foi introduzido o conceito de métodos advice leves, que não requerem a instanciação de um objeto Invocation. O objeto Invocation contém muita informação conceitual a respeito do que está sendo chamado, mas ainda é possível obter boa parte desta informação por outros meios. De volta a exemplo de logging, pode-se reescrever LoggingAspect sobre o que fazer quando campos são modificados:</p>
<pre>
package bank;

import org.jboss.aop.advice.annotation.Arg;
import org.jboss.aop.advice.annotation.JoinPoint;
import org.jboss.aop.advice.annotation.Target;
import org.jboss.aop.joinpoint.FieldAccess;

public class LoggingAspect{

   public void logBefore(@JoinPoint FieldAccess fieldAccess, @Target BankAccount account, @Arg int value){
      System.out.println("F: setting field " + fieldAccess.getField().getName() + " for BankAccount " + account.getAccountNumber());
      System.out.println("F: Field old value " + account.getBalance());
      System.out.println("F: New value will be " + value);
   }

   public void logAfter(@Target BankAccount account)[
      System.out.println("F: Field new value " + account.getBalance());
      System.out.println("F: Done");
   }
}
</pre>
<p>O método log original foi dividido em dois métodos. Um advice do tipo before, logBefore(), que será disparado ates do campo ser modificado, e um advice do tipo after, logAfter(), que será disparado após o campo ser modificado. Para o método logBefore(), o parâmetro fieldAccess, anotado com @JoinPoint?, contém informação sobre o campo a ser modificado, o parâmetro account, anotado com @Target, recebe o objeto cujo campo será modificado, e o parâmetro value, anotado com @Arg, recebe o novo valor que será atribuído ao campo.</p>
<p>De maneira análoga, para o método logAfter(), o parâmetro account, anotado com @Target, recebe o objeto cujo campo foi modificado. É importante notar que como os métodos advice leves nunca recebem um parâmetro Invocation, não há necessidade de se chamar Invocation.invokeNext(). O framework JBoss AOP sabe quais advices chamar antes e após uma chamada ao joinpoint alvo. Para amarrar estes advices, é utilizado o seguinte xml:</p>
<pre>
&lt;aop&gt;
   &lt;aspect class="bank.LoggingAspect"/&gt;
   &lt;bind pointcut="set(* bank.BankAccount-&gt;balance)"&gt;
      &lt;before aspect="bank.LoggingAspect" name="logBefore"/&gt;
      &lt;after aspect="bank.LoggingAspect" name="logAfter"/&gt;
   &lt;/bind&gt;
&lt;/aop&gt;
</pre>
<p>Esta declaração é similar ao exemplo de logging anterior, mas ao invés de utilizar around nesta amarração, foi utilizada uma entrada before e uma entrada after, especificando que logBefore() deve ser chamado antes do campo ser modificado e logAfter() deve ser chamado após o campo ser modificado. Ao executar este exemplo temos a seguinte saída:</p>
<pre>
*** Creating account 1
*** Bank Account constructor
*** BankAccount.credit()
F: setting field balance for BankAccount 1
F: Field old value 0
F: New value will be 150
F: Field new value 150
F: Done
*** Creating account 2
*** Bank Account constructor
*** BankAccount.credit()
F: setting field balance for BankAccount 2
F: Field old value 0
F: New value will be 230
F: Field new value 230
F: Done
*** Balance acount 1: 150
*** Balance acount 2: 230
*** Transfer 50 from account 1 to account 2
*** BankAccount.debit()
F: setting field balance for BankAccount 1
F: Field old value 150
F: New value will be 100
F: Field new value 100
F: Done
*** BankAccount.credit()
F: setting field balance for BankAccount 2
F: Field old value 230
F: New value will be 280
F: Field new value 280
F: Done
*** Balance acount 1: 100
*** Balance acount 2: 280
</pre>
<p>Além dos tipos before e after, também é possível utilizar advices do tipo throwing, que são chamados quando o joinpoint alvo lança uma exceção, e advices do tipo finally, que são chamados após o joinpoint alvo, não obstante uma exceção ter sido ou não lançada pelo joinpoint. Como vimos, advices do tipo after são chamados após a execução o joinpoint alvo, desde que nenhuma exceção tenha sido lançada por ele.</p>
<p><strong>Observer com introduções de interfaces e mixins</strong></p>
<p>Supondo que fosse necessário enviar uma notificação de alguma maneira quando o saldo da conta bancária for modificado. Uma opção para implementar este comportamento seria implementar o padrão de projeto Observer, mas é indesejável incluir todo o código de infra-estrutura deste padrão na classe BankAccount. Primeiramente, considere uma anotação ao campo balance, que será monitorado.</p>
<pre>
package bank;

public class BankAccount{

   int accountNumber;

   @Observed
   int balance;
   ...
}
</pre>
<p>Em seguida, uma implementação de Observable:</p>
<pre>
package bank;

import java.util.ArrayList;
import java.util.List;

public class ObservableMixin implements Observable{

   private List<Observer> observers = new ArrayList<Observer>();

   public void addObserver(Observer listener){
      observers.add(listener);
   }

   public void removeObserver(Observer listener){
      observers.remove(listener);
   }   

   public void notifyObservers(Object event){
      for (Observer observer : observers){
         observer.update(event);
      }
   }
}
</pre>
<p>Esta é uma classe mixin, que implementa a interface Observable. Ela contém todo o código de infra-estrutura necessário para a parte Observable do padrão. E pode ser introduzida em POJOs utilizando o seguinte xml:</p>
<pre>
&lt;aop&gt;
   &lt;introduction expr="hasfield(* *-&gt;@bank.Observed)"&gt;
      &lt;mixin&gt;
         &lt;interfaces&gt;
            bank.Observable
         &lt;/interfaces&gt;
         &lt;class&gt;bank.ObservableMixin&lt;/class&gt;
      &lt;/mixin&gt;
   &lt;/introduction&gt;
      ...
</pre>
<p>Este xml faz duas coisas. Primeiramente, faz com que todas as classes que tenham um campo anotado com @Observed implemente a interface Observable e seus méodos. Em segundo lugar, quando alguém tenta chamar os métodos da interface Observable, as chamadas são delegadas para uma instância da interface ObservableMixin.</p>
<p>A seguir, um aspecto é declarado para monitorar campos anotados com @Observed quando estes são modificados, conforme mostra o seguinte xml:</p>
<pre>
...
   &lt;aspect class="bank.ObserverAspect"/&gt;
   &lt;bind pointcut="set(* bank.BankAccount-&gt;@bank.Observed)"&gt;
      &lt;around aspect="bank.ObserverAspect" name="fieldChanged"/&gt;
   &lt;/bind&gt;
&lt;/aop&gt;
</pre>
<p>O aspecto é um advice do tipo around que captura os valores antes e depois da modificação do campo.</p>
<pre>
package bank;

import java.lang.reflect.Field;

import org.jboss.aop.joinpoint.FieldWriteInvocation;

public class ObserverAspect{

   public Object fieldChanged(FieldWriteInvocation invocation) throws Throwable{
      Observable tgt = (Observable)invocation.getTargetObject();
      Field fld = invocation.getField();
      String fieldName = fld.getName();
      fld.setAccessible(true);
      Object oldVal = invocation.getField().get(tgt);
      Object result = invocation.invokeNext();
      Object newVal = invocation.getField().get(tgt);
      tgt.notifyObservers("Changed " + fieldName + " from " + oldVal + " to " + newVal);
      return result;
   }
}
</pre>
<p>Como as classes capturadas pelo pointcut são classes que implementam a interface Observable, é seguro realizar um casting para esta interface. Então, os valores antes e depois da modificação do campo são registrados e a interface Observable é utilizada para notificar os observadores a respeito da modificação. Conforme mencionado, a chamada a Observable.notifyObservers() acabará sendo respondida pela classe ObservableMixin.</p>
<p>Finalmente, o método Bank.main() será modificado para registrar um Observer com uma instância de BankAccount.</p>
<pre>
   public static void main(String[] args){
      System.out.println("*** Creating account 1");
      BankAccount acc1 = new BankAccount(1);
      acc1.credit(150);
      bankAccounts.put(acc1.getAccountNumber(), acc1);

      System.out.println("*** Creating account 2");
      BankAccount acc2 = new BankAccount(2);
      acc2.credit(230);
      bankAccounts.put(acc2.getAccountNumber(), acc2);

      System.out.println("Installing observer");
      ((Observable)acc2).addObserver(new Observer()
         public void update(Object evt)

            System.out.println("!!! Observer: " + evt);

      );

      System.out.println("*** Balance acount 1: " + acc1.getBalance());
      System.out.println("*** Balance acount 2: " + acc2.getBalance());

      //Transfer some money
      System.out.println("*** Transfer 50 from account 1 to account 2");
      transfer(acc1, acc2, 50);

      System.out.println("*** Balance acount 1: " + acc1.getBalance());
      System.out.println("*** Balance acount 2: " + acc2.getBalance());
   }
</pre>
<p>Apesar de a classe BankAccount não implementar a interface Observable até que o processo de weaving tenha ocorrido, o compilador Java não realiza nenhuma verificação quando o casting para uma interface é realizado (apenas para uma superclasse), portanto, o casting de BankAccount para Observable irá compilar. (Se o exemplo for executado sem weaving, um ClassCastException será disparado pois BankAccount não implementará a interface Observable). Quando este exemplo é executado, pode-se ver quando o Observer registrado é notificado:</p>
<pre>
*** Creating account 1
*** Bank Account constructor
*** BankAccount.credit()
*** Creating account 2
*** Bank Account constructor
*** BankAccount.credit()
Installing observer
*** Balance acount 1: 150
*** Balance acount 2: 230
*** Transfer 50 from account 1 to account 2
*** BankAccount.debit()
*** BankAccount.credit()
!!! Observer: Changed balance from 230 to 280
*** Balance acount 1: 100
*** Balance acount 2: 280
</pre>
<p><strong>Conclusão</strong></p>
<p>Partindo de uma aplicação simples e adicionando comportamento extra a ela usando JBoss AOP, algumas das características oferecidas pelo framework foram exploradas. Além de adicionar algumas anotações para auxiliar expressões de pointcut, (e ainda há maneiras menos intrusivas, se bem que mais inconvenientes, de se obter um efeito similar), o núcleo da aplicação foi mantido intacto, e comportamento transversal extra foi adicionado, tal como logging e segurança, com a aplicação de aspectos, bem como pela combinação de aspectos, introdução de interface e mixins para implementar o padrão Observer.</p>
<p>Enviado por: <strong>Paulo Crestani</strong><br />
Desenvolvedor Java, Dextra Sistemas</p>
<img src="http://feeds.feedburner.com/~r/dextra-jblog/~4/9llELPfPVFY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.dextra.com.br/jblog/?feed=rss2&amp;p=38</wfw:commentRss>
		<feedburner:origLink>http://blogs.dextra.com.br/jblog/?p=38</feedburner:origLink></item>
		<item>
		<title>Regex - Classe de caracteres acentuados.</title>
		<link>http://feedproxy.google.com/~r/dextra-jblog/~3/pdEa6CYkSwk/</link>
		<comments>http://blogs.dextra.com.br/jblog/?p=9#comments</comments>
		<pubDate>Thu, 30 Apr 2009 12:58:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[caracteres]]></category>

		<category><![CDATA[dicas]]></category>

		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://blogs.dextra-inc.com/jblog/?p=9</guid>
		<description><![CDATA[Olá pessoal,
Como dissemos no primeiro post, a equipe de desenvolvedores Java da Dextra irá postar uma série de artigos e dicas sobre desenvolvimento neste Blog, e como primeiro post, iremos apresentar uma dica sobre Regex (expressões regulares).
Várias vezes precisamos utilizar expressões regulares para validar algum campo ou para extrair partes dele.
Normalmente, quando queremos dizer que [...]]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal,</p>
<p>Como dissemos no primeiro <em>post</em>, a equipe de desenvolvedores Java da Dextra irá postar uma série de artigos e dicas sobre desenvolvimento neste Blog, e como primeiro post, iremos apresentar uma dica sobre Regex (expressões regulares).</p>
<p>Várias vezes precisamos utilizar expressões regulares para validar algum campo ou para extrair partes dele.</p>
<p>Normalmente, quando queremos dizer que há caracteres alfanuméricos em uma expressão, utilizamos o<em> \w</em>. Porém ele se limita à classe <em>[a-zA-Z_0-9]</em>, não incluindo os caracteres acentuados. O que fazíamos era adicionar nesta classe estes caracteres um a um, mais ou menos assim:<em> [\wÁáÉé]</em>.</p>
<p>Para facilitar nossa vida, há um <em>range</em> que inclui todos estes caracteres: À-ú, deixando nossa classe  bem mais simples:</p>
<p><em>[\wÀ-ú]</em><br />
ou a String em java: &#8220;[\\wÀ-ú]&#8221;</p>
<p>Esperamos que esta dica tenha sido útil para você <img src='http://blogs.dextra.com.br/jblog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Enviado por: <strong>Raoni Fortes Normanton<br />
</strong>Desenvolvedor Java, Dextra Sistemas<strong></strong></p>
<img src="http://feeds.feedburner.com/~r/dextra-jblog/~4/pdEa6CYkSwk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.dextra.com.br/jblog/?feed=rss2&amp;p=9</wfw:commentRss>
		<feedburner:origLink>http://blogs.dextra.com.br/jblog/?p=9</feedburner:origLink></item>
		<item>
		<title>Apresentação</title>
		<link>http://feedproxy.google.com/~r/dextra-jblog/~3/PtVaHW5eFpQ/</link>
		<comments>http://blogs.dextra.com.br/jblog/?p=3#comments</comments>
		<pubDate>Thu, 30 Apr 2009 12:36:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Apresentação]]></category>

		<category><![CDATA[Desenvolvedores]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blogs.dextra-inc.com/jblog/?p=3</guid>
		<description><![CDATA[Olá Pessoal!
Como um meio de compartilhar experiências de desenvolvimento Java com a comunidade,  a Dextra abriu este canal pelo qual a equipe de desenvolvedores irá postar uma série de artigos e dicas sobre a tecnologia. Serão abordados assuntos que exponham experiências e reflexões sobre o dia-a-dia do desenvolvimento de aplicações.
Sejam todos bem vindos!
Equipe de Desenvolvimento [...]]]></description>
			<content:encoded><![CDATA[<p>Olá Pessoal!</p>
<p>Como um meio de compartilhar experiências de desenvolvimento Java com a comunidade,  a Dextra abriu este canal pelo qual a equipe de desenvolvedores irá postar uma série de artigos e dicas sobre a tecnologia. Serão abordados assuntos que exponham experiências e reflexões sobre o dia-a-dia do desenvolvimento de aplicações.</p>
<p>Sejam todos bem vindos!</p>
<p>Equipe de Desenvolvimento Java - Dextra Sistemas</p>
<img src="http://feeds.feedburner.com/~r/dextra-jblog/~4/PtVaHW5eFpQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blogs.dextra.com.br/jblog/?feed=rss2&amp;p=3</wfw:commentRss>
		<feedburner:origLink>http://blogs.dextra.com.br/jblog/?p=3</feedburner:origLink></item>
	</channel>
</rss>
