// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= Suporte aos Processadores de Anotação no NetBeans IDE, Parte II: Utilizando Processadores Próprios de Anotação Personalizada no IDE
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: Suporte aos Processadores de Anotação no NetBeans IDE, Parte II: Utilizando Processadores Próprios de Anotação Personalizada no IDE - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, Suporte aos Processadores de Anotação no NetBeans IDE, Parte II: Utilizando Processadores Próprios de Anotação Personalizada no IDE

_Contribuição de Jesse Glick, redigido e mantido por Irina Filippova _


* *Utilizando Processadores Próprios de Anotação Personalizada no IDE*

image::../../../images_www/articles/71/netbeans-stamp-71-72-73.png[title="O conteúdo desta página se aplica ao NetBeans IDE 7.0, 7.1, 7.2 e 7.3"]

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.

A aplicação de amostra usada nesta seção foi criada por Jesse Glick e publicada como uma link:http://wiki.netbeans.org/FaqApt[+entrada de FAQ+] das releases anteriores do IDE.

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.

*Para concluir este tutorial, você precisa dos seguintes recursos e softwares.*

|===
|Software ou Recurso |Versão Necessária 

|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |7.0, 7.1, 7.2, 7.3 

|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+JDK (Java Development Kit)+] |versão 6 ou 7 

|link:http://code.google.com/p/projectlombok/downloads/list[+lombok.jar+] |v1.12.4 ou mais recente 
|===


== Definindo uma Anotação e Criando um Processador de Anotação

Neste exercício, você criará um projeto de biblioteca de classes.

1. Escolha Arquivo > Novo Projeto e selecione o tipo de projeto de Bibliotecas de Classes Java na categoria Java. Clique em Próximo.
2. Digite * ``AnnProcessor`` * como Nome do Projeto e especifique um local para o projeto. Clique em Finalizar.

Quando você clica em Finalizar, o IDE cria o projeto de biblioteca de classes e lista o projeto na janela Projetos.



. Clique com o botão direito do mouse no nó do projeto AnnProcessor na janela Projetos e escolha Propriedades.


. Na categoria Códigos-fonte, confirme se JDK 6 ou JDK 7 está especificado como o formato de código-fonte/binário.


. Selecione a guia Bibliotecas e confirme se a plataforma Java está definida como JDK 1.6 ou JDK 1.7. Clique em OK para fechar a janela Propriedades do Projeto.

Neste exercício, você criará dois pacotes Java e uma classe Java em cada um destes pacotes.

1. Clique com o botão direito do mouse no nó Pacotes de Código-fonte sob o nó do projeto AnnProcessor e escolha Novo > Pacote Java.
2. Digite * ``ann`` * como Nome do Pacote e clique em Finalizar para criar o novo pacote Java.
3. Repita as duas etapas anteriores para criar um pacote Java chamado * ``proc`` *.

Após ter criado os dois pacotes Java, a estrutura do projeto deverá ser similar à seguinte imagem.

image::images/packages.png[title="A estrutura do projeto para o processador de anotação."]


. Clique com o botão direito do mouse no pacote Java  ``ann``  e selecione Nova > Classe Java.


. Digite * ``Handleable`` * para o nome da classe. Clique em Finalizar.


. Modifique o novo arquivo  ``Handleable.java``  para fazer as alterações a seguir. Salve o arquivo.

[source,java]
----

package ann;

public *@interface* Handleable {

}
----

É 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  ``interface``  precisa ser precedida por um sinal  ``at``  (@). Essa anotação é denominada  ``Handleable`` .

*Informações Adicionais.* 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  ``@Target(value = {ElementType.TYPE})``  para classes e  ``@Target(value = {ElementType.METHOD}).``  Isso, a declaração de anotação torna-se anotada com _meta-anotações_.

Agora precisamos adicionar um código para que o processador de anotação processe a anotação  ``Handleable`` .



. Clique com o botão direito do mouse no pacote * ``proc`` * e selecione Nova > Classe Java.


. Digite * ``HandleableProcessor`` * para o Nome da Classe. Clique em Finalizar.


. Modifique a classe  ``HandleableProcessor.java``  para adicionar o código a seguir. Salve as alterações.

