Conteúdo


Percorra o Skyway: gerando aplicativos Spring com o Rational e o Skyway Builder

O desenvolvimento em Spring ainda mais rápido!

Comments

Imagine que você está entrando em um novo projeto e, no dia da sua chegada, se depara com um papel de parede com cem ou mais entidades. Sua missão é criar um modelo UML para a lógica de negócios e codificar o aplicativo. Certamente, a lógica de negócios baseia-se em criar, ler, atualizar e excluir os dados representados pelas entidades. É claro que codificar o aplicativo não é tão difícil quanto era antigamente, quando o AOP e o Spring não existiam. Grande parte do código padrão não é mais usada, devido a conceitos como Injeção de Dependência, Anotações e Programação Orientada ao Aspecto. Por isso, o uso de Spring padrão real é um requisito em seu novo projeto. Embora você esteja bastante contente com esse requisito, não espera implementar, por exemplo, todas as consultas do localizador de cada atributo Entity, juntamente com incontáveis métodos de acesso em todas as camadas de um aplicativo Java™ Enterprise Edition (JEE). Isso definitivamente levará muito tempo e, além do mais, é extremamente entediante.

Agora, é possível vislumbrar uma esperança. A escolha da composição certa para o conjunto de ferramentas oferece um passo inicial que possibilita que você se concentre imediatamente na lógica de negócios. Por meio da integração do IBM® InfoSphere™ Data Architect, do IBM® Rational® Software Architect e do Skyway Builder, como mostra a Figura 1, você obtém um poderoso conjunto de ferramentas que permite industrializar seu desenvolvimento em JEE.

Figura 1. Composição de ferramenta
Composição de ferramenta
Composição de ferramenta

Use esta composição de ferramenta para ter modelos separados, que podem ser transformados uns nos outros. Um modelo de dados pode ser transformado em um modelo de aplicativo, e o modelo de aplicativo pode ser transformado em uma DSL Spring do Skyway. A DSL Spring é uma linguagem específica de domínio do Skyway para aplicativos empresariais. Atualmente, a melhor prática é gerar códigos a partir de uma DSL, que é mais simples de usar do que uma linguagem de finalidade geral, como UML. A DSL Spring é um conjunto formalizado de modelos EMF. O Skyway Builder é uma ferramenta de geração e armação de códigos para acelerar o desenvolvimento de aplicativos da Web baseados em Spring. O Mecanismo de Geração do Skyway segue as melhores práticas de MDSD. Por exemplo, o código gerado é separado do código manual. O projeto que contém o modelo de DSL é separado do projeto da Web gerado pelo mecanismo. Por isso, você nunca estará preso ao modelo caso decida prosseguir sem geração. Devido ao fato de que o EMF é a essência do Skyway Builder, seu Mecanismo de Geração é bastante flexível e altamente extensível.

Existem cinco edições disponíveis, desde a edição de software livre até a edição comercial.

  • Community
  • Standard
  • Web Services
  • Professional
  • Rational Software Architect

A Edição Rational Software Architect se integra ao Rational Software Architect e oferece suporte a transformações de UML em Spring e vice-versa. Além disso, essa edição acrescenta um perfil do Spring e estereótipos da modelagem UML. A edição Rational Software Architect pode ser instalada com o Rational Software Architect versões 7.5.2, 7.5.3 e 7.5.4.

O exemplo a seguir oferece uma percepção mais profunda sobre os recursos do MDSD desse conjunto de ferramentas.

Pré-requisitos

Para possibilitar as transformações de LDM em Rational Software Architect, é necessário aplicar o perfil LogicalDataModel ao modelo. Esse recurso deve ser instalado.

  1. Inicie o IBM® Installation Manager.
  2. Selecione Modify e o produto a ser modificado (IBM® Rational® Software Delivery Platform).
  3. Clique em Next.
  4. Selecione InfoSphere Data Architect Integration sob o tópico Lifecycle and architecture tool integration, como é mostrado na Figura 2.
Figura 2. Ativar o Data Architect Integration
Ativar o Data Architect Integration
Ativar o Data Architect Integration
  • Para acompanhar os exemplos dados neste artigo, é necessária alguma familiaridade com o Spring, fluxo da Web do Spring e Rational Software Architect.
  • Para obter uma maior compreensão, assista ao vídeo "UML to Skyway" (10 minutos).
  • Para instalar o Skyway Builder, solicite um teste e siga as instruções de instalação.
  • Os links são fornecidos na seção Recursos.
  • O projeto do Rational Software Architect está disponível na seção Recursos para download.

Modelar o domínio do aplicativo

Você está pronto para começar. Comece criando um novo Projeto UML na perspectiva Modeling do Rational Software Architect, como é mostrado no vídeo do Skyway. O projeto é chamado de ApplicationManagement-UML.

Para transformações de LDM, inicialmente clique duas vezes no seu modelo e adicione o perfil LogicalDataModel na guia Details (Figura 3).

Na seção seguinte, aplique estereótipos para a transformação de DSL do Skyway e para a transformação de LDM. Se você não pretende usar um LDM, ou se já existe um modelo de dados, não é necessário aplicar estereótipos do perfil LogicalDataModel.

Figura 3. Adicionando o perfil do Modelo de Dados Lógicos
Adicionando o perfil do Modelo de Dados Lógicos
Adicionando o perfil do Modelo de Dados Lógicos

