Dev (Back & Front)ARTIGO

Apresentando o Spring Roo – Parte 05: grave complementos avançados e de Wrapper do Spring Roo

Neste artigo, será criado um complemento avançado que fornecerá uma implementação de compareTo() para entidades criadas em seu aplicativo. Como deseja incluir o código Java em seu aplicativo, é preciso criar um complemento avançado.

A parte 3 desta série, “Apresentando o Spring Roo”, discute a arquitetura de complementos do Spring Roo e como criar internacionalização e complementos simples usando o comando criar complemento. Este artigo foca os dois tipos restantes de complementos suportados pelo Spring Roo, isto é, complemento avançado e de wrapper. Recomenda-se que a Parte 3 seja consultada antes de continuar.

Introdução ao complemento avançado

O complemento avançado permite que o Spring Roo faça tudo que um complemento simples pode fazer, como atualizar um arquivo Maven POM com dependências ou plug-ins, atualizar ou incluir arquivos de configuração, além de aprimorar tipos JavaJava42 conteúdosNovidades do Java 26 (para desenvolvedores)Dev (Back & Front) · mar 2026Visual Studio Code para Java: o guia completo (dicas, configuração e extensões)Dev (Back & Front) · out 2025Quarkus: Modernizando a linguagem Java para a era da nuvemDev (Back & Front) · nov 2020Ver tudo em Dev (Back & Front) existentes e introduzir novos tipos Java usando AspectJ ITDs. A capacidade de incluir um código fonte torna os complementos avançados muito eficientes em comparação a todos os demais complementos. Antes de criar um complemento avançado do Spring Roo, considere um complemento avançado existente fornecido pelo Spring Roo.

Complemento avançado em ação

Um complemento avançado é o JPA, que executa trabalho relacionado à persistência, isto é, incluindo suporte para bancos de dadosBanco de dados134 conteúdosSQL ou NoSQL: eis a questão!!Data · mar 2020Banco de dados: como organizar e dar segurança para milhões de dados de loteriasData · mai 20215 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data e criando novas entidades. Para visualizar isso em ação, abra o shell Roo e execute os comandos em Lista 1. Neste artigo, o Spring Roo versão 1.2.0.M1 é utilizado.

project --topLevelPackage com.dw.demo --projectName entity-demo 
jpa setup --database FIREBIRD --provider HIBERNATE 
entity --class ~.domain.Book

Ambos os comandos configuração de jpa e entidade correspondem a um complemento avançado chamado org.springframework.roo.addon.jpa. A saída dos comandos configuração de jpa e entidade no shell Roo possibilita uma clara distinção entre complementos simples e avançados. Lista 2 mostra a saída do comando configuração de JPA.

Created SRC_MAIN_RESOURCES/META-INF/spring/database.properties 
Updated ROOT/pom.xml [added dependencies ...] 
Updated SRC_MAIN_RESOURCES/META-INF/spring/applicationContext.xml 
Created SRC_MAIN_RESOURCES/META-INF/persistence.xml

A saída do comando configuração de jpa mostra que ele está executando funções de configuração, como a inclusão de dependências em pom.xml, atualizando o applicationContext.xml do Spring e criando o persistence.xml específico à persistência. Presume-se que o comando de configuração de JPA corresponda a um complemento simples, porque não está criando ou atualizando o código fonte Java. Use um complemento simples para cenários semelhantes à configuração mostrada acima.

Lista 3 mostra a saída do comando entidade especificado.

Created SRC_MAIN_JAVA/com/dw/demo/domain 
Created SRC_MAIN_JAVA/com/dw/demo/domain/Book.java 
Created SRC_MAIN_JAVA/com/dw/demo/domain/Book_Roo_Configurable.aj 
Created SRC_MAIN_JAVA/com/dw/demo/domain/Book_Roo_Jpa_Entity.aj 
Created SRC_MAIN_JAVA/com/dw/demo/domain/Book_Roo_Entity.aj 
Created SRC_MAIN_JAVA/com/dw/demo/domain/Book_Roo_ToString.aj

A saída mostra a criação de um arquivo Java chamado Book.java e quatro arquivos *.aj. A regra final para identificar um complemento avançado é a geração de arquivos Java ou *.aj, ou ambos, como no caso do comando de entidade. Esses *Roo_*.aj são chamados de Inter-type Declarations (ou ITDs). As ITDs permitem um tipo (um aspecto) para fazer declarações para outro tipo, isto é, é possível modificar a estrutura estática de qualquer tipo incluindo métodos, campos ou alterando sua hierarquia de tipo. O Roo usa uma ITD como um artefato de geração de códigos e os gerencia durante todo o seu tempo de vida. As ITDs permitem que o Roo gere um código em uma unidade de compilação separada, mas elas são combinados na mesma classe compilada.