*Observação.* O valor de  ``@SupportedSourceVersion``  (em *negrito*) dependerá da versão do JDK que você está usando e será  ``(SourceVersion.RELEASE_7)``  ou  ``(SourceVersion.RELEASE_6)`` .


[source,java]
----

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_7*)
public class HandleableProcessor extends AbstractProcessor {

    /** public for ServiceLoader */
    public HandleableProcessor() {
    }

    public boolean process(Set<? extends TypeElement> 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);
    }
}
----

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).

Primeiro, você especifica os tipos de anotações que o processador de anotações suporta (usando  ``@SupportedAnnotationTypes`` ) e a versão dos arquivos de código-fonte que são suportados (usando  ``@SupportedSourceVersion`` ); nesse caso, a versão é JDK 6: 


[source,java]
----

@SupportedAnnotationTypes("ann.Handleable")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
----

A seguir, declare uma classe pública para o processador que estenda a classe  ``AbstractProcessor``  do pacote  ``javax.annotation.processing`` .  ``AbstractProcessor``  é a superclasse padrão para processadores de anotação concretos, que contém os métodos necessários para processar anotações.


[source,java]
----

public class HandleableProcessor extends AbstractProcessor {
...
}
----

Você agora precisa fornecer um construtor público para a classe.


[source,java]
----

public class HandleableProcessor extends AbstractProcessor {
*    public HandleableProcessor() {
    }*
...

}
----

A seguir, chame o método de  ``process`` () da classe  ``AbstractProcessor``  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.


[source,java]
----

public class HandleableProcessor extends AbstractProcessor {*
   *...
*     public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
     ...
     }
*
}
----

A lógica do processador de anotação está contida dentro do método  ``process()``  da classe  ``AbstractProcessor`` . Observe que, por meio de  ``AbstractProcessor`` , você também acessa a interface  ``ProcessingEnvironment`` , 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).


[source,java]
----

public class HandleableProcessor extends AbstractProcessor {*
   *...
     public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {//For each element annotated with the Handleable annotation
            *for (Element e : roundEnv.getElementsAnnotatedWith(Handleable.class)) {

*//Check if the type of the annotated element is not a field. If yes, return a warning*.
if (e.getKind() != ElementKind.FIELD) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
"Not a field", e);
continue;
}
            *//Define the following variables: name and clazz*.**
String name = capitalize(e.getSimpleName().toString());
TypeElement clazz = (TypeElement) e.getEnclosingElement();
*//Generate a source file with a specified class name. *
            try {
JavaFileObject f = processingEnv.getFiler().
createSourceFile(clazz.getQualifiedName() + "Extras");
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
"Creating " + f.toUri());
Writer w = f.openWriter();
*//Add the content to the newly generated file*.
                    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;
    * }*
...
}
----

O último bloco neste código declara o método  ``capitalize``  que é usado para colocar em maiúscula o nome do elemento anotado.


[source,java]
----

public class HandleableProcessor extends AbstractProcessor {*
   *...*

  private static String capitalize(String name) {
char[] c = name.toCharArray();
c[0] = Character.toUpperCase(c[0]);
return new String(c);
}
*}
----


. Compile o projeto clicando com o botão direito do mouse no projeto  ``AnnProcessor``  e escolhendo Compilar.


== Usando o processador de anotação no IDE

Nesta seção, você criará um projeto da Aplicação Java no qual o processador de anotações será usado.

1. Escolha Arquivo > Novo Projeto e selecione o tipo de projeto da Aplicação Java na categoria Java. Clique em Próximo.
2. Na página Nome e Localização, digite * ``Demo`` * como Nome do Projeto e especifique o local do projeto.
3. Digite * ``demo.Main`` * no campo Criar Classe Principal. Clique em Finalizar.
image::images/demo-project-wizard.png[title="Criando projeto de Demonstração no assistente de Novo Projeto."]


. Abra a janela Propriedades do Projeto e confirme se JDK 6 ou JDK 7 está selecionado como o formato de código-fonte/binário no painel Códigos-fonte e se a plataforma Java está definida como JDK 1.6 ou JDK 1.7 no painel Bibliotecas.


. Modifique a classe  ``Main.java``  para adicionar o código a seguir. Salve as alterações.

[source,java]
----

package demo;

*import ann.Handleable;*

public class Main *extends MainExtras* {

    *@Handleable
    private String stuff;*