Agora que o trabalho preliminar foi feito, é possível continuar com a modelagem do seu primeiro objeto de domínio (também conhecido como entidade). Você deseja modelar um domínio para gerenciar aplicativos (da Web) via JMX (Java Management Extensions). Por isso, é necessário saber o nome dos aplicativos a serem gerenciados, conhecer o ambiente (de produção ou de testes) no qual eles estão implementados, seus parâmetros de conexão, hosts, e assim por diante.

  1. Crie uma estrutura de pacotes de sua escolha (por exemplo, com.ibm.de.eas.application.management.domain)
    1. No Project Explorer: clique com o botão direito do mouse no modelo ou pacote e selecione: Add UML > Package
    2. Em cada pacote, há um diagrama de formato livre criado automaticamente, chamado Main, como mostra a Figura 4.
      Figura 4. Criar a estrutura do seu pacote
      Criar a estrutura do seu pacote
      Criar a estrutura do seu pacote
  2. Clique duas vezes no diagrama de formato livre Main para modelar as classes do seu domínio. Para isso, selecione o estereótipo DomainObject na paleta Spring do Skyway, conforme mostra a Figura 5, e clique no diagrama de formato livre.
    Figura 5. Selecione um estereótipo na paleta Spring do Skyway
    Selecione um estereótipo na paleta Spring do Skyway
  3. Dê um nome ao primeiro Application do Objeto de Domínio, como mostra a Figura 6.
    Figura 6. O Aplicativo da Classe de Domínio
    O Aplicativo da Classe de Domínio
  4. Mova o mouse sobre a estrutura da classe e será exibida uma barra de ferramentas para adicionar atributos e operações.
    1. Clique no primeiro ícone para adicionar o atributo-chave primário.
    2. Digite id:Integer no editor, como mostra a Figura 7, e pressione Enter.
      Figura 7. Adicionar o atributo-chave primário
      Adicionar o atributo-chave primário
  5. Agora, adicione um atributo String.
    Digite name:String no editor, como mostra a Figura 8, e pressione Enter.
    Figura 8: Adicionar um atributo String
    Figura 8: Adicionar um atributo String
  6. Selecione id - attribute e clique na guia Stereotypes, na visualização Properties.
    1. Aplique o estereótipo Id do perfil do Spring para a transformação de DSL do Skyway
    2. Aplique o estereótipo PrimaryKey do perfil LogicalDataModel, conforme é mostrado na Figura 9. Posteriormente, isso será necessário para a transformação em um Modelo de Dados Lógicos.
      Figura 9. Aplicar os estereótipos-chave primários
      Aplicar os estereótipos-chave primários
      Aplicar os estereótipos-chave primários
  7. Depois de aplicar o estereótipo PrimaryKey, um ícone de chave torna-se visível à esquerda do atributo, como mostra a Figura 10.
    Figura 10. Ícone de chave do estereótipo primário
    Ícone de chave do estereótipo primário
  8. Mova o mouse sobre a estrutura da classe e serão exibidas setas para a criação de referências. Clique em uma seta e arraste-a para um destino a fim de criar uma referência.
    1. Na Figura 11, crie uma autorreferência de muitos para muitos.
      Figura 11. Criar um relacionamento
      Criar um relacionamento
    2. Selecione a referência e especifique a multiplicidade na visualização Properties. Altere os nomes da função para manager e managed, conforme mostrado na Figura 12.
      Figura 12. Funções do relacionamento e multiplicidade
      Funções do relacionamento e multiplicidade
      Funções do relacionamento e multiplicidade
  9. Para a transformação de LDM, é necessário marcar este objeto de domínio como estereótipo de entidade. Para isso, selecione a classe e aplique um estereótipo na visualização Properties, como é mostrado na Figura 13. Agora, o trabalho principal de um Objeto de Domínio está concluído.
    Figura 13. Aplicar o estereótipo de entidade
    Aplicar o estereótipo de entidade
  10. Conforme foi descrito anteriormente, é necessário concluir o modelo de domínio e adicionar alguns atributos, entidades e referências (como mostra a Figura 14) para obter algo mais robusto que um exemplo Hello World.
    Figura 14. O modelo de domínio Gerenciamento de Aplicativo
    O modelo de domínio Gerenciamento de Aplicativo
    O modelo de domínio Gerenciamento de Aplicativo

Embora seja possível modelar objetos de acesso aos dados, WebController e Business Services (consulte a Figura 5. Paleta Spring do Skyway), neste exemplo você para por aqui. Você irá gerar essas classes com o utilitário de Armação CRUD do Skyway Builder. A integração do Skyway com o Rational Software Architect é bidirecional, e é possível enviar as classes geradas de volta para o modelo de aplicativo.

O modelo de domínio agora está pronto para ser transformado em DSL ou LDM do Skyway No entanto, antes de se aprofundar no Skyway Builder, continue a Transformação do Modelo de Dados para criar as tabelas do banco de dados IBM® DB2® Version 9.7.

Transformar em um modelo de dados

Esta seção detalha as etapas necessárias para transformar um modelo de aplicativo do Rational Software Architect em um LDM do InfoSphere Data Architect. Com alguns cliques, é possível obter o Modelo de Dados Físicos de um DB2 e os scripts DDL para criar as tabelas.

Transformação de UML em LDM

Para transformar um diagrama de classe UML em LDM, é necessário criar uma Configuração de Transformação no Rational Software Architect (lembre-se dos pré-requisitos mostrados na Figura 2. Ativar o Data Architect Integration).

  1. Selecione seu Projeto UML e pressione Ctrl+N para abrir a caixa de diálogo Wizard Selection.
  2. Vá para Transformations e clique duas vezes em Transformation Configuration, como mostra a Figura 15.
    Figura 15. Criar a Configuração de Transformação
    Figura 15. Criar a Configuração de Transformação
  3. Vá para Data Model Transformations e selecione UML to Logical Data Model
  4. Dê um nome à transformação (ApplicationManagement-Uml_TO_LogicalDataModel na Figura 16) e clique em Next.
    Figura 16. Criar a Configuração de Transformação de UML em LDM
    Criar a Configuração de Transformação de UML em LDM
    Criar a Configuração de Transformação de UML em LDM
  5. Selecione o modelo de aplicativo Application Management como Selected source e o projeto ApplicationManagement-UML como Selected target, como mostra a Figura 17.
  6. Clique em Next.
    Figura 17. Especificar origem e destino da transformação de UML em LDM
    Especificar origem e destino da transformação de UML em LDM
    Especificar origem e destino da transformação de UML em LDM
  7. Limite o comprimento das cadeias de caractere (255 na Figura 18).
  8. Clique em Finish.
    Figura 18. Definir o comprimento padrão das cadeias de caractere
    Definir o comprimento padrão das cadeias de caractere
    Definir o comprimento padrão das cadeias de caractere
  9. Sempre que você alterar o modelo da sua classe, será possível transformá-lo em um LDM. Para isso, basta clicar em Run na sua Configuração de Transformação, como mostra a Figura 19.
    Figura 19. Iniciar a transformação de LDM
    Iniciar a transformação de LDM
    Iniciar a transformação de LDM
  10. É possível escolher seu arquivo LDM na visualização Navigator, como mostra a Figura 20. Basta clicar com o botão direito do mouse para copiá-lo e, em seguida, colá-lo em um projeto de Design de Dados no InfoSphere Data Architect.
    Figura 20. O arquivo LDM
    O arquivo LDM
    O arquivo LDM

Agora que o Modelo de Dados Lógicos foi transformado, é necessário criar um Modelo de Dados Físicos no InfoSphere Data Architect para o banco de dados DB2.

De Modelo de Dados Lógicos para Modelo de Dados Físicos com o InfoSphere Data Architect