Após visualizar a saída do comando entidade, considere como esses artefatos (arquivos .java e.aj) são gerados pelo Spring Roo. Consultea  Lista 4 para obter uma amostra de um arquivo Book.java.

package com.dw.demo.domain; 

import org.springframework.roo.addon.entity.RooEntity; 
import org.springframework.roo.addon.javabean.RooJavaBean; 
import org.springframework.roo.addon.tostring.RooToString; 

@RooJavaBean 
@RooToString 
@RooEntity 
public class Book { 
}

O arquivo Java parece normal, exceto para anotações na classe. Observando os nomes da anotação e os arquivos .aj, nota-se que algumas dessas anotações correspondem à funcionalidade incluída por arquivos .aj. Por exemplo: RooToString corresponde ao arquivo Book_Roo_ToString.aj e ao método incluir toString(). RooEntity corresponde a Book_Roo_Entity .aj, Book_Roo_Jpa_Entity e métodos relacionados à persistência. Deixemos o resto de lado por ora. Para entender como essas anotações levam à geração de ITDs, explore como o Spring Roo fornece funcionalidades de complemento avançado.

  1. Na inicialização de shell Roo, ele varrerá todas as classes e registrará todas as que implementam a interface CommandMarker . A interface CommandMarker informa ao Roo que essas classes definirão os comandos que esse complemento pode executar;
  2. Todos os complementos avançados registram seus serviços no tempo de execução de OSGi fornecido pelo Spring Roo. Esses serviços especificam condições nas quais ele acionará a geração de códigos. Para todos os complementos avançados, o ponto de acionamento é a presença de uma anotação. Por exemplo, um complemento avançado para a geração do método toString() é acionado somente se um tipo Java tiver a anotação RooToString. Esse é o caso com outras anotações;
  3. Mediante o uso de entity --class ~.domain.Book, o complemento criará um arquivo Java chamado Book.java com anotações. Outros complementos são acionados quando um tipo Java tem essas anotações e os arquivos .aj são gravados para eles.

Um maior esclarecimento será evidente quando criar seu próprio complemento avançado.

O complemento org.springframework.roo.addon.jpa é apenas um exemplo de complemento avançado fornecido pelo Spring Roo. Outros complementos avançados incluem: GWT, controlador, JSON e muito mais. A liberação do Spring Roo 1.2.0 contém mais dois complementos avançados:—addon-equals e addon-jsf. O addon-equals fornece implementação para métodos equivalentes e código hash para uma entidade e o addon-jsf fornece suporte a JSF em aplicativos Spring Roo. Para a reprodução da captura instantânea mais recente do Spring Roo, crie o código do Spring Roo ou faça o download da captura instantânea noturna do repositório do Spring Roo.

Inclua o método compareTo() na minha classe de entidade

Os objetos de valor ou entidades são comumente necessários para implementar a interface java.lang.Comparable e fornecer a implementação para o método compareTo() . A interface comparável impõe ordenação total sobre os objetos de cada classe que a está implementando. Quando Comparável é implementado, é possível:

  1. Chamar java.util.Collections.sort e java.util.Collections.binarySearch;
  2. Chamar java.util.Arrays.sort e java.util.Arrays.binarySearch;
  3. Usar objetos como chaves em um java.util.TreeMap;
  4. Usar objetos como elementos em um java.util.TreeSet.

Neste artigo, será criado um complemento avançado que fornecerá uma implementação de compareTo() para entidades criadas em seu aplicativo. Como deseja incluir o código Java em seu aplicativo, é preciso criar um complemento avançado.

 Configuração do Projeto

A documentação do Spring Roo explica de forma eloquente como configurar um projeto e um repositório Maven no código do Google; portanto, é desnecessário repeti-lo aqui. Observe que “spring-dw-roo-compareto-addon” será usado como o nome do projeto.

Caso não esteja usando a versão mais recente do Spring Roo, 1.2.0.RC1, faça download dela no website do projeto. Descompacte e instale essa versão conforme explicado na parte 1.

O Spring Roo descontinuou ou removeu algumas das classes usadas em versões anteriores.

Criando um complemento avançado

Após configurar o projeto, será possível visualizar um diretório chamado spring-dw-roo-compareto-addon com apenas uma pasta .svn. Na linha de comandos, acesse o diretório spring-dw-roo-compareto-addon e inicie o shell Roo. Então, digite o comando a seguir:

addon create advanced --topLevelPackage org.xebia.roo.addon.compareto --projectName spring-dw-roo-compareto-addon

Pronto! Um complemento avançado acabou de ser criado.

Em seguida, no shell Roo, dispare o comando realizar pacote para criar um complemento jar. Lista 5 mostra os arquivos gerados pelo complemento criar avançado .