    *public static void main(String[] args) {
        new Main().handleStuff("hello");
    }*
}
----

O código contém os seguintes elementos:

* instrução de importação para o processador personalizado de anotação  ``ann.Handleable`` 
* a classe pública  ``Main``  que estende a classe  ``MainExtras``  ( ``MainExtras``  deve ser gerada por seu processador de anotação durante a compilação)
* um campo privado denominado  ``stuff``  que é anotado com a anotação  ``@Handleable`` 
* o método  ``main``  que chama o método  ``handleStuff`` , declarado na classe  ``MainExtras``  automaticamente gerada

Em nosso exemplo simples, o método  ``handleStuff``  somente imprime o valor atual. Você pode modificar este método para executar outras tarefas.

Após salvar o código  ``Main.java`` , 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.



. Clique com o botão direito do mouse no nó do projeto  ``Demo`` , na janela Projetos, escolha Propriedades e, em seguida, selecione a categoria Bibliotecas na janela Propriedades do Projeto.


. Na guia Compilar, clique em Adicionar Projeto e localize o projeto  ``AnnProcessor`` .
image::images/demo-properties-compile.png[title="Guia Compilar na categoria Bibliotecas da janela Propriedades do projeto"]

A guia Compilar corresponde a opção  ``-classpath``  do link:http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#options[+compilador Java+]. 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.



. Selecione a categoria Compilação na janela Propriedades do Projeto e marque as caixas de seleção Ativar Processamento de Anotações e Ativar Processamento de Anotações no Editor.


. Especifique o processador de anotações a ser executado clicando no botão Adicionar ao lado da área de texto Processadores de Anotações e digitando * ``proc.HandleableProcessor`` * no campo FQN do Processador de Anotações. 
image::images/demo-processor-fqn.png[title="Caixa de diálogo FQN do Processador de Anotação"]

A categoria Compilação na janela Propriedades do Projeto deve ser semelhante à imagem a seguir.

image::images/demo-properties-compiling.png[title="Categoria compilação na janela Propriedades do projeto"]


. Clique em OK na janela Propriedades.

*Observação.* No arquivo  ``Main.java``  talvez você ainda veja os erros de compilação. Isso é porque o IDE ainda não pode localizar o arquivo  ``MainExtras.java``  que declara o método  ``handleStuff`` . O arquivo  ``MainExtras.java``  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  ``Main.java`` .



. Clique com o botão direito do mouse no projeto Demo e escolha Construir.

Após construir o projeto, se você examinar os projetos na janela Projetos, poderá agora ver um novo nó  ``Códigos-fonte Gerados``  com o arquivo  ``demo/MainExtras.java`` .

image::images/demo-generated-sources.png[title="Janela Projetos com Origens Geradas"]

Caso você revise o conteúdo do arquivo  ``MainExtras.java``  gerado, verá que o processador de anotações gerou a classe  ``MainExtras``  com o método  ``handleStuff`` . O método  ``handleStuff``  é aquele chamado a partir do arquivo  ``Main.java``  anotado.


[source,java]
----

package demo;
public abstract class MainExtras {
    protected MainExtras() {}
    /** Handle something. */
    protected final void handleStuff(java.lang.String value) {
        System.out.println(value);
    }
}
----


. Clique com o botão direito do mouse no projeto Demonstração e escolha Executar.

Quando você clicar em Executar, deverá ver o seguinte na janela Saída. O projeto Demonstração é compilado e imprime a mensagem.

image::images/demo-run.png[title="Janela Projetos com Origens Geradas"]
link:/about/contact_form.html?to=3&subject=Feedback:%20Using%20the%20Annotation%20Processors%20Support%20in%20NetBeans%20IDE[+Enviar Feedback neste Tutorial+]


== Consulte Também

Consulte os seguintes recursos para obter mais informações sobre anotações em aplicações Java:

* Documentação Java SE - link:http://download.oracle.com/javase/6/docs/technotes/guides/language/annotations.html[+Anotações+]
* Tutorial Java SE - link:http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html[+Anotações+]
* link:http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#processing[+Compilador do Java: Opções de Processamento de Anotação+]
* link:http://blogs.oracle.com/darcy/[+Weblog de Joseph D. Darcy's Weblog+] - dicas úteis sobre a especificação JSR-269