O InfoSphere Data Architect (anteriormente conhecido como Rational Data Architect) é um modelador visual de dados. Este exemplo usa a Versão 7.5.2.

  1. Inicie o InfoSphere Data Architect.
  2. Copie o arquivo domain.ldm no Rational Software Architect.
  3. Cole o seu arquivo LDM em um projeto de design de dados no InfoSphere Data Architect, como mostra a Figura 21.
    Figura 21. Importar o Modelo de Dados Lógicos
    Importar o Modelo de Dados Lógicos
  4. Clique com o botão direito do mouse no modelo importado e selecione Transform to Physical Data Model.
  5. Analise as opções. Altere o separador da Tabela de Junção para um sublinhado ("_") e altere o nome do esquema de banco de dados.
  6. Clique em Finish.
    Figura 22. Transformar em um Modelo de Dados Físicos
    Transformar em um Modelo de Dados Físicos
    Transformar em um Modelo de Dados Físicos
  7. Analise as tabelas do seu Modelo Físico de Dados. As chaves ID e ID1 da Tabela de junção APPLICATION_APPLICATION não são descritivas o suficiente. De acordo com as funções da Autorreferência do aplicativo (consulte a Figura 12. Funções do Relacionamento e Multiplicidade), altere as chaves conforme é mostrado na Figura 23 de
    • ID para MANAGER_ID
    • ID1 para MANAGED_ID
    Figura 23. Alterar os nomes da chave da tabela de junção
    Alterar os nomes da chave da tabela de junção
    Alterar os nomes da chave da tabela de junção
  8. Gere a DDL (clique com o botão direito do mouse e selecione Generate DDL como mostra a Figura 24) e, em seguida, selecione Run SQL no script de resultado em uma conexão do banco de dados.
    Figura 24. Gerar a DDL e Executar o SQL
    Gerar a DDL e Executar o SQL
    Gerar a DDL e Executar o SQL

Agora, as tabelas foram criadas e é possível continuar gerando o projeto da Web do Spring. Será necessário preencher as tabelas do banco de dados com o aplicativo de CRUD que será criado na próxima etapa. Como alternativa, é possível usar os scripts DDL da seção Download.

Transformar em DSL Spring do Skyway

Você criou modelos estereotipados Spring e LDM e as tabelas das entidades. Agora, use a transformação de DSL do Skyway para transformar o projeto UML em um projeto da Web dinâmico em Java que seja habilitado para Spring e que contém todas as classes anotadas e arquivos de configuração apropriados do Spring. É necessário um projeto do Skyway para transformar o modelo de aplicativo UML.

  1. No assistente do Projeto, clique duas vezes em Skyway project. Chame o projeto de ApplicationManagement, como mostra a Figura 25.
    Figura 25. Criar um projeto do Skyway
    Criar um projeto do Skyway
  2. O projeto do Skyway gera o esqueleto de um projeto da Web dinâmico em Spring (ApplicationManagement-Web) e um archive corporativo, ou um projeto EAR (ApplicationManagement-EAR). O modelo de DSL Spring do Skyway e o aplicativo da Web são estritamente separados, como é mostrado na Figura 26. O código gerado e o código manual são separados fisicamente um do outro. Isso segue as melhores práticas de MDSD.
    Figura 26. Um Projeto vazio do Skyway
    Um Projeto vazio do Skyway
    Um Projeto vazio do Skyway
  3. Agora, é necessário criar a Configuração de Transformação. Comece seguindo o que é descrito em Transformação de UML em Modelo de Dados Lógicos, mas selecione a Transformação UML to Java Spring em Java Transformations, como mostra a Figura 27. A origem da transformação é o modelo UML, enquanto o destino é o projeto da Web dinâmico ApplicationManagement-Web.
    Figura 27. Criar Transformação de UML em Spring Java
    Criar Transformação de UML em Spring Java
    Criar Transformação de UML em Spring Java
  4. A execução da transformação preenche a pasta Spring DSL do projeto do Skyway com os objetos de domínio do modelo UML. Ao mesmo tempo, o projeto do Skyway cria as classes Java na pasta generated do projeto da Web.
    Figura 28. O Modelo de DSL Spring gerado
    O Modelo de DSL Spring gerado
    O Modelo de DSL Spring gerado

Armação CRUD

A armação CRUD do Skyway permite gerar a funcionalidade Create, Read, Update and Delete a partir de um objeto de domínio existente do Skyway.

  1. Para cada objeto de domínio, inicie a Geração do CRUD: Clique com o botão direito do mouse e selecione Scaffolding > Generate CRUD, como se vê na Figura 29.
    Figura 29. Armar suas entidades
    Figura 29. Armar suas entidades
    Figura 29. Armar suas entidades
  2. O mecanismo gera pacotes para cada camada (DAO, serviço e Web). O Objeto de Acesso aos Dados obteve diversos métodos de localizador para consultar o banco de dados. Neste ponto, a origem de dados deve ser configurada para resolver os erros (mostrados na Figura 30) relativos às conexões com o banco de dados (é necessário especificar uma conexão).
    Figura 30. Resultado da armação
    Resultado da armação
    Resultado da armação
  3. Para configurar a conexão, clique duas vezes no DAO e selecione a guia Database Configuration. Lá, é possível selecionar uma origem de dados, que pode ser criada na perspectiva Database Development. Dê uma olhada na atividade Import Types mostrada na Figura 31. Seguindo uma abordagem de desenvolvimento diferente, é possível criar seus objetos de domínio simplesmente fazendo engenharia reversa do banco de dados.
    Figura 31. Configurar o DAO
    Configurar o DAO
    Configurar o DAO
  4. Agora, vamos ver nas anotações JPA (Java Persistence API) da sua classe de domínio Java Application. Você não está usando o recurso de criação automática de tabelas porque nesta abordagem de desenvolvimento as tabelas já estão funcionando. Certifique-se de que as colunas das relações (Colunas de junção) estão mapeadas corretamente. Por isso, é necessário definir a anotação Joincolumn. A Coluna de Junção da relação jmxconnection é JMXCONNECTIONID, como é mostrado na Listagem 1.
    Listagem 1. Referência Jmxconnection gerada da classe Application
    @OneToOne(cascade = {
    CascadeType.PERSIST,
    CascadeType.MERGE,
    CascadeType.REFRESH,
    CascadeType.REMOVE }, fetch = FetchType.LAZY)
    @XmlElement(name = "", namespace = "")
    private Jmxconnection jmxconnection;

    Para fornecer essas informações, faça o seguinte no projeto do Skyway, como mostra a Figura 32:
    1. clique duas vezes no Objeto de Domínio Application, no Modelo do Skyway, para alterar o Mapeamento de Persistência.
    2. Altere o campo Map as para ONE_TO_ONE.
    3. Altere a opção Join Table para Application
    4. Em Join Column, adicione jmxconnectionid.
    A Listagem 2 mostra o código após essas alterações.
    Figura 32. Mapeamento da Coluna de Junção
    Mapeamento da Coluna de Junção
    Mapeamento da Coluna de Junção
    Listagem 2. A referência Jmxconnection gerada após a alteração do mapeamento de persistência
    @OneToOne(cascade = {
    CascadeType.PERSIST,
    CascadeType.MERGE,
    CascadeType.REFRESH,
    CascadeType.REMOVE }, fetch = FetchType.LAZY)
    @JoinColumns( { @JoinColumn(name = "jmxconnectionid") })
    @XmlElement(name = "", namespace = "")
    private Jmxconnection jmxconnection;