Created ROOT/pom.xml 
Created SRC_MAIN_JAVA 
Created SRC_MAIN_RESOURCES 
Created SRC_TEST_JAVA 
Created SRC_TEST_RESOURCES 
Created SPRING_CONFIG_ROOT 
Created ROOT/readme.txt 
Created ROOT/legal 
Created ROOT/legal/LICENSE.TXT 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto/ComparetoCommands.java 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto/ComparetoOperations.java 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto/ComparetoOperationsImpl.java 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto/ComparetoMetadata.java 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto/ComparetoMetadataProvider.java 
Created SRC_MAIN_JAVA/org/xebia/roo/addon/compareto/RooCompareto.java 
Created ROOT/src/main/assembly 
Created ROOT/src/main/assembly/assembly.xml 
Created SRC_MAIN_RESOURCES/org/xebia/roo/addon/compareto 
Created SRC_MAIN_RESOURCES/org/xebia/roo/addon/compareto/configuration.xml

Alguns dos arquivos gerados, como pom.xml, readme.txt e license.txt, não precisam de introdução, pois foram apresentados na parte 3 e são autoexplicativos. Os artefatos mais interessantes são:

  • ComparetoCommands.java;
  • ComparetoOperations.java;
  • ComparetoOperationsImpl.java;
  • ComparetoMetadata.java;
  • ComparetoMetadataProvider.java;
  • RooCompareto.java.

Agora, veremos os artefatos gerados um a um.

  • ComparetoCommands.java : Esta classe implementa a interface CommandMarker e expõe dois tipos de métodos:—um com a anotação CliAvailablityIndicator e outro com a anotação CliCommand . A anotação CliAvailablityIndicator informa ao Spring Roo quando o comando deve estar visível. Por exemplo, o comando ‘entidade‘ não será disponibilizado antes de o usuário definir as configurações de persistência no shell Roo ou diretamente no projeto. Os métodos anotados com @CliCommand registram o comando com o shell Roo. A anotação @CliCommand possui dois atributos: valor, que define o nome do comando; e ajuda, que define a mensagem de ajuda exibida quando o comando de ajuda é digitado. Para obter uma explicação detalhada da classe *Commands , consulte a parte 3.
  • ComparetoOperationsImpl.java : A classe ComparetoCommands delega todo o trabalho para a classe ComparetoOperationsImpl. Os quatro métodos gerados nesta classe são:
    • isCommandAvailable(): Este método é chamado pelo método anotado com CliAvailabilityIndicator ComparetoCommands na classe ComparetoCommands para verificar se o comando deve estar visível ou não. Isso é para assegurar que os comandos estejam cientes do contexto. Este método executa várias validações. Por exemplo, se o projeto tiver sido criado, somente o comando estará visível; ou se a persistência tiver sido configurada, somente o comando deverá estar visível. Não é obrigatório ter uma condição para que o comando esteja visível. Simplesmente retorne verdade para garantir que o comando esteja sempre visível.
    • setup(): Este método é chamado pelo método setup() , na classe ComparetoCommands que é anotada com @CliCommand. O código esclarece que esta classe é responsável por executar tarefas relacionadas à configuração, como incluir dependências Maven, incluir repositórios Maven ou criar ou atualizar arquivos de contexto do Spring (como no complemento Jamon Roo na parte 3).
    • annotateType(): Este método e annotateAll() são novos métodos que não existem em complementos simples. A funcionalidade deste método é incluir uma anotação (RooCompareto) no tipo Java especificado. Este método utiliza alguns serviços fornecidos pelo Spring Roo para buscar os detalhes da Classe para o tipo Java determinado e anexar a anotação RooJCompareto a ele.
    • annotateAll(): Este método encontra todos os tipos que são anotados com a anotação RooJavaBean e chama o método annotateType() em todos esses tipos. Utilize este método quando todas as entidades forem obrigadas a ter a anotação RooCompareto .
  • RooCompareto.java: A presença desta anotação aciona o complemento para gerar o código.
  • ComparetoMetadataProvider.java: Esta classe é um serviço do Spring Roo e é chamada pelo Roo para recuperar os metadados para o complemento. Esta classe registra acionadores para incluir e remover metadados. Nenhuma mudança é necessária nesta classe, mas lembre-se que ela tem um método chamado getMetadata() que será chamado pelo Spring Roo sempre que houver qualquer tipo Java com a anotação RooCompareto .
  • ComparetoMetadata.java: Esta classe é responsável por gerar o ITD correspondente ao complemento. No código gerado, ela usa uma classe chamada ItdTypeDetailsBuilder para criar uma ITD com um campo e um método. Posteriormente neste artigo, você alterará o código padrão gerado para atender aos requisitos de incluir um método compareTo e implementar a interface Comparável.

Modificando o complemento para atender aos requisitos

Você deseja criar um complemento que deve incluir o método compareTo para classes de entidade. Será preciso:

Incluir a dependência Maven commons-lang versão 3.1 no projeto de destino. Isso é necessário, porque commons-lang fornece uma classe de construtor chamada CompareToBuilder que será usada para criar o método compareTo.

  • Faça com que a classe de entidade implemente a interface Comparável;
  • Crie uma ITD para o método compareTo.

