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 Java↳Java42 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 dados↳Banco 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.
- Na inicialização de shell Roo, ele varrerá todas as classes e registrará todas as que implementam a interface
CommandMarker.A interface CommandMarkerinforma ao Roo que essas classes definirão os comandos que esse complemento pode executar; - 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; - 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:
- Chamar
java.util.Collections.sortejava.util.Collections.binarySearch; - Chamar
java.util.Arrays.sortejava.util.Arrays.binarySearch; - Usar objetos como chaves em um
java.util.TreeMap; - 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 interfaceCommandMarkere expõe dois tipos de métodos:—um com a anotaçãoCliAvailablityIndicatore outro com a anotaçãoCliCommand. A anotaçãoCliAvailablityIndicatorinforma 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@CliCommandregistram o comando com o shell Roo. A anotação@CliCommandpossui 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 classeComparetoCommandsdelega todo o trabalho para a classeComparetoOperationsImpl. Os quatro métodos gerados nesta classe são:isCommandAvailable(): Este método é chamado pelo método anotado comCliAvailabilityIndicator ComparetoCommandsna classeComparetoCommandspara 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étodosetup(), na classeComparetoCommandsque é 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 eannotateAll()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çãoRooJComparetoa ele.annotateAll(): Este método encontra todos os tipos que são anotados com a anotaçãoRooJavaBeane chama o métodoannotateType()em todos esses tipos. Utilize este método quando todas as entidades forem obrigadas a ter a anotaçãoRooCompareto.
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çãoRooCompareto.ComparetoMetadata.java: Esta classe é responsável por gerar o ITD correspondente ao complemento. No código gerado, ela usa uma classe chamadaItdTypeDetailsBuilderpara 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étodocompareToe 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-langno projeto de destino. Atualize o arquivo configuration.xml para que tenha a dependênciacommons-langem 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
CompareToBuildere, 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
roopara 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.
- Digite
comparetoe 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 setupa próxima etapa lógica é incluir o métodocompareToem 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étodocompareToem 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 comando
realizar pacoteno 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 complementocompareTo. É 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 setupecompareto 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.comEsse 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
- Explore a documentação do Spring Roo e encontre tudo de que precisa para usar o Roo efetivamente.
- Certifique-se de ler o resto desta série do Spring Roo:
- Busque o código para Spring Roo nesta visualização na web do Código Fonte do Spring Roo.
- Saiba mais sobre o java.lang.Comparable .
- Leia a documentação do Spring Roo sobre como configurar um projeto e repositório Maven no código do Google.
- Acompanhe a documentação do Spring Roo para registrar o complemento com o RooBot.
- Na área de Software Livre no developerWorks, encontre informações extensas sobre instruções, ferramentas e atualizações de projetos para ajudar no desenvolvimento com tecnologias de software livre e usá-las com produtos IBM.
- Na zona de tecnologia Java do developerWorks, encontre artigos, tutoriais, fóruns, entre outros, sobre cada aspecto da programação Java.
- Fique por dentro dos eventos técnicos e webcasts do developerWorks com ênfase em uma série de produtos IBM e tópicos do segmento de mercado de TI.
- Participe de um resumo de instruções gratuito do developerWorks para se atualizar rapidamente sobre produtos e ferramentas IBM e tendências do segmento de mercado de TI.
- Ouça os podcasts do developerWorks para obter entrevistas e discussões interessantes para os desenvolvedores de software.
- Siga o developerWorks no Twitter.
- Assista às demos do developerWorks que variam de instalação e configuração de produtos para iniciantes a funcionalidades avançadas para desenvolvedores experientes.
Obter produtos e tecnologias
- Acesse o website do repositório do Spring Roo para fazer download da captura instantânea noturna do código.
- Faça download da versão mais recente do Spring Roo, 1.2.0.RC1 a partir do website do projeto.
- Faça download do código fonte integral do complemento compareTo do repositório do código Google.
- Acessea versão de teste do software IBM (disponível para download ou no DVD) e inove em seu próximo projeto de desenvolvimento de software livre usando o software especialmente para desenvolvedores.
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 nuvem↳Cloud30 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






