| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <!-- |
| Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. |
| --> |
| <html> |
| <head> |
| <title>Suporte aos Processadores de Anotação no NetBeans IDE</title> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" > |
| <link rel="stylesheet" type="text/css" href="../../../netbeans.css"> |
| <meta name="keywords" content="NETBEANS, TUTORIAL, GUIDE, USER, DOCUMENTATION"> |
| <meta name="description" content="A very simple and quick introduction to the NetBeans IDE workflow by walking you through the creation of a |
| simple Hello World Java console application." > |
| </head> |
| |
| <body> |
| |
| <h1>Suporte aos Processadores de Anotação no NetBeans IDE, Parte II: Utilizando Processadores Próprios de Anotação Personalizada no IDE </h1> |
| <p><em>Contribuição de Jesse Glick, redigido e mantido por Irina Filippova </em></p> |
| <div class="margin-around"> |
| <div class="feedback-box margin-around float-left" style="margin-right:15px"> |
| <p><b>Conteúdo</b></p> |
| |
| <ul class="toc"> |
| <li><a href="annotations.html">Introdução</a></li> |
| <li><a href="annotations.html#map">Mapa das Opções javac e Comandos IDE</a> </li> |
| <li><a href="annotations-lombok.html">Utilizando Projeto Lombok para Anotações Personalizadas</a></li> |
| <li><strong>Utilizando Processadores Próprios de Anotação Personalizada no IDE</strong> |
| <ul> |
| <li><a href="#defineann">Definindo uma Anotação e Criando um Processador de Anotação</a></li> |
| <li><a href="#useprocessor">Usando o Processador de Anotação</a> </li> |
| </ul> |
| </li> |
| <li><a href="#seealso" title="Consulte Também"><strong>Consulte Também </strong></a></li> |
| </ul> |
| </div> |
| </div> |
| <img alt="O conteúdo desta página se aplica ao NetBeans IDE 6.9, 7.0 e 7.1" class="stamp" src="../../../images_www/articles/71/netbeans-stamp-71-72-73.png" title="O conteúdo nesta página se aplica ao NetBeans IDE 6.9, 7.0 e 7.1" width="114" /> |
| <p>Nesta seção do tutorial, você aprenderá a adicionar um processador de anotação personalizado de redação própria a um projeto no IDE. Este tutorial não ensina como criar um processador de anotação. Ele explica como adicioná-lo a um projeto NetBeans IDE. </p> |
| <p>A aplicação de amostra usada nesta seção foi criada por Jesse Glick e publicada como uma <a href="http://wiki.netbeans.org/FaqApt" target="_blank">entrada de FAQ</a> das releases anteriores do IDE. </p> |
| <p>O processador de anotação usado como exemplo gera uma classe principal da classe anotada. A classe principal gerada também contém um método chamado usando a classe anotada. Siga as instruções abaixo sobre como criar e adicionar um processador personalizado de anotação em um projeto do IDE. </p> |
| <p style="clear:both"><b>Para concluir este tutorial, você precisa dos seguintes recursos e softwares.</b></p> |
| |
| <table> |
| <tbody> |
| <tr> |
| <th class="tblheader" scope="col">Software ou Recurso</th> |
| <th class="tblheader" scope="col">Versão Necessária</th> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html" target="_blank">NetBeans IDE</a></td> |
| <td class="tbltd1">7.1, 7.2, 7.3 </td> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java Development Kit (JDK)</a></td> |
| <td class="tbltd1">versão 6</td> |
| </tr> |
| |
| </tbody> |
| </table> |
| |
| <p><strong class="notes">Observações:</strong></p> |
| <ul> |
| <li>O suporte a processadores de anotações personalizadas foi adicionado na release 6.9 do NetBeans IDE. Este tutorial não funcionará com versões anteriores do IDE. </li> |
| </ul> |
| |
| <h2><a name="defineann"></a>Definindo uma Anotação e Criando um Processador de Anotação</h2> |
| <p>Neste exercício, você criará um projeto de biblioteca de classes.</p> |
| <ol> |
| <li>Escolha Arquivo > Novo Projeto e selecione o tipo de projeto de Bibliotecas de Classes Java na categoria Java. Clique em Próximo.</li> |
| <li>Digite <tt>AnnProcessor</tt> como Nome do Projeto e especifique uma localização para o projeto. Clique em Finalizar. |
| <p>Quando você clica em Finalizar, o IDE cria o projeto de biblioteca de classes e lista o projeto na janela Projetos.</p> |
| </li> |
| <li>Clique com o botão direito do mouse no nó do projeto AnnProcessor na janela Projetos e escolha Propriedades.</li> |
| <li>Na categoria Códigos-fonte, confirme se JDK 6 está especificado como o formato de código-fonte/binário.</li> |
| <li>Selecione a guia Bibliotecas e confirme se a plataforma Java está definida como JDK 6. Clique em OK para fechar a janela Propriedades do Projeto.</li> |
| </ol> |
| |
| <p>Neste exercício, você criará dois pacotes Java e uma classe Java em cada um destes pacotes.</p> |
| <ol> |
| <li>Crie um pacote Java denominado <strong><tt>ann</tt></strong> clicando no nó Pacotes de Código-fonte sob o nó do projeto AnnProcessor e escolha Novo > Pacote Java. Digite <tt>ann</tt> como o Nome do Pacote e clique em Finalizar.</li> |
| <li>Repita a etapa anterior e crie um pacote Java denominado <strong><tt>proc</tt></strong>. |
| <p>Após ter criado os dois pacotes Java, a estrutura do projeto deverá ser similar à seguinte imagem.</p> |
| <img alt="tela da janela Projetos mostrando pacotes Java" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/packages.png" title="A estrutura do projeto para o processador de anotação."></li> |
| <li>Clique com o botão direito do mouse no pacote Java <tt>ann</tt> e selecione Nova > Classe Java.</li> |
| <li>Digite <strong><tt>Handleable</tt></strong> para o nome da classe. Clique em Finalizar.</li> |
| <li>Modifique o novo arquivo <tt>Handleable.java</tt> para fazer as alterações a seguir. Salve o arquivo. |
| <pre>package ann; |
| |
| public <strong>@interface</strong> Handleable { |
| |
| }</pre> |
| |
| <p>É assim que as anotações são declaradas, de forma muito similar a uma declaração de interface. A diferença é que a palavra-chave <tt>interface</tt> precisa ser precedida por um sinal <tt>at</tt> (@). Essa anotação é denominada <tt>Handleable</tt>.</p> |
| |
| <p class="notes"><strong>Informações Adicionais.</strong> Nas declarações de anotação, você também pode especificar parâmetros adicionais, por exemplo, quais tipos de elementos podem ser anotados, por exemplo, classes ou métodos. Você fazer isso adicionando <tt>@Target(value = {ElementType.TYPE})</tt> para classes e <tt>@Target(value = {ElementType.METHOD}).</tt> Isso, a declaração de anotação torna-se anotada com <em>meta-anotações</em>. </p> |
| |
| <p>Agora precisamos adicionar um código para que o processador de anotação processe a anotação <tt>Handleable</tt>.<p> |
| </li> |
| <li>Clique com o botão direito do mouse no pacote <strong><tt>proc</tt></strong> e selecione Nova > Classe Java.</li> |
| <li>Digite <strong><tt>HandleableProcessor</tt></strong> para o Nome da Classe. Clique em Finalizar.</li> |
| <li>Modifique a classe <tt>HandleableProcessor.java</tt> para adicionar o código a seguir. Salve as alterações. |
| <pre class="examplecode">package proc; |
| |
| import ann.Handleable; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.Writer; |
| import java.util.Set; |
| import javax.annotation.processing.AbstractProcessor; |
| import javax.annotation.processing.RoundEnvironment; |
| import javax.annotation.processing.SupportedAnnotationTypes; |
| import javax.annotation.processing.SupportedSourceVersion; |
| import javax.lang.model.SourceVersion; |
| import javax.lang.model.element.Element; |
| import javax.lang.model.element.ElementKind; |
| import javax.lang.model.element.TypeElement; |
| import javax.lang.model.type.TypeMirror; |
| import javax.tools.Diagnostic; |
| import javax.tools.JavaFileObject; |
| |
| @SupportedAnnotationTypes("ann.Handleable") |
| @SupportedSourceVersion(SourceVersion.RELEASE_6) |
| public class HandleableProcessor extends AbstractProcessor { |
| |
| /** public for ServiceLoader */ |
| public HandleableProcessor() { |
| } |
| |
| public boolean process(Set annotations, |
| RoundEnvironment roundEnv) { |
| for (Element e : roundEnv.getElementsAnnotatedWith(Handleable.class)) { |
| if (e.getKind() != ElementKind.FIELD) { |
| processingEnv.getMessager().printMessage( |
| Diagnostic.Kind.WARNING, |
| "Not a field", e); |
| continue; |
| } |
| String name = capitalize(e.getSimpleName().toString()); |
| TypeElement clazz = (TypeElement) e.getEnclosingElement(); |
| try { |
| JavaFileObject f = processingEnv.getFiler(). |
| createSourceFile(clazz.getQualifiedName() + "Extras"); |
| processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, |
| "Creating " + f.toUri()); |
| Writer w = f.openWriter(); |
| try { |
| PrintWriter pw = new PrintWriter(w); |
| pw.println("package " |
| + clazz.getEnclosingElement().getSimpleName() + ";"); |
| pw.println("public abstract class " |
| + clazz.getSimpleName() + "Extras {"); |
| pw.println(" protected " + clazz.getSimpleName() |
| + "Extras() {}"); |
| TypeMirror type = e.asType(); |
| pw.println(" /** Handle something. */"); |
| pw.println(" protected final void handle" + name |
| + "(" + type + " value) {"); |
| pw.println(" System.out.println(value);"); |
| pw.println(" }"); |
| pw.println("}"); |
| pw.flush(); |
| } finally { |
| w.close(); |
| } |
| } catch (IOException x) { |
| processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, |
| x.toString()); |
| } |
| } |
| return true; |
| } |
| |
| private static String capitalize(String name) { |
| char[] c = name.toCharArray(); |
| c[0] = Character.toUpperCase(c[0]); |
| return new String(c); |
| } |
| }</pre> |
| <p>Vamos examinar mais de perto as partes principais que compõem o código para o processador de anotações (observe que, por conveniência, somente partes do código são fornecidas). </p> |
| <p>Primeiro, você especifica os tipos de anotações que o processador de anotações suporta (usando <tt>@SupportedAnnotationTypes</tt>) e a versão dos arquivos de código-fonte que são suportados (usando <tt>@SupportedSourceVersion</tt>); nesse caso, a versão é JDK 6: <br> |
| <pre class="examplecode"> |
| @SupportedAnnotationTypes("ann.Handleable") |
| @SupportedSourceVersion(SourceVersion.RELEASE_6)</pre> |
| <p>A seguir, declare uma classe pública para o processador que estenda a classe <tt>AbstractProcessor</tt> do pacote <tt>javax.annotation.processing</tt>. <tt>AbstractProcessor</tt> é a superclasse padrão para processadores de anotação concretos, que contém os métodos necessários para processar anotações.</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor { |
| ... |
| }</pre> |
| <p>Você agora precisa fornecer um construtor público para a classe.</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor { |
| <strong> public HandleableProcessor() { |
| }</strong> |
| ... |
| |
| }</pre> |
| <p>A seguir, chame o método de <tt>process</tt>() da classe <tt>AbstractProcessor</tt> principal. Por meio deste método, as anotações disponíveis para processamento são fornecidas. Além disso, este método contém informações sobre o ciclo de processamento.</p> |
| |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor {<strong> |
| </strong>... |
| <strong> public boolean process(Set annotations, |
| RoundEnvironment roundEnv) { |
| ... |
| } |
| </strong> |
| }</pre> |
| <p>A lógica do processador de anotação está contida dentro do método <tt>process()</tt> da classe <tt>AbstractProcessor</tt>. Observe que, por meio de <tt>AbstractProcessor</tt>, você também acessa a interface <tt>ProcessingEnvironment</tt>, que permite que os processadores de anotação usem diversos recursos úteis, como um Filer (um handler de arquivamento que permite que os processadores de anotação criem novos arquivos) e um Messager (um meio pelo qual os processadores de anotação reportam erros).</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor {<strong> |
| </strong>... |
| public boolean process(Set annotations, |
| RoundEnvironment roundEnv) {<br> |
| //For each element annotated with the Handleable annotation |
| <strong>for (Element e : roundEnv.getElementsAnnotatedWith(Handleable.class)) { |
| <br> </strong>//Check if the type of the annotated element is not a field. If yes, return a warning<strong>.<br> if (e.getKind() != ElementKind.FIELD) {<br> processingEnv.getMessager().printMessage(<br> Diagnostic.Kind.WARNING,<br> "Not a field", e);<br> continue;<br> } |
| </strong>//Define the following variables: name and clazz<strong>.</strong><strong><br> String name = capitalize(e.getSimpleName().toString());<br> TypeElement clazz = (TypeElement) e.getEnclosingElement();<br> </strong>//Generate a source file with a specified class name. <strong> |
| try {<br> JavaFileObject f = processingEnv.getFiler().<br> createSourceFile(clazz.getQualifiedName() + "Extras");<br> processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,<br> "Creating " + f.toUri());<br> Writer w = f.openWriter();<br> </strong>//Add the content to the newly generated file<strong>. |
| try {<br> PrintWriter pw = new PrintWriter(w);<br> pw.println("package "<br> + clazz.getEnclosingElement().getSimpleName() + ";");<br> pw.println("public abstract class "<br> + clazz.getSimpleName() + "Extras {");<br> pw.println(" protected " + clazz.getSimpleName()<br> + "Extras() {}");<br> TypeMirror type = e.asType();<br> pw.println(" /** Handle something. */");<br> pw.println(" protected final void handle" + name<br> + "(" + type + " value) {");<br> pw.println(" System.out.println(value);");<br> pw.println(" }");<br> pw.println("}");<br> pw.flush();<br> } finally {<br> w.close();<br> }<br> } catch (IOException x) {<br> processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,<br> x.toString());<br> }<br> }</strong><br> return true; |
| <strong> }</strong> |
| ... |
| }</pre> |
| <p>O último bloco neste código declara o método <tt>capitalize</tt> que é usado para colocar em maiúscula o nome do elemento anotado.</p> |
| <pre class="examplecode">public class HandleableProcessor extends AbstractProcessor {<strong> |
| </strong>...<strong> |
| |
| private static String capitalize(String name) {<br> char[] c = name.toCharArray();<br> c[0] = Character.toUpperCase(c[0]);<br> return new String(c);<br> } |
| </strong>}</pre> |
| </li> |
| <li>Compile o projeto clicando com o botão direito do mouse no projeto <tt>AnnProcessor</tt> e escolhendo Compilar.</li> |
| </ol> |
| |
| |
| <h2><a name="useprocessor"></a>Usando o processador de anotação no IDE</h2> |
| <p>Nesta seção, você criará um projeto da Aplicação Java no qual o processador de anotações será usado.</p> |
| <ol> |
| <li>Escolha Arquivo > Novo Projeto e selecione o tipo de projeto da Aplicação Java na categoria Java. Clique em Próximo.</li> |
| <li>Na página Nome e Localização, digite <tt>Demo</tt> como o Nome do Projeto e especifique o local do projeto.</li> |
| <li>Digite <strong><tt>demo.Main</tt></strong> no campo Criar Classe Principal. Clique em Finalizar.<br> <img alt="tela do assistente Novo Projeto" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-project-wizard.png" title="Criando projeto de Demonstração no assistente de Novo Projeto."></li> |
| |
| <li>Abra a janela de propriedades do projeto e confirme se o JDK 6 está selecionado como o formato de código-fonte/binário no painel Códigos-fonte e que a plataforma Java esteja definida como JDK 6 no painel Bibliotecas.</li> |
| <li>Modifique a classe <tt>Main.java</tt> para adicionar o código a seguir. Salve as alterações. |
| <pre class="examplecode">package demo; |
| |
| <strong>import ann.Handleable;</strong> |
| |
| public class Main <strong>extends MainExtras</strong> { |
| |
| <strong>@Handleable |
| private String stuff;</strong> |
| |
| <strong>public static void main(String[] args) { |
| new Main().handleStuff("hello"); |
| }</strong> |
| }</pre> |
| <p>O código contém os seguintes elementos:</p> |
| <ul> |
| <li>instrução de importação para o processador personalizado de anotação <tt>ann.Handleable</tt></li> |
| <li>a classe pública <tt>Main</tt> que estende a classe <tt>MainExtras</tt> (<tt>MainExtras</tt> deve ser gerada por seu processador de anotação durante a compilação)</li> |
| <li>um campo privado denominado <tt>stuff</tt> que é anotado com a anotação <tt>@Handleable</tt> </li> |
| <li>o método <tt>main</tt> que chama o método <tt>handleStuff</tt>, declarado na classe <tt>MainExtras</tt> automaticamente gerada |
| |
| <p>Em nosso exemplo simples, o método <tt>handleStuff</tt> somente imprime o valor atual. Você pode modificar este método para executar outras tarefas.</p></li> |
| </ul> |
| <p>Após salvar o código <tt>Main.java</tt>, você verá que o IDE relata diversos erros de compilação. Isso acontece porque o processador de anotação ainda não foi adicionado no projeto.</p> |
| </li> |
| <li>Clique com o botão direito do mouse no nó do projeto <tt>Demo</tt> na janela Projetos, escolha Propriedades e, a seguir, selecione a categoria Bibliotecas na janela Propriedades.</li> |
| <li>Na guia Compilar, clique em Adicionar Projeto e localize o projeto <tt>AnnProcessor</tt>.<br> <img alt="tela da guia Compilar na categoria Bibliotecas da janela Propriedades do projeto" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-properties-compile.png" title="Guia Compilar na categoria Bibliotecas da janela Propriedades do projeto"> |
| |
| <p>A guia Compilar corresponde a opção <tt>-classpath</tt> do <a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#options" target="_blank">compilador Java</a>. Como o processador de anotação é um arquivo JAR único que contém a definição da anotação e o processador de anotação, ele deve ser adicionado na classpath do projeto, que é a guia Compilar.</p> |
| </li> |
| <li>Selecione a categoria Compilação na janela Propriedades e selecione as caixas de seleção Ativar o Processamento de Anotações e Ativar o Processamento de Anotações no Editor.</li> |
| <li>Especifique o processador de anotações a ser executado clicando no botão Adicionar próximo à área de texto Processadores de Anotações e digite <tt>proc.HandleableProcessor</tt> no campo FQN do Processador de Anotações. <br> <img alt="tela da caixa de diálogo FQN do Processador de Anotações" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-processor-fqn.png" title="Caixa de diálogo FQN do Processador de Anotação"> |
| |
| <p>A categoria Compilação na janela Propriedades deve se parecer com a imagem a seguir.</p> |
| <img alt="tela da categoria Compilação na janela Propriedades do projeto" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-properties-compiling.png" title="Categoria compilação na janela Propriedades do projeto"> |
| |
| </li> |
| <li>Clique em OK na janela Propriedades. |
| |
| <p class="notes"><strong>Observação.</strong> No arquivo <tt>Main.java</tt> talvez você ainda veja os erros de compilação. Isso é porque o IDE ainda não pode localizar o arquivo <tt>MainExtras.java</tt> que declara o método <tt>handleStuff</tt>. O arquivo <tt>MainExtras.java</tt> será gerado após você desenvolver o projeto Demo pela primeira vez. Se Compilar ao Salvar estiver ativado para seu projeto, o IDE compilou o projeto quando você salvou o <tt>Main.java</tt>.</p> |
| </li> |
| <li>Clique com o botão direito do mouse no projeto Demo e escolha Construir. |
| <p>Após construir o projeto, se você examinar os projetos na janela Projetos, poderá agora ver um novo nó <tt>Códigos-fonte Gerados</tt> com o arquivo <tt>demo/MainExtras.java</tt>.</p> |
| <img alt="tela da janela Projetos com Origens Geradas" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-generated-sources.png" title="Janela Projetos com Origens Geradas"> |
| |
| <p>Caso você revise o conteúdo do arquivo <tt>MainExtras.java</tt> gerado, verá que o processador de anotações gerou a classe <tt>MainExtras</tt> com o método <tt>handleStuff</tt>. O método <tt>handleStuff</tt> é aquele chamado a partir do arquivo <tt>Main.java</tt> anotado. </p> |
| <pre class="examplecode">package demo; |
| public abstract class MainExtras { |
| protected MainExtras() {} |
| /** Handle something. */ |
| protected final void handleStuff(java.lang.String value) { |
| System.out.println(value); |
| } |
| }</pre> |
| </li> |
| <li>Clique com o botão direito do mouse no projeto Demonstração e escolha Executar. |
| <p>Quando você clicar em Executar, deverá ver o seguinte na janela Saída. O projeto Demonstração é compilado e imprime a mensagem.</p> |
| <img alt="tela da janela Projetos com Origens Geradas" class="margin-around b-all" src="../../../images_www/articles/72/java/annotations/demo-run.png" title="Janela Projetos com Origens Geradas"> |
| <!-- <img src="../../../images_www/articles/69/java/annotations/output-demo.png" alt="Output of the Demo project." width="408" height="123" class="margin-around"></li>--> |
| </ol> |
| <div class="feedback-box"><a href="/about/contact_form.html?to=3&subject=Feedback:%20Using%20the%20Annotation%20Processors%20Support%20in%20NetBeans%20IDE">Envie-nos seu Feedback</a><br style="clear:both;" /> |
| </div> |
| <h2><a id="seealso" name="seealso"></a>Consulte Também</h2> |
| <p>Consulte os seguintes recursos para obter mais informações sobre anotações em aplicações Java:</p> |
| <ul> |
| <li>Documentação Java SE - <a href="http://download.oracle.com/javase/6/docs/technotes/guides/language/annotations.html" target="_blank">Anotações</a></li> |
| <li>Tutorial Java SE - <a href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html" target="_blank">Anotações</a> </li> |
| <li><a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#processing" target="_blank">Compilador do Java: Opções de Processamento de Anotação</a> </li> |
| <li><a href="http://blogs.sun.com/darcy/">Weblog de Joseph D. Darcy's Weblog</a> - dicas úteis sobre a especificação JSR-269 </li> |
| </ul> |
| </body> |
| </html> |