Incluindo a dependência maven

Para atender a esses requisitos, as mudanças são necessárias nas classes ComparetoOperationsImpl e ComparetoMetadata . Faça uma mudança de cada vez.

  • Primeiro, inclua a dependência Maven commons-lang no projeto de destino. Atualize o arquivo configuration.xml para que tenha a dependência commons-lang em vez da dependência de lote do Spring fornecida padrão, como em Lista 6.
 
<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<configuration>
   <dependencies>
      <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
         <version>3.1</version>
      </dependency>
   </dependencies>
</configuration>

Em seguida, modifique a implementação do método setup() na classe ComparetoOperationsImpl para ler a dependência Maven commons-lang em vez da dependência Maven de lote do Spring, como em Lista 7. O método annotateType e annotateAll() não são mostradas aqui, porque eles não apresentam mudanças.

@Component
@Service
public class ComparetoOperationsImpl implements ComparetoOperations {

@Reference
private ProjectOperations projectOperations;

@Reference
private TypeLocationService typeLocationService;

@Reference
private TypeManagementService typeManagementService;

/** {@inheritDoc} */
public void setup() {
// Install the add-on Google code repository needed to get the annotation
projectOperations.addRepository("",
new Repository("Compareto Roo add-on repository",
"Compareto Roo add-on repository",
"https://spring-dw-roo-compareto-addon.googlecode.com/svn/repo"));
List<Dependency> dependencies = new ArrayList<Dependency>();
// Install the dependency on the add-on jar (
dependencies.add(new Dependency("org.xebia.roo.addon.compareto",
"org.xebia.roo.addon.compareto", "0.1.0.BUILD-SNAPSHOT",
DependencyType.JAR, DependencyScope.PROVIDED));
Element configuration = XmlUtils.getConfiguration(getClass());
for (Element dependencyElement : XmlUtils.findElements(
"/configuration/dependencies/dependency",
configuration)) {
dependencies.add(new Dependency(dependencyElement));
}
projectOperations.addDependencies("", dependencies);
}
}

As mudanças feitas até agora são semelhantes às mudanças usadas para criar um complemento simples Jamon na parte 3.

Faça com que a classe de entidade implemente a interface comparável

Após fazer mudanças no código para incluir a dependência Maven, é necessário garantir que sua classe de entidade implemente a interface java.lang.Comparable. Para fazer isso, modifique a ITD gerada pela classe ComparetoMetadata . As classes de metadados geram a ITD usando a classe ItdTypeDetailsBuilder que fornece vários métodos de inclusão para incluir métodos, campos, anotações, interface, entre outros, em uma ITD. Para fazer com que um tipo Java implemente uma interface, use o método addImplementsType na classe ItdTypeDetailsBuilder , como na Lista 8. Somente o construtor ComparetoMetadata é exibido porque a construção da ITD ocorre nele.

public ComparetoMetadata(String identifier, JavaType aspect Name,
PhysicalTypeMetadata  governorPhysicalTypeMetadata) {
super(identifier, aspect Name, governorPhysicalTypeMetadata);
Assert.isTrue(isValid(identifier), "Metadata identification string '" +
identifier + "' does not appear to be a valid");
JavaType comparableInterface = new JavaType("java.lang.Comparable");
builder.addImplementsType(comparableInterface);
itdTypeDetails = builder.build();
}

Crie uma ITD para o método compareTo

Após fazer com que um tipo Java implemente a interface Comparável, é preciso fornecer a implementação do método compareTo. A classe CompareToBuilder fornece uma interface fluente para criar o método compareTo. O complemento equivalentes do Spring Roo usa o EqualsBuilder e o HashcodeBuilder para fornecer a implementação para os métodos equivalentes e código hash. Usaremos um exemplo para garantir que haja dúvidas sobre como o CompareToBuilder auxilia na criação do método compareTo . Suponhamos que você tenha uma entidade chamada Book e deseja fornecer a implementação compareTo para ela usando o CompareToBuilder. Lista 9 mostra a classe Book e compareTo .

import org.apache.commons.lang3.builder.CompareToBuilder;

public class Book implements Comparable {
    private String title;
    private String author;
    private double price;
    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    // getters and setters

    public int compareTo(Book o) {
	if(!(o instanceof Book)){
	  return -1;
	}
	Book book = (Book)o
        return new CompareToBuilder().append(this.title, book.title).append(this.author, 
            book.author).append(this.price, book.price).toComparison();
    }

    @Override
    public String toString() {
        return "Book [title=" + title + ", author=" + author + ", price=" + price + "]";
    }

}

O método compareTo na Lista 9 faz o seguinte:

  • Se “o” não for instanceOfBook , retorne -1;
  • Se “o” for instanceOfBook , digite cast o para Book;
  • Crie um objeto da classe CompareToBuilder e, em seguida, chame o método anexar nos campos.