Como foi dito anteriormente, fazer isso para todas as relações é um trabalho repetitivo e entediante. Por isso, agora você aprenderá como é possível evitar isso e verá como é fácil customizar a geração das suas entidades.

Customizar Modelos do Skyway

A geração do código é baseada em modelos JET. Para ajustar ou alterar a geração de código, é possível criar um projeto de Modelo do Skyway (consulte a Figura 25. Criar um projeto do Skyway) e modificar os modelos. Aqui, altere o modelo DataType.jet para modificar a informação Join a fim de satisfazer às convenções corporativas. A Listagem 3 mostra o modelo antes de quaisquer alterações.

  1. O Modelo JET das classes DomainObject é ApplicationManagement-Templates\templates\com.skyway.integration.data.xml\templates\DataType.jet.
    Listagem 3. Alterando o modelo JET (antes)
    line 01: <c:iterate select="$model/relationships" var="relationship">
    line 02: 
    line 03:   <persistence:relationshipType select="$relationship" />
    line 04: 
    line 05:   <persistence:joinColumns select="$relationship" />
    line 06: 
    line 07:   <persistence:joinTable select="$relationship" />
    line 08: 
    line 09:   <jaxb:xmlElement select="$relationship" dataType="$model" />
    line 10:   private <sw:declareClassVariable select="$relationship"><java:import>
                 <java:import><sw:javaType select="$relationship" package="true"/>
                 </java:import></sw:declareClassVariable>
    line 11: </c:iterate>
  2. Altere a parte em que está ocorrendo a iteração nas referências do modelo. Por exemplo, se você tiver uma cardinalidade de ONE, faça a Anotação da Coluna de Junção, use o nome do relacionamento e o id anexo (consulte a linha de código 10 na Listagem 4, que mostra o modelo após a modificação).
    Listagem 4. Alterando o modelo JET (depois)
    line 01: <c:iterate select="$model/relationships" var="relationship">
    line 02:   <sw:relationshipCardinality select="$relationship" var="cardinality" />
    line 03: 
    line 04:   <persistence:relationshipType select="$relationship" />
    line 05: 
    line 06:   <c:if test="$cardinality = 'MANY'" >
    line 07:     @JoinTable(name = "<sw:javaType select="$model" package="false"/>_
                 <sw:javaType select="$relationship/targetDataType"/>")
    line 08:   </c:if>
    line 09:   <c:if test="$cardinality = 'ONE'" >
    line 10:     @JoinColumns( { @JoinColumn(name = "
                   <sw:getVariableName select="$relationship" capitalize="false"/>id") })
    line 11:   </c:if>
    line 12:   
    line 13:   <jaxb:xmlElement select="$relationship" dataType="$model" />
    line 14:   private <sw:declareClassVariable select="$relationship"><java:import>
                 <java:import><sw:javaType select="$relationship" package="true"/>
                 </java:import></sw:declareClassVariable>
    line 15: </c:iterate>
  3. Para o exemplo dado, você obtém @JoinColumns( { @JoinColumn(name = "jmxconnectionid") }) após a geração, conforme mostra a Listagem 5.
    Listagem 5. Referência Jmxconnection gerada após alteração do modelo JET
    @OneToOne(cascade = {
      CascadeType.PERSIST,
      CascadeType.MERGE,
      CascadeType.REFRESH }, fetch = FetchType.LAZY)
    @JoinColumns( { @JoinColumn(name = "jmxconnectionid") })
    @XmlElement(name = "", namespace = "")
    private Jmxconnection jmxconnection;
  4. Para forçar uma nova geração, exclua as classes afetadas (neste exemplo, exclua o pacote ApplicationManagement-Web\generated\com\ibm\de\eas\application\management\domain") e remova todos os projetos (Selecione Project > clean). Está curioso para ver se isso funciona? Experimente para Implementar e Testar o Aplicativo de CRUD

Implementar e Testar o aplicativo de CRUD

Implementando em Apache Tomcat

Se você estiver realizando a implementação em Apache Tomcat a partir do IBM Rational Software Architect para o IBM® WebSphere®, será necessário gerenciar o caminho de construção manualmente. Consulte a seção Recursos para obter mais informações sobre o gerenciamento do caminho de construção no Eclipse.

Testar o aplicativo

Inicie o servidor e digite http://localhost:8080/ApplicationManagement-Web/indexApplication.html no seu navegador. Você verá uma tabela de todos os aplicativos registrados. Clique no link da coluna Id (como mostra a Figura 33) e você verá os detalhes do aplicativo selecionado.

Figura 33. Página de Visão Geral do Aplicativo
Página de Visão Geral do Aplicativo
Página de Visão Geral do Aplicativo

Integrar o código herdado do Spring

Agora, você sabe como criar um aplicativo da Web do Spring MVC totalmente funcional a partir de um Modelo UML usando apenas alguns cliques. Ao ajustar os modelos de Geração de Código, você dispõe de uma grande flexibilidade (por exemplo, para atender às convenções que podem haver em um ambiente corporativo). Em seguida, você aprenderá como é fácil incorporar o código Java existente ao aplicativo. O Skyway oferece dois ganchos para isso.

Os ganchos

  1. Gancho 1: A pasta resources do aplicativo da Web contém configurações do Spring para essa finalidade. Basta adicionar seu código como um bean Spring a esses arquivos que não estão marcados como gerados, conforme mostra a Figura 34.
    Figura 34. Adicionar beans Spring codificados manualmente
    Adicionar beans Spring codificados manualmente
    Adicionar beans Spring codificados manualmente
  2. Gancho 2: Clique duas vezes na pasta Spring Dsl do projeto do Skyway, vá para a guia Spring configuration e registre seu arquivo de configuração Spring na camada Web ou Service, como mostra a Figura 35.
    Figura 35. Registrar seu próprio arquivo de configuração Spring no modelo do Skyway
    Registrar seu próprio arquivo de configuração Spring no modelo do Skyway
    Registrar seu próprio arquivo de configuração Spring no modelo do Skyway

Adicionando o código existente

Para o exemplo JMX, use o segundo gancho e registre o arquivo ApplicationManagement-jmx-context.xml mostrado na Listagem 6. Esse arquivo contém um pouco da mágica do Spring. O bean codificado manualmente com.ibm.de.eas.application.management.jmx.Administrator é exposto como um MBean JMX e é acessível para consoles de Administração, como o JConsole ou, é claro, a Ferramenta de Gerenciamento de Aplicativos. Coloque nosso código manual (consulte as listagens a seguir, de 6 a 10) na pasta src do projeto da Web (consulte a Figura 26. Um projeto vazio do Skyway).

Listagem 6. Arquivo ApplicationManagement-jmx-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-2.5.xsd
      http://www.springframework.org/schema/jee
      http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">
                   	
      <!-- my administration mbean -->
      <bean id="admin" class="com.ibm.de.eas.application.management.jmx.Administrator"/>
	
      <bean id="jmxAttributeSource"
        class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

       <!-- will create management interface using annotation metadata -->
       <bean id="assembler"
        class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
        <property name="attributeSource" ref="jmxAttributeSource"/>
       </bean>

       <!-- will pick up the ObjectName from the annotation -->
       <bean id="namingStrategy"
         class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
         <property name="attributeSource" ref="jmxAttributeSource"/>
       </bean>
		
       <bean id="AdministratorExporter" 
          class="org.springframework.jmx.export.MBeanExporter">
        <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>
	<property name="exposeManagedResourceClassLoader" value="true"/>
	<property name="beans">
	  <map>
            <entry key="ApplicationManagement-Web:name=Administrator" value-ref="admin"/>
	  </map>
	</property>
	<property name="assembler" ref="assembler"/>
        <property name="namingStrategy" ref="namingStrategy"/>
        <property name="autodetect" value="true"/>
       </bean>	
</beans>

A classe Administrator demonstra dois showcases:

  • O atributo value pode ser lido e gravado a partir de um aplicativo remoto (como o JConsole) por meio dos métodos expostos readValue e writeValue.
  • O bean é um Singleton que lê Objetos do Domínio do Aplicativo do banco de dados usando o ApplicationService que é gerado pelo utilitário de Armação CRUD do Skyway. Para cada instância do Aplicativo, o método getApplicationProxies() cria um proxy JMX. Com a ajuda do proxy, seu aplicativo é capaz de acessar cada Aplicativo Remoto registrado e lê os dados do seu sistema operacional. Evidentemente, é possível registrar um novo aplicativo no aplicativo CRUD gerado pelo Skyway.

O arquivo Administrator.java é mostrado na Listagem 7.

Listagem 7. Arquivo ApplicationManagement-Web/src/com/ibm/de/eas/application/management/jmx/Administrator.java
package com.ibm.de.eas.application.management.jmx;

import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
import org.springframework.jmx.export.annotation.ManagedResource;

import com.ibm.de.eas.application.management.domain.Application;
import com.ibm.de.eas.application.management.service.ApplicationService;

/**
 * 
 * Example of a Bean which is exposed by Spring as a MBean 
 * The attribute value can be changed by a JMX Administration Console
 *
 */
@ManagedResource(objectName = "ApplicationManagement-Web:name=Administrator", 
		description = "JMX Administration")
public class Administrator implements BeanFactoryAware {

	private static Logger logger = Logger.getLogger(Administrator.class);

	private transient Set<ApplicationProxy> applicationProxies = null;

	/**
	 * This Service is generated with Skyways CRUD Scaffolding
	 * The Bean is automatically wired by Spring´s Dependency Injection
	 */
	@Autowired
	private transient ApplicationService applicationService;

	private String value = "default";

	/**
	 * reads Application data from the database and returns JMX Proxies for each
	 * registered application
	 * 
	 * @return Set<ApplicationProxy>
	 * @throws Exception
	 */
	public Set<ApplicationProxy> getApplicationProxies() throws Exception {
		if (applicationProxies == null)
			applicationProxies = new HashSet<ApplicationProxy>(1);

		if (applicationProxies.size() == 0) {
			Set<Application> applications;
			// read the registered Applications from the database ...
			applications = applicationService.loadApplications();

			for (Application application : applications) {
                           // ... and create JMX Proxies for each application
                           applicationProxies.add(new ApplicationProxyImpl(application));
			}
		}
		return applicationProxies;
	}

	public String getValue() {
		return value;
	}

	/**
	 * Test Method, this is accessible via JMX 
	 * @return String value
	 */
	@ManagedOperation(description = "readValue")
	public String readValue() {
		logger.debug("get value " + value);
		return value;
	}

	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(
	 *      org.springframework.beans.factory.BeanFactory)
	 */
	@Override
	public void setBeanFactory(BeanFactory bf) throws BeansException {
		// make the Spring Context accessible for each application in this jvm
		// not usable for production environments, 
		//  concurrent applications would overwrite their reference
		AppContext.set(bf);
	}

	
	public void setValue(String value) {
		this.value = value;
	}

	/**
	 * This Method is accessible from a JMX Administration Console
	 * 
	 * @param value
	 * @return the value changed
	 */
	@ManagedOperation(description = "writeValue")
	@ManagedOperationParameters( { @ManagedOperationParameter(name = "value", 
			description = "value") })
	public String writeValue(String value) {
		this.value = value;
		logger.debug("value " + value + " set");
		return "value " + value + " set";
	}
}

A Listagem 8 mostra a interface para recuperar dados de um aplicativo remoto. Use esses métodos para visualizar os dados em uma tabela exibida por uma página JSP.

Listagem 8. A interface ApplicationProxy
package com.ibm.de.eas.application.management.jmx;

import java.lang.management.OperatingSystemMXBean;

import com.ibm.de.eas.application.management.domain.Application;

/**
 * JMX Proxy Interface Example.
 * 
 * access the OperatingSystemMXBean of a remote application to read
 * some data like heap size, etc.
 * 
 */
public interface ApplicationProxy {
	public abstract OperatingSystemMXBean getOperatingSystem();
	public abstract String getUrl();
	public abstract String getServerUrl();
	public Application getApplication();
}

O código na Listagem 9 é uma solução simplificada para fins de demonstração. As origens não estão prontas para produção. Para obter maiores explicações, consulte a referência da Estrutura Spring. Uma explicação muito detalhada fugiria do escopo deste artigo.

Listagem 9. A implementação de ApplicationProxy
package com.ibm.de.eas.application.management.jmx;

import java.io.Serializable;
import java.lang.management.OperatingSystemMXBean;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.management.MBeanServerConnection;

import org.apache.log4j.Logger;
import org.springframework.jmx.support.MBeanServerConnectionFactoryBean;

import com.ibm.de.eas.application.management.domain.Application;

/**
 * Only for demonstration purposes !
 * 
 * This class creates a JMX Proxy of a given Application Domain Object
 * Internally it creates a MBeanServerConnection and registers itself and
 * the Remote OperatingSystemMXBean of the Application
 */
final public class ApplicationProxyImpl implements ApplicationProxy {

 /**
  * wraps the jmx url for a given application
  */
 final class JmxConnection implements Serializable {
  
  private static final long serialVersionUID = 6234025617250549332L;
  private Application application = null;
  private Integer namingPort;
  private Integer port;
  private String serverUrl;

  public JmxConnection(Application application) {
   super();
   this.port = application.getJmxconnection().getPort();
   this.namingPort = application.getJmxconnection().getNamingPort();
   this.application = application;
   createUrl();
  }

  private void createUrl() {
   String hostName = application.getContainer().getHost().getName();
   String appName = application.getWebappName();
   if (namingPort == null || namingPort == 0) {
    serverUrl = "service:jmx:rmi:///jndi/rmi://" + hostName + ":"
      + port + "/jmxrmi";
   } else {
    serverUrl = "service:jmx:rmi://" + hostName + ":" + namingPort
      + "/jndi/rmi://" + hostName + ":" + port + "/"
      + appName;
   }
  }

  public Integer getPort() {
   return port;
  }

  public String getServerUrl() {
   return serverUrl;
  }

  @Override
  public String toString() {
   return getServerUrl();
  }
 }

 private static Logger logger = Logger.getLogger(ApplicationProxyImpl.class);
 private static final String OPS = "ops";
 private Application application = null;
 /**
  * Spring ID MBeanServer
  */
 private String idMBeanServer = null;
 private JmxConnection jmxConnection = null;
 private Map<String, Object> proxies = new HashMap<String, Object>();
 private String url = null;

 public ApplicationProxyImpl(Application application) {
  super();
  this.application = application;
  String host = application.getContainer().getHost().getName();
  String app = application.getName();
  idMBeanServer = host + app;
  url = "http://" + host + ":" + application.getPort() + "/"
    + application.getWebappName();
  jmxConnection = new JmxConnection(application);
 }

 private void createMBeanServerConnection() {
  try {
   if (jmxConnection != null) {
    String surl = jmxConnection.getServerUrl();
    Properties p = new Properties();
    p.put("serviceUrl", surl);
    MBeanServerConnection conn = (MBeanServerConnection) AppContext
      .registerBean(idMBeanServer,
        MBeanServerConnectionFactoryBean.class, p);
    logger.info("JMX MBean Server registered to " + idMBeanServer
      + " with " + surl);
    registerProxies(conn);
   }
  } catch (Exception e) {
   logger.error(e.getMessage(), e);
  }
 }

 public Application getApplication() {
  return application;
 }

 /*
  * (non-Javadoc)
  * 
  * @see com.ibm.de.eas.application.management.jmx.ApplicationProxy#
  * getOperatingSystemMBean()
  */
 public OperatingSystemMXBean getOperatingSystem() {
  // create MBean and
  // register ops to spring container
  return (OperatingSystemMXBean) getProxies().get(OPS);
 }

 private Map<String, Object> getProxies() {
  if (proxies.size() == 0) {
   try {
    createMBeanServerConnection();

   } catch (Exception e) {
    logger.warn("Problem with JMX Connection: " + e.getMessage());
    proxies.clear();
   }
  }
  return proxies;
 }

 public String getServerUrl() {
  return jmxConnection.toString();
 }

 public String getUrl() {
  return url;
 }

 /**
  * register MBean Proxy to the Spring DI-Container
  */
 private void registerProxies(MBeanServerConnection mbeanServerConnection) {
  String id = OPS;
  Object proxy = AppContext.registerMBean(id + idMBeanServer,
    "java.lang:type=OperatingSystem", OperatingSystemMXBean.class,
    mbeanServerConnection);
  proxies.put(id, proxy);
 }
}

A Listagem 10 mostra a classe de registro helper do Spring.

Listagem 10. A classe de registro helper do Spring
package com.ibm.de.eas.application.management.jmx;

import java.util.Enumeration;
import java.util.Properties;

import javax.management.MBeanServerConnection;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.jmx.access.MBeanProxyFactoryBean;

public class AppContext {
   static BeanFactory beanFactory = null;
   private static Logger logger = Logger.getLogger(AppContext.class);

   public static BeanFactory get() {
      return beanFactory;
   }

   public static void set(BeanFactory bf) {
      beanFactory = bf;
   }

   /**
    * This method uses Spring to register and create MBeans dynamically
    * 
    * @param id - Spring Context id
    * @param objectname - the name of the MBean
    * @param proxyInterface - the interface of the MBean
    * @param mbeanServerConnection - the connection to access the MBean
    * @return - the instance of the MBean
    */
   @SuppressWarnings("unchecked")
   public static Object registerMBean(String id, String objectname,
         Class proxyInterface, MBeanServerConnection mbeanServerConnection) {
      try {
         
         Properties props = new Properties();
         props.put("objectName", objectname);
         props.put("proxyInterface", proxyInterface);
         props.put("server", mbeanServerConnection);
         
         
         registerBean(id, MBeanProxyFactoryBean.class, props);
         
         return AppContext.get().getBean(id);

      } catch (Throwable t) {
         logger.warn("Error creating the MBean Proxy " + objectname
               + ": " + t.getMessage(), t);
      }
      return null;
   }

   /**
    * 
    * Registers a bean to the Spring Context at runtime
    * 
    * @param id - Spring Context id
    * @param clazz - Class to register to Spring
    * @param props - Properties to set to the Instance of clazz
    * @return
    */
   @SuppressWarnings("unchecked")
   public static Object registerBean(String id, Class clazz, Properties props) {

      BeanDefinitionBuilder builder = BeanDefinitionBuilder
            .rootBeanDefinition(clazz);

      Enumeration<Object> keys = props.keys();
      while (keys.hasMoreElements()) {
         Object k = (Object) keys.nextElement();
         builder.addPropertyValue(k.toString(), props.get(k));
      }

      ((BeanDefinitionRegistry) AppContext.get()).registerBeanDefinition(id,
            builder.getBeanDefinition());
      
      return get().getBean(id);
   }

}

Estender o aplicativo com um fluxo da Web

Agora que a sua infraestrutura JMX está pronta para ser executada, finalmente é necessário criar uma visualização para ver os dados em seus aplicativos gerenciados. Você usará o editor visual do Skyway para Spring Web Flow (SWF) a fim de criar um simples fluxo do usuário do Detalhe Principal. O SWF é usado para modelar interações do usuário que ocorrem em diversas solicitações.

Criar o fluxo

  1. Primeiro, crie um pacote de modelos no projeto do Skyway e, em seguida, crie um fluxo da Web usando o assistente Web Flow (clique com o botão direito do mouse e selecione New > Web Flow), como mostra a Figura 36.
  2. Dê o nome admin ao fluxo da Web.
  3. O assistente Web Flow pedirá um local onde arquivar o modelo do SWF (admin.xml, o arquivo de configuração Spring para fluxos da Web). Salve-o em ApplicationManagement-Web\WebContent\WEB-INF\flows.
    Figura 36. Criar um Fluxo da Web do Spring
    Criar um Fluxo da Web do Spring
    Criar um Fluxo da Web do Spring
  4. Em seguida, construa seu fluxo da Web simplesmente arrastando States e Transitions para a tela.
    1. Defina o bean auxiliar como uma variável do fluxo da Web.
      • Pressione o sinal de mais ("+") no Flow configuration element
      • Insira o nome da variável (adminView)
      • Insira o nome da sua classe de Visualização (com.ibm.de.eas.application.management.flow.admin.Admin)
      Agora, o bean de Visualização com.ibm.de.eas.application.management.flow.admin.Admin pode ser acessado de uma página JSP, ou do fluxo da Web com a expressão adminView.
    2. Prepare a primeira parte do fluxo da Web para testá-la.
      • Arraste um View state e dê o nome de admin.
      • Vincule Flow configuration element a View state usando transition.
      • Dê o nome admin à transição.
      Agora, a primeira parte do fluxo da Web está pronta para ser testada. Se ocorrer um evento admin (clique em uma URL ou em um botão), o fluxo da Web admin entrará no estado de visualização admin. Uma vez que você não especificou nenhuma página para esse estado de visualização, por convenção admin.jsp será exibido ao usuário.
    3. Faça o mesmo com outro estado de visualização.
      • Arraste outro View state e dê o nome de viewOperatingSystemDetail.
      • Vincule Flow configuration element a View State viewOperatingSystemDetail usando transition.
      • Dê o nome de showOperatingSystemDetail à transição.
      Se ocorrer um evento showOperatingSystemDetail (clique em uma URL ou em um botão), o fluxo da Web admin entrará no estado de Visualização viewOperatingSystemDetail. Uma vez que você não especificou nenhuma página para esse estado de Visualização, por convenção viewOperatingSystemDetail.jsp será exibido ao usuário.
    4. Para voltar ao estado de Visualização de administração:
      • Defina um End state e dê um nome a ele (por exemplo, goBack).
      • Vincule o estado de Visualização ao estado Final usando uma transição.
      • Dê um nome à Transição (por exemplo, goBack).
      Os resultados são mostrados na Figura 37
    Figura 37. Criar um fluxo da Web do Spring
    Criar um fluxo da Web do Spring
    Criar um fluxo da Web do Spring

    Agora, é possível ver o código resultante da modelagem visual. O Skyway gerou o admin.xml mostrado na Listagem 11, um JSP para o View state de administração e um JSP para o segundo View state.

    Listagem 11. Modelo admin.xml do Fluxo da Web do Spring
    <?xml version="1.0" encoding="UTF-8"?>
    <flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns="http://www.springframework.org/schema/webflow" 
        xsi:schemaLocation="http://www.springframework.org/schema/webflow 
        http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
      
      <var class="com.ibm.de.eas.application.management.flow.admin.Admin" 
                name="adminView"/>
      <view-state id="admin"/>
      <view-state id="viewOperatingSystemDetail">
        <transition on="goBack" to="goBack"/>
      </view-state>
      <end-state id="goBack"/>
      <global-transitions>
        <transition on="admin" to="admin"/>
        <transition on="showOperatingSystemDetail" to="viewOperatingSystemDetail"/>
      </global-transitions>
    </flow>
  5. Agora, crie manualmente a classe de visualização que é definida pelo fluxo e referenciada por uma página JSP. Acessando o método getRemote(), a página JSP pode apresentar os dados operacionais de cada aplicativo persistido. A referência ao seu MBean de administração é preenchida pela Injeção de Dependência do Spring (anotação @Autowired), como mostra a Listagem 12.
    Listagem 12. Visualizar o Bean com.ibm.de.eas.application.management.flow.admin.Admin
    package com.ibm.de.eas.application.management.flow.admin;
    
    import java.io.Serializable;
    import java.util.Set;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    
    import com.ibm.de.eas.application.management.jmx.Administrator;
    import com.ibm.de.eas.application.management.jmx.ApplicationProxy;
    
    public class Admin implements Serializable {
       
       /**
        * 
        */
       private static final long serialVersionUID = -486243002544361404L;
       
       @Autowired
       @Qualifier("admin")
       private transient Administrator administrator;
       
       public String getValue(){
          return administrator.getValue();
       }
       
       public void setValue(String value){
          administrator.setValue(value);
       }
          
       public Set<ApplicationProxy> getRemote() throws Exception {
          return administrator.getApplicationProxies();
       }   
    }
  6. Conforme foi definido anteriormente, é possível acessar a classe de visualização na página JSP com adminView. Para acessar atributos (ou métodos), use expressões como ${adminView.value}. Nas Versões 2.0 e posteriores da especificação JSP, a linguagem da expressão é incorporada. A expressão provoca uma chamada do método getValue(). Para iterar o resultado do método getRemote(), use uma variável de iteração (por exemplo, current), que é do tipo ApplicationProxy. Para acessar atributos de relações de ApplicationProxy, use expressões como ${current.application.name}. Veja a seguir o botão para inserir a transição na visualização detalhada: <input type="submit" name="_eventId_showOperatingSystemDetail" value="Details"/>. showOperatingSystemDetail é a transição que você modelou para inserir o estado de visualização viewOperatingSystemDetail. A Listagem 13 mostra esses pontos.
    Listagem 13. Aprimorar o admin.jsp
    <%@ page language="java" isELIgnored="false" 
          contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <jsp:directive.include file="/WEB-INF/sitemesh-decorators/include.jsp"/>
    <html>
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
     <title>Administration</title>
     <skyway:javascript src="prototype.js"></skyway:javascript>
     <skyway:javascript src="skyway.js"></skyway:javascript>
     <skyway:javascript src="skyway-internal.js"></skyway:javascript>
    </head>
    <body>
    <skyway:form action="${flowExecutionUrl}" commandName="">
    <skyway:label value="${adminView.value}"></skyway:label>
    <br><br>
        <table id="applicationTable">
            <thead>
            <tr>
                <th>ID</th>
                <th>Application</th>
                <th>Console Url</th>
                <th>Jmx Url</th>            
            </tr>
            </thead>
            <tbody>
        <c:forEach items="${adminView.remote}" var="current" varStatus="i">
            <c:choose>
                <c:when test="${(i.count) % 2 == 0}">
                    <c:set var="rowclass" value="tableRow1"/>
                </c:when>
                <c:otherwise>
                    <c:set var="rowclass" value="tableRow2"/>
                </c:otherwise>
            </c:choose>            
            <tr class="${rowclass}">                        
                <td>${current.application.id}</td>
                <td>${current.application.name}</td>
                <td>${current.url}</td>            
                <td>${current.serverUrl}</td>            
            </tr>
        </c:forEach>
            </tbody>
        </table>
    <input type="submit" name="_eventId_showOperatingSystemDetail" value="Details" />
    </skyway:form>
    </body>
    </html>
  7. Para mostrar os detalhes, como mostra a Listagem 14, use a classe de visualização conforme descrito anteriormente, mas acesse os métodos OperatingSystem e MBean: ${current.operatingSystem.systemLoadAverage}.
    Listagem 14. Aprimorar viewOperatingSystemDetail.jsp
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
    pageEncoding="ISO-8859-1"%>
    <jsp:directive.include file="/WEB-INF/sitemesh-decorators/include.jsp"/>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
        "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Operating System Details</title>
    </head>
    <body>
    <skyway:form action="${flowExecutionUrl}" commandName="">
    <skyway:label value="Operating System Details"></skyway:label><br><br>
        <table id="opsTable">
            <thead>
            <tr>            
                <th>Application</th>
                <th>Name</th>
                <th>Version</th>            
                <th>AvailProc</th>
                <th>Load</th>
                <th>Arch</th>
            </tr>
            </thead>
            <tbody>
        <c:forEach items="${adminView.remote}" var="current" varStatus="i">
            <c:choose>
                <c:when test="${(i.count) % 2 == 0}">
                    <c:set var="rowclass" value="tableRow1"/>
                </c:when>
                <c:otherwise>
                    <c:set var="rowclass" value="tableRow2"/>
                </c:otherwise>
            </c:choose>            
            <tr class="${rowclass}">
                <td>${current.application.id}:${current.application.name}</td>
                <td>${current.operatingSystem.name}</td>
                <td>${current.operatingSystem.version}</td>
                <td>${current.operatingSystem.availableProcessors}</td>
                <td>${current.operatingSystem.systemLoadAverage}</td>
                <td>${current.operatingSystem.arch}</td>
            </tr>
        </c:forEach>
            </tbody>
        </table>
        <input type="submit" name="_eventId_goBack" value="Back" />
    </skyway:form>
    </body>
    </html>

Testar o fluxo

Abra a configuração inicial do seu servidor e configure o servidor Mbean JMX da parte codificada manualmente. Adicione o código mostrado na Listagem 15:

Listagem 15. Parâmetro JVM para ativar o JMX
 -Dcom.sun.management.jmxremote.port=9001
                -Dcom.sun.management.jmxremote.authenticate=false
                -Dcom.sun.management.jmxremote.ssl=false

Inicie o servidor e insira http://localhost:8080/ApplicationManagement-Web/admin. O admin na URL é a transição que você modelou antes. Com essa URL, o SWF de administração é iniciado e exibe o admin.jsp, como mostra a Figura 38.

Figura 38. A visualização de Administração
A visualização de Administração
A visualização de Administração

Quando você clica no botão Details, o estado de visualização viewOperatingSystemDetail é inserido e o JSP correspondente é apresentado ao usuário, como mostra a Figura 39.

Figura 39. A visualização do Sistema Operacional
A visualização do Sistema Operacional
A visualização do Sistema Operacional

O que você aprendeu

Neste artigo, você aprendeu como gerar um aplicativo Spring totalmente funcional baseado em transformações do modelo. Você transformou um modelo de aplicativo em um modelo de dados lógicos para finalmente criar as tabelas de banco de dados. Em seguida, em apenas alguns minutos, você transformou o modelo de aplicativo na DSL Spring para armar o aplicativo da Web baseado em Spring. Você viu a alteração dos mapeamentos da tabela de Entidades JPA com o editor visual do Skyway para os tipos de dados. Você aprendeu como fazer o mesmo alterando o modelo de geração de código JET. Em seguida, aprendeu sobre a separação entre o código de origem criado manualmente e o código de origem gerado, e sobre como adicionar o código manual ao projeto. Finalmente, você usou o Visual Builder para fluxo da Web do Spring para modelar uma interação do usuário que referencia o código herdado.

O conjunto de ferramentas Rational Software Architect, InfoSphere Data Architect e Skyway é uma ajuda significativa para acelerar e simplificar o processo de entrega do software. Ele concentra sua atenção no modelo e minimiza o tempo dedicado aos detalhes de implementação. A economia de tempo, especialmente no caso de aplicativos grandes, é enorme. Se você for um usuário iniciante de Java e Spring, obtenha um aplicativo da Web baseado em Spring sólido e bem projetado que seja fácil de estender. Os erros de design são facilmente evitados e você acelera seu aprendizado sobre o desenvolvimento de aplicativos Spring. Devido à base Eclipse EMF, é possível até mesmo estender o modelo de DSL Spring para atender às suas necessidades mais sofisticadas.

E agora, quando você percorrerá o Skyway?

Agradecimentos

Obrigado ao Dr. Jürgen Herrmann e a Martin Braun pela revisão e comentários deste artigo. Obrigado ao Dr. Klaus Schlöter e à equipe SDC pelo seu valioso feedback na sessão de produção do Skyway.


Recursos para download


Temas relacionados


Comentários

Acesse ou registre-se para adicionar e acompanhar os comentários.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Rational, Tecnologia Java
ArticleID=487887
ArticleTitle=Percorra o Skyway: gerando aplicativos Spring com o Rational e o Skyway Builder
publish-date=05062010