Crie o método compareTo incrementalmente com estas etapas:

  • Se “o” não for instanceOf Book, retorne -1

Antes de incluir a verificação instanceOf , crie o método compareTo . Consulte Lista 10.

public ComparetoMetadata(String identifier, JavaType aspect Name, 
    PhysicalTypeMetadata governorPhysicalTypeMetadata) { 
        super(identifier, aspect Name, governorPhysicalTypeMetadata); 
        Assert.isTrue(isValid(identifier), 
            "Metadata identification string '" + identifier + 
            "' does not appear to be a valid"); 

    JavaType comparableInterface = new JavaType("java.lang.Comparable"); 
    builder.addImplementsType(comparableInterface); 
    builder.addMethod(getCompareToMethod()); 

    itdTypeDetails = builder.build(); 
} 

private MethodMetadata getCompareToMethod() { 
    final JavaType parameterType = JavaType.OBJECT; 
    final List parameterNames = 
        Arrays.asList(new JavaSymbolName("obj")); 
    final InvocableMemberBodyBuilder bodyBuilder = 
        new InvocableMemberBodyBuilder(); 
    bodyBuilder.appendFormalLine("return -1;"); 
    final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder(getId(), 
        Modifier.PUBLIC, new JavaSymbolName("compareTo"), 
        JavaType.INT_PRIMITIVE, 
            AnnotatedJavaType.convertFromJavaTypes(parameterType), 
        parameterNames, bodyBuilder); 
        return methodBuilder.build(); 
}

O getCompareToMethod() gera os metadados do método compareTo usando a classe MethodMetadataBuilder . MethodMetadataBuilder é uma classe Builder fornecida pelo Spring Roo para criação de metadados de método. Para criar os metadados de método, primeiro construa um objeto MethodMetadataBuilder , passando argumentos, como modificador de acesso, nome de método, tipo de retorno, lista de parâmetros ou um construtor de corpo de método para criar os metadados para o método compareTo como na Lista 11.

private MethodMetadata getCompareToMethod() { 
        final JavaType parameterType = JavaType.OBJECT; 
        String parameterName = "obj"; 
        final List parameterNames = 
            Arrays.asList(new JavaSymbolName(parameterName)); 
        final InvocableMemberBodyBuilder bodyBuilder = 
            new InvocableMemberBodyBuilder(); 
        final String typeName = destination.getSimpleTypeName(); 
        bodyBuilder.appendFormalLine("if (!(" + parameterName + 
            " instanceof " + typeName + ")) {"); 
        bodyBuilder.indent(); 
        bodyBuilder.appendFormalLine("return -1;"); 
        bodyBuilder.indentRemove(); 
        bodyBuilder.appendFormalLine("}"); 

        bodyBuilder.appendFormalLine("return -1;"); 
        final MethodMetadataBuilder methodBuilder = 
            new MethodMetadataBuilder(getId(), 
            Modifier.PUBLIC, new JavaSymbolName("compareTo"), 
            JavaType.INT_PRIMITIVE, 
            AnnotatedJavaType.convertFromJavaTypes(parameterType), 
            parameterNames, bodyBuilder); 
        return methodBuilder.build(); 
    }
  • Se “o” for instanceOfBook, digite cast o para Book

A próxima etapa é um cast, portanto, é possível criar o método compareTo . Para fazer isso, anexe esta linha após a verificação instanceOf:

bodyBuilder.appendFormalLine(typeName + " rhs = (" + typeName + ") " + 
    OBJECT_NAME + ";");
  • Crie o objeto da classe CompareToBuilder e, em seguida, chame o método anexar nos campos

Para criar o método compareTo , é necessário acesso a todos os campos de uma classe. A classe ComparetoMetadata não contém nenhuma informação sobre o tipo, portanto, não é possível obter campos da classe. Essas informações podem ser fornecidas pelo ComparetoMetadataProvider como na Lista 12.

protected ItdTypeDetailsProvidingMetadataItem getMetadata(String metadataId,
    JavaType aspect Name, PhysicalTypeMetadata governorPhysicalTypeMetadata, 
    String itdFilename) { 

        final String[] excludeFields = {};

        final MemberDetails memberDetails = 
            getMemberDetails(governorPhysicalTypeMetadata); 
        if (memberDetails == null) { 
            return null; 
        } 

        final JavaType javaType = 
            governorPhysicalTypeMetadata.getMemberHoldingTypeDetails().getName();

        final List compareToFields = 
            locateFields(javaType, excludeFields, memberDetails, metadataId); 

        return new ComparetoMetadata(metadataId, aspect Name,
        governorPhysicalTypeMetadata, compareToFields);
    } 

private List locateFields(final JavaType javaType, final String[]
        excludeFields, final MemberDetails memberDetails, final String
        metadataIdentificationString) { 

	final SortedSet locatedFields = new TreeSet(new
    	  Comparator() { 
            public int compare(final FieldMetadata l, final FieldMetadata r) { 
                return l.getFieldName().compareTo(r.getFieldName()); 
            } 
        }); 

        final List excludeFieldsList = 
            CollectionUtils.arrayToList(excludeFields); 
        final FieldMetadata versionField = 
            persistenceMemberLocator.getVersionField(javaType); 

        for (final FieldMetadata field : memberDetails.getFields()) { 
            if (excludeFieldsList.contains(field.getFieldName().getSymbolName())) { 
                continue; 
            } 
            if (Modifier.isStatic(field.getModifier()) ||
        Modifier.isTransient(field.getModifier()) ||
      		field.getFieldType().isCommonCollectionType() 
                    || field.getFieldType().isArray()) { 
                continue; 
            } 
            if (versionField != null && 
                field.getFieldName().equals(versionField.getFieldName())) { 
                    continue; 
                } 

            locatedFields.add(field); 

            metadataDependencyRegistry.registerDependency(
                field.getDeclaredByMetadataId(), 
                metadataIdentificationString
            ); 
        } 

        return new ArrayList(locatedFields); 
    }

Quando tiver os campos, passe-os para ComparetoMetadata a fim de que possa criar o método compareTo , como mostra a Lista 13.

private List compareToFields; 

public ComparetoMetadata(String identifier, JavaType aspectName, 
    PhysicalTypeMetadata governorPhysicalTypeMetadata, 
    List compareToFields) { 

        super(identifier, aspectName, governorPhysicalTypeMetadata); 
        Assert.isTrue(isValid(identifier), 
            "Metadata identification string '" + identifier + 
                "' does not appear to be a valid"); 

        this.compareToFields = compareToFields; 
        if (!CollectionUtils.isEmpty(compareToFields)) { 
            JavaType comparableInterface = new JavaType("java.lang.Comparable"); 
            builder.addImplementsType(comparableInterface); 
            builder.addMethod(getCompareToMethod()); 
        } 
        itdTypeDetails = builder.build(); 

    } 

    private MethodMetadata getCompareToMethod() { 
        final JavaType parameterType = JavaType.OBJECT; 
        String parameterName = "obj"; 
        final List parameterNames = 
            Arrays.asList(new JavaSymbolName(parameterName)); 
        final InvocableMemberBodyBuilder bodyBuilder = 
            new InvocableMemberBodyBuilder();
        final ImportRegistrationResolver imports = 
            builder.getImportRegistrationResolver(); 
            imports.addImport(
                newJavaType("org.apache.commons.lang3.builder.CompareToBuilder")
            );

        final String typeName = destination.getSimpleTypeName(); 
        bodyBuilder.appendFormalLine("if (!(" + parameterName + " instanceof " + 
            typeName + ")) {"); 
        bodyBuilder.indent(); 
        bodyBuilder.appendFormalLine("return -1;"); 
        bodyBuilder.indentRemove(); 
        bodyBuilder.appendFormalLine("}"); 

        bodyBuilder.appendFormalLine(typeName + " rhs = (" + typeName + ") " + 
            parameterName + ";"); 
        final StringBuilder builder = new StringBuilder(); 
        builder.append("return new CompareToBuilder()"); 

        for (final FieldMetadata field : compareToFields) { 
            builder.append(".append(" + field.getFieldName() + ", rhs." + 
                field.getFieldName() + ")"); 
        } 
        builder.append(".toComparison();"); 

        bodyBuilder.appendFormalLine(builder.toString()); 

        final MethodMetadataBuilder methodBuilder = 
                new MethodMetadataBuilder(getId(), 
                    Modifier.PUBLIC, new JavaSymbolName("compareTo"), 
                    JavaType.INT_PRIMITIVE, 
                    AnnotatedJavaType.convertFromJavaTypes(parameterType), 
                    parameterNames, bodyBuilder); 
        return methodBuilder.build(); 
    }

Teste

Isso conclui a implementação do complemento compareTo . É possível fazer download do código de origem completo deste complemento a partir do repositório de código do Google. Agora, é possível testar o compareTo que acabou de ser criado.

  • Saia do shell roo e execute o comando instalação limpa do mvn . Durante o processo de construção, será solicitada a passphrase GPG;
  • Após o complemento do Roo ser criado, abra uma nova linha de comandos e crie um diretório chamado livraria;
  • Acesse o diretório livraria e digite o comando roo para abrir um shell Roo;
  • Execute os comandos de Lista 14 no shell Roo.
project --topLevelPackage com.xebia.roo.bookshop --projectName bookshop  
jpa setup --database HYPERSONIC_IN_MEMORY --provider HIBERNATE  
entity jpa --class ~.domain.Book  
field string --fieldName title --notNull  
field string --fieldName author --notNull  
field number --fieldName price --type double --notNull
  • Para instalar e iniciar o complemento, digite o que segue no shell Roo:
osgi start --url file://<location to compareTo addon jar>

Isso deverá instalar e ativar seu complemento compareTo. É possível visualizar o status do complemento usando o comando OSGi ps.

  • Digitecompareto e pressione tab para visualizar os três comandos do complemento compareto na Lista 15.
roo> compareto

compareto add      compareto all      compareto setup
  • As etapas configuradas na Lista 15 confirmará se o complemento compareto está adequadamente instalado. A próxima etapa é executar o comando configuração, que configurará as dependências necessárias. Consulte Lista 16.
roo> compareto setup 

Updated ROOT/pom.xml [added repository 
    https://spring-dw-roo-compareto-addon.googlecode.com/svn/repo; 
    added dependencies org.xebia.roo.addon.compareto:org.xebia.roo.addon.compareto:
        0.1.0.BUILD,
    org.apache.commons:commons-lang3:3.1;
    removed dependency org.apache.commons:commons-lang3:3.0.1]
  • Quando executar o comando compareto setup a próxima etapa lógica é incluir o método compareTo em classes de entidade. Isso pode ser feito por meio de compareto add ou compareto all, dependendo se deseja gerar o método compareTo para somente uma classe de entidade ou todas as classes de entidade. Incluiremos o método compareTo em todas as classes de entidade na amostra do aplicativo bookshop (consulte Downloads). Consulte Lista 17.
roo> compareto all 
Updated SRC_MAIN_JAVA/com/xebia/roo/bookshop/domain/Book.java 
Created SRC_MAIN_JAVA/com/xebia/roo/bookshop/domain/Book_Roo_Compareto.aj

Como pode ver acima, na saída do comando compareto all, um ITD chamado Book_Roo_Compareto.aj é gerado. Esse arquivo conterá o método compareTo. A Lista 18 mostra o Book_Roo_Compareto.aj.

import org.apache.commons.lang.builder.CompareToBuilder; 

privileged aspect Book_Roo_Compareto { 

    declare parents: Book implements java.lang.Comparable; 

    public int Book.compareTo(java.lang.Object obj) { 
        if (!(obj instanceof Book)) { 
            return -1; 
        } 
        Book rhs = (Book) obj; 
        return new CompareToBuilder().append(author, 
            rhs.author).append(id, rhs.id).append(price, rhs.price).append(title, 
            rhs.title).toComparison(); 
    } 

}
  • Execute o comandorealizar pacote no shell Roo para verificar se tudo está compilado corretamente após incluir o complemento. Para sua surpresa, a construção falhará porque o Maven não consegue resolver dependências do pacote configurável do Sprin Roo. Essas dependências de pacote configurável vêm do complemento compareTo . É necessária a dependência do complemento, porque suas entidades têm de ser anotadas com a anotação Compareto. Essa é a única coisa que precisa do complemento. A melhor forma encontrada é criar outro módulo Maven e ter todas as dependências do complemento lá. É semelhante com o que o Sprin Roo faz. O Spring Roo não cria dependência com cada complemento usado. Ele possui anotações jar de Spring Roo comuns que contêm todas as dependências. O xebia-spring-roo-addon-annotation do projeto foi criado e a anotação Compareto foi inserida neste módulo. Em seguida, o configuration.xml foi atualizado para incluir esse jar no projeto do cliente, em vez do jar do complemento. A Lista 19 mostra o configuration.xml.
 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<configuration> 
  <dependencies> 
    <dependency> 
      <groupId>org.apache.commons</groupId> 
      <artifactId>commons-lang3</artifactId> 
      <version>3.1</version> 
    </dependency> 
    <dependency> 
      <groupId>org.xebia.roo.addon</groupId> 
      <artifactId>xebia-spring-roo-addon-annotations</artifactId> 
      <version>0.0.1</version> 
    </dependency> 
  </dependencies> 

  <repositories> 
    <repository> 
      <id>spring-roo-addon-annoations</id> 
      <name>Spring Roo Addon Annotation</name> 
      <url>https://xebia-spring-roo-addon-annotations.googlecode.com/svn/repo</url> 
    </repository> 
  </repositories>  
</configuration>

Atualize a classe ComparetoOperationsImpl do método setup() para ler as novas dependências e repositórios especificados no arquivo configuration.xml atualizado. Consulte Lista 20.

public void setup() { bu

List<Dependency> dependencies = new ArrayList<Dependency>();

Element configuration = XmlUtils.getConfiguration(getClass());
for (Element dependencyElement :
XmlUtils.findElements("/configuration/dependencies/dependency",
configuration)) {

dependencies.add(new Dependency(dependencyElement));

}

projectOperations.addDependencies("", dependencies);

List<Element> repositories = XmlUtils.findElements(
"/configuration/repositories/repository", configuration);
for (Element repositoryElement : repositories) {
Repository repository = new Repository(repositoryElement);
projectOperations.addRepository(projectOperations.getFocusedModuleName(),
repository);
}
}

Em seguida, siga estas etapas:

  • Crie o complemento novamente executando instalação limpa do mvn.
  • Gere novamente o cliente como na etapa 4.
  • Para remover o complemento antigo, digite este comando no shell Roo:
addon remove --bundleSymbolicName
org.xebia.roo.addon.compareto
  • Instale o complemento novamente executando o comando osgi install;
  • Quando o complemento for instalado, execute os comandos compareto setup e compareto all;
    As ITDs compareTo poderão ser visualizadas. Execute o comando realizar pacote e tudo funcionará direito.

Quando testar que seu complemento está funcionando em seu ambiente de desenvolvimento, será possível realizar seu push para o projeto do código do Google criado. Para publicar o complemento para o mundo, siga o mesmo procedimento usado para publicar o complemento i18n na parte 3. Da mesma forma, para registrar o complemento com o RooBot, siga a documentação do Spring Roo.

Torne os drivers JDBC não OSGi compatíveis com OSGi com o complemento de wrapper

Um caso de uso comum do complemento de wrapper é para a conversão de drivers JDBC não OSGi para pacotes configuráveis compatíveis com OSGi. Um local em que é necessário quebrar um driver JDBC é quando você tem de realizar engenharia reversa em um banco de dados Oracle usando o Roo. O Spring Roo não fornece drivers JDBC Oracle OSGi, devido a problemas de copyright. Antes de fazer a engenharia reversa de um banco de dados Oracle, primeiro torne o driver compatível com OSGi. Para criar um complemento de wrapper para um driver JDBC Oracle:

  • Instale o jar JDBC Oracle em seu repositório Maven da máquina local digitando este comando
mvn install:install-file -Dfile=ojdbc5.jar -DgroupId=com.oracle 
  -DartifactId=ojdbc5 -Dversion=11.2.0.2 -Dpackaging=jar
  • Crie um novo diretório chamado oracle-wrapper-addon e, a partir da linha de comandos, acesse o diretório.
  • Abra o shell Roo e execute o comando de complemento de wrapper: addon create wrapper --topLevelPackage com.oracle.wrapper.jdbc --groupId com.oracle --artifactId ojdbc5 --version 11.2.0.2 --vendorName Oracle --licenseUrl oracle.com Esse comando gerará somente arquivos pom.xml que serão usados para converter um driver JDBC Oracle não OSGi em um driver OSGi
  • De dentro do shell Roo, excute este comando para criar o pacote configurável do OSGi: perform command --mavenCommand bundle:bundle

Pronto. Um pacote configurável de OSGi foi criado com sucesso a partir de um jar não OSGi.

Conclusão

Neste artigo, você aprendeu sobre o complemento avançado e de wrapper no Spring Roo. Também aprendeu a criar complementos avançados e de wrapper. Isso conclui sua exploração em um recurso muito importante do Spring Roo: gravação de complementos. Sempre que desejar estender a funcionalidade do Spring Roo, lembre-se de pensar sobre a criação de complementos.

Na próxima parte desta série, “Apresentando o Spring Roo”, será discutido como gravar aplicativos GWT usando o Spring Roo.

Downloads

Descrição Nome Tamanho Método de download
Sample code bookshop.zip 14KB HTTP
Sample code spring-dw-roo-compareto-addon.zip 18KB HTTP

Informações sobre métodos de download

Recursos

Aprender

Obter produtos e tecnologias

Discutir

Conecte-se com outros usuários do developerWorks enquanto explora os blogs, fóruns, grupos e wikis voltados para desenvolvedores. Ajude a desenvolver o software livre do mundo real na comunidade do developerWorks.

***

Sobre o autor: Shekhar Gulati é consultor Java na Xebia Índia. Ele tem seis anos de experiência corporativa em Java. Possui ampla experiência em projetos do portfólio Spring, como Spring, Spring-WS e Spring Roo. Seus interesses são Spring, bancos de dados NoSQL, Hadoop, estruturas RAD, como Spring Roo, computação em nuvemCloud30 conteúdosGerenciamento de infraestrutura multicloud com Kubernetes proporciona otimização e economiaDevSecOps · set 2021Vivo assina contrato para aquisição da IPNET e cresce em cloud computingDevSecOps · ago 20245 tendências da computação em nuvem para as empresasDevSecOps · abr 2022Ver tudo em DevSecOps (principalmente, serviços PaaS, como Google App Engine, CloudFoundry, OpenShift), Hadoop. Escreve constantemente para JavaLobby, Developer.com, IBM developerWorks e seu próprio blog em http://whyjava.wordpress.com/. Você pode segui-lo no Twitter @ http://twitter.com/#!/shekhargulati.

***

Artigo original disponível em: http://www.ibm.com/developerworks/br/library/os-springroo5/index.html

 

é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com/developerworks/br

Ver perfil