Escolar Documentos
Profissional Documentos
Cultura Documentos
br
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
2
TIRANDO O MÁXIMO DO JAVA EE 5 OPEN-SOURCE
Paulo Alvim
Powerlogic Publishing. Rua Paraíba, 330. 19º andar. Funcionários. Belo Horizonte – MG. Brasil.
3
Tirando o Máximo do Java EE 5 Open-Source com jCompany© Developer Suite
Marcas Registradas
Todos os termos mencionados neste livro
conhecidos como marcas registradas ou
comerciais foram adequadamente destacados.
ISBN: 978-85-907848-0-7
4
Sobre o autor
Paulo Alvim graduou-se em Ciência da Computação pela UFMG em 1987. Em 20 anos de experiência no
desenvolvimento de produtos de software corporativos, participou da implantação de quase uma centena
de projetos corporativos, em diversos segmentos de negócio e baseados em tecnologias distintas, de
mainframes a aplicações Web, passando por Cliente/Servidor e Unix.
Iniciou sua carreira trabalhando com ferramentas de geração de código COBOL para mainframe,
projetando em 1989 o repositório da ferramenta CASE ET-SADS, um dos poucos produtos desta categoria
então produzidos no Brasil. A partir daí, especializou-se em tecnologias Orientadas a Objetos e em
Metodologias de Desenvolvimento de Sistemas (MDS), passando a ministrar cursos de Engenharia da
Informação e a prestar consultoria por todo o Brasil, em modelagem de dados semântica, I-CASE e OO.
Após uma breve passagem pela programação orientada a eventos em arquitetura Unix com o ambiente
Ally da Unisys, em 1991, partiu para a Orientação a Objetos aplicada na recém popularizada arquitetura
Cliente/Servidor, tornando-se o primeiro Certified PowerBuilder Developer da América Latina, em 1994.
Neste período, desenvolveu o framework Dr.Object para PowerBuilder e fundou a Powerlogic, passando a
coordenar projetos de missao crítica para desligamentos de mainframes, em ambiente RAD.
A tecnologia Java se estabeleceu como prioritária na Powerlogic a partir de 1998; e Java EE Open-Source
a partir de 2002. Em 2003, Paulo Alvim idealizou o jCompany Developer Suite, concebido para oferecer
uma alternativa de desenvolvimento Java EE Open-Source gerenciável para grandes corporações,
permanecendo como seu principal desenvolvedor até 2005. Com o sucesso do jCompany, a empresa
cresceu para 160 colaboradores em 2007 e se tornou uma das maiores especialistas em softwares Open-
Source do Brasil.
Atualmente, Paulo Alvim comanda uma equipe de aproximadamente 30 profissionais na divisão de
produtos da Powerlogic, desenvolvendo a expansão do jCompany para a suíte de Application Lifecycle
Management “Powerlogic jALM”, utilizando Métodos Ágeis/SCRUM em um ambiente certificado MPS.Br
Nível F.
5
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
6
para quem é este livro
Este livro se destina aos profissionais da área de Desenvolvimento de Software envolvidos com a
tecnologia Java EE e interessados na utilização de produtos e frameworks Open-Source, para
produção de aplicações corporativas. Arquitetos de Software, Engenheiros de Software, Analistas de
Sistemas e Desenvolvedores/Programadores, iniciados em tecnologia Java EE, se beneficiarão da visão
integrada e pragmática que orientam o conteúdo e tutoriais deste livro.
É um livro também destinado ao uso em Entidades de Ensino, para cursos de graduação ou extensão em
TI, com ênfase em tecnologias Java EE Open-Source (veja política acadêmica do fabricante,
incluindo cessão de licenças gratuitas para salas de aula e laboratórios em www.powerlogic.com.br).
Este não é um livro para introdução à linguagem Java e tecnologias Java EE - e nem para
exploração em detalhes de nenhum produto Open-Source específico. Porém, não são esperados
conhecimentos avançados em nenhuma destas áreas.
Profissionais que tenham noções teóricas e um pouco de prática em desenvolvimento Java e para Web
(mesmo que em outras tecnologias, como PHP ou ASP) serão capazes de compreender melhor as
realizações de Caso de Uso descritas, valorizando apropriadamente a produtividade e o uso integrado do
Java EE 5, ferramentas e frameworks Open-Source, providos pelo jCompany Developer Suite.
Eu não possuo o jCompany Developer Suite – ainda assim este livro é útil para mim?
Certamente! Além de aprender com o uso de uma arquitetura de referência, várias das facilidades
descritas no livro trazem “melhores práticas” que podem ser aplicadas à programação Java EE sobre
arquitetura MVC2 para Web, em geral, incluindo padrões de Interfaces com o Usuário, Mapeamento
Objeto-Relacional e programação OO em geral.
Nota do Editor: A Powerlogic lançou recentemente diversas modalidades de suítes que visam facilitar o
acesso de pequenos e médios Desenvolvedores ao jCompany Developer:
o jCompany Developer Professional Suite – Demo & Academic Version: Este livro possui em
anexo um DVD com uma cópia do jCompany Developer Professional Suite – Demo Version.
Para seu uso, basta obter uma licença de demostração com validade de 3 (três) meses em
www.powerlogic.com.br, gratuitamente. Licenças acadêmicas podem ser obtidas mediante acordos
“não burocráticos” com o fabricante Powerlogic, sendo também gratuitas e renováveis
indefinidamente (para uso em laboratórios e salas de aula).
o jCompany Developer Professional Suite – Entry Level Version: Esta modalidade dá acesso a 1
(uma) licença oficial do jCompany Developer Professional Suite a preços acessíveis, para
Pessoas Físicas e Pequenas Empresas.
Importante: Esta versão permite o desenvolvimento de ilimitadas aplicações, para um
desenvolvedor registrado – mas não é fornecida em volume, sendo limitada a “uma licença
por CPF e CNPJ”.
o jCompany Full-Stack Framework – Community Version: Outra alternativa é o uso do
jCompany FS Framework – Community Version, versão gratuita disponibilizada em licença
GPLv3, com previsão de liberação para abril/2008. Esta versão não possui ferramentas de
geração de código, garantias de gerência de configuração e alguns outros módulos discutidos neste
livro mas, através de artigos complementares, pode ser utilizada para ganhos de produtividade
consideráveis.
o jCompany Developer Enterprise Suite: Para grandes negócios, a recomendação é a aquisição
dos modelos corporativos sobre licença POSL 2.0 (Código Aberto Gerenciado) que vêm com um
leque mais abrangente de facilidades, homologação para Application Servers comerciais, controle de
versão avançado, suporte e manutenção empresariais.
7
Convenções
O autor preferiu adotar critérios pragmáticos para convenções do uso de termos em inglês. Devido ao
alto volume de jargão tecnológico encontrado na bibliografia e nas tecnologias de ponta utilizadas (com a
presença de muitos termos que, inclusive, ainda não receberam "batismo" para português), grande
parcela de termos técnicos são mantidos em inglês, sem diferenciação de grafia. Para ajudar
nesta área, um glossário com grande parte destes termos é disponibilizado ao final deste livro.
Os termos em inglês que não sejam do jargão tecnológico são apresentados em itálico.
Foram utilizados quatro elementos de destaque legendados – todos possuem índices remissivos
disponíveis, ao final do livro:
o Figuras. Baseadas em “imagens” para a maior parte das ilustrações de modelos, telas da IDE e das
aplicações nos Navegadores.
o Trechos de Código. Baseados em “caixas de texto” para amostras de códigos maiores, que possam
permitir “corte e colagem” em versões eBook.
o Citações Externas. Citações de autores da referência bibliográfica.
o Esquemas. Diagramas de gestão de leiaute.
Além disso, citações do próprio autor são representadas em itálico, sem aspas e sem legenda.
8
VOLUME I - FUNDAMENTOS
MÓDULO A – APRESENTAÇÃO.
9
Dedicado à minha família - Simone, Matheus (5) e Sophia (2).
Agradeço a todos que tornaram possível este projeto: a Marco Antônio Guapo, editor da revista Mundo
Java, pela idéia inicial; ao meu sócio Helson Queiróz Duarte, pelo crucial apoio; aos amigos da Powerlogic
e aos demais que contribuíram com a revisão, muitos em espírito colaborativo; aos profissionais de TI
que, presentes em três anos de seminário técnico (Road Show) em todo o Brasil, me realimentaram com
idéias e críticas para delinear este livro.
Obrigado a todos, sobretudo, pelas palavras sinceras de apoio e entusiasmo – sem este combustível,
poucas obras seriam concretizadas.
10
Índice analítico
A. Apresentação ......................................................................................................... 19
A1 Introdução ao jCompany Developer Suite...........................................................................21
As oportunidades do eBusiness ................................................................................................. 21
Tirando o máximo do Java EE Open-Source ................................................................................ 22
- “Java EE” como mercado comum e plataforma de flexibilidade .................................................... 22
- “Tirando o máximo do Java EE” para os negócios ...................................................................... 22
- “Open-Source” como estratégia de projetos.............................................................................. 23
O jCompany Developer Suite .................................................................................................... 23
- Uma breve introdução ao jCompany ........................................................................................ 23
- A busca pela “hiper-produtividade”.......................................................................................... 24
- Qualidade para produtividade sustentável ................................................................................ 24
- Produtividade corporativa, em escala industrial ......................................................................... 25
- Por que o jCompany funciona?................................................................................................ 25
jCompany FS Framework ......................................................................................................... 26
- Arquitetura de Software Corporativa........................................................................................ 26
- Framework .......................................................................................................................... 26
- Framework de Integração ...................................................................................................... 26
- Arquitetura de Software com o jCompany FS Framework ............................................................ 26
jCompany IDE ........................................................................................................................ 27
- Ambiente Integrado de Desenvolvimento ................................................................................. 27
jCompany Patterns & Methods .................................................................................................. 29
- Padrões de Solução em Alto Nível ........................................................................................... 29
- Casos de Uso Padrões ........................................................................................................... 29
- Colaborações Padrões ........................................................................................................... 29
- Padrões de Agregações de Entidades ....................................................................................... 30
- Padrões de Interfaces com o Usuário. ...................................................................................... 31
jCompany Test for Developer.................................................................................................... 31
- Testes de Unidade ................................................................................................................ 31
jCompany Configuration Management ........................................................................................ 32
- Gerência de Configuração ...................................................................................................... 32
Open-Source Application Lifecycle Management........................................................................... 33
- jCompany QA Suite ............................................................................................................ 34
- jCompany Production Suite ................................................................................................ 34
- eCompany Portal Suite....................................................................................................... 34
- eCompany Reports............................................................................................................. 35
- eCompany Process Suite .................................................................................................... 35
- Powerlogic jALM: Esquema de Integração................................................................................. 35
Sumário ................................................................................................................................ 37
A2 Instalando o jCompany.......................................................................................................39
Gerência de Configuração em Java EE Open-Source ..................................................................... 39
- Reúso x Geração de Código .................................................................................................... 39
- Reúso x Gerenciamento de Configuração e Controle de Versões................................................... 39
- “Best-of-Breed” x “One-Stop-Shop”......................................................................................... 40
- Atualização Automatizada ...................................................................................................... 41
Instalação do jCompany Developer Suite.................................................................................... 41
- Entendendo as modalidades de licenciamento ........................................................................... 41
- Conferindo os pré-requisitos para instalação ............................................................................. 44
- Efetuando a instalação via DVD (Linux e Windows) .................................................................... 44
- Efetuando a instalação via Download (Cópia de Demonstração) ................................................... 45
Conferindo o que foi instalado................................................................................................... 45
- Organização Geral ................................................................................................................ 45
- Eclipse e Plugins ................................................................................................................... 46
- Projetos jCompany................................................................................................................ 48
- Repositório Maven ................................................................................................................ 50
- Matéria-Prima Open-Source: Códigos Fonte e Javadoc Configurados ............................................ 52
- Servidores de Aplicação ......................................................................................................... 52
- Documentação da Metodologia ............................................................................................... 53
- Produtos para Instalação Adicional .......................................................................................... 53
Sumário ................................................................................................................................ 54
A3 Entendendo o Ambiente de Desenvolvimento .....................................................................55
11
Entendendo a Metodologia de Desenvolvimento
Introdução ............................................................................................................................. 55
- A breve história do mercado de IDEs ....................................................................................... 55
A IDE Eclipse.......................................................................................................................... 56
- Por que o Eclipse?................................................................................................................. 56
- Eclipse x Netbeans................................................................................................................ 56
O Eclipse no jCompany ............................................................................................................ 57
- O Eclipse para desenvolvimento Java EE .................................................................................. 57
- Aprendendo mais sobre o Eclipse ............................................................................................ 58
- Os plugins homologados pelo jCompany................................................................................... 59
- Os plugins próprios do jCompany ............................................................................................ 61
- Metodologia de construção Java EE - Documentação on-line integrada (Tutorial)............................ 62
- Metodologia de construção Java EE - Roteiros “Cheat-Sheets” ..................................................... 64
- Aprendendo com o Exemplo RH Demo (Tutorial) ....................................................................... 65
Criando novos projetos de desenvolvimento................................................................................ 68
- Entendendo as modalidades de projeto .................................................................................... 68
- Criando o projeto JSF “rhtutorial” (Tutorial) .............................................................................. 69
Sumário ................................................................................................................................ 72
A4 Entendendo a Arquitetura de Desenvolvimento ..................................................................73
Introdução ............................................................................................................................. 73
- Reúso de Arquitetura de Software ........................................................................................... 73
Estudo de Evolução de Arquiteturas de Software Java EE. ............................................................. 73
- O que é Arquitetura de Software? ........................................................................................... 73
- Arquitetura de Software “Invisível”.......................................................................................... 74
- Arquitetura de Software “Anêmica” ......................................................................................... 75
- Arquitetura de Software Intermediária ..................................................................................... 76
- Arquitetura de Software Madura ............................................................................................. 77
- Arquitetura de Software Provida pelo jCompany FS Framework ................................................... 77
- Outras Soluções Arquiteturais do jCompany Developer Suite....................................................... 78
- A Síndrome do NIH (Not Invented Here) .................................................................................. 79
- Aprendendo a Reusar Arquitetura............................................................................................ 79
Revisão de Fundamentos ......................................................................................................... 79
- Como Representaremos a Arquitetura? .................................................................................... 79
- Arquitetura em Camadas (Layers) ........................................................................................... 80
- Baixo Acoplamento (Menos dependências, mais estabilidade) ...................................................... 82
- Alta Coesão (Melhor encapsulamento, maior reuso) ................................................................... 83
- Fatoração de Código (Menos redundâncias, mais eficácia)........................................................... 83
- Refatoração de Código (Fatoração contínua) ............................................................................. 83
- Arquitetura de Software proposta no jCompany ........................................................................ 84
“Visão Geral” - Grandes Camadas e Blocos da Arquitetura do Framework ........................................ 84
- Visão Geral da Arquitetura do jCompany FS Framework ............................................................. 84
"Visão de Módulos” - Dependência entre os projetos gerados ........................................................ 86
- A arquitetura MVC no jCompany ............................................................................................. 86
- Organizando Classes de Domínio............................................................................................. 87
- Arquitetura MVC-2 clássica do J2EE ......................................................................................... 87
- Camada de Domínio Ortogonal em Java EE 5 ............................................................................ 89
- Organização de Projetos de Desenvolvimento ........................................................................... 91
- Dependências com o jCompany .............................................................................................. 94
- Dependências com o jCompany, “em tempo de desenvolvimento”................................................ 94
- Dependências com o jCompany, “em tempo de execução” .......................................................... 95
- Dependências com a camada de reúso Open-Source (OSS)......................................................... 96
“Visão Interna” - Estrutura e artefatos dos projetos gerados ......................................................... 97
- Introdução........................................................................................................................... 97
- Aprendendo mais sobre o Apache Maven.................................................................................. 97
- O projeto principal (Controle e Visão) ...................................................................................... 97
- O projeto “modelo” (Serviços de Negócio e Persistência) .......................................................... 103
- O projeto “comuns” (Entidades e Contratos) ........................................................................... 104
Sumário .............................................................................................................................. 107
A5 Entendendo a Metodologia de Desenvolvimento ...............................................................109
Introdução ........................................................................................................................... 109
- Alinhando Metodologia com Arquitetura ................................................................................. 109
Processos de Desenvolvimento de Sistemas.............................................................................. 110
- Definição ........................................................................................................................... 110
- Metodologia ou Processo? .................................................................................................... 111
- Processos Iterativos x Processo em Cascata............................................................................ 111
- Processos Iterativos e Fábricas de Software............................................................................ 112
- Práticas para Especificação - Projeto Lógico e Físico ................................................................. 113
- Práticas para Construção Java EE .......................................................................................... 113
12
Índice
13
Entendendo a Metodologia de Desenvolvimento
14
Índice
15
Entendendo a Metodologia de Desenvolvimento
16
Índice
- Anatomia da Fase de Desempilhamento (do retorno da fachada até resposta). ............................ 435
- Modelo de classes principais da camada Controle. ................................................................... 437
- Modelo de classes do tipo “PhaseListener” .............................................................................. 437
- Modelos da Agregação “PlcBaseJsfAction” ............................................................................... 438
- Compreendendo a seqüência em maior detalhe – Depuração e Logging II (Tutorial) ..................... 444
- Compreendendo a seqüência real – Depuração e Logging III (Tutorial) ....................................... 446
Programações da Camada Modelo - Fachada ............................................................................. 449
- Visão geral ........................................................................................................................ 449
- Programações da Subcamada de Fachada (DP Façade)............................................................. 449
- Modelos da Subcamada de Fachada....................................................................................... 449
- Anatomia da IoC para obtenção da Interface de Fachada. ......................................................... 450
- Anatomia de comunicação da Fachada com camadas inferiores. ................................................ 452
- Anatomia do gerenciamento do objeto de contexto “PlcBaseContextVO” ..................................... 453
- Anatomia de gerenciamento de transação .............................................................................. 455
- Pool de Conexões e Sessão de Persistência............................................................................. 458
- Especialização de contrato de fachada existente. ..................................................................... 459
Programações da Camada Modelo – Serviços de Negócio ............................................................ 461
- Programações da Subcamada de Serviços .............................................................................. 461
- Programações em Business Objects (BO ou Manager) .............................................................. 461
- Anatomia de seqüência típica de processamento de classes Manager.......................................... 462
- Programações em Application Services (AS) ........................................................................... 464
- Anatomia de seqüência típica de processamento de classes AS.................................................. 465
Programações da Camada Persistência..................................................................................... 467
- Estrutura de classes de configuração – Hibernate. ................................................................... 467
- Auto-Detect Dialect............................................................................................................. 468
- Estrutura de classes de configuração – JPA. ............................................................................ 469
- Estrutura de classes de persistência – DP DAO ........................................................................ 469
- Exemplo de código de Data Access Object (DAO). ................................................................... 470
Sumário .............................................................................................................................. 473
E17 Regras de Negócio & Batch .............................................................................................474
Implementação do Caso de Uso “UC005 Calcular Folha de Pagamento!”........................................ 474
- Analisando a Especificação – Caso de Uso Principal .................................................................. 474
- Analisando a Especificação – Extensão ................................................................................... 476
- Obtendo Classes de Domínio em Java .................................................................................... 476
- Gerando Mapeamento para Classe - Objeto-Relacional VI ......................................................... 477
- Implementando Application Services (AS) – Programação de Camada Modelo I............................ 478
- Implementando Objetos de Exceção (Exception) – Programação de Camada Modelo II ................. 480
- Implementando Data Access Objects (DAO) – Programação de Persistência I .............................. 482
- Aprimorando cláusulas de OQL – Programação de Persistência II ............................................... 486
- Externando cláusulas OQL – Programação de Persistência III .................................................... 488
- Aprimorando a arquitetura de classes DAO – Programação de Persistência IV .............................. 490
- Utilizando DI em classes de AS ............................................................................................. 493
- Criando serviços adicionais em “FuncionarioDAO” – Programação de Persistência V ...................... 493
- Delegando cálculos do negócio para Entidades – Programação de Domínio II............................... 495
- Realizando manutenções programaticamente – Programação de Persistência VI........................... 496
- Utilizando subqueries – Programação de Persistência VII .......................................................... 498
- Realizando escalonamentos temporais básicos – Programação Batch I........................................ 500
- Testando processamento batch – Programação Batch II ........................................................... 502
Sumário .............................................................................................................................. 503
E18 Regras de Negócio MVC Interativas ................................................................................504
Implementação da Extensão “UC005.1 Calcular Folha Interativo!”................................................ 504
- Analisando a Especificação ................................................................................................... 504
- Colaborações Padrão “plcControle” ........................................................................................ 504
- Criando página de disparo manualmente – Edição de Camada Visão VII ..................................... 505
- Criando implementações de controle manualmente – Edição de Camada Controle IX .................... 507
- Chamando serviços via fachada “de aplicação” – Edição de Camada Controle X............................ 509
- Entendendo a aplicação implementada................................................................................... 512
- Chamando serviços via fachada “de negócio” .......................................................................... 513
Sumário .............................................................................................................................. 515
F. Relatórios com Eclipse BIRT ................................................................................. 516
F19 Introdução ao Eclipse BIRT.............................................................................................518
Implementação do Caso de Uso “UC006 Auditar Operação!” ........................................................ 518
Analisando a Especificação ..................................................................................................... 518
- O Eclipse BIRT ................................................................................................................... 519
- Criando o relatório com modelo "Tabular"............................................................................... 519
- Alterando propriedades gerais do relatório.............................................................................. 524
17
Entendendo a Metodologia de Desenvolvimento
18
A
Módulo
Apresentação
.
A
19
Entendendo a Metodologia de Desenvolvimento
20
1
Capítulo
Introdução ao jCompany
1
A
Developer Suite
As oportunidades do eBusiness
A s empresas têm sido desafiadas como nunca a competirem em escala global e, para tal, o domínio
das tecnologias Web não é mais algo do qual possam prescindir. Saindo da automação das tarefas
rotineiras das áreas de retaguarda para a vanguarda dos negócios, a Web oferece, nos dias de hoje,
muito mais oportunidades do que a maioria das empresas tem conseguido compreender e
assimilar.
Neste cenário atual de aceleração da história, os negócios são desafiados primariamente pela famosa
previsão de Gordon Moore conhecida com a “Lei de Moore”: a capacidade do hardware continua a
dobrar a cada dois anos, sem aumento dos custos, e com ela também o espaço de inovação do
software. Enquanto esta lei durar – e irá por, pelo menos, mais 20 anos - as oportunidades criativas na
área de software continuarão excepcionalmente anabolizadas, um poderoso arsenal competitivo para
empresas ágeis e em aprendizado constante, que saibam utilizá-lo.
E percebamos bem: software se constrói com outros softwares. Como um produto invisível e
abstrato, um programa de computador reusa e é construído a partir de outras categorias de programas,
tais como ferramentas de construção, frameworks e bibliotecas para reuso. E com o próprio ferramental
à disposição dos desenvolvedores se expandindo juntamente com os limites criativos de suas aplicações
de negócios, deveríamos estar em um ciclo virtuoso, não é mesmo?
Por que, então, continuam falhando tantos projetos de TI? Por que não estamos todos comemorando
resultados surpreendentes, potencializados pelo avançado estágio do software?
Fugindo da extensão que uma resposta completa exigiria, vamos nos ater um dos fatores de consenso,
resumido por Scott Rosenberg, o fundador do famoso Web-Site www.salon.com: software é difícil, porque
não se consegue atualizar os profissionais de desenvolvimento, na mesma velocidade em que as
possibilidades se atualizam.
“(...) É por isso que não existe Lei de Moore para software. Chips podem dobrar de capacidade a
cada ano ou dois; nossos cérebros não.”
Ref. A1.1. Scott Resenberg, em Dreaming in Code [Rosenberg, Scott 2007].
Por motivos como este, empresas cujo foco não seja desenvolvimento de software têm partido para a
terceirização quase total desta expertise tecnológica... O problema é que este modelo de distanciamento
da tecnologia logo expõe as suas falhas. O ritmo de evolução dos terceiros também é limitado; de
qualquer modo será preciso de um bom nível de domínio técnico, para se gerenciar terceirizações no
nível adequado de detalhe; e por aí vai... Em suma, logo se descobre que este modelo não elimina o risco
- será preciso gerenciá-lo, enfrentando o problema cultural.
Arquiteturas pobres, falta de criatividade e de inovação sinérgica entre tecnologia e negócios, são outros
fatores sempre presentes, quando a distância cultural entre as pessoas de negócio e as de tecnologia é
muito grande... No fim, não há como nos furtarmos à pergunta da Era do Conhecimento: “Como domar
novas tecnologias e convertê-las em inovação para os negócios?”
Nasce daí a nossa grande motivação com este livro: prover informações de uma forma prática e atual,
contribuindo com informações, padrões e soluções de software que ajudem aos arquitetos e
desenvolvedores de software a resolver problemas corporativos, na velocidade dos tempos atuais.
21
Capítulo A1
O desenvolvimento de uma aplicação corporativa do mundo real carrega consigo muitos problemas
que escapam ao radar de um único produto Open-Source, e que, portanto, devem ser
equacionados no escopo da arquitetura corporativa.
Felizmente, são estas as lacunas que o jCompany Developer Suite procura preencher. Seu uso durante
o livro nos possibilitará almejar resultados rápidos e traçar uma estratégia de assimilação gradual, sem
abrirmos mão de resultados iniciais minimamente razoáveis... Mas este é o assunto central de todo o
livro, sobre o qual nos debruçaremos na prática, a partir do próximo módulo. Por hora, voltemos aos
nossos pilares de sustentação...
Em parte isso se explica pelos benefícios que a própria Lei de Moore, por si, já promove: a própria
evolução orgânica do hardware e a atualização de versões de tecnologias de base permitem às áreas
de TI hoje apresentarem algum resultado, o que preserva em muitas a acomodação de “jogar pelo
empate”. Um bom exemplo são empresas que preservam gerações obsoletas de aplicações, caras e
defeituosas, para além de seu limite de vida razoável (acredite, já nos deparamos com empresas
rodando aplicações de mainframe monousuárias, mantidas a preço de ouro, somente por inércia
tecnológica!).
o Mas no outro extremo, também muito perigoso, estão os que chamamos de compradores de
tecnologia fashion, que costumam ser coadjuvantes dos verdadeiros protagonistas, fornecedores de
software que supervalorizam tecnologias emergentes em produtos repletos de “excessos de
engenharia” (overenginnering).
Defendemos uma posição mediana. Nosso objetivo de “tirar o máximo do Java EE Open-Source” não
deve ser confundido com “apreender tecnologia pela tecnologia”, mas como uma busca por absorver
aquelas frações de novas tecnologias de software que realmente são um meio oportuno para o fim maior,
de viabilizar resultados de negócio diferenciados e criativos.
Mas como poderemos, neste livro, sugerir soluções de negócio criativas?
É simples: não poderemos. Como não discutiremos nenhuma vertical de negócio específica, esta é uma
missão nobre que caberá única e exclusivamente ao desenvolvedor nela contextualizado. Mas faremos o
que nos é possível: trazer soluções que poupam boa parcela de tempo de desenvolvimento de
uma forma geral, para que profissionais de TI possam exercitar melhor sua criatividade, com foco em
22
Introdução ao jCompany Developer Suite
Para quem uma vez experimenta a liberdade do Open-Source, as APIs proprietárias dos códigos
fechados representam verdadeiros “Firewalls de Projeto”. Barram soluções que exigem adaptação e
flexibilidade em níveis maiores de detalhe, retardam a correção de bugs e reduzem a taxa de
comunicação entre técnicos, entendimento e customização que possam pretender.
Além disso, o movimento do Open-Source Software (OSS) já estabeleceu com sucesso uma verdadeira
revolução sócio-cultural na área de TI, com seus fóruns de troca de conhecimentos, padrões e técnicas
de trabalho em níveis inéditos. Neste aspecto, é um de nossos principais aliados no desafio básico de
minimizar o déficit de conhecimento.
*
Ainda assim, muitos profissionais mal sintonizados com os objetivos de sua empresa e com os rumos dos negócios na atualidade,
gostam de reinventar commodities, como frameworks de base.
23
Capítulo A1
extremamente trabalhosas, dentre vários outros “suplementos” de alto valor agregado, mantidos pela
equipe de desenvolvimento dedicada da Powerlogic. Esta equipe é formada por dezenas de
desenvolvedores, profissionais de QA, Web-Design e de Produtação, trabalhando em um ambiente
certificado em MPS.Br nível F (CMMI-2) com base em práticas ágeis (SCRUM), condizentes com o mundo
Open-Source.
Neste modelo, os clientes são convidados a participarem ativamente, de forma colaborativa. Um exemplo
deste espírito “2.0” de gestão evolutiva do jCompany é o seu “Fórum de Suporte aos Clientes”, lista de
email que mantém em contato toda a comunidade de Clientes do produto, permitindo trocas de
experiências nos mesmos moldes de listas de discussão do mundo Open-Source.
E ainda há a possibilidade de qualquer profissional de clientes se engajar como um desenvolvedor
colaborativo (prosumer), após sua devida certificação e participação comprovada nas listas de usuários.
Neste patamar, ele tem acesso ao repositório de fontes oficial do produto, pode contribuir com o produto
diretamente, acelerando questões de interesse de sua empresa (naturalmente, mediante aprovação do
Product Owner), dentre outros benefícios. Verifique, com o fabricante (www.powerlogic.com.br), mais
informações sobre estas facilidades.
O framework existe através do módulo jCompany Full Stack Framework, com uma alta parcela de
contribuição, mas diversos outros módulos importantes e integrados proporcionam a sinergia responsável
pelo resultado final diferenciado da suíte jCompany.
Quando comparado ao desempenho de uma solução típica para desenvolvimento Java EE, caracterizada
pelo aproveitamento mediano de técnicas de Orientação a Objetos, arquiteturas de software “anêmicas”,
ausência de gerência de configuração e uso de IDEs agnósticas (que desconhecem o processo e não
podem incentivar “melhores práticas”), o jCompany pode apresentar níveis de “hiper-
produtividade”.
E esta não é hoje uma mera alegação. A Powerlogic tem colhido estes resultados ao longo de 8 (oito)
anos de experiência pioneira tendo a tecnologia Java como seu Core Business. No que são hoje mais de
uma centena de projetos corporativos em produção, o jCompany veio reduzindo prazos da ordem de
grandeza de “meses” para “semanas”, e com aumento considerável da qualidade: mais flexibilidade,
escalabilidade, performance, usabilidade e estabilidade.
24
Introdução ao jCompany Developer Suite
de base MVC (Model-View-Controller), importante para maior flexibilidade em evoluções e para se manter
a complexidade sob controle, mas não necessariamente para se desenvolver “mais rápido”.
Por outro lado, quase todas as preocupações com produtividade do jCompany também consideram o
aspecto qualidade.
Por exemplo, antes de usar técnicas de “geração de artefatos”, o jCompany esgota prioritariamente as
possibilidades mais sofisticadas da “Orientação a Objetos” (OO). Deste modo, apesar de aumentar a
curva de aprendizado, o resultado de produtividade é consistente, preservado nas fases de manutenção.
Ao eliminar código, em lugar de proliferá-los mais rapidamente (como na geração de código), a
Orientação a Objetos também diminui a probabilidade de erros.
Robôs eliminam por completo a necessidade de trabalho humano, sendo em geral o ápice da
otimização. Em software, generalizações de Orientação a Objetos funcionam como robôs industriais,
eliminando a necessidade de codificação manual de partes de programas. Esta é a área de atuação
do jCompany FS Framework.
o Automação indireta (Ferramentas)
Quando o trabalho é meramente intelectual, e mesmo o uso de ferramentas arrojadas não proveja
ganhos significativos, a orientação na forma de repasse de experiências e padrões históricos de
solução (best-practices) é a forma de se maximizar resultados. Em software, como em qualquer
processo industrial, a definição de “padrões de solução” para problemas freqüentes, documentação
extensiva e roteiros “passo a passo” ativos e inteligentes, podem orientar os profissionais
decisivamente, na codificação manual de programas. É a área de atuação do jCompany Patterns
& Methods.
o Conferência (Controle de Qualidade)
Um ambiente de produção que envolva tecnologia nos vários âmbitos citados, necessitará de uma
25
Capítulo A1
jCompany FS Framework
- Framework
Um framework é um conjunto de classes que colaboram entre si de modo a prover um reúso abrangente,
de grandes blocos de comportamento. Por ser reutilizável e customizável de forma refinada através de
diferentes técnicas OO, um framework permite um ganho impossível, ou muito difícil, de ser obtido via
“chamadas de sub-rotinas”, reúso típico dos ambientes de desenvolvimento de “terceira geração”.
Quando concebido com a profundidade e abrangência necessárias, um bom framework será o principal
representante da Arquitetura de Software Corporativa, uma manifestação concreta de seus objetivos,
contribuindo no dia a dia do desenvolvimento para:
o Definir fronteiras, evitando devaneios desnecessários em blocos não homologados de tecnologias;
o Promover “melhores práticas”, trazendo atalhos que tornem natural esta opção;
o Eliminar trabalho repetitivo, generalizando grande parcela das soluções;
o Diminuir a variabilidade indesejável de “soluções diferentes para um mesmo tipo de problema”,
trazendo fôrmas prontas de solução, customizáveis;
Com tudo isso, um bom framework se transforma no agente da arquitetura responsável por elevar o
patamar mínimo de qualidade e produtividade, para todos os projetos em seu perfil de
atuação.
- Framework de Integração
O jCompany FS Framework não é um framework comum, mas um “framework de integração”. Este
tipo de framework funciona uma camada acima de outros, chamados framewoks de base, atuando como
um “framework de frameworks”. Esta robustez arquitetural é hoje necessária para fazer frente ao grande
aumento de complexidade das tecnologias da era do eBusiness, as chamadas tecnologias Web.
Uma das características fortes de um framework de integração como o jCompany FS Framework é
exatamente não “reinventar a roda” praticando, em seu nível, a orientação de reúso que prega. Ao
incorporar frameworks de base de larga aceitação no mercado e se concentrar somente em
especializações holísticas, de mais alto nível, ele agrega um tremendo valor à arquitetura geral, ao
mesmo tempo em que preserva a cultura de mercado.
26
Introdução ao jCompany Developer Suite
Figura A1.2. Arquitetura em camadas de uma aplicação Java EE com o jCompany Full Stack Framework.
jCompany IDE
27
Capítulo A1
Os utilitários do jCompany IDE não são componentes para reuso, a serem incluídos nos executáveis das
aplicações. Por outro lado, aumentam a produtividade dos desenvolvedores nas atividades
necessárias para produzirem códigos e artefatos específicos da sua camada de negócios.
Existem duas áreas chave para onde o módulo jCompany IDE traz produtividade diferenciada, indo
além das facilidades genéricas propiciadas pelo Eclipse, pelo Maven e pela camada de reúso Open-
Source:
o Plugins de Criação “Orientados pelo Processo”, capazes de produzir uma primeira versão de
projetos e artefatos envolvidos em Casos de Uso Padrões, que seguem “melhores práticas” previstas
na Arquitetura de Software, Padrões e Métodos Corporativos. Por exemplo, os plug-ins de processo
do jCompany IDE geram formulários JSF, menus, mapeamento Objeto-Relacional, fluxos de
navegação padrões, etc., otimizados e minimalistas, em qualidade final de produção.
o Organização de projetos e dependências segundo o padrão Maven, incluindo repositório
simplificado e rotinas de construção e liberação rápida via MOJOs (Maven Objects), para diversos
Application Servers, levando em conta a Arquitetura de Software Corporativa.
Com isto, o módulo jCompany IDE provê um Ambiente Integrado de Desenvolvimento “inteligente”,
conhecedor da arquitetura, padrões de alto nível e “melhores práticas” da organização.
Trata-se de um avanço nítido com relação ao que se poderia extrair de IDEs no passado, ou do que se
pode esperar do Eclipse ou Netbeans com seus plug-ins de edição genéricos, incapazes de reforçar
“melhores práticas”.
28
Introdução ao jCompany Developer Suite
Figura A1.4. Alguns Casos de Uso, Inclusões e Extensões Padrões do jCompany Patterns & Methods.
Os Casos de Uso Padrões do jCompany partem das idéias de Alistair Cockburn [Cockburn, Alistair 2003],
evoluindo radicalmente seus conceitos de “Caso de Uso CRUD” e “Caso de Uso Parametrizado”, tanto
conceitualmente como através de uma solução de implementação automatizada.
- Colaborações Padrões
Os Casos de Uso Padrões do jCompany estão definidos em nível lógico. Eles são, por exemplo, úteis
mesmo em outros paradigmas tecnológicos, que não o Java EE.
Mas o jCompany traz também “padrões de realização de Casos de Uso completos”, voltados para
especificação para Java EE especificamente, chamados “Colaborações Padrões”. As Colaborações são
“estereótipos” de Caso de Uso, representadas de forma pontilhada na UML, que simbolizam
especificações de “projeto físico”, ou realizações de um Caso de Uso.
O módulo jCompany FS Framework implementa diretamente estas Colaborações Padrões definidas,
através de generalizações OO de alto nível, para a parte Java envolvida. Em seguida o módulo
jCompany IDE gera os artefatos não generalizáveis, como os numerados na Figura A1.5, provendo um
grande índice de automação final.
29
Capítulo A1
Figura A1.5. Visão estrutural de uma Colaboração, exibindo artefatos Java EE padrões, exigidos para seu
funcionamento.
Esta sinergia entre projetos lógico, físico e implementação soluciona de forma elegante um clássico
problema do desenvolvimento de software: a transição da etapa de Elaboração para Construção.
Figura A1.6. Agregação de Entidades com estereótipos que definem padrões da Arquitetura.
30
Introdução ao jCompany Developer Suite
Além dos padrões de formulário e suas operações, padrões de “gestão de leiaute” também são definidos,
trazendo uma proposta visual e de ergonomia para toda a aplicação.
- Testes de Unidade
O módulo jCompany Test for Developer traz um framework para apoio ao desenvolvimento de Testes
de Unidade para arquitetura MVC2-P (Model-View-Controller type 2 with Persistence), baseado
principalmente nos frameworks de base JUnit e EasyMock.
Ele também segue a mesma filosofia de reúso de matéria-prima Open-Source do jCompany FS
Framework, porém em escala bem reduzida de complexidade, como ilustrado na Figura A1.9.
31
Capítulo A1
#3. Arquitetura de Testes de Unidade – Framework de Integração: Framework provendo uma fina
camada de especialização e “melhores práticas” de Testes de Unidade para camadas Controle,
Modelo, Domínio e Persistência.
Traz também classes “Stubs” (Mocks concretos) para simular objetos complexos de controle, tais como
HttpRequest.
Muito embora se trate do módulo da suíte com menor contribuição quando comparado aos demais, o seu
bom uso pode ser de grande valor para reforçar qualidade e práticas de refactoring, ao longo das
manutenções.
- Gerência de Configuração
Dificilmente um profissional iniciante na área de Desenvolvimento de Aplicações de Software corporativo
compreenderá porque o módulo jCompany Configuration Management tem o mesmo peso em termos
de contribuição que o módulo jCompany IDE, como ilustrado na Figura A1.1.
O fato é que, dentro da disciplina de “Gerência de Configuração”, tão enfatizada em certificações de
maturidade tais como CMMI, estão questões chave para manutenção da integridade (e,
consequentemente, da qualidade e produtividade geral) de todos os outros módulos da solução, ao longo
do tempo, garantindo:
Integração dos Itens de Configuração
Controle de Versões (Integridade Continuada)
Em uma suíte altamente integrada, como vemos na Figura A1.10, todos os componentes envolvidos, em
todas as camadas de cada módulo da solução, precisam estar funcionando harmonicamente. Para tanto,
necessitam não somente de estarem versões apropriadas, homologadas juntamente com as versões dos
demais componentes, mas ainda pré-configurados para funcionamento imediato, com pouco esforço.
32
Introdução ao jCompany Developer Suite
Manter uma instalação e controle de versão unificado para um universo de mais de quarenta projetos de
origem distinta, e mais de uma centena de “itens de configuração” (projetos, componentes, capítulos de
documentação, roteiro Cheat-Sheet, plug-ins, etc.), como é o caso do jCompany Developer Suite, é
uma tarefa hercúlea. Especialmente quando se passa a contar com uma base instalada que exige
manutenções de linhas de base em paralelo.
Em grandes organizações, onde é de se esperar o desenvolvimento de dezenas ou centenas de projetos
sobre uma mesma Arquitetura de Software Corporativa, a simples terceirização de boa parte deste
trabalho de “embalagem integrada de software Open-Source” e do controle de sua Linha de Base, de
forma unificada, pode compensar o uso do jCompany e retornar o investimento.
33
Capítulo A1
Soluções para este tipo de abrangência “topo-de-linha” são conhecidas no mercado como produtos para
Application Lifecycle Management (ALM). Com elas, se torna possível uma gestão integrada via
ferramentas que oferecem rastreamento entre artefatos diversos produzidos e consumidos em cada fase,
além de gerenciamento de mudanças com análise de impacto, cálculos de ROI, dentre outros benefícios.
Apesar de serem objetos de desejo, as poucas soluções de mercado na área de ALM são ainda de código
fechado e incorrem facilmente em licenciamentos milionários. Um outro agravante é o “excesso de peso”
que estas suítes tradicionais costumam trazer. Por estes motivos, customizações refinadas logo se
manifestam como difíceis, senão impossíveis, de serem realizadas, culminando em implantações parciais
(subutilização) ou fracassos completos.
Como alternativa ao código fechado, a Powerlogic dispõe de uma interessante alternativa de ALM,
disponível em modelo Open-Source 2.0: o Powerlogic jALM. O Powerlogic jALM é obtido a partir da
integração do jCompany com outras suítes para atendimento às outras fases e disciplinas, todas com a
mesma filosofia de integração e especialização de insumos Open-Source, em código aberto.
Não é o objetivo deste livro uma discussão com este nível de abrangência, mas vale à pena
apresentarmos o seu espectro geral, para expor nossos limites e possibilidades:
- jCompany QA Suite
Integra e especializa frameworks e ferramentas líderes do mundo Open-Source para a área
de Garantia da Qualidade (Quality Assurance – QA), oferecendo produtividade diferenciada
na automação da averiguação de qualidade, que inclui testes funcionais, de unidade e
cobertura (coverage), averiguação de padrões e convenções de código, testes de
performance e escalabilidade.
Além disso, provê um ambiente de integração contínua e de trabalho em equipe “pronto para uso”, com
controle de versão de executáveis ultra-simplificado, incluindo versionamento a um clique (“one-click
versioning”) e liberação a um clique (“one-click deploy”). O jCompany QA Suite integra artefatos de
implementação e testes a requisitos, Casos de Uso e Casos de Testes cadastrados no eCompany Process,
deste modo viabilizando matrizes de rastreabilidade do “requisito ao código”, incluindo os testes
automatizados.
34
Introdução ao jCompany Developer Suite
- eCompany Reports
É uma solução para construção, escalonamento e disponibilização de relatórios para
Web, baseada no Eclipse BIRT e escalonador Quartz, que permite que sejam
planejadas execuções de relatórios com argumentos pré-definidos e lista de distribuição,
de forma batch, de modo a evitar sobrecargas em aplicações on-line.
O eCompany Reports oferece à suíte de ALM um instrumento de flexibilidade para se criar e
disponibilizar relatórios customizados que acessam o repositório de todos os demais produtos, baseados
em um único esquema relacional integrado, sob Oracle, MS SQL-Server, Sybase, PostGree ou
MySQL.
Relatórios BIRT podem incluir gráficos, quebras e indicadores visuais sofisticados, em formato PDF ou
HTML.
Figura A1.12. Gerenciamento de Ciclo de Vida completo de Aplicações de Software, Open-Source 2.0.
35
Capítulo A1
#1. Nesta fase a empresa define seu processo no eCompany Process. Produz documentação
utilizando conteúdo rico em formato 5w2h, arquivos anexados etc., configura formulários para
apontamentos de evidências e estratégias de rastreabilidade, visando atender certificações de
mercado ou interesses internos. Em seguida, registra seus produtos (ativos de software,
sistemas em produção ou desenvolvimento) e os segmenta em componentes para melhor
gestão. Projetos e requisitos são então registrados e gerenciados de forma integrada ao
processo previamente definido, e vinculados à gestão de produtos de software.
#2. Os requisitos de clientes são replicados para a base de ferramentas CASE (atualmente
disponível para Enterprise Architect©, mas customizável para quaisquer outras), que permitem
então modelagem UML de soluções com rastreamento possível dos requisitos para modelos de
solução tais como Casos de Uso ou Colaborações. Padrões (templates) de modelagem de
Projeto Físico que consideram a arquitetura do jCompany podem ser utilizados, de modo a
maximizar estratégias de geração de código com base em modelos.
#3. Ferramentas CASE contendo modelos de Projeto Físico, sucintos e objetivos, geram classes
Java para o jCompany Developer Suite, e também permitem engenharia reversa, deste modo
provendo um ambiente de construção integrado com o de modelagem, bidirecional.
#4. O jCompany Developer Suite produz executáveis de forma produtiva e com pautas mínimas de
qualidade, performance, escalabilidade e segurança assegurados por uma arquitetura
homogênea e pré-testada, ferramentas e métodos que promovem o uso de padrões em alto
nível, que evitam códigos artesanais em excesso, diminuindo a variabilidade perigosa de
resultados.
#5. Analistas de Teste utilizando o jCompany QA Suite produzem Casos de Teste automatizados de
forma produtiva, que investigam não conformidades em executáveis construídos pela equipe de
desenvolvimento e também suas práticas de codificação, através da vistoria de códigos fonte.
Executáveis são gerados diariamente ou várias vezes por dia, automaticamente, sempre que
alguém atualiza algum artefato de software no repositório Subversion, e todos os testes de
regressão são realizados automaticamente, com sinalização dos resultados via email para
equipes de desenvolvimento e QA.
#6. Usuários responsáveis pela aplicação podem usar o jCompany Security para definir políticas de
segurança neste estágio, de posse da aplicação pronta para entrar em produção. Isso não
somente permite flexibilidade para criação dinâmica de roles (atores) e suas permissões, ser
necessidade de redeploy da aplicação, como também reforça decisivamente a segurança em si,
já que não expõe as políticas de segurança aos técnicos de desenvolvimento ou suporte.
#7. Casos de Uso utilizados por usuários-chave, de decisão, são disponibilizados no eCompany
Portal, na área de “Meu Portal” destes usuários (MyPortal), que deste modo agrega todas as
diversas aprovações, manutenções, consultas, relatórios e indicadores gerenciais, em um local
de acesso a um clique, disponíveis logo após a autenticação dos usuários no portal corporativo
da empresa. Estas “transações” organizadas de forma “orientada a usuários” maximizam o
retorno para a empresa ao promoverem e viabilizarem o uso simples e apoiado por
ferramentas de Groupware tais como fórum, contact-center, faq, etc.
#8. Relatórios e gráficos são AD-HOC são disponibilizados para usuários, de forma independente de
aplicações, provendo informações analíticas de forma ágil e com segurança, incluindo
informações personalizadas que acessem as diversas bases do jALM, para portifólio específico
de gestão.
#10. O feedback final dos usuários, na forma de erros (bugs), sugestões, idéias e dúvidas, são
coletados e gerenciados com apoio pelo eCompany Contact-Center, que recebe estes relatos de
forma integrada a Produtos, Componentes e Requisitos. Estes itens caem em uma triagem de
atendimento definida (workflow de atendimento), e podem ser “promovidos” a requisitos,
realimentando o ciclo e, finalmente, dando aos gestores uma visão gerencial completa.
36
Introdução ao jCompany Developer Suite
Sumário
Neste capítulo, discutimos brevemente os desafios que as organizações vêm enfrentando para
absorverem inovações tecnológicas, em um ritmo competitivo. Caracterizamos como tentaremos
contribuir nesta área, e o que queremos dizer por “tirar o máximo do Java EE Open-Source”.
Apresentamos o jCompany Developer Suite como uma solução completa para construção de aplicações
Java EE, com base em arquitetura Open-Source customizável, em suas diversas dimensões de atuação.
Prosseguimos analisando a arquitetura de alto nível de todos os seus módulos: jCompany FS Framework,
jCompany IDE, jCompany Patterns & Methods, jCompany Test For Developer e jCompany Configuration
Management.
Por fim, vimos como o jCompany se encaixa em uma estratégia mais ampla, de Open-Source
Application Lifecycle Management, contextualizando o produto dentro do espectro maior da solução
Powerlogic jALM.
37
Capítulo A1
38
2
Capítulo
Instalando o jCompany
2
A
De fato, o caminho mais eficiente para se construir uma solução é “não construí-la”, reutilizando
uma existente.
Uma outra possibilidade que poderia ser encarada como “alternativa ao reuso” seria a geração de código,
em suas várias variantes: MDA*, plugins de IDE, geração via templates (snippets), dentre outras.
Mas o fato é que não deveríamos escolher entre “reuso”, e “geração de código”, mas nos
preocupar em combinar apropriadamente estas técnicas. A geração de código utilizada
precocemente, para produzir códigos que poderiam ser generalizados em frameworks, por exemplo, traz
resultados medíocres ou desastrosos no médio prazo. Por outro lado, nem tudo é generalizável, e nem
somente de classes Java são compostos os artefatos Java EE.
Portanto, antes de pensarmos em geração de código, deveríamos maximizar a fatoração do código
em todo segmento generalizável, utilizando principalmente a Orientação a Objetos. Somente então,
após esta etapa e sobre esta camada genérica, uma estratégia de geração de código seria adequada.
Seja para produzir código Java específico, não generalizável, seja para produzir artefatos “não-Java”.
O jCompany utiliza esta estratégia:
o A parte Java é especialmente tratada por Orientação a Objetos, com técnicas diversas de
generalização, pelo módulo jCompany Full Stack Framework, voltadas para maximização do
reuso.
o Sobre a camada acima, os artefatos Java EE tais como páginas JSP, mensagens, configurações XML
e declarações (anotações) para mapeamento Objeto-Relacional e metadados, não generalizáveis,
têm sua produção apoiada por abordagens de geração de artefatos, através do módulo
jCompany IDE.
Mas há um efeito colateral normalmente negligenciado, típicos de ambientes OO com alto índice de
reuso, que torna esta discuessão especialmente relevante para nosso capítulo: quanto maior o índice
de reuso, mais complexas se tornam as exigências de Gerência de Configuração,
especialmente atividades de Controle de Versões.
*
Model Driven Architecture. Transformações e Geração de Código a partir de Modelos, tipicamente UML.
39
Capítulo A2
E esta complexidade deve ser mantida, íntegra, ao longo do tempo, em “versões subseqüentes” dos
projetos. Como vários dos componentes reutilizados sofrerão evoluções individualmente, demandarão
uma provável convivência entre gerações, ou seja, do mesmo componente com diferentes versões
simultâneas, convivendo em diferentes instâncias de aplicações.
Algumas empresas ficam se perguntando por que a produtividade esperada não está ocorrendo. Algumas
das causas certamente são organizações simplificadas dos projetos e ambientes de desenvolvimento ou,
no extremo oposto, arquiteturas excessivamente complicadas, ineficazes e confusas.
Felizmente, ao utilizarmos o jCompany também estaremos reutilizando soluções pré-configuradas e
terceirizando boa parte da problemática do controle de versões! O jCompany, em si, reusa
“melhores práticas” sugeridas nesta área, através de ferramentas tais como Maven, especializando-as
para oferecer um bom “ponto de partida” para adequações.
A organização de projetos sugerida pelo jCompany para aplicações principais, módulos, camada
Bridge, etc., juntamente com as rotinas de empacotamento baseadas nos arquivos POM do Maven,
são especialmente concebidas para maximizar o reuso.
A idéia é permitir que, mesmo projetos iniciais, tenham um “espaço mínimo” de arquitetura que os
permita escalar em complexidade sem exigir redundâncias e permitindo customizações refinadas.
- “Best-of-Breed” x “One-Stop-Shop”
Um desenvolvedor Java EE típico, envolvido com reúso de matéria-prima Open-Source deverá instalar,
configurar e integrar plugins, componentes JAR, projetos e módulos da arquitetura, aplicações exemplos,
utilitários Maven/Ant, ferramentas de teste, dentre dezenas de outros “itens de configuração”, melhores
em seus segmentos. Uma tarefa nada trivial e em vários níveis de abstração abaixo das preocupações de
negócio.
E isso se complica com a cultura da concorrência meritocrática predominante no mundo Open-Source,
que leva ao destaque produtos das mais variadas origens. O framework Tiles, por exemplo, nasceu do
francês “Cedric Demoulin”, o Hibernate nasceu do australiano “Gavin King”, o Struts/JSF, do
americano “Craig McClanahan”, e assim por diante. Cada um destes frameworks foram elencados pela
comunidade como líderes de sua categoria, e precisam ser combinados com os demais, para uma solução
arquitetural específica.
Este tipo de reúso de produtos “melhores em seu segmento” (Best-of-Breed) é uma possibilidade
fantástica que nos traz o mundo Open-Source, e não deve ser desconsiderada...
Mas a falta de “embalagem” e a alta complexidade nesta gerência de configuração muitas vezes levam
empresas a optarem por soluções proprietárias. Tais empresas sabem da importância fundamental de
homogeneidade do ambiente de desenvolvimento, para estabilidade e suporte em escala industrial. É a
cultura da “loja tem-de-tudo” (One-Stop-Shop) tradicional em software, onde uma solução é
totalmente desenvolvida e comercializada por um único fabricante.
A tendência desta última abordagem é de ser pior em opções de funcionalidades, mas melhor em
configuração e controle de versões. Felizmente, a filosofia do jCompany é um meio termo, trazendo
vantagens dos dois mundos: componentes “Best-of-Breed” em uma configuração de “One-
Stop-Shop”.
Vamos ilustrar esta problemática contando uma experiência real:
Em 2003, a versão 1.5 do jCompany não trazia ainda um instalador automatizado como
atualmente... Mas já fazia um trabalho razoável entregando um CD ao Cliente contendo um
“roteiro detalhado de instalação e configuração” do ambiente de desenvolvimento, além de versões
corretas e homologadas dos frameworks e utilitários envolvidos.
Esta abordagem reduzia o índice de não-conformidades e variabilidade em configuração de
ambientes de desenvolvimento, típicas do mundo Open-Source e predominantes na época (e em
algumas empresas até hoje). Porém, ainda assim, devido à intervenção manual necessária, os
problemas ainda eram muitos, se comparados com soluções fechadas de mercado. Erros comuns
eram “variáveis de ambientes erradas por erros de digitação”, “conflitos de JAR em Classpath”,
“variações de Sistema Operacional Linux”, para falar de alguns.
Quando o problema não implicava em imobilidade, ou seja, não impedia o desenvolvedor de
trabalhar, suas conseqüências poderiam ser até piores – pois o permitia trabalhar, mas em um
40
Instalando o jCompany
Poder instalar toda uma complexa solução de produtividade Java EE Open-Source para a
construção de aplicações Web, a partir de uma única mídia e de um assistente de instalação
“clássico”, é realmente algo de grande valor. Muitos chamam a isso de “engarrafar o Open-
Source”.
- Atualização Automatizada
Existem duas abordagens de automação da atualização de versão e configuração, bastante interessantes,
incorporadas pelo jCompany, para facilitar a manutenção da integridade de versões dos
produtos integrados na arquitetura em geral, ao longo do tempo:
o A atualização automatizada provida pelo Maven, para componentes do módulo jCompany FS
Framework;
o E o gerenciador de atualizações (Update Manager) provido pelo Eclipse, para atualização
automatizada de plugins e alguns outros componentes do módulo jCompany IDE.
Mas estas são ainda soluções parciais, quando observamos todos os itens de configuração controlados
pelo jCompany Developer Suite. Muitos destes itens não são “cobertos” por nenhuma das estratégias
acima, como as versões do próprio ambiente Java (JSDK), do aplicativo Maven, dos vários Application
Servers e códigos fontes de projetos Eclipse.
Por este motivo, o módulo jCompany Configuration Management traz rotinas de automação
complementações às acima citadas, que aumentam o leque de produtos automaticamente configurados,
por instaladores automatizados. Além disso, o jCompany Configuration Management possibilita que
todo este manancial de software seja instalável a partir de uma única mídia em DVD – algo ainda
insubstituível, especialmente para instalações iniciais ou evoluções para grandes versões.
Ao final, com todas estas opções, atualiza-se uma grande pilha (Stack) de produtos simultaneamente, na
ordem de dezenas de grandes projetos, em uma única atualização de versão do jCompany - algo por si
já de grande valia, para desenvolvimentos corporativos.
Já vimos que, para o máximo do reuso, precisaremos de excelência em Gerência de Configuração.
Felizmente, o jCompany Configuration Management também traz soluções de base, nesta área.
41
Capítulo A2
jCompany o Licenciamento comercial de Código o Inclui todos os módulos, sem o Disponível em blocos de 5, 10, 20,
Developer Aberto Gerenciado (Managed Open- nenhuma restrição funcional: 50, 100 e ilimitados
Enterprise Suite Source 2.0), através da licença - jCompany FS Framework - Desenvolvedores simultâneos, com
Powerlogic Open-Source Advanced; §
cascata de preços .
Licence (POSL 2.0). - jCompany IDE - Advanced;
- jCompany Configuration o Participação em lista de emails
o Nenhuma taxa de liberação em Management - Advanced; exclusiva
produção (no runtime fee). - jCompany Test for Developer; jcompanysuporte@powerlogic.com
- jCompany Patterns & Methods. br, integrando todos os clientes
o Possibilita o desenvolvimento tanto
“Enterprise” em comunidade
de aplicações abertas e gratuitas o Gerência de Configuração colaborativa.
(software livre) quanto comerciais. Avançada (jCompany
Configuration Management - o Suporte gratuito para instalação
o Acesso permitido a todos os
Advanced): através do e-mail
códigos fontes, de todos os
- Controle de Versões com suporte@powerlogic.com.br .
módulos da suíte, inclusive para
‡ garantia de integridade e
alterações . compatibilidade de evoluções; o Suporte oficial telefônico, por e-
- Entrega de mídia para grandes mail e Web-Site, por valor entre
o Acesso permitido a todas as 15% a 30% do valor da licença, ao
documentações (arquivos versões;
- Homologação para Application ano.
editoráveis disponíveis), inclusive
para alterações*. Servers Open-Source e o Garantia de atualização antecipada
comerciais tais como Weblogic, de versões por 15% do valor de
o Permissão para cessão dos WebSphere e OAS, incluindo EJB3 licença, ao ano (uma grande
códigos-fontes do módulo e JPA. **
versão ao ano, no mínimo) .
jCompany FS Framework para
terceiros, sem exigência de novo o Gerência de Licenças OSS. A
Powerlogic assume a o Atualização de versão não
licenciamento por parte de quem o antecipada por 30% do valor de
recebe, desde que como parte da responsabilidade pela gestão e
respeito aos licenciamentos dos licença - e 15% para cada grande
cessão de aplicações que o utilizam versão adicional, para saltos acima
- tanto para aplicações produtos Open-Source entregues
com a solução. de uma versão.
proprietárias quanto para
software livre, aberto e gratuito o Garantia de recebimento de
todos os novos módulos da
suíte. Alguns módulos em
planejamento são:
- jCompany BPM;
- jCompany SOA;
- jCompany Advanced RIA;
- jCompany Advanced MDA.
‡
Os códigos fontes de plugins e da documentação não são disponibilizados na mídia padrão, para economia de espaço, mas podem ser
requisitados quando desejado, pelos clientes.
§
Ver preços e descontos para maiores quantidades (cascata) com o fabricante, em plc@powerlogic.com.br.
**
Para grandes versões até segundo nível somente (Ex.: 5.0, 5.5, 6.0, 6.5). Pequenas liberações (releases) de terceiro nível são
gratuitas (Ex.: 5.01, 5.02, 5.51, etc.).
††
Ver variações exatas no web-site d fabricante.
42
Instalando o jCompany
jCompany o Licenciamento comercial de Código o Inclui somente módulos: o Restrita a somente 1 (uma) licença
Developer Aberto Gerenciado (Managed Open- - jCompany IDE – Basic; por CPF ou CNPJ, não sendo
Professional Source 2.0), através da licença - jCompany FS Framework – oferecida em escala.
Suite – Entry Powerlogic Open-Source Basic;
Level Version Licence (POSL 2.0). - jCompany Configuration o Suporte gratuito para instalação
Management - Basic. através do e-mail
o Nenhuma taxa de liberação em suporte@powerlogic.com.br .
produção (no runtime fee). o jCompany FS Framework –
Basic: o Suporte colaborativo via listas de
o Possibilita o desenvolvimento tanto - Não inclui projetos da camada comunidades, não sendo oferecido
de aplicações gratuitas (software Bridge; suporte oficial.
livre) quanto comerciais. - Não inclui tecnologia Struts; o Garantia de atualização antecipada
o Inclui códigos fontes do módulo o jCompany IDE – Basic: de versões por 35% do valor de
jCompany FS Framework, mas - Não inclui plugin de edição visual licença, ao ano.
não dos demais módulos e de metadados;
documentação. o Atualização não antecipada por 60%
o Gerência de Configuração do valor de licença, para uma
o Permissão para cessão dos códigos- Avançada (jCompany versão principal; e 25% para cada
fontes do módulo jCompany FS Configuration Management - grande versão adicional.
Framework para terceiros, sem Basic):
exigência de novo licenciamento o Compatibilidade das aplicações
- Controle de Versões com desenvolvidas com a suíte
por parte de quem o recebe, desde garantia de integridade e
que como parte da cessão de Enterprise.
compatibilidade de evoluções;
aplicações que o utilizam - - Sem entrega de mídia o Garantia de recebimento de
somente para software livre, (atualização via download evolução nos novos módulos
aberto e gratuito. somente); incluídos apenas, dentro da
- Homologação apenas para política de atualização.
Application Servers Open-Source
Tomcat, Glassfish e jBoss. o Disponível para Sistema Operaciona
Windows apenas.
o Gerência de Licenças OSS. A
Powerlogic assume a
responsabilidade pela gestão e
respeito aos licenciamentos dos
produtos Open-Source entregues
com a solução.
jCompany o Licenciamento gratuito temporário o Mesma funcionalidade descrita para o Disponível como licenças individuais
Developer através da licença Powerlogic a versão Professional, exceto: (pessoa física) gratuitas.
Professional Demo Licence (PDL 1.0). - Código semi-ofuscado do
Suite - Demo jCompany FS Framework; o Suporte gratuito para instalação
Version o Para avaliação e estudo individual - Marcas d’água em leiautes de através do e-mail
apenas. Não permite liberação de aplicações e em alguns plugins; suporte@powerlogic.com.br, para
Importante: Esta aplicações para produção. - Exclusão de alguns conjuntos de usuários registrados.
é a versão peles (CSS).
disponibilizada em o Inclui códigos fontes do módulo o Sem garantia de compatibilidade
DVD com este jCompany FS Framework semi- com as outras modalidades.
livro ou via ofuscados, mas não dos demais
download gratuito módulos e documentação.
(eBook)
o Duração típica da licença de 3 (três)
meses, renovável mediante contato
com o fabricante.
jCompany o Licenciamento gratuito temporário o Mesma funcionalidade descrita para o Disponível como licenças individuais
Developer através da licença Powerlogic a versão Demo, apenas com (alunos) gratuitas.
Professional Academic Licence (PAL 1.0). alteração da marca d’água.
Suite - Academic o Suporte gratuito para instalação
Version o Licença especial para uso livre e através do e-mail
gratuito em sala de aula ou em suporte@powerlogic.com.br, para
laboratórios de escolas de segundo usuários registrados.
ou terceiro graus (curso superior),
públicas ou privadas, incluindo o Sem garantia de compatibilidade
cursos de extensão. com as outras modalidades.
43
Capítulo A2
jCompany Full- o Licenciamento aberto e gratuito o Versão comunitária do o Disponível gratuitamente, para uso
Stack Framework através da licença General Public jCompany FS Framework – e redistribuição.
- Community Licence Versão 3 (GPLv3). Basic. O código fonte pode variar
Version com relação à versão o Suporte colaborativo apenas.
o Nenhuma taxa de liberação em §§
gerenciada . o Sem garantia de compatibilidade
produção (no runtime fee).
com as outras modalidades.
o Na ausência de plugins de geração
o Possibilita o desenvolvimento de
de código, a criação e edição de Funcionamento esperado em
aplicações de software livre, de o
‡‡ artefatos deve ser feita através de Windows e Linux, para qualquer
acordo com o padrão GPL . “templates” e “snippets” cedidos IDE (Eclipse, Netbeans, etc.).
***
pela comunidade .
‡‡
Para maiores informações, consulte a licença e base de conhecimento, no Web-Site da Free Software Foundation.
§§
A própria Powerlogic contribui com evoluções, na medida em que a versão gerenciada evolui – porém sem compromissos ou
qualquer tipo de garantia.
***
Este próprio autor está escrevendo artigo complementar a este livro, para apoio ao uso da versão comunitária (como desenvolver
sem os plugins de geração de código, basicamente).
†††
O uso de 512 MB de RAM é possível mas impedirá a utilização de plugins de edição visual de XML e JSPs (formulários), que exigem
mais recursos do Eclipse, o que é especialmente incômodo para iniciantes em Java. A configuração de 2GB RAM permitirá o uso com
margem de segurança de outros programas típicos, simultaneamente ao jCompany, tais como clientes de e-mail e várias instâncias de
Navegadores.
44
Instalando o jCompany
Após a execução, o programa Assistente de Instalação exibirá uma tela de boas vindas, conforme
demonstrado na Figura A2.2.
A partir desse ponto, devem-se seguir todas as instruções apresentadas pelo Assistente de Instalação.
Todo o processo deverá demorar em torno de 10 minutos, variando em função de configurações da
máquina.
- Organização Geral
Todos os artefatos que compõem o ambiente do jCompany são instalados abaixo do diretório informado
durante o assistente, cujo padrão é “[drive]:/powerlogic/jCompanyXX”, que será referenciado como
“[jCompany_base]”, nesta documentação.
No diretório raiz da instalação do jCompany, encontram-se basicamente arquivos contendo as notas de
liberação, com informações sobre as novidades da versão/release, e os arquivos “.bat”, que devem ser
utilizados para se abrir o ambiente de desenvolvimento. Existem algumas alternativas de execução, que
devem ser selecionadas cuidadosamente, em função da memória que se possui disponível na máquina:
45
Capítulo A2
Opções correspondentes com sufixo “Clean” Para rodar o Eclipse limpando áreas de caching.
É uma opção do Eclipse que somente precisa ser
utilizada em situações onde forem percebidos
problemas com relação a atualizações de
plugins.
Em ambiente Windows, o jCompany também cria opções na barra de ferramenta, para facilitar o acesso,
correspondentes a cada disparo acima.
Importante: O instalador do jCompany não configura nenhuma variável global de ambiente, o que
permite convívio com diversas versões simultâneas e ambientes existentes do desenvolvedor.
- Eclipse e Plugins
O primeiro recurso a ser conferido é o Eclipse. Para tanto, deve-se acionar um dos disparadores acima
citados, conforme as considerações feitas, e aguardar pela inicialização do Eclipse. A apresentação de um
diálogo de entrada conforme a Figura A2.4 é sinal de que se está utilizando o Eclipse homologado e
especializado para o jCompany.
Uma conferência mais detalhada, incluindo número de versões e liberações menores, pode ser realizada
utilizando-se a opção de menu “Help -> About Eclipse Plataform”, conforme a Figura A2.4.
Acionando-se um dos botões que contém o logotipo dos principais plugins, pode-se consultar a versão
detalhada de cada plugin componente, como exibido para o jCompany, na Figura A2.5.
46
Instalando o jCompany
Diretório “[jCompany-base]\eclipse”
Subdiretório Objetivo
links Diretório padrão do Eclipse para arquivos que contém hiperlinks para
configurações externas de outros plugins.
plugins Diretório padrão do Eclipse para conter plugins de sua plataforma básica
(JDT, etc.)
workspace Diretório padrão do Eclipse para conter projetos. Deve ficar no mesmo nível
do Eclipse, para que seja mantido, ao longo de atualizações.
47
Capítulo A2
Figura A2.6. Exemplo do diretório de instalação do Eclipse, abaixo do diretório raiz do jCompany.
- Projetos jCompany
Em sua versão corporativa, o jCompany instala mais de duas dezenas de projetos próprios, já pré-
configurados para importação no Eclipse, abaixo do diretório “meus_projetos”. Nas modalidades de
avaliação, acadêmica ou profissional, alguns projetos do framework não são disponibilizados com fontes
ou não estarão presentes. A tabela abaixo resume a política:
Diretório “[jcompany-base]\meus_projetos”
48
Instalando o jCompany
49
Capítulo A2
- Repositório Maven
O Apache Maven é a principal ferramenta de gerenciamento de configuração e também de automação
dos processos de compilação, construção e liberação, utilizada pelo jCompany Configuration
Management‡‡‡.
O Maven deve ser utilizado pela empresa para um controle refinado de versões, gerenciando bibliotecas
de componentes específicos e reutilizáveis por cada aplicação. É também utilizado em maior extensão
pelo jCompany QA Suite, que possui especializações em plugins Maven para a área de controle de
qualidade. Veremos um pouco mais sobre Maven quando formos compreender a estrutura padrão dos
pacotes (packages) que compõem as aplicações e rotinas de liberação – vamos, por enquanto, apenas
entender a estrutura básica de seu repositório.
O repositório Maven contém todos os componentes homologados para utilização em projetos jCompany,
em diferentes momentos:
‡‡‡
O jCompany traz rotinas alternativas escritas em Ant, porém são mantidas apenas para compatibilidade com versões anteriores.
50
Instalando o jCompany
o Componentes para uso em “tempo de compilação” apenas. Neste caso, os componentes não
precisam ser montados no executável da aplicação (não compõem o executável da aplicação), mas
apenas referenciados pelo Class Path dos projetos do Eclipse. Normalmente, é o caso das APIs Java
EE (javaee-5.jar, mail.jar, servlet.jar, etc.) ou clientes JMS (jboss*.jar), que já existem ou devem
ser montados diretamente no Application Server.
o Componentes para uso em “tempo de montagem”. Neste caso, os componentes não somente
entram em tempo de compilação, no Class Path do Eclipse, como são montados dentro do
executável da aplicação (compõem o executável da aplicação). É o caso da maioria das bibliotecas
Open-Source (jboss-seam*.jar, trinidad-impl*.jar, etc.)
o Componentes para uso em “tempo de execução” apenas. Neste caso, os componentes não
precisam estar presentes nem em tempo de montagem nem em tempo de compilação dos projetos,
pois não são utilizados diretamente por eles. No entanto, são homologados para uso pelo Application
Server. É o caso dos drivers JDBC homologados (o10jdbc14.jar, mysql-connector.jar, etc.).
Estes componentes podem ter ainda dois formatos típicos de arquivo:
o JAR, que agrupam classes em forma executável (.class), e serão montados abaixo de diretórios
“WEB-INF/lib” dos arquivos executáveis das aplicações (WAR).
o WAR, que agrupam artefatos Web que são liberados em forma fonte, tais como CSS,
Javascript, JSP, Tag-files, mídia, etc., e serão expandidos a partir do diretório raiz dos arquivos
executáveis das aplicações (WAR)§§§.
Existem diversos diretórios abaixo do diretório raiz do repositório Maven, em “[jcompany-
base]\repositorio”, que não devem ser de preocupação do desenvolvedor, por serem de uso interno do
Maven.
O principal diretório a ser entendido é o diretório “[jcompany-base]\repositorio\powerlogic”.
Diretório “[jcompany-base]\repositorio\powerlogic”
Subdiretório Objetivo
§§§
No caso das JSPs, há uma opção de pré-compilação para quando forem liberadas para ambiente de produção Tomcat, deste modo
significando que não serão montadas como código fonte nos executáveis, mas como sua versão binária “.class”. Os demais Application
Servers possuem utilitários próprios para este objetivo, acionáveis em tempo de liberação (deployment).
51
Capítulo A2
Será difícil “tirar o máximo” do desenvolvimento Java EE Open-Source sem práticas eventuais de
inspeção em códigos de produtos reutilizados, para depuração e customizações refinadas. Se bem
configurados na IDE, tanto o Javadoc quando os códigos fontes se tornam uma ajuda essencial,
facilmente disponíveis e melhor utilizados.
É para promover este hábito que o jCompany sempre instala, além das versões binárias dos frameworks
e utilitários homologados, seus códigos fontes e javadocs em versões correspondentes, já corretamente
configurados também para acesso via Eclipse.
- Servidores de Aplicação
O diretório “[jcompany-base]\servers” contém os Application Servers Open-Source utilizados para
homologação de aplicações produzidas pelo jCompany:
Diretório “[jCompany-base]\servers”
Subdiretório Objetivo
tomcat Tomcat 6.x: Não costuma ser rigorosamente batizado de Application Server por
não possuir container EJB e todos os serviços Java EE. Porém, tem qualidade de
****
O Maven possui utilitários que copiam as dependências para projetos Eclipse, mas o fazem sem manter a coesão (agrupamentos)
lógica da arquitetura, terminando por gerar projetos configurados no Eclipse com baixo nível de abstração.
52
Instalando o jCompany
produção desde sua versão 5.x, e excepcional performance na versão 6.x graças
à utilização de recursos para acesso nativo a sockets. É recomendado como
opção principal para desenvolvimento e também para produção quando
trabalhando somente com POJOs. Estes podem ser portados para EJB3, se
desejado, em estágios finais, e homologado neste momento em alguma das
outras duas opções.
Importante 1: Esta relação pode variar conforme o release exato do jCompany. Novas opções podem
ser adicionadas ou retiradas, bem como releases menores destes produtos atualizados.
O uso do Tomcat e Glassfish como primeiras opções de homologação garante aderência de aplicações
produzidas pelo jCompany às implementações de referência da SUN, o que aumenta as chances de
portabilidade para qualquer outra opção. Mas ainda resta à Powerlogic a realização de trabalhos
adicionais nesta área, para solucionar idiossincrasias de cada ambiente, não garantidas pela
especificação.
Importante 2: O JBoss AS, e opções comerciais mais comuns de mercado, tais como BEA Weblogic
10.x, IBM WebSphere 7.x e OAS 10g também são homologadas, sob demanda, nas versões
corporativas do jCompany, Mas, por serem proprietários, estes produtos não são incluídos em sua
distribuição.
- Documentação da Metodologia
O jCompany incorpora métodos e padrões para a fase de Construção em tecnologia Java EE, incluindo
roteiros “passo-a-passo” para a codificação de Casos de Uso padronizados, em alto nível. Esta
metodologia fica integrada a IDE, em sua Ajuda On-Line, no formato HTML e com conteúdo disponível
para busca textual, e também abaixo do diretório “[jcompany-base]\jcompany_documentacao”, em
formatos originais que permitem edição e customização facilitada, caso seja desejável.
A licença do jCompany é permissiva com relação a modificações, seja no código fonte ou documentação
da metodologia. Obviamente, ao modificar-se algum artefato produzido e mantido pela Powerlogic, com
exceção do uso de pontos específicos de extensão (APIs), corre-se o risco de ter-se que reaplicar
alterações em uma eventual atualização de versão.
Portanto, deve-se utilizar estas prerrogativas somente em último caso, evitando-se modificar
demasiadamente os artefatos.
53
Capítulo A2
Sumário
Neste capítulo, discutimos sobre como a busca por um alto índice de produtividade via reúso requer
especial atenção nas disciplinas de gerência de configuração e controle de versões.
Mostramos porque isto é especialmente verdade em um mundo Java EE Open-Source, citando as
dificuldades comumente encontradas para se manter um ambiente de desenvolvimento Open-Source
estável ao longo das versões e da escalada de complexidade dos projetos – condição básica para que se
mantenha produtivo, receptivo ao reuso.
Apresentamos o instalador integrado do jCompany como uma solução nesta área, destacando os vários
benefícios advindos de uma gerência de configuração que garante a instalação unificada de dezenas de
produtos “melhores em sua categoria” (Best-of-Breed), configurados e pré-homologados para
funcionamento em conjunto.
Por fim, tecemos explicações sobre os procedimentos básicos de instalação e para o entendimento inicial
de todo o diretório resultante, seu propósito e critério de organização.
No próximo capítulo vamos entender o Ambiente Integrado de Desenvolvimento do jCompany, baseado
no Eclipse, e criar o nosso primeiro projeto…
54
3
Capítulo
Entendendo o Ambiente de
3
A
Desenvolvimento
Introdução
A té a década de 80, um desenvolvedor de software típico lidava com uma diversidade de ferramentas
para realizar o seu trabalho: editores de códigos fontes, utilitários de compilação e montagem, produtos
para depuração e logging, dentre outros. Esta desconexão de ferramentas aceitava e tornava freqüente
mesmo os erros mais elementares, tais como diretivas e caminhos (paths) inválidos - um mundo nada
fácil para iniciantes.
Com o advento das interfaces gráficas e popularização das tecnologias Cliente/Servidor na década de 90,
começaram a surgir, finalmente, as “aplicações” do desenvolvedor. Fabricantes como Microsoft, Borland e
Sybase (PowerSoft) introduziram tais produtos, que tomaram de assalto os departamentos de TI por
simplificarem o acesso ao resultado e aumentarem a produtividade em geral.
Logo seguidos pela IBM e Oracle, os fabricantes líderes neste segmento disputavam presença nas
empresas mantendo um valor médio de licença em torno de U$ 5.000,00 por desenvolvedor (Opções
mais baratas estavam disponíveis, mas com restrições técnicas para uso corporativo). Nada mal para
estes fornecedores, com o mundo em franca informatização...
Mas com a demanda para desenvolvimento Cliente/Servidor encolhendo no final da década passada, eles
tiveram que reposicionar suas IDEs para a tecnologia Java. E o fizeram praticando a mesma base de
preços tradicional. Novos players surgiram nesta fase, tais como a BEA, IntelliJ e a própria Sun, de olho
em um filão promissor.
Esta disputa entrou pelo século XXI tendo na ferramenta JBuilder da Borland alguns sinais de liderança,
seguida pelo JDeveloper da Oracle e pelo WSAD da IBM. Mas as vendas eram ainda pífias. Comunidades
do incipiente movimento Open-Source começavam a disponibilizar alternativas na forma de editores de
código Java com alguma inteligência que, apesar de não serem IDEs competitivas em funcionalidades,
tinham na gratuidade apelo suficiente para desacelerar vendas
Este não seria ainda um advento ameaçador para os fornecedores, caso a IBM não houvesse decidido
doar o núcleo de seu ambiente de desenvolvimento, o WSAD, para a comunidade Open-Source, batizado
como “Eclipse Plataform”. O mercado terminou por torná-lo seu ambiente de desenvolvimento
preferencial, com mais de 80% de adesão, em alguns poucos anos.
Com uma opção de qualidade e gratuita, as empresas puderam utilizar as somas economizadas com a
“não aquisição” de IDEs no desenvolvimento de mais projetos e/ou aumento de sua produtividade via
aquisição, pelo mesmo custo, de uma solução muito mais abrangente. Por exemplo, englobando
frameworks, geradores de código, metodologias, ferramentas CASE, ambientes para desenvolvimento em
equipes, etc.
Com seus produtos encalhados, os fabricantes tradicionais tiveram que tomar outros rumos: alguns
mantiveram seus produtos para vendas fashion (pela marca), comprando outras empresas para tentar
agregar valor à sua opção; outros abriram o código de seus produtos e os doaram para comunidades
Open-Source, como tentativa de concorrer com o Eclipse... Mas nada disso convenceu o mercado ou
alterou o seu market-share.
55
Capítulo A3
A breve história do nascimento e ocaso do mercado de IDEs é uma grande demonstração prática
do poder e benefícios do movimento OSS (Open-Source Software) para as empresas compradoras
de TI.
A IDE Eclipse
- Eclipse x Netbeans
No momento da escrita deste livro, em setembro/2007, a única alternativa considerada pela Powerlogic,
como possível para uma portabilidade futura dos plugins jCompany Code Generator, seria a IDE
Netbeans, da Sun, outra opção Open-Source ††††.
A principal vantagem do Netbeans, quando citada em comparações com o Eclipse, tem sido o seu
ambiente “pronto para uso”, no que se refere ao desenvolvimento Java EE 5. E, em nossa experiência, é
procedente: a economia de tempo em pesquisa, seleção e configuração manual de plugins, tarefas
especialmente difíceis para iniciantes em Java, não deve ser desprezada, pois facilita a adoção,
eliminando as barreiras culturais iniciais.
Existem outras comparações mais minuciosas (algumas mais “sentimentais” e outras mais “imparciais”)
entre estes produtos, mas, honestamente, saindo do que dissemos, estaríamos entrando em “micro-
comparações”.
Mas o fato é que esta vantagem inicial do Netbeans sobre o Eclipse como IDE Java EE é revertida quando
comparamos este ambiente com um ambiente Eclipse+jCompany!
Além de prover uma instalação da IDE Eclipse turbinada, com diversos plugins totalmente configurados, o
jCompany já instala frameworks, utilitários, documentação da metodologia com checklists integrados a
IDE, tudo isso imediatamente funcional, muitas vezes à frente do que uma IDE sozinha poderia prover.
Trata-se de um “pronto para uso” bem mais “pronto”...
Curiosamente, a mesma “ultra flexibilidade” que atrapalha o iniciante no Eclipse é também a responsável
por possibilitar a existência de um ambiente gerenciado com alto nível de integração com a IDE, como o
do jCompany Developer Suite.
††††
Após o confuso lançamento de um produto comercial chamado Java Studio Creator e da decisão subseqüente de integrá-lo ao
Netbeans – sua alternativa Open-Source de mais aceitação, a Sun se valeu do lançamento do Java EE 5 para oferecer um salto
qualitativo neste último que, de fato, lhe trouxe o status de “concorrente do Eclipse”. Apesar de ter ainda um “market-share” pequeno,
a simples existência de um concorrente neste nicho é saudável, e já ajudou a “aumentar os músculos” na comunidade Eclipse.
56
Entendendo o Ambiente de Desenvolvimento
O Eclipse no jCompany
‡‡‡‡
O jCompany utiliza apenas uma parte do total de plugins hoje embalados em conjunto pelo Red Hat, conhecidos como JBoss Tools
(versao Open-Source) ou Red Hat Developer Studio - RHDS (versão comercial). Basicamente, o jCompany se vale dos editores de Tiles
e JSF/Struts, originalmente criados pela empresa Exadel e adquiridos pelo jBoss Group. Neste livro, será utilizada a sigla RHDS, de
forma simplificada, não significando que este produto esteja inteiramente disponível.
57
Capítulo A3
A Figura A3.2 já foi descrita em detalhes no capítulo introdutório, e ilustra a arquitetura de alto nível do
ambiente Eclipse, considerando-se as camadas de edição Java EE e também outros plugins “paralelos”,
não necessariamente “empilhados” sobre o JDT ou WTP.
Hum... Se o desenvolvedor for um iniciante no mundo Eclipse, já deverá estar percebendo que,
exatamente devido à sua arquitetura excepcionalmente flexível, pode-se demandar um bom tempo para
uma compreensão profunda do mesmo, em toda sua amplitude.
Felizmente, isso não é necessário em um primeiro momento! Poderemos iniciar imediatamente a sua
utilização para o nosso propósito, com boa produtividade, especialmente porque o jCompany vem com
um roteiro de utilização que apóia decisivamente os iniciantes, acionando os plugins apropriados através
de roteiros "passo a passo" que o conduzem até a obtenção do resultado final, para diversas situações
comuns.
58
Entendendo o Ambiente de Desenvolvimento
RHDS – Red Hat Developer Como citado, complementam o suporte principal do desenvolvimento
§§§§ especializando o WTP para que reconheça arquivos de configuração
Studio
de frameworks de uso comum tais como Struts, JSF, Tiles, Hibernate
e JPA, edição visual de arquivos (.jsp), dentre outros.
Eclipse BIRT Conjunto de plugins mantidos pela empresa Actuate para confecção
de relatórios WYSIWYG sofisticados, podendo incluir gráficos,
quebras e totalizações, exportação de dados e geração em vários
formatos.
§§§§
No momento desta escrita, em dezembro de 2007, a Red Hat anunciou a liberação de um modelo comercial utilizando-se deste
nome. Esta versão, no entanto, é bastante diferente da utilizada pelo jCompany, que somente reutiliza alguns produtos chave dos
produtos, originalmente disseminados com nome de JBoss Tools. Apesar de bem confuso, este modelo de licenciamento não é
impeditivo para o uso dos componentes de software parciais do JBoss Tools, como utilizado pelo jCompany.
59
Capítulo A3
Hibernate Console Permite a configuração de uma fábrica Hibernate local, para testes e
codificação assistida de HQL. Verifica também a sintaxe dos HQLs
embutidos em códigos Java, dentre outros recursos.
Rhino Javascript Plugin que traz recursos para edição e depuração de arquivos
Javascript.
*****
Estes plugins são instalados separadamente no diretório “[jcompany_base]\eclipse\pluginsPlc”,. Deste modo, ficam separados de
plugins padrões da plataforma Eclipse ou daqueles adicionados pelo desenvolvedor.
60
Entendendo o Ambiente de Desenvolvimento
Esta categoria de plugins pressupõe o uso de determinada arquitetura, no caso, a provida pelo
jCompany FS Framework. Note que estes plugins não seriam de serventia, isolados do
framework, por exemplo - mas são excepcionalmente melhores para a produção de uma primeira
versão de resultado que siga “melhores práticas”.
o Os “plugins de edição” genéricos, para complementação e ajustes livres que se façam
necessários, a partir daí.
O seu propósito é bem distinto do primeiro: permitirem uma elaboração flexível e livre do que quer
que se faça necessário ajustar, nos vários formatos de artefatos Java EE, e com flexibilidade
exigida por especificidades de cada Caso de Uso. Esta categoria de plugin é mais comum no
mercado - o jCompany, como já vimos, reutiliza para este fim os plugins WTP e da Red Hat.
61
Capítulo A3
Figura A3.6. Plugin de edição WYSIWYG do Red Hat Studio, especializado para modificações genéricas de JSP.
Figura A3.7. Diretório de instalação dos plugins de processo do jCompany (jCompany Artifact Generator)
*
Exceto em cópias de avaliação.
62
Entendendo o Ambiente de Desenvolvimento
quaisquer informações desde informações sobre padrões e práticas de construção recomendados, até
dúvidas freqüentes respondidas.
Aprender a utilizar bem a Ajuda On-Line é como se pode “aprender a pescar” conhecimentos. Vamos,
portanto, exercitar um pouco este acesso, configurando a Ajuda On-line para nos permitir uma busca
textual restrita à metodologia e base de conhecimento do jCompany, e fazendo uma pesquisa-modelo:
1. Acionar o menu “Help -> Help Contents”
2. Na página principal do Help On-Line, clicar em “Search Scope”. No diálogo “New Search List”, digitar
“Powerlogic” em “List name” e selecionar o tópico “Powerlogic jCompany” na lista.
3. Selecionar o filtro da busca somente para jCompany, no diálogo “Select Search Scope”.
4. Testar a busca restrita, digitando “email” no campo “Search”. Deve-se reparar que não somente
aparecerão os vários capítulos onde ocorra o termo, mas que estarão ordenados por número de
ocorrências e com o termo em destaque à direita.
*
O resultado pode depender da versão (e release) utilizada. Cópias de avaliação, por exemplo, podem não conter a documentação
completa.
63
Capítulo A3
Figura A3.10. Pesquisa por ‘email’ retornando capítulos da metodologia e base de conhecimento
Figura A3.11. Pesquisa com Control+F dentro do capítulo para achar termos.
64
Entendendo o Ambiente de Desenvolvimento
Figura A3.12. Listas de pendências do usuário ou equipe, associadas ou não a linhas de códigos fontes.
2. Novas tarefas podem ser criadas a partir de opção da visão, como na figura 10, ou simplesmente
comentando-se, dentro de códigos fontes, com determinados prefixos padrões, tais como “TODO”,
“FIXME” e outros que podem ser definidos.
Já os Cheat-Sheets têm um objetivo bem distinto das Tasks, que é o de “orquestração*” do processo
de desenvolvimento. Os Cheat-Sheets são definidos através de roteiros com ações de
desenvolvimento, que podem, em cada passo, acionar um plugin distinto. Deste modo, após uma
seqüência de passos discretos, o desenvolvedor pode produzir um resultado complexo, tal como a
produção de um Caso de Uso, passando por dez ou mais plugins distintos, ao todo.
Vamos conhecer o funcionamento de um Cheat-Sheet no próximo tópico, importando e liberando a
aplicação de exemplo “rhdemo”.
*
O conceito de “orquestrador” reside do fato de que, de forma similar ao “maestro” conduz a sua orquestra, os Cheat-Sheets
conduzem o desenvolvedor para executar a atividade certa, na ordem certa e chamando o plugin correto (mais apropriado para a ação,
segundo o processo). Mas os roteiros do Cheat-Sheets em si não contém e nem executam nenhuma ação que não seja de
acionamentos e explicações, assim como o maestro não toca nenhum instrumento.
65
Capítulo A3
3. Seguir agora as instruções de cada passo do roteiro, clicando em “Click to Complete” em seguida ou
conforme orientação da documentação do passo.
66
Entendendo o Ambiente de Desenvolvimento
5. Agora vamos acionar um segundo roteiro dos Cheat-Sheets, chamado “Executando o RH Demo”.
Certifique-se de estar com o projeto jcompany_rhdemojsf (ou jcompany_rhdemo, para Struts)
selecionados, e siga as instruções do roteiro.
Importante: Não iremos redundar as instruções do roteiro neste livro, mas seguem abaixo algumas
dicas e exemplos de ações chave no processo, para conferência:
o Não modifique o arquivo de configuração de pool, já que vamos utilizar o SGBD-R Apache
Derby, para o qual a configuração já está pronta.
o Para ativar o SGBD-R Apache Derby, que já vem pré-configurado e disponível para cada projeto
(iremos ver mais em detalhes em capítulos subseqüentes), clique direto no projeto e, em
seguida, em “Apache Derby -> Start Derby Network Server”.
o Acione o Tomcat somente após o Derby estar ativo, através do ícone do gato (Tomcat Sysdeo),
e verifique se as últimas mensagens de log na janela console contêm a porta do serviço
67
Capítulo A3
7. Navegue pelas opções da aplicação “RH Demo”, se desejado, para obter uma impressão geral sobre
padrões de interface e aparência dos Casos de Uso disponibilizados. Iremos desenvolver uma
aplicação similar, do zero absoluto, neste livro – mas não exatamente a mesma!
68
Entendendo o Ambiente de Desenvolvimento
o [jcompany_base]\meus_projetos\
jcompany_ini_struts
o Nome (Opção): Struts Cria 1 (um) projeto Eclipse, contendo Pode ser utilizado para
Arquivo Modelo: todas as camadas MVC separadas por projetos mais simples, com
[jcompany_base]\meus_projetos\ pacotes: dez ou menos Casos de Uso,
jcompany_ini.zip por exemplo, para evitar-se
Projeto Modelo Expandido para o [nome do projeto]: Projeto “principal”, proliferação de projetos de
Customização: contendo artefatos para todas as desenvolvimento nestes casos.
camadas Visão, Controle, Modelo,
o [jcompany_base]\meus_projetos\ Persistência e Comuns. Obs.: É importante notar que
jcompany_ini é possível se trabalhar
rigorosamente dentro das
exigências de separações de
camada, dentro de um mesmo
projeto de desenvolvimento.
Um melhor entendimento sobre a arquitetura de desenvolvimento MVC sugerida pelo jCompany será
obtido mais a frente, ainda neste capítulo. Por hora, vamos criar um projeto inicial, que utilizaremos nos
tutoriais deste livro, a partir do modulo B.
69
Capítulo A3
*
Figura A3.22. Diálogo de criação do projeto “rhtutorial” preenchido .
E clicar em “Finish”†.
Obs.: Aguardar alguns instantes (30 segundos a alguns minutos, dependendo da capacidade e
configurações da máquina), para os três projetos envolvidos serem criados.
3. O roteiro abrirá, nos passos seguintes, arquivos de configuração chaves para o desenvolvimento
Java EE, a saber:
Figura A3.23. Arquivo de configuração de pool JDBC padrão para o Tomcat (DBCP).
*
Importante: Se receber uma mensagem solicitando a apresentação da licença de uso, vá ao site da Powerlogic e se registre para
receber uma licença de demonstração. O processo é rápido e todo automatizado - após um cadastro básico, um e-mail lhe será enviado
com um arquivo em anexo, para ser incluído no diretório raiz do jCompany. Com isso, o uso fica liberado.
†
Se ocorrer um erro ao usar o nome rhtutorial (porque o projeto “rhtutorial” já existe abaixo do diretório “meus_projetos”), renomeie
o projeto existente para “rhtutorialplc” ou use um outro nome no novo projeto, como “rhtutorial2”. Isto é necessário porque, em alguns
releases de demonstração, o projeto “rhtutorial” contendo a aplicação desenvolvida neste livro já vem configurado com este nome.
70
Entendendo o Ambiente de Desenvolvimento
Figura A3.24. Arquivo de configuração Maven, do projeto. Reparar na versão sugerida e nos módulos.
4. É aconselhável que se execute uma liberação desta aplicação para o Tomcat, tal como fizemos com
a aplicação “Rh Demo”, a fim de se conferir se o esqueleto geral está correto. Para tanto, basta
seguir as orientações de liberação do roteiro, e conferir se a página principal da aplicação abre no
Tomcat, agora com o endereço http://localhost:8080/rhtutorial. (Utilizar o mesmo usuário e senha
“admin” e “senha”, utilizados no “rhdemo”).
71
Capítulo A3
Sumário
Neste capítulo, discutimos a importância da IDE Eclipse, incluindo os benefícios que trouxe para o
mercado com a eliminação de custos de aquisição neste segmento e também seus méritos técnicos, que
permitiram a criação do ferramental customizado no jCompany, totalmente pré-configurado e instalável
em um único acionamento.
Discutimos ainda sobre como o jCompany especializa o Eclipse, trazendo: plugins Open-Source
homologados de terceiros e plugins Open-Source próprios, além de documentação e roteiros Cheat-
Sheets de sua metodologia de construção, integrados a IDE.
Aprendemos a explorar a busca textual da Ajuda On-Line e a operação básica de Cheat-Sheets, criando
nosso projeto “rhtutorial”, que será utilizado durante os capítulos subseqüentes.
No capítulo IV iremos compreender a fundo a arquitetura dos projetos gerados, tanto do ponto de vista
de estruturação interna (pacotes, classes e artefatos padrões), quando externa (dependências e visão
geral da arquitetura MVC).
72
4
Capítulo
Entendendo a Arquitetura
4
A
de Desenvolvimento
Introdução
O jCompany Developer Suite pode ser compreendido como uma solução de reúso em nível
arquitetural. E não apenas para reúso de camadas de base de arquitetura para as aplicações
desenvolvidas, mas também para o ambiente de desenvolvimento (IDE) e de Testes de Unidade. Estas
soluções arquiteturais de base são providas, respectivamente, pelos módulos jCompany FS
Framework, jCompany IDE e jCompany Test for Developer.
Mas qual seria a diferença deste tipo de reúso em comparação ao reúso mais pontual, digamos, em nível
de uma classe ou pequeno grupo de colaboração de classes?
O reúso arquitetural possibilita reúso de estratégias complexas englobando desde o reúso de
colaborações extensas de frameworks, somada à produção assistida de especializações preconizadas por
métodos e padrões delineados pela arquitetura. Este tipo de reúso é de mais alto nível que os demais.
Digamos, uma integração de várias estratégias de reúso pontuais, que produz um resultado de
valor visível para o cliente (Ex.: um Caso de Uso potencial) e não soluções parciais intermediárias.
Em outras palavras: muito embora sejam importantes as táticas de reúso em nível de classe ou via
padrões de projeto (Design Patterns), o reúso arquitetural é de nível mais estratégico,
fundamental para quem deseja ganhos de produtividade e qualidade em ambientes com
desenvolvimentos em larga escala. Estes ganhos equivalem aos que se consegue construindo
uma nova casa a partir de componentes maiores, pré-fabricados, em comparação a se começar
selecionando madeira para fabricar portas, por exemplo.
Apesar de não existir uma única solução de arquitetura perfeitamente adequada a todas as situações, as
diversas dimensões de arquitetura pré-implementadas no jCompany são customizáveis...
Para isso vingar na prática, porém, torna-se necessário um entendimento mais profundo das suas
implementações, inclusive das motivações fundamentais (Rationale) que guiaram a Powerlogic em sua
proposta. Este capítulo inicia esta discussão.
“Uma Arquitetura de Software para um sistema é a que define a estruturação deste sistema, que
compreende seus Elementos, a Relação entre eles e as Propriedades externamente visíveis destes
Elementos e Relações.”
Ref. A4.1. [TS-4619 JavaOne 2006]
“A arquitetura de qualquer aplicação deve ao menos incluir (quando não se basear em)
considerações de performance. A arquitetura de uma aplicação corporativa deve considerar os
Ciclos de Vida de Objetos, assim como a sua forma de uso”
Ref. A4.3. [Haines, Steven 2006]
73
Capítulo A5
Não há muita controvérsia sobre a importância decisiva que uma boa Arquitetura de Software pode ter
em processo de desenvolvimento de software em geral. Também há um grande reconhecimento, por
parte de especialistas, com relação ao papel central que os frameworks assumem nesta questão. Porém,
muitas empresas não chegam a experimentar os resultados prometidos nesta área…
Para não corrermos este risco, e obtermos os melhores resultados, nossa proposta somará o reúso de
uma arquitetura abrangente com padrões de alto nível e automação de atividades, orquestradas por
Cheat-Sheets do Eclipse.
Nossa arquitetura também será ajustada para a eficiência de processamento, um outro ponto comumente
negligenciado. É um erro imaginar a arquitetura apenas do ponto de vista estrutural e teórico. A
arquitetura influi decisivamente em performance, e devem ser considerados os comportamentos
dinâmico e prático da aplicação, além dos fatores usabilidade, flexibilidade e outras dimensões
concorrentes, em nossa problemática.
Não se satisfaça com uma Arquitetura de Software rasa. Mesmo uma arquitetura incipiente poderá
produzir um bocado de documentos e diagramas impressionantes, mas trará resultados medíocres,
quando algum. Uma arquitetura para o perfil típico de projetos corporativos, por exemplo, deve
definir, em detalhes, dependências entre projetos e módulos, pacotes dentro de projetos,
artefatos, eventos de programação de alto nível e, finalmente, trazer um bom número de
generalizações e padrões que conduzam a um resultado visível para o negócio, rapidamente.
Neste estágio, as lacunas estão vazias entre a plataforma de infra-estrutura Java EE (1) e as aplicações
de negócio (4). Por este motivo, um enorme potencial para erros está à espreita dos desenvolvedores,
que ficam às voltas com programações repetitivas de código, que deveriam estar fatorados em
nível arquitetural.
Não há como evitar. Para uma arquitetura real, será necessário que os arquitetos passem do
domínio dos conceitos para a “experiência de uso nas tecnologias, suas possíveis combinações,
deficiências e valores, além de prováveis variações de uso”.
Montar uma arquitetura madura demanda um tempo que não pode ser facilmente abreviado –
especialmente uma que envolva altíssimas taxas de reuso, partindo de soluções “best-of-breed” Java EE
Open-Source. Nesta filosifia, que é a adotada pelo jCompany, a recomendação é escolher peças
74
Entendendo a Arquitetura de Desenvolvimento
“melhores em seu segmento”. Algumas dezenas de tecnologias, projetos e componentes OSS deverão ser
entendidos, selecionados, especializados e integrados, muitos deles em áreas de conhecimento com
razoável distinção das demais.
Por exemplo, a camada Visão do MVC envolve a orquestração de diversas tecnologias complexas, tais
como JSP/HTML, Javascript, CSS, Ajax, técnicas de gestão de leiautes, etc., nenhuma delas de
domínio específico do mundo Java ou OO, de domínio dos Arquitetos de Software. O resultado,
na prática, é uma quase ausência de arquitetura para a camada Visão, delegada para
tratamento superficial pelos Web-Designers.
Refinar uma boa arquitetura para a camada Controle também tem seus desafios, já que esta é bem
mais complexa, tecnologicamente, do que as camadas subseqüentes de Modelo/Domínio ou Persistência.
É uma outra camada onde o nível de soluções de arquitetura costuma ser muito raso, basicamente
consistindo de homologação de algum framework de base, "em seu estágio bruto".
As camadas de Modelo, Domínio e Persistência, por serem mais puramente ligadas a linguagem Java
e às regras de negócio, costumam receber 90% da atenção nos trabalhos típicos de Arquitetura de
Software, ao menos em seu estágio inicial. Porém, ao longo do tempo se fará necessário um esforço
nas demais camadas, que exigirão um considerável aprofundamento tecnológico...
75
Capítulo A5
Mas para ser de “nível intermediário”, realisticamente, esta arquitetura irá requerer uma comprovação de
uso satisfatório em produção – seguido das inevitáveis refatorações - por pelo menos dois anos. É um
período mínimo, após a construção da primeira versão, durante o qual uma equipe de perfil abrangente*
conseguirá evoluir para este nível de maturidade.
A partir deste ponto, no entanto, este modelo começa a apresentar suas limitações, especialmente se a
implementação arquitetural for concebida e desenvolvida totalmente por equipe interna:
*
Composta de Arquiteto de Software, Analistas de Negócio, Web-Designers, Peritos nas Tecnologias, Documentadores, Analistas de
Teste, etc.
76
Entendendo a Arquitetura de Desenvolvimento
o Desvio de Foco: Uma equipe de valor estará dedicando boa parte de seu tempo em atividades
totalmente fora do foco do negócio, já que grande parte da solução arquitetural não é diferencial
para seu negócio.
o Aumento de Custo: Mesmo que haja uma contratação de terceiros para a manutenção desta
camada, perdem-se os ganhos de escala possíveis, a partir do reúso da parcela “commodity” da
arquitetura.
o Problemas de Gestão: Normalmente, os problemas se agravam na medida em que começa a
existir uma “base instalada” da arquitetura em produção. Na fase de manutenção, requisitos de
Gerência de Configuração passam a consumir uma grande parcela de esforço da equipe
interna, para manter ramos “de evolução” em paralelo com ramos “compatíveis”. A partir daí, não é
incomum que o entusiasmo técnico das primeiras fases dê lugar a turn-overs ou queda considerável
de produtividade.
A percepção mais comum é de que há uma dificuldade de ordem prática para que esta solução “familiar”
evolua para o próximo passo. Na medida em que as pressões de negócio sobre aplicações implantadas
prevalecem como prioridade, como haverá de ser, há uma tendência à estagnação ou lentidão para a
incorporação de inovações, medo de reformulações, etc..
Neste estágio, as preocupações de nível arquitetural que não sejam absolutamente dependentes do
contexto específico da empresa são totalmente desacopladas de preocupações de natureza comum ou
commodity.
Este é o primeiro modelo que oferece um importante raciocínio de negócios: a terceirização das
camadas arquiteturais “2” e “3”, horizontais, de forma a possibilitar a concentração da organização nas
camadas “4” e “5”. De fato, somente as duas últimas têm relevância para o ambiente específico
de TI e verticais de negócio.
Com esta possibilidade, aumenta-se não somente o foco no negócio. Diminui-se o custo e herda-se
qualidade e maturidade, abreviando-se longos anos e um grande número de problemas.
77
Capítulo A5
Figura A4.5. Arquitetura em camadas de uma aplicação Java EE com o jCompany Full Stack Framework.
78
Entendendo a Arquitetura de Desenvolvimento
Todo reúso exige esforço de compreensão e adesão ao que se deseja reutilizar, em um primeiro
momento, e deve possibilitar diferenciações e flexibilidade para ganhos em níveis mais altos. Isso
vale para o reúso de arquitetura, de objetos ou de componentes.
Revisão de Fundamentos
*
São o que Rod Johson, o criador do Spring, chama de “Own Career Driven Architects” [Johnson, Rod 2004] - indivíduos que não
compreendem a importância, para sua empresa, de orientarem a sua “criatividadde” para camadas de negócio. É a insistência em não
reusar, pelo desafio (ou interesse) pessoal de fazer.
79
Capítulo A5
o “Visão Interna” (Internal View): Utilizaremos a Visão Interna para representar como estão
organizados os projetos de desenvolvimento, do ponto de vista de sua estruturação interna. É um
tipo de visão de “micro-arquitetura”, considerando organização dos pacotes e artefatos padrões
definidos.
o “Visão Comportamental” (Behavior View): Utilizaremos a Visão Comportamental para
representar como as categorias de classes colaboram entre si em algumas anatomias de requisição
MVC-P típicas.
o “Visão de Execução” (Runtime View): Utilizaremos a Visão de Execução para representar como
podemos embalar e liberar os conjuntos de componentes em tempo de execução, distribuindo-os ou
mantendo-os em co-habitação, e como eles se relacionam nestas possíveis variações de infra-
estrutura. (Volume II)
o “Visão da Interface com o Usuário” (GUI View): Utilizaremos a Visão de Interface com o
Usuário para representar os padrões de leiautes, formulários e componentes disponíveis, como estão
organizados e interação entre si. Ela não contempla questões de usabilidade, discutidas fora do
âmbito da arquitetura.
Além das representações principais para as visões acima, o detalhamento da arquitetura requer
documentos mais extensos que, por motivos didáticos, não são disponibilizados neste livro. Eles estão
disponíveis na documentação do módulo “jCompany Patterns & Methods”, cedido com a licença
corporativa do jCompany.
Neste capitulo, apresentaremos as três primeiras visões: "Geral", "de Módulos" e “Interna”. Com a
exceção da "Visão de Execução", que somente será abordada no Volume II desta série, as demais serão
discutidas em capítulos subseqüentes.
80
Entendendo a Arquitetura de Desenvolvimento
Olhando a revisão à direita, real, percebemos que se trata de uma arquitetura muito mais complexa
que a sugerida à esquerda. Neste caso, inclusive mais instável, pois sofre de um mal conhecido
como “referência circular”. Este é um problema que gera alto acoplamento, e deve ser evitado em
todas as camadas de abstração de um software.
Obs.: Mesmo nestes casos, muitas vezes a diagramação em camadas é utilizada, para simplificar
o diagrama em si, ou enfatizar um comportamento. Por exemplo, a diagramação da esquerda, na
Figura A4.10, é mais simples; mas quando é exigido um rigor técnico, pode dar margem a confusão.
Repare a versão mais exata à direita, exibindo claramente que C dependente diretamente de A e B.
o Camadas paralelas e ortogonais: Como as organizações de software são bem mais complexas do
que pode sustentar a metáfora do “bolo de festa”, no mundo real nós iremos nos deparar com
combinações mais sofisticadas das várias abordagens possíveis, ou várias “dimensões de camadas”.
81
Capítulo A5
Nas Figura A4.11 e Figura A4.12 vemos duas combinações em camadas “reais”, que produzem
arquiteturas estáveis, corretamente diagramadas, e inclusive muito comuns em software.
Mesmo em uma arquitetura mais elaborada, como no caso da Figura A4.12, é importante percebermos
que o raciocínio fundamental de “minimizar dependências através do uso de camadas” continua presente.
Mas quais são os critérios para definirmos nossas camadas? O que cada camada irá conter e como
dependerão umas das outras? Bom, estas respostas serão obtidas a partir de um raciocínio OO que
deverá seguir inicialmente os velhos princípios de baixo acoplamento e alta coesão.
82
Entendendo a Arquitetura de Desenvolvimento
Certa vez, uma contribuição a um release menor do Tomcat 5.x introduziu a exigência de
declaração “implements Serializable” para todos os objetos que fossem mantidos em sessão (a
intenção da equipe do Tomcat era atender a um aprimoramento de suporte a Clusters).
As únicas classes que realizavam registro em sessão eram, naturalmente, as que possuíam acesso
(dependência) a interfaces de Servlet. Apesar de ser uma mudança trivial nos objetos (uma
simples declaração), em várias situações de migração para Tomcat 5.x, em todo o mundo, algumas
classes de controle “escapavam” à revisão e cancelavam em produção, manifestando a
“instabilidade” provocada por esta dependência.
É um típico problema produzido em camadas mais baixas da arquitetura, que não acontece nas
superiores (de negócio, por exemplo), graças à organização em camadas do MVC.
Pela nossa experiência, os maiores "crimes de baixa coesão” ocorrem nos métodos “de partida”,
que iniciam a resposta a um evento externo. Exemplos são o método “doGet” de um Servlet ou o
“contextInitialized” em uma implementação de ServletContextListener, ou um “execute” de um DP
Command, utilizado em um framework qualquer. Nestes pontos da arquitetura, não é difícil
encontrarmos verdadeiros programas “COBOL”, em sintaxe Java!
Fatoração de código “pró-forma” é, de longe, uma das questões da arquitetura que mais afetam a
produtividade, e um dos objetivos principais de frameworks de integração!
Uma arquitetura onde são admitidas grandes quantidades de “código burro”, por limitações de tempo ou
de conhecimentos mais aprofundados de OO e Java, fracassará ao menos parcialmente. Se não na
primeira versão da aplicação, nas fases seguintes, com as insustentáveis manutenções.
“A melhor escrita é a reescrita (...). Todo bom escritor sabe disto, e isto é verdadeiro para software
também”
Ref. A4.4. Paul Graham, citando E. B. White, em Hackers and Painters [Graham, Paul 2004]. Pág. 212
Mais recentemente, a “fatoração de código” deu lugar a uma sucessora: a “refatoração de código”
(Refactoring).
Bastante discutida por autores diversos com destaque para Kent Beck e Martin Fowler [Fowler, Martin
2004] e automatizada até certo ponto em IDEs tais como Eclipse, esta mudança de ênfase para a
refatoração faz sentido na medida em que admitimos a dificuldade de se produzir códigos bem fatorados,
“de saída”.
A verdade que hoje conhecemos é que, ao contrário do que alguns metodologistas eminentemente
teóricos apregoam, dificilmente se obtém uma boa arquitetura, na sua primeira versão.
Especialistas nas tecnologias e processos de Especificação (CASE UML, Ferramentas MDA, etc.), mas que
pouco ou nada conhecem das tecnologias e processos de Construção, terão ainda mais dificuldade neste
objetivo. Portanto, será prudente partir de preceitos arquiteturais que visem facilitar a “refatoração ou
reformulação de códigos” de uma forma geral, com a produção do mínimo de instabilidade possível.
83
Capítulo A5
Manutenções de objetos em sua forma básica são operações commodity, candidatas primárias à
fatoração de código em qualquer linguagem de programação, especialmente em linguagens OO tais
como Java, e não deveriam ser resolvidas primariamente com geração de código - “rapidez” que
não se preserva nas manutenções.
Mas, indo além destas operações de manutenção de ciclo de vida, o jCompany generaliza por inteiro
dezenas de outras programações sofisticadas e recorrentes em sistemas corporativos, tais como
“clonagem de documentos”, “assistentes”, “leiaute dinâmico para impressão”, “exploradores de dados
(treeview)”, “exportação de dados”, e muitas outras. Todas elas generalizações que prevêem espaço para
especializações em nível corporativo ou em nível de Caso de Uso, respeitando a arquitetura MVC.
Iremos experimentar estas promessas na prática, no próximo módulo. Neste capítulo, vamos apresentar
a "Visão Geral", “Visão de Módulos” e “Visão Interna” da arquitetura de software proposta pelo
jCompany.
Mas, mesmo sendo macro, esta representação é muito simplória para estudos arquiteturais. Isto porque
nem a camada “3”, do jCompany (Arquitetura Reutilizada) nem a camada “4: , Bridge (Arquitetura
Específica), funcionam como Layer, todo o tempo, como o diagrama pode sugerir.
Exceto nos percentuais de requisitos onde os Casos de Uso Padrões são suficientes, o desenvolvedor
poderá (e isto será desejável), acessar a camada “2” (JBoss Seam, Tiles, JPA/Hibernate, etc.)
diretamente ou, mais raramente, a camada “1”, em nível do Application Server ou JVM.
84
Entendendo a Arquitetura de Desenvolvimento
#1. Nas parcelas de requisitos de Casos de Uso centrados em dados, tanto o jCompany FS
Framework quanto a complementação Bridge praticamente isolam a aplicação das camadas
de baixo, atuando como camadas (Layers). É importante notar as setas tracejadas de
dependência, indicando que estas "camadas" comunicam entre si, para oferecer um resultado
MVC completamente generalizado.
#2. Em requisitos que fogem ou suplementam os suportados pelos padrões, o acesso pode ser
direto à camada de frameworks de base. Deste modo, a arquitetura não restringe; possibilita
ao desenvolvedor elaborar quaisquer soluções que sejam convenientes, para cada caso.
Em quanto por cento dos casos o jCompany FS Framework e a Bridge funcionarão como camadas? Bom,
isso depende da natureza dos requisitos de cada projeto. Em um estudo de ROI (Retorno sobre o
Investimento), elaborado pela Powerlogic, a torta apresentada na Figura A4.15 é tomada como base,
para um projeto corporativo típico.
Assim, em 40% dos casos, em média, espera-se que o jCompany FS Framework atue como uma
camada, evitando contato direto de códigos de negócio com frameworks de base.
Nos demais segmentos de requisitos, o framework irá contribuir provendo serviços de IoC, DI, AOP para
gerência de transações, leiautes, etc.; todos bastante úteis, mas que não visam isolamento. Deste
modo mantém-se a liberdade para que o desenvolvedor acesse qualquer recurso de base, quando
necessário for.
Veja a contribuição esperada (também em média, é claro), para cada fatia de natureza de requisitos,
acima definida, na Figura A4.16.
85
Capítulo A5
Quando funciona como camada, o nível de contribuição do framework do jCompany no estudo foi
impressionante. Mas mesmo considerando-se o percentual de contribuição nas outras fatias,
devidamente ponderados, obtém-se ganhos expressivos!
2. Uso de camada de persistência, subdivindo a de modelo, através do DP DAO (ao que chamamos,
resumidamente, de MVC2-P)
5. Arquitetura rica, também para a camada Visão, com exclusivo “IoC Universal”, inclusive para esta
camada.
2. Em segundo lugar, o jCompany define uma nova camada para serviços de persistência,
subdivisão da camada Modelo, provendo contratos abstratos (Interface e DP Abstract
Factory), além de implementações concretas genéricas e alternativas, para Hibernate ou
JPA. A camada de Persistência não é uma sub-divisão “clássica” do MVC, mas como é um “layer”
verdadeiro e muito comum no mercado, iremos enfatizá-lo com a sigla MVC2-P.
O DDD enfatiza uma organização OO tão pura quanto possível para o modelo de Domínio, o que
concorre eventualmente com organizações para código distribuído do Java EE. Algumas vezes o Java
EE apresenta padrões que apresentam pequenas otimizações, de mais baixo nível, mas que não são
tão elegantes quanto um modelo rico de Domínio preconizado pelo DDD.
Mas, se por outro lado uma arquitetura que enfatize uma “distribuição potencial” de componentes,
como o Java EE, pode ser considerada “overengineering” [Johnson, Eric 2002], por outro pode ser
útil em estratégias que pretendam maximizar o reúso em runtime usando SOA, por exemplo.
A arquitetura sugerida no jCompany oferece um balanço razoável entre estas duas escolas:
Na prática, isto significa que programações de Domínio podem ser ricas e “não anêmicas”
86
Entendendo a Arquitetura de Desenvolvimento
[Fowler, Martin 2004], refletindo uma linguagem de negócios, mas também publicáveis ao
menor esforço e de forma eficiente, através de um Web-Service ou serviço EJB3 remoto - se,
quando e onde preciso for.
4. Em quarto lugar, o jCompany refina a arquitetura para “dentro de cada camada MVC2-P”,
definindo uma organização refinada de pacotes e novas categorias de classes internas tais como
Service e Helper, utilizadas com DP Composite [Freeman, Freeman 2004] para maximizar a coesão
e minimizar ainda mais o acoplamento.
Como vimos, esta é uma camada especialmente mal resolvida em arquiteturas típicas do mercado,
devido à sua complexidade e diversidade de tecnologias (JSF, Tag-Files, JSTL, JSP, Tiles, Javascript, CSS,
DHTML, Ajax/DOJO, etc.). Para fazer frente a este desafio, o jCompany define leiautes reutilizáveis e
controlados pelo framework (leiautes dinâmicos com Tiles), componentes visuais especializados, soluções
para reúso e especialização de peles, rotinas Javascript/Ajax, etc., tudo isso com DPs e conceitos OO
aplicados, como nas demais camadas. Este assunto será discutido de forma específica, em capítulo sobre
customização de Web-Design.
Figura A4.17. Arquitetura MVC preconizada no J2EE clássico (até EJB 2.1).
#1. Usuário aciona aplicação: No modelo MVC-2, um servlet recepciona todas as requisições do
usuário (e não os componentes de visão tais como JSP ou JSF, como no MVC-1)
87
Capítulo A5
#2. Camada controle chama “serviços” de negócio: Um aparato de Design Patterns tais como
Business Delegate, Session Façade e outros são tipicamente utilizados para um maior
isolamento entre a camada da aplicação (Controle e Visão) e a camada de negócio (Modelo), e
também devido a uma pressuposição de “remoting”, ou seja, da potencial distribuição destas
camadas por máquinas distintas, em runtime. Classes remotas são, principalmente EJB Session
Beans 2.x.
#3. Todas as principais camadas compartilham utilitários. Muito embora não sejam
representados com freqüência, componentes JAR contendo bibliotecas suplementares para
operações com data, logging, numéricas, tratamento de exceções, etc., são dispostas de forma
a estarem disponível em todas as camadas.
#4. Uso de Entity Beans 2.x: A persistência ideal do ponto de vista da especificação é obtida
através de classes EJB Entity Beans e uso de linguagem EJB-QL.
#5. Uso de Session Beans (DAO): Alternativamente, classes de EJB Session Bean substituem
Entity Beans, devido a limitações tecnológicas ou de performance, requerendo codificação de
SQL diretamente, nos códigos Java.
#6. Acesso a serviços de persistência: Seja por responsabilidade do container EJB, no caso dos
Entity Beans ou do desenvolvedor nos DAOs, somente através de classes desta camada o
repositório de armazenamento (Ex.: SGBD-R) é acessado.
#7. Criação do meio de transporte: Após a recuperação de informações persistidas, seja por
que meio forem, a codificação da cópia dos dados de Entity Beans ou JDBC Result Sets para
DTOs (Data Transfer Objects) é obrigatória.
#8. Controle de fluxo de navegação: No modelo MVC-2, as classes de Controle decidem para
que classes de visualização irão delegar a finalização da resposta ao usuário. Uma nova versão
de Interface com o Usuário é então selecionada, em função do estado atual da conversação.
#9. Despacho da visualização: Classes representando tecnologias da camada Visão tais como
JSP, JSTL, Tiles ou JSF despacham algum formato de visualização para dispositivos de cliente,
tais como HTML, XML, PDF, CSV, etc..
Perceba que, como a estrutura de dados dos formulários de negócio é composta em sua maior parte por
propriedades das entidades do negócio, a estrutura das classes de DTO terminava por ser 90% a 100%
redundante com a estrutura das classes Entity Bean. Por conseqüência, a manutenção desta redundância
exigia códigos “burros” de transferência de dados (de->para), instanciações de classes desnecessárias,
etc..
Os outros graves problemas desta especificação Entity Bean (até a versão 2.x), tais como sérias
restrições da linguagem de persistência EJB-QL, limitação ao uso de herança, etc., findavam por
configurar um verdadeiro desastre em termos de produtividade - e Orientação a Objetos.
Na prática, muitos resolviam este problema simplesmente desistindo dos Entity Beans 2.x (de fato, quase
inutilizáveis). Mas quem não os substituía por algum framework de mapeamento Objeto-Relacional tal
como o Hibernate, passava a programar JDBC em EJB Session Beans, como exemplificado em (E), com
manipulação direta de “result sets” e cópias de/para DTOs (ou VOs), caindo em níveis de produtividade
de técnicas de programação da geração “COBOL”. Na verdade em níveis piores, devido às deficiências
intrusivas da geração EJB 2.x, como visto.
Felizmente, os Entity Beans 2.x são agora “legado”, substituídos na versão EJB 3.0 por POJOs (Plain Old
Java Objects) que corrigem, da “água para o vinho”, todas as limitações clássicas.
Uma seqüela disso é que os Entity Beans 3.0 foram inteiramente reconcebidos, e não sofrerão mais
evoluções na sua forma original 2.x – ruim para quem os utilizava acreditando cegamente neste tipo de
“padrão forçado de comitê”; bom para o restante do mercado, que já havia trocado o uso de Entity Beans
2.x por alternativas que agora se tornaram o “padrão de-facto”, como o Hibernate/JPA*.
*
O criador da Hibernate, Gavin King, foi um dos líderes da especificação EJB3, especialmente da parte de Entity Beans, que foi
redefinida dentro do padrão JPA (Java Persistance Architecture). Por isso, o JPA é hoje 80% similar arquiteturalmente ao que já se
usava na Hibernate.
88
Entendendo a Arquitetura de Desenvolvimento
Padrões “de facto” do mercado Open-Source, via de regra, superam os “de comitê”. Somente nos
últimos anos, os condutores estratégicos do Java EE, especialmente a SUN, têm estado mais
atentos aos anseios dos desenvolvedores, e não somente dos fabricantes de Application Server.
Esta tendência deve levar à diminuição (mas não eliminação), de padrões artificais, concebidos
sem exploração técnica.
#1. Camada comuns engloba utilitários e DTOs eventuais: As classes utilitárias comuns a
todas as camadas MVC principais, bem como eventuais DTOs que ainda sejam necessários são
encapsulados na visão “Comuns”.
#2. Camada de persistência mais “leve”, utilizando JPA-QL: A camada de persistência agora
pode dispensar codificação de inclusões, alterações, exclusões e de tratamentos de
concorrência, geração de identificadores automáticos, dentre outros trabalhos realizados de
forma transparente pelo JPA. Além disso, a linguagem JPA-QL retorna grafos de entidades de
domínio prontamente disponíveis para uso pelas demais camadas de forma OO, e não mais
“result sets” JDBC, relacionais.
#3. Camada ortogonal para Entidades de Domínio: A camada de domínio agora representa
um objeto clássico de OO, com propriedades e responsabilidades (métodos) do negócio, além
de poderem ser utilizadas em qualquer camada MVC2-P. É importante notar que agora, as
nobres classes desta camada são as mais estáveis da arquitetura, não dependendo de serviços
de nenhuma outra, nem de persistência, por exemplo (a camada de Persistência recupera
dados e disponibiliza para a de Domínio).
89
Capítulo A5
Na camada simplificada como “Comuns” (1) estão incluídas classes de utilitários comuns de base OSS
(Apache Commons, Apache Log4j, etc.), do jCompany (classes sufixadas com Helper), os DTOs
restantes e, ainda, os contratos (as Interfaces, somente) de fachada, entre as camadas.
A Figura A4.19 mostra uma radiografia um pouco mais detalhada da Arquitetura de Software MVC2-P*
proposta para Java EE 5 pelo jCompany, exibindo também algumas dependências especificas de cada
camada, ao centro (Mat. Prima OSS, Service, Helper):
Figura A4.19. Arquitetura MVC2-P com dependências ortogonais globais e internas das camadas.
#1. DP Façade: Apesar de representarmos, didaticamente, uma seta com dependência entre
Controle e Modelo (do Controle para a subcamada de implementação de Fachada), o DP Façade
é utilizado nesta interação, de modo que há um acomplamento leve, facilitando
reimplementações de serviços, se/quando necessário.
#2. Transporte DTO e Context: Quando um Caso de Uso apresenta formulário com estrutura
bastante distinta das Entidades, pode-se lançar como recurso de transporte os tradicionais
DTOs (Data Transfer Objects), como exceção, não mais como regra! Além disso, um POJO com
DP Context Object é utilizado pelo jCompany para transportar, genericamente, informações de
contexto da camada Controle para Modelo, que podem ser úteis (perfil do usuário autenticado,
metadados de colaboração, etc.)
#3. Utilitários Globais: Classes do jCompany com sufixo Helper trazem funções diversas,
complementares a funções de utilitários de mercado, de interesse de todas as camadas.
#5. Serviços e utilitários Específicos: Dentro de cada grande camada MVC2-P, há subdivisões
de pacotes segmentando e encapsulando serviços e utilitários internos do jCompany,
específicos para a camada.
#6. Matéria-Prima OSS Específica: Cada camada MVC2-P possui um conjunto agrupado de
dependências externas de interesse seu apenas (definido tanto no Maven quanto em User
Libraries do Eclipse). Este agrupamento simplifica a gestão de dependências, evitando falhas
básicas de arquitetura produzida por desenvolvedores. Ex.: Importações de serviços de
persistência na camada Controle.
*
Neste livro, utilizaremos MVC2-P, quando quisermos enfatizar uma arquitetura MVC do tipo 2, com subcamada de Persistência bem
definida.
90
Entendendo a Arquitetura de Desenvolvimento
o Há uma dependência ortogonal, por parte de todas as camadas MVC2-P, com a camada de Domínio,
além de utilitários comuns, resquícios de DTO e contratos de fachada (somente as Interfaces).
o A camada de Domínio, por sua vez, desconhece e independe de quaisquer das camadas MVC2-P. Ela
se torna assim, como é de se esperar, a parte mais estável da arquitetura, funcionando com um
“layer ortogonal”. O conceito da ortogonalidade pode ser melhor visualizado pelo rearranjo didático
da Figura A4.20.
91
Capítulo A5
Obs.: Um quarto projeto pode ter sido gerado, apenas para facilidade de geração de arquivos EAR via
Maven.
Na organização da Figura A4.21, é importante notar que não há uma relação “um-para-um” entre uma
camada da arquitetura e um projeto de desenvolvimento na IDE, já que a proliferação de projetos de
desenvolvimento é também prejudicial, aumentando a complexidade muitas vezes sem
vantagens práticas.
Por outro lado, agrupar todas as camadas em um único projeto costuma também ser uma
simplificação exagerada, na medida em que facilita a quebra de arquitetura MVC*.
O jCompany sugere um agrupamento considerado bom para a média dos projetos corporativos, em seus
templates INI, mas deve-se realizar ajustes, customizando-se estes templates, para algumas situações.
Alguns bons exemplos são:
o Caso a aplicação pretendesse renderizar objetos para mais de uma tecnologia de Visão (Ex.: HTML e
também XML/XSLT ou WML), então seria uma boa escolha separar os pacotes de Visão, presentes
no projeto “rhtutorial”, em outro projeto independente. Deste modo, poder-se-ia ter dois projetos
para esta camada Visão, bem desacoplados.
o O mesmo raciocínio valeria, caso a pretensão fosse utilizar duas implementações de persistência. Se
fosse o caso, compensaria fatorar o(s) pacote(s) de persistencia do “rhtutorial_modelo” para um
projeto próprio de persistência†.
*
Isso porque facilita aos desenvolvedores eventualmente instanciarem dependências de outras camadas, disponíveis globalmente em
um único Class Path.
†
Note que, desde que classes de uma camada MVC2-P estejam segmentadas, pelo menos, por pacotes com baixo acomplamento,
reorganizar os projetos não seria uma tarefa complexa. E como veremos, esta é uma preocupação do jCompany, que descreveremos
na “Visão Interna” da arquitetura proposta.
92
Entendendo a Arquitetura de Desenvolvimento
Figura A4.22. Principais pacotes que segmentam internamente as camadas, dentro de projetos.
Nos exemplos em Figura A4.24, Figura A4.25 e Figura A4.26, vemo como estas dependências são
configuradas no Eclipse:
93
Capítulo A5
94
Entendendo a Arquitetura de Desenvolvimento
Mas a forma sugerida pelo jCompany é um pouco mais flexível, para facilitar evoluções futuras: Os JARs
que compõem o framework de integração são agrupados em bibliotecas do usuário (User Library) do
Eclipse - e estas bibliotecas é que são incluídas como dependências em Libraries, como ilustrado na
Figura A4.28.
#1. Bibliotecas do usuário (User Libraries), que encapsulam os JARs, para cada camada.
Note que esta simplificação visa diminuir o número de bibliotecas de dependência na IDE, e aumentar o
nível de abstração, evitando-se “micro-definições” de dependência, em nível de JARs individuais. Facilita,
por exemplo, que desmembramentos futuros de JARs (que ocorrerão, certamente), não afetem a
dependência MVC “lógica”, definida nos projetos, mas somente a organização interna das User Libraries.
A visão de abstração em arquitetura nos permite simplificações como essa. Mas, se o arquiteto ou
desenvolvedor preferir alguma variação, ele poderá alterá-la em seu projeto após a geração, ou alterar o
template INI utilizado, em nosso caso o “jcompany_jsf_ini.zip”.
95
Capítulo A5
Obs. 1: Para dependências somente em “tempo de execução”, é necessário o devido registro das
dependências nos arquivos “pom.xml” do Maven, mas não necessariamente no Eclipse! O jCompany já
cuida deste tipo de configuração, automaticamente.
Obs. 2: Os projetos da camada visão do jCompany são disponibilizados como “WAR” para o Maven, que
os expande e mescla com o WAR da aplicação (ou EAR), em tempo de montagem, para funcionamento
em execução.
Figura A4.30. Modelo de Componentes completo em nível macro, para o projeto RH que será desenvolvido.
96
Entendendo a Arquitetura de Desenvolvimento
Figura A4.31. User Libraries agrupadas por “comuns, controle e modelo”, como dependências Eclipse.
Obs.: A biblioteca “oss_base_qa” é utilizada para Testes de Unidade, e será discutida em capitulo
dedicado a esta área.
- Introdução
Nesta visão, vamos entender como os três projetos gerados no capítulo anterior estão organizados, do
ponto de vista de sua estrutura interna. Esta visão engloba a organização de diretórios e de artefatos
sugeridos pela arquitetura.
A organização inicial de diretórios adotada pelo jCompany segue convenções recomendadas pela
ferramenta Apache Maven, resultado de anos de prática em organização de projetos colaborativos e
mundiais do grupo Apache. A organização “opinativa” do Maven, como gostam de frisar os seus autores,
é mais rigorosa, porém permite a esta ferramenta compreender mais a fundo o projeto (onde estão suas
classes de teste, artefatos de configuração da aplicação, etc.) e, por conseqüência, contribuir mais.
Seguir o padrão de pacotes do Maven nos ajudará na atualização de versões, geração de
rotinas de montagem, compilação e liberação de executáveis. Além disso, plugins Maven poderão
gerar métricas interessantes e um Web-Site em nível bem adiantado de acabamento para nossos
projetos, uma vez que utilizemos a sua “arquitetura sugerida”.
97
Capítulo A5
[br.]com.[empresa].[projeto].controle.[jsf|listener|tiles]
onde
*
A organização baseada em dependências de tecnologias visa aumentar a “estabilidade” de cada pacote, mantendo-os com o mínimo
possível de acoplamentos (‘imports’). São possíveis subdivisões em pacotes “funcionais” abaixo do pacote de tecnologia (ex: por Casos
de Uso), ou mesmo alteração desta ênfase, colocando-se pacotes “funcionais” antecedendo os pacotes de tecnologia, se desejado.
98
Entendendo a Arquitetura de Desenvolvimento
com.powerlogic.jcompany.config.[emp|appl*URLs*]
onde
o com.powerlogic. jcompany.config.funcionarioman\
package-info.java: anotações para URL ‘/funcionarioman’
o com.powerlogic. jcompany.config.funcionariosel\
package-info.java: anotações para URL ‘/funcionariosel’
99
Capítulo A5
O “pseudo source-folder webapp” merece um maior detalhamento, já que contém diversos diretórios
padrão Java EE e arquivos de configuração padrões:
1. /META-INF É um folder padrão Java, que deve constar exatamente com este
nome e em maiúsculas. Contém os seguintes arquivos:
*
É importante perceber que o agrupamento de todos estes recursos abaixo da pasta “plc” é proposital e excepcionalmente importante
para a performance das aplicações, já que todos estes são recursos passiveis de serem mantidos em caching, no cliente (nos
Navegadores). Para acionar este excepcional recurso de performance, o jCompany já traz pré-configurado o filtro PlcClienteFilter no
web.xml, mapeado para todos os arquivos abaixo de “/plc”. Este é mais outro motivo para reforçar o uso desta convenção, e agrupar
recursos desta mesma natureza, abaixo deste diretório.
100
Entendendo a Arquitetura de Desenvolvimento
Nota 2: O logo da empresa, para login, topo e janela sobre, pode ser
mantida na camada “Bridge” para não ficar rendundado em cada projeto,
em uma arquitetura mais corporativa.
4.1 /plc/javascript** Obs.: Nos últimos releases, houve uma refatoração no jCompany,
promovendo o arquivo AppGeral.js para diretório próprio, em
“/plc/javascript”. Possivelmente, versões mais recentes já possuem
esta distinção.
6. /WEB-INF/ É um folder padrão Java EE, que deve constar exatamente com este
nome e em maiúsculas, e deve conter, em sua raiz, arquivos de
configuração diversos.
101
Capítulo A5
leiaute.
Classe Objetivo
Pela descrição que vimos até aqui, já devemos ter percebido que as classes incluídas nos projetos
gerados não contêm código procedimental em Java. Os poucos artefatos com conteúdo gerados são
alguns arquivos de JSP e mídias de exemplo, para permitirem uma apresentação inicial de Web-Design
para a aplicação, a ser modificada para o contexto de cada empresa/aplicação.
Os verdadeiros propósitos do plugin de criação de projetos, e de outros que compõem o jCompany
Artifact Generator, são reforçar:
102
Entendendo a Arquitetura de Desenvolvimento
[br.]com.[empresa].[projeto].modelo.[facade|modelo|persistencia]
onde
103
Capítulo A5
aplicação.
onde
3. src/main/resources Contém diretório padrão META-INF para JARs, neste caso com
(Pseudo Source Folder) configurações (opcionais) para EJBs.
Configurado como Source
folder no Eclipse para
melhorar visualização no
Package Explorer, muito
embora não contenha
classes Java.
As classes Java definidas no template INI para projetos “modelo” têm o seguinte propósito:
Classe Objetivo
104
Entendendo a Arquitetura de Desenvolvimento
[br.]com.[empresa].[projeto].[entidade|facade|comuns]
onde
2. src/main/resources Contém diretório padrão META-INF para JARs, neste caso com
(Pseudo Source Folder) configurações de persistência JPA (persistence.xml), e também o
Configurado como arquivo hibernate.cfg.xml.
Source folder no Eclipse
para melhorar Estas declarações de persistência são idealmente mantidas no mesmo
visualização no Package projeto das Entidades, para maior coesão, e não implicam em
Explorer, muito embora dependências ou acoplamentos, por serem apenas configurações
não contenha classes (metadados).
Java.
As classes Java definidas no projeto template default para “comuns” têm o seguinte propósito:
Classe Objetivo
105
Capítulo A5
106
Entendendo a Arquitetura de Desenvolvimento
Sumário
Neste capítulo, fizemos uma breve revisão sobre preceitos da Arquitetura de Software e discutimos a
“Visão Interna” e “Visão de Módulos” da arquitetura incorporada e proposta pelo jCompany, tomando
como base os três projetos gerados no capítulo anterior.
Ao expormos os critérios (“Rationale”) utilizados pela Powerlogic para absorção e concepção da
arquitetura sugerida, provemos as condições necessárias para ajustes específicos e especializações
corporativas, que se façam necessários.
No próximo capítulo iremos sair da Arquitetura de Software para ingressar na Metodologia de Construção
Java EE incorporada no jCompany, começando por entender seus Casos de Uso Padrão e a aplicação
que iremos desenvolver, mais em detalhes.
O retorno a este capítulo, após uma maior experimentação prática no jCompany, é altamente
recomendável.
107
Capítulo A5
108
5
Capítulo
Entendendo a Metodologia
5
A
de Desenvolvimento
Introdução
N o capítulo anterior, vimos como a arquitetura de base proposta pelo jCompany pode ser utilizada
como catalisadora para a definição de uma Arquitetura de Sistemas Corporativa (ASC) madura, com
alto nível de automação através de generalizações abrangentes. Posicionamos este tipo de solução de
software como “horizontal”, por resolver problemas comuns a várias verticais de negócio, dentro de um
portifólio típico de aplicações.
Já o nosso tema deste capítulo, a Metodologia de Desenvolvimento de Sistemas (MDS), se
desenvolverá em torno de práticas e padrões para a construção da parte “vertical” da solução - ou seja,
da solução de negócio em si.
O ideal é que uma MDS reconheça o nível de abstração e de generalização disponíveis na ASC, e que a
complemente, otimizando práticas de especificação e construção. Este ideal pode não se
manifestar na prática por dois motivos:
o Arquitetura Invisível ou Anêmica. Analistas e/ou desenvolvedores projetando e construindo
camadas horizontais de software em aplicações de negócio, simplesmente por insuficiência na
padronização e automação em nível da arquitetura.
o Metodologias Invisíveis ou Anêmicas. Metodologias inexistentes (desenvolvimento artesanal, ao
sabor das qualidades individuais de cada profissional) ou uso de MDS genéricas mal contextualizadas
que, por exemplo, desconhecem a arquitetura.
Discutimos o primeiro motivo no capítulo anterior. Vejamos então o segundo.
Uma seqüela típica de MDS desalinhada com ASC são especificações prolixas, que não reconhecem os
estereótipos da arquitetura e que, por isso, além de serem mais custosas para serem obtidas,
comunicam mal.
Para o máximo de resultados, é imprescindível que a Arquitetura de Sistemas Corporativa seja tão
automatizada quanto possível, e reconhecida pela Metodologia de Desenvolvimento de Sistemas.
Deste modo, analistas e/ou desenvolvedores podem calibrar melhor o nível de abstração de seu
trabalho, tanto no projeto quanto na implementação - evitando desperdícios e maximizando o
reuso.
Do ponto de vista da especificação, o jCompany traz um módulo chamado jCompany Patterns &
Methods, que propõe padrões e práticas de especificações de Casos de Uso, Modelagem de Classes,
Processos Ágeis, dentre outros. É um módulo representado por documentação extensa, somente
disponível com a licença corporativa do produto.
Do ponto de vista da construção, o jCompany traz roteiros automatizados através do recurso de Cheat-
Sheets do Eclipse, além de plugins que geram versões que obedecem a padrões concebidos na
metodologia.
Tal como no caso análogo, da arquitetura, os métodos e padrões propostos pelo jCompany Patterns &
Methods devem servir de base para a definição de uma MDS corporativa, devendo ser considerados
como “insumos reutilizáveis” para este trabalho.
109
Capítulo A5
- Definição
Na Wikipedia, um Processo de Desenvolvimento de Sistemas (PDS) é definido como “a estrutura imposta
ao desenvolvimento de um produto de software”.
Uma empresa que queira eliminar “não conformidades” e reforçar “melhores práticas” de produtividade
deverá definir atividades, responsabilidades, métodos, ferramentas e padrões para diversas fases do
desenvolvimento de sistemas em si e áreas de apoio relacionadas.
Segundo o Processo Unificado [Booch, Jackobson, Rumbaugh 1998], as fases fundamentais de um PDS
são:
o Concepção (principalmente Levantamento de Requisitos)
o Elaboração (principalmente Projetos Lógico e Físico)
o Construção (principalmente Codificação e Testes Unitários)
o Transição (principalmente Testes de Aceitação e Liberação para Produção)
Os frameworks de processo mais pesados e abrangentes irão incluir outras áreas tais como Gerência de
Configuração, Garantia da Qualidade de Processo e Produto, Medição e Análise, etc., além das áreas
“fundamentais”.
A Figura A5.1. Exemplo das fases de um PDS mais abrangente.Figura A5.1 exibe um gráfico com esta
visão mais abrangente, utilizado para representar todo o Gerenciamento de Ciclo de Vida de Aplicações
(Application Lifecycle Managment – ALM).
Por sua complexidade, quase nenhuma empresa define seu PDS inteiramente do zero, já que existem
vários frameworks de base nesta área. Alguns exemplos são: o “Processo Unificado (Unified Process -
UP)” já citado; e os mais recentes processos ágeis, tais como “SCRUM” e “XP”, em larga popularização.
Além destes, podemos citar os “modelos de processo” mais abrangentes, tais como o CMMI, o MPS.Br
(no Brasil) e o ISO 15504.
*
Esta “pequena” discussão se torna bem mais relevante, na medida em que, muitas vezes, a adoção de processos inadequados está na
raiz dos problemas de projeto. Não há solução de produtividade que sobreviva a um PDS modelo “Cascata”, gerenciado com práticas de
comunicação primitivas (ex.: formalidades em papel!) e visao ignóbil acerca da natureza peculiar de um projeto de software.
110
Entendendo a Metodologia de Desenvolvimento
- Metodologia ou Processo?
Neste livro, iremos adotar alguns jargões preferenciais:
o “Metodologia de Desenvolvimento de Sistemas” (MDS) quando quisermos nos referir a um
espectro mais restrito de disciplinas, limitado às fases de Concepção, Elaboração, Construção e
Transição, de um Processo de Desenvolvimento de Sistemas (PDS).
o “Processos de Desenvolvimento de Sistemas” (PDS), quando quisermos nos referir a um
espectro maior, englobando áreas adicionais conforme identificadas por frameworks de processo tais
como o CMMI, ISO ou MPS.Br. Por exemplo, Gerência de Configuração, Medição e Análise, Garantia
da Qualidade de Produto e Processo, etc..
o O jargão do Processo Unificado (UP) [Boock, Jacobson, Rumbaugh 1998], quando falarmos em
métodos, fases e alguns padrões de especificação.
o A UML - Unified Modeling Language [Pender, Tom], quando o assunto for modelagem e
especificação de sistemas.
A escolha destes jargões é meramente por conveniência, já que são os mais difundidos no mercado. Não
há nenhuma restrição específica das soluções de desenvolvimento que apresentaremos, com relação ao
uso de métodos ágeis, por exemplo, ou quaisquer outras abordagens convencionais.
“Praticamente todo livro e artigo em Projeto de Aplicações, nos últimos 15 anos ou mais, tem
criticado o desenvolvimento em cascata. (...) Eles funcionam bem quando os requisitos são
facilmente garimpados e raramente mudam. Infelizmente, como a tônica é a mudança nos
negócios, tais situações são cada vez mais raras.”
Ref. A5.1. Peter Bye e Cris Britton em “IT Architectures and Middleware”. Pág. 207.
Mas, apesar de sua ineficácia ser hoje de um consenso geral, o modelo em cascata é, de forma acidental,
ainda o mais utilizado! “Acidental” porque, na prática, têm muitas vezes sido utilizados desta forma
inconscientemente, especialmente por grandes empresas que trabalham com terceirização de projetos
e equipes distribuídas geograficamente.
E qual seriam os motivos desta distorção? Os processos “em cascata” são mais simples de se entender,
por serem os mais conhecidos pela humanidade, nas engenharias clássicas. Qualquer estudante irá
compreender uma analogia dos “Processos de Desenvolvimento de Sistemas” com os “Processos da
Engenharia Civil”, por exemplo – simplificação que contribui para manter o atraso cultural nas áreas de
TI, desde os anos 70.
Este tipo de analogia, perigosamente didática, não expressa de forma apropriada a natureza única do
software, um bem “invisível”, “abstrato” e de “simulação” da dinâmica de negócios. Uma natureza que
requer um paradigma diferenciado, atualmente melhor representado por métodos Iterativos e Ágeis.
111
Capítulo A5
Por todos estes motivos, não há hoje estudiosos na área de TI ou nenhum framework de
processo que preconize o modelo “Cascata”... O que existe, porém, são implantações imperfeitas de
processos Iterativos como citamos, ressaltando o caso do Processo Unificado. Aplicados desta forma, tais
processos trazem os mesmos resultados medíocres já conhecidos, da época da Engenharia da
Informação. Como diz o ditado:
“É insensatez querer fazer algo sempre da mesma forma, e esperar por resultados diferentes”
Ref. A5.3. Atribuído a Albert Einstein
A Figura A5.2. Diagrama do Processo Unificado, destacando em branco uma iteração. mostra um
esquema simplificado com relação à Figura A5.1. Exemplo das fases de um PDS mais abrangente.,
evidenciando o aspecto iterativo do Processo Unificado.
No diagrama clássico do UP, uma iteração é representada graficamente através dos “montinhos”, que
sugerem a intensidade da ocorrência de uma determinada disciplina, em cada fase.
Note que, na iteração #2 destacada, durante a fase de Elaboração, além de “análise” e “projeto”, são
esperadas boas quantidades de trabalhos simultâneos de “implementação” (codificação de programas) e
inclusive de “testes”! Como fazê-lo, em modelos clássicos de fábricas de software?
2. Maior controle contratual para diminuição de custos e riscos. Gestores financeiros anseiam
por mais controle sobre os contratos de TI, visando redução de custos e riscos, e muitas vezes não
aceitam desenvolvedores de terceiros alocados ao lado de seus Analistas de Negócio.
Mas o fato é que o modelo contratual de “terceirização em preço fechado” dificulta tremendamente a
instauração de um processo verdadeiramente iterativo:
o Exige uma grande visão de projeto antecipada, para efeitos de contratação (Análise “Big-Bang”);
o Produz dificuldades contratuais que degradam a adaptabilidade (controles de mudança rigorosos,
que inibem a agilidade);
112
Entendendo a Metodologia de Desenvolvimento
Esta é uma possibilidade que deve ser explorada e pode ser decisiva para o sucesso de um grande
número de projetos de TI de natureza desafiadora!
2. Maior controle contratual para diminuição de custos e riscos. Este é um mito. Não há
contrato que compense os prejuízos que um processo inadequado, em “Cascata”, possa produzir. E
este processo inadequado, por si, introduz e anaboliza riscos, como muitas empresas continuam
constatando. A produtividade e qualidade liberadas pelo jCompany possibilitam entregas de produto
“apresentável aos usuários” em iterações de semanas, não meses. Eis aí uma fórmula que,
comprovadamente, contribui para reduzir custo e riscos.
113
Capítulo A5
E esta alegação não é pouca coisa: se somarmos o resultado de todos tutoriais encontrados nos livros de
Hibernate/JPA, JSF, JBoss Seam, Spring e Eclipse, por exemplo, que fazem parte de nossa
“referência bibliográfica”, não obteremos um resultado funcional que chegue à metade do que
produziremos neste livro.
Este resultado, inicialmente, deve-se ao fato de o jCompany trabalhar reutilizando os benefícios da
maioria destes produtos. Mas, além disso, também se deve ao elevado nível de especializações e
padronizações presentes nas diversas dimensões de arquitetura, métodos, padrões e técnicas de
automação.
- Agregações de Objetos
Entender o conceito de “Agregação de Objetos” é fundamental para a introdução aos Casos de Uso
Padrões do jCompany que veremos inicialmente. Portanto, iremos recapitular este conceito de OO,
tomando como base o Modelo de Classes da Figura A5.3.
*
Figura A5.3. Modelo de Classe de Exemplo .
O trecho acima é um recorte de um modelo maior, que utilizaremos neste livro, representando um grafo
cujos vértices são “classes” e as arestas são “associações”. Chamaremos a este recorte, portanto, de
“Grafo de Classes”, no qual podemos identificar 3 vértices e 2 arestas.
o 3 (três) classes: Uf, UnidadeOrganizacional e Endereco.
o 1 (uma) agregação de classes: Entre UnidadeOrganizacional e Endereco.
o 1 (uma) associação Simples: Entre Endereco e Uf.
Estas classes definem estruturas possíveis de dados, mas são os objetos, ou “instâncias destas classes”,
que irão conter os dados em si, durante a execução de uma aplicação, e compor os formulários de nossa
aplicação visíveis para o usuário, que representam “documentos eletrônicos de negócio”.
Tal como no grafo de classes, estes objetos se relacionam conforme a estrutura definida pelas classes,
variando conforme o “estado” (situação corrente) da aplicação.
*
Este diagrama traz um mix de modelagem diferente dos tradicionais. Perceba que usa tipos Java juntamente com restrições e
operações em nível conceitual. Os “tamanhos” (multiplicidade) de propriedades também são atípicos, além de diversos estereótipos.
Este tipo de padrão é descrito na documentação do jCompany Patterns & Methods
114
Entendendo a Metodologia de Desenvolvimento
A Figura A5.4 representa um “Grafo de Objetos” hipotético para uma possível configuração de objetos,
em um determinado momento de execução da aplicação. Podemos compreender este diagrama, de forma
análoga, como um “Grafo de Objetos”, que representa instâncias do “Grafo de Classes” que o define.
Na Figura A5.4, seccionamos o único grafo formado por todo o modelo em três subgrafos, para fins
didáticos, porque normalmente são estes subgrafos que compõem a estrutura de um documento típico de
negócio (ou formulário da aplicação), como pode ser conferido na Figura A5.5.
Figura A5.5. Exemplo de formulário possível para manter o esquema de objetos da figura 4.
Aqui retornamos ao nosso ponto inicial, para estabelecermos algumas convenções de nomenclatura e
modelagem OO importantes:
o Formulários do negócio lidam não com um objeto, mas com um “Grafo de Objetos”.
o Já um Grafo de Objetos é um corte do Modelo de Objetos envolvido em uma transação,
exemplificados na Figura A5.4 pelos “Subgrafos 1, 2 e 3”.
o Por sua vez, uma Agregação de Objetos é aquele subconjunto de objetos do Grafo,
modificados simultaneamente, exemplificados na Figura A5.4 pelas “Agregações 1, 2 e 3”.
o As classes “UnidadeOrganizacional” e “Endereco” são partes de uma mesma agregação de
classes/objetos, mas não “Uf”.
o No entanto, “Uf” participa do mesmo Grafo de Objetos utilizado no formulário de
“Manutenção de Departamentos” (“UnidadeOrgacional”).
115
Capítulo A5
Esta compreensão nos ajudará a especificar de forma simples e objetiva um grande número de Casos de
Uso, bem comuns.
“Uma Agregação é um cluster de objetos associados que nós tratamos como uma unidade para o
propósito de mudanças de dados. Cada Agregação tem uma raiz e um contorno. O contorno define
o que está dentro da Agregação. A raiz é uma única Entidade, dentre as contidas na Agregação, e a
única para a qual objetos externos à agregação podem manter referências”
Ref. A5.4. Eric Evans em Domain-Driven Design [Evans, Eric 2004]. Págs. 126-127.
“Pode ser de grande ajuda ter um framework técnico que permita a você declarar Agregações e
então automaticamente garantir suas restrições. Sem este apoio, a equipe deve ter a autodisciplina
para codificar consistentemente com as regras da Agregação”
Ref. A5.5. Eric Evans em Domain-Driven Design [Evans, Eric 2004]. Pág. 129.
Esta é uma das estratégias que o jCompany adota, e realiza de forma bastante extensiva e interessante.
O jCompany permite que declaremos em seus metadados, não somente a estrutura da Agregação
principal, composta das classes que sofrem alterações em conjunto, como também todo o Grafo de
classes participante, incluindo as classes de consulta. A partir daí, padroniza soluções e as
generaliza completamente, em todas as camadas MVC-P, ao ponto de dispensar totalmente o uso
de código procedimental Java, até um estágio avançado.
*
Ao quebrar, sem necessidade, a manutenção de uma Agregação em vários “formulários de CRUD” do tipo “mantém um objeto da
agregação por vez”, exige-se do usuário que navegue por várias páginas, provocando dezenas de transmissões na rede e requisições
ao App Server desnecessárias (muitas vezes até transações de SGBD). Esta abordagem de “Web-Design” é uma verdadeira
abominação para aplicações corporativas multi-usuário, com entrada de dados massiva.
116
Entendendo a Metodologia de Desenvolvimento
Figura A5.6. Formulário único que mantém a Agregação “Funcionário -> Dependentes -> Hist. Profissional”.
117
Capítulo A5
“Devemos criar um caso de uso parametrizado, que funcione como um apelido para cada um
destes itens. Escolhemos chamar esse caso de uso de Encontrar um <Qualquer>. (...)”
Ref. A5.6. Alistair Cockburn em “Escrevendo Casos de Uso Eficazes”. Pág. 149.
“O comportamento de pesquisa comum é localizado e escrito apenas uma vez. A consistência entre
mecanismos de procura é garantida, (...) De fato, a equipe de implementação foi encorajada a dar
apenas uma especificação para seu mecanismo de pesquisa (...)”
Ref. A5.7. Alistair Cockburn em “Escrevendo Casos de Uso Eficazes”. Pág. 150.
O que Alistair Cockburn sugere são dicas para se eliminar o trabalho de especificação repetitiva que estas
duas categorias de Caso de Uso tendem a produzir, e é por esta trilha que o jCompany caminha. Não
somente identificando com mais detalhes estes Casos de Uso Padrões no jCompany Patterns &
Methods, como provendo generalizações avançadas via jCompany FS Framework e, por fim, gerando
artefatos específicos para cada camada MVC-P, via jCompany IDE.
o No jCompany, esta primeira categoria de “Casos de Uso CRUD” é chamada, de forma mais
extensa, de “Casos de Uso Padrões para Manutenção do Ciclo de Vida de Agregações de Objetos”
ou, resumidamente, de “Padrões para Manutenção”.
o O jCompany também padroniza e atender com implementações genéricas os “Casos de Uso
Parametrizados”, chamados de “Casos de Uso Padrões para Exibição de Coleções de Agregações”
(Ex.: seleções, consultas e relatórios) ou, resumidamente, “Padrões de Exibição”. Neste caso,
através de simples declarações de argumentos e operadores, o jCompany irá realizar um QBE
(Query By Example) MVC-P, dispensando codificação Java.
A tabela a seguir resume o objetivo de cada Caso de Uso Padrão, o que serão detalhados ao longo dos
próximos capítulos, quando estaremos implementando efetivamente vários deles.
118
Entendendo a Metodologia de Desenvolvimento
independentes.
Manter Classe Este Caso de Uso prevê a manutenção de todos os objetos de uma
classe, de uma só vez. Por isso, somente deve ser utilizado em
classes com poucos objetos.
Manter Agregação Simples Este Caso de Uso prevê a manutenção de uma “Agregação de
Objetos Simples”, que não envolva composição do tipo Mestre-
Detalhe e variantes.
Manter Agregação Consulta- Este Caso de Uso prevê a manutenção de uma “Agregação de
Mestre/Mantém-Detalhe Objetos” que inclua uma composição do tipo Mestre-Detalhe, onde
o Mestre (raiz da agregação) já tenha sido incluído por outro Caso
de Uso Padrão.
Manter Agregação Consulta- Este Caso de Uso prevê a manutenção de uma “Agregação de
Mestre/Mantém-Detalhe- Objetos” que inclua uma composição do tipo Mestre-Detalhe-
SubDetalhe SubDetalhe, onde o Mestre (raiz da agregação) já tenha sido
incluído por outro Caso de Uso Padrão.
Manter Preferência de Aplicação Este Caso de Uso prevê a manutenção de preferências globais
do responsável (administrador) pela aplicação. Também
conhecidos como parâmetros globais.
Manter Preferência de Usuário Este Caso de Uso prevê a manutenção de preferências de cada
(para a Aplicação) usuário para a aplicação, podendo este registrar opções de
personalização de uso ou outras que se façam necessárias.
119
Capítulo A5
Consultar Objetos Este Caso de Uso prevê a consulta em formato não otimizado para
impressão (HTML, sem quebras), de coleções de grafos contendo
informações de diversos objetos.
Consultar/Imprimir Este Caso de Uso prevê a consulta em formato otimizado para impressão
Objetos (PDF, com quebras), de coleções de grafos contendo informações de
diversos objetos.
120
Entendendo a Metodologia de Desenvolvimento
Inclui Exclusão Lógica Este Subcaso de Uso provê cenário adicional para a exclusão, que deixa de
ser física (eliminação da agregação) para se tornar uma alteração de
propriedade padrão “sitHistoricoPlc” de “A” (Ativo) para “I” (Inativo).
Agregações onde sitHistoricoPlc=”I” são então consideradas excluídas para
o ponto de vista de usuários.
Inclui Auditoria Rígida Este Subcaso de Uso provê cenário adicional para registrar objetos
contendo “imagens” de dados alterados, incluídos ou excluídos em outras
classes “espelho”, para efeitos de auditoria.
Inclui Auditoria Este Subcaso de Uso provê diversos cenários adicionais que mantém uma
Recursiva auditoria de alterações, porém na mesma classe, através de padrões de
recursividade. É útil quando há possibilidade de se retornar com um estado
anterior de um objeto, com certa freqüência.
Inclui Pesquisa Este Subcaso de Uso provê cenários adicionais que alteram a pesquisa de
Paginada coleções contendo grafos de objetos para evitar que traga registros em
demasiado em seleções de objeto visando edição para manutenção,
limitando a quantidade por página.
Inclui Arquivo Este Subcaso de Uso provê cenários adicionais que permitem a anexação
Anexado (upload) de arquivos e sua recuperação (download) juntamente com a
agregação principal.
Inclui Aprovação Este Subcaso de Uso provê diversos cenários adicionais similares ao da
Auditoria Recursiva, que mantém uma lógica de “fluxo de aprovação”
(workflow) de um nível, mantendo uma agregação nos estados pendente de
aprovação (“P”), aprovada (“A”) ou reprovada/inativa (“I”), permitindo
ainda envio de email de reprovação e republicação de reprovações
anteriores.
Extensão Exportação Este Subcaso de Uso provê cenários alternativos (que podem ou não ser
acionados pelo usuário, após uma pesquisa de seleção ou consulta), para
exportação dos dados resultantes para formatos tais como CSV ou XML.
Extensão Assistente Este Subcaso de Uso provê cenários alternativos (que podem ou não ser
acionados pelo usuário, durante a entrada de dados), para acionar
diálogos de assistente de entrada de dados, passo a passo (Wizards).
Extensão Exploração Este Subcaso de Uso provê cenários alternativos que podem ou não ser
de Dados acionados pelo usuário, durante a entrada de dados, para que uma
121
Capítulo A5
Extensão Detalhe por Este Subcaso de Uso provê cenários alternativos que podem ou não ser
Demanda acionados pelo usuário, provocando a recuperação de coleções de objetos
de detalhe, quando são declarados como “por demanda”.
*
Exposições sobre um domínio complexo seriam monótonas em nosso contexto atual. Por isso, nós não iremos explicar em detalhes
cada Caso de Uso, deixando para fazê-lo progressivamente, na medida em que evoluirmos no tutorial de construção da aplicação.
122
Entendendo a Metodologia de Desenvolvimento
São os seguintes os objetivos dos Atores em cada Caso de Uso da Figura 12:
123
Capítulo A5
Sistema SOA UC011 Consultar Nível de Salário Serviço de Web-Services que deve
de Funcionário permitir consulta de nível salarial,
para um funcionário.
Executivo UC013 Consultar Gráfico Total de Consultar gráfico que possa ser
Despesa Folha Pagto por utilizado em Portal Corporativo, por
Unidade Organizacional meio de Portlet.
Contabilidade UC014 Gerar arquivo XML com Receber por email os dados de
Externa resultados de cálculo de cálculo de Folha em anexo,
Folha criptografados.
Esta segunda versão irá nos possibilitará a implementação de integrações típicas de eBusiness, tais
como:
124
Entendendo a Metodologia de Desenvolvimento
- Introdução
O leitor mais interessado em Casos de Uso pode ter reparado que o diagrama da Figura A5.12 encerra os
nomes dos Casos de Uso com “+”, enquanto os demais encerram com “!”. Além disso, a coloração é
branca para os Casos de Uso da Figura A5.12 e azulada para os demais.
Esta notação é recomendada por Alistair Cockbur [Cockburn, Alistair. 2003], e diz respeito ao Nível de
Objetivo do Caso de Uso. São os seguintes os níveis principais sugeridos:
Para uma discussão sobre a importância de se destacar “Níveis de Objetivo” nos Casos de Uso, sugerimos
a referência [Cockburn, Alistair. 2003]. Para nós, esta segmentação é especialmente importante porque
desejamos partir da especificação para a implementação de modo claro e automatizado.
Neste sentido, temos que distinguir bem entre este “Nível de Objetivo” e o “Nível de Implementação”:
o Para o Projeto Lógico em si, o importante é uma boa marcação do Nível de Objetivo nos modelos
de Caso de Uso, nível mais importante para o usuário.
o Para o Projeto Físico (e rastreamento com a implementação), o mais importante é a diferenciação de
um Caso de Uso como “Concreto”, para deixar claro que ele está em Nível de Implementação -
especialmente quando já existam padrões definidos na Arquitetura com suporte direto
para sua implementação, que é o nosso caso*.
Um bom exemplo sobre a distinção entre estes níveis pode ser obtido através da Figura A5.13. Todos os
Casos de Uso deste diagrama estão em Nível de Objetivo do Usuário (!), mas nem todos são
“Concretos”! O “UC001 Manter Estrutura Organizacional!” é modelado como “Abstrato", o que
percebemos pelo texto em itálico, padrão de notação UML para estes casos.
*
Uma outra dica para percebermos que estamos em Nível de Implementação, é o detalhamento do Caso de Uso. Abaixo de um nível
Padrão de Implementação, teremos forçosamente que introduzir conceitos de Realizações de Caso de Uso via Colaborações do Projeto
Físico, que veremos mais adiante.
125
Capítulo A5
Aqui, vale uma consideração: Esta especificação somente é válida porque, em nosso exemplo, estamos
supondo que a classe de UF não seja “de uso corporativo”. Em nossa hipótese, de forma simplificada, ela
serve apenas ao propósito de normalizar dados para o cadastro de Endereços de Unidades
Organizacionais.
Como “Manter UF-“ não é considerado com um “Objetivo do Usuário” por si, algumas conseqüências
podem acontecer em nossa aplicação como, por exemplo, a classe “Uf” pode conter instâncias de UFs
somente para as Unidades Organizacionais existentes†.
*
Ou seja, o resultado de uso relevante para usuários é definir toda a Estrutura Organizacional, composta de Matriz, Filiais, seus
endereços - e incluindo relação de UFs, de apoio para este fim.
†
Este é um cenário apenas didático. No mundo real, para que uma empresa evite tabelas redundantes de “UF”, o Caso de Uso
“UC001.1 – Manter UF-“ teria que ser promovido para “UC001 - Manter UF!”, em Nível do Objetivo do Usuário.
126
Entendendo a Metodologia de Desenvolvimento
Note que a especificação acima ainda independe de implementarmos ou não em jCompany! Portanto,
ela ainda está em nível lógico, sendo suficiente para se especificar para qualquer outro contexto
tecnológico de desenvolvimento que defina padrões, neste nível...
Outras observações importantes:
o A representação acima é apenas uma “Visão Estrutural”. A “Visão Comportamental”,
representada tipicamente pelos Cenários de Caso de Uso ou Diagramas de Seqüência, nem precisa
ser representada, já que não identificamos nenhuma variação importante de comportamento com
relação ao comportamento do Caso de Uso Padrão “Manter Classe”*.
o O estereótipo <<plcManClasse>> indica que o padrão do Caso de Uso “Manter UF-“ é o “Manter
Classe” e que, portanto, nosso Caso de Uso deve herdar os cenários deste padrão. No
repositório da ferramenta CASE existe um relacionamento de herança entre os Casos de Uso, para
facilitar rastreabilidade, não representado em nosso diagrama.
o Restrições invariáveis (que não mudam, conforme os Casos de Uso) estão representadas
junto às Entidades de Domínio. Deste modo, ficam encapsuladas, sendo mais bem entendidas e
naturalmente reutilizadas. Uma “decoração” importante foi a representação de tamanhos nas
propriedades, o que torna também a representação suficiente para o uso de mapeamento Objeto-
Relacional e definição de tamanhos padrões para campos correspondentes na interface.
o Mesmo a especificação da Interface com o Usuário está sucinta mas suficiente, já que a navegação,
leiautes e barras de botões são todos padronizados na Arquitetura de Software, não apresentando
variações em nosso caso.
*
Para facilitar a compreensão deste padrão de modelagem, foram inseridos dois capítulos do jCompany Patterns & Methods, no
Apêndice A deste livro. Consulte-os, por exemplo, para conhecer a descrição dos cenários para o Caso de Uso para o padrão “Manter
Classe”.
127
Capítulo A5
Figura A5.17. Projeto Físico para Caso de Uso “UC001.1 Manter UF-“.
Perceba que o diagrama acima é um Projeto Físico suficiente para nosso Caso de Uso Padrão “Manter UF-
“. É um exemplo minimalista de Projeto “por Exceção”, que somente define uma Colaboração padrão
“plcTabular” e inclui ainda o estereótipo no formulário, indicando para seguir o padrão de formulário para
a Colaboração, em tecnologia JSP/JSF.
É uma especificação minimalista, tão simples quanto possível - poderíamos inclusive não diagramá-la, a
exceção do formulário. De fato, quando não há muita diferenciação com relação aos padrões, somente
temos que projetar “o reuso”, evitando repetições de cenários na especificação.
Importante: No caso acima, definimos o nome da Colaboração coincidente com o nome da URL, que
segue convenções do jCompany (“/uf”). Isso significa que implementaremos para Web e que teremos
uma relação “um-para-um” entre uma Colaboração e uma URL! Estas são convenções importantes
para rastreamento do projeto com implementações em jCompany.
São as seguintes as “Colaborações Padrões” do jCompany:
128
Entendendo a Metodologia de Desenvolvimento
Estes diagramas de Realização de Casos de Uso (Visão Estrutural) serão apresentados para discussão
mais detalhada, caso a caso, antes de inicarmos o desenvolvimento de cada um deles, no próximo
módulo.
*
Existe em duas modalidades, uma utilizando tecnologia Jasper Reports e outra utilizando Eclipse BIRT.
129
Capítulo A5
Sumário
Neste capítulo, fizemos uma breve introdução aos métodos e padrões propostos pelo jCompany,
discutindo a importância de que sejam inseridos em um Processo de Desenvolvimento de Sistemas
verdadeiramente Iterativo.
Revimos fundamentos úteis para a compreensão da Modelagem de Classes, definindo o conceito de
Grafos e Agregações de Classes/Objetos, e analisando como estes se relacionam com
documentos/formulários corporativos. A seguir, discutimos as motivações para automatizarmos a
Manutenção do Ciclo de Vida de Agregações de Objetos e Consultas básicas em MVC, através de Casos
de Uso Padrões suportados pela arquitetura e metodologia.
Relacionamos, então, os Casos de Uso Padrões do jCompany, além de Inclusões, Extensões e
Colaborações relacionadas, que utilizaremos neste livro.
Por fim, apresentamos os modelos para a aplicação “RH Tutorial”, em suas duas versões, enfatizando o
primeiro Caso de Uso, que desenvolveremos no próximo capítulo.
130
B
Módulo
Casos de Uso .
B
Centrados em Dados
(Primários)
Este é um módulo prático, que traz tutoriais com passos para implementação de
Casos de Uso Padrões do jCompany Developer Suite, incluindo variações típicas
(Inclusões e Extensões aos Casos de Uso).
131
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
132
6
Capítulo
Implementando o Padrão
6
B
“Manter Classe”
A primeira especificação de Caso de Uso que iremos implementar está definida no diagrama da Figura
B6.1.
Este diagrama simples, com seus estereótipos, é suficiente para nos dizer exatamente tudo o que
precisamos saber para codificar este Caso de Uso, com precisão. Isso porque este é um Caso de Uso
Padrão, definido pelo jCompany e automatizado em grande parte, tanto por generalizações presentes na
arquitetura, através do jCompany FS Framework, quanto por gerações de artefatos via jCompany
IDE - Artifact Generator, para a parte específica*.
Importante: Caso você não tenha realizado o tutorial de criação de projeto do Capítulo 3, faça
agora, antes de iniciar este capítulo.
- Obtendo Classes de Domínio em Java
Em todos os Casos de Uso Padrões do jCompany, somente as classes que representam Entidades de
Domínio precisam existir, como ponto de partida para o restante do desenvolvimento, assistido por
roteiros Cheat-Sheets.
De posse desta(s) classe(s), todos os demais artefatos Java EE necessários para a finalização do Caso de
Uso serão gerados por assistentes de criação dos plugins do módulo jCompany IDE, chamados de
jCompany Artifact Generator. Portanto, tudo o que precisamos para iniciar a construção do nosso
primeiro Caso de Uso é a obtenção da classe Java “Uf”, por alguma de duas formas:
*
Apesar da aparente simplicidade, mesmo este Caso de Uso Padrão inicial, chamado “Manter Classe”,
esconde complexidades e perigos que muitas vezes passam despercebidos, mesmo por um
desenvolvedor sênior. Recomendamos que a definição deste padrão seja lida, nos capítulos do Apêndice
A, para uma melhor compreensão de tudo o que está envolvido.
133
Capítulo B6
Neste caso, poderiam ser utilizadas estratégias de geração de código (ou MDA), para obtenção da
classe a partir de um modelo UML como o da Figura B6.1. Em nosso caso, inclusive, seria
especialmente simples se fazer isto, uma vez que nossos modelos já estão no mesmo “plano de
abstração” das classes de construção, utilizando diretamente os nomes e tipos padrões Java. Pode-
se utilizar qualquer ferramenta CASE razoável para este fim, mas recomendamos o Enterprise
Architect (EA - www.sparxsystems.com), como uma das melhores opções atuais, em
custo/benefício.
o Criando-se as classes Java diretamente via Eclipse.
Figura B6.2. Diálogo padrão para criação de Classes, no pacote padrão para Entidades de Domínio
2. Dar o nome Uf (seguindo convenção Java para nomes de classe), marcar ‘abstract’ e herdar da
classe pré-existente AppBaseEntity, disponibilizada quando da criação do projeto, conforme a Figura
B6.3. Obs.: estas duas práticas são recomendações, não obrigações, e serão explicadas mais
adiante.
134
Implementando o Padrão “Manter Classe”
3. Digitar as propriedades nome e sigla como private e tipo String (como para todas as classes do
pacote java.lang, o import é desnecessário), conforme a Figura B6.4.
Figura B6.4. Classe Java correspondente à Entidade UF, com comentário Javadoc e práticas recomendadas.
Como dissemos, a classe acima poderia ser facilmente gerada por qualquer ferramenta CASE razoável, a
partir de modelagem UML. Mas repare que existem suplementos na especificação da entidade
reproduzida na Figura B6.1:
o Responsabilidades (responsibilities);
o Restrições (constraints);
o Tamanhos máximos para as propriedades.
Iremos discorrer sobre elas, nos próximos tópicos.
Além disso, no modelo UML não herdamos de AppBaseEntity. De onde, então, tiramos isso?
A herança de AppBaseEntity, no nosso caso, herda três propriedades pré-mapeadas, altamente
recomendadas como “padrões corporativos” (embora opcionais). Em Nossa hipótese, desenvolvedores
são instruídos para sempre herdarem estas propriedades, de modo que esta parte não precise ser
replicada por todas as especificações*.
Deste modo, se dois usuários estão alterando o mesmo registro simultaneamente, há garantia de
que um não irá sobrepor atualização de outro, caso o segundo não esteja com a versão atualizada
dos dados recuperados.
Esta é uma técnica altamente recomendada que, se não usada, implica em soluções alternativas
bem piores, tais como:
1. Uso de “concorrência pessimista” (locks no SGBD durante a atualização por um usuário),
algo em desuso e que penaliza dramaticamente a performance (mesmo com estratégias de
“trava em nível de registros” dos SGBDs atuais);
2. Implementação manual de técnica similar, pelos desenvolvedores. Ao não usarem esta
automação, desenvolvedores deverão codificar este teste nas condições “where” de seus
“updates” e “deletes” – e em todas elas, para evitar problemas de concorrência;
3. Em nossa experiência, quando não se usa o controle de versao do JPA (já existente há anos no
Hibernate), na prática os desenvolvedores ignoram este problema e deixam ir para produção
aplicações sem tratamento de concorrência. Isto é conhecido como o anti-padrão “last
commit wins” (a última modificação sobrepõe anteriores, mesmo que o usuário corrente
*
Por questão de espaço, não incluímos um documento fictício de “deliberações corporativas”. Mas ele deve existir e conter padrões
abrangentes como este, para possibilitar especificação por exceção (Specification by Exception).
135
Capítulo B6
ignore uma modificação recente nos dados). Em sistemas de missão crítica, com alto índice de
concorrência, este cenário oferece grande risco, e deve ser tratado.
o dataUltAlteracao e usuarioUltAlteracao: Estas propriedades implementam o que é chamado no
jCompany de “auditoria pauta mínima”. Seus valores são atualizados pelo jCompany para guardar
o login do usuário que realizou a última alteração no objeto (registro no SGBD), e também a
data/hora desta modificação.
Elas se prestam para eventuais averiguações de segurança (auditorias), para rastrear usuários que
introduzem informações prejudiciais à empresa, por má fé ou inadvertidamente. Apesar de somente
manter o último usuário, costuma ser possível se encontrar o histórico de modificações com a
análise de logs dos SGBDs.
É um tipo de auditoria mais leve que a criação de “classes espelho”, conhecidas no jCompany como
“auditoria rígida”. Estas últimas são utilizadas para classes de maior relevância e/ou que precisem de
auditorias mais freqüentes.
Já a responsabilidade “exibe” é um mecanismo padrão de especificação sugerido pelo jCompany,
através do qual o projetista indica qual(is) propriedade(s) ele deseja utilizar para representar objetos da
Entidade quando aparecerem pelos formulários da aplicação (Ex.: combos, radios, vinculados, ou títulos).
A especificação Java prevê um método padrão para esta finalidade, chamado “toString” (manifestação
em formato String, do objeto), que é utilizado pelo jCompany para este fim (chamamos a este método,
também, de “lookup” do objeto). Portanto, a especificação “exibe” nos define o que implementar o
método “toString” de cada Entidade, apropriadamente.
- Entendendo as Restrições Invariáveis (Invariant Constraints)
As restrições ou validações invariáveis (invariant constraints) são restrições que devem sempre ser
atendidas antes da criação ou alteração definitiva, de uma agregação de objetos. Elas se contrapõem às
validações variáveis, que variam em conformidade com “cada Caso de Uso”.
O melhor local para se especificar e implementar restrições invariáveis, portanto, é no Modelo de Classes
(de Domínio), muito embora muitos o façam em especificações de Caso de Uso ou em definições de
formulário.
Veremos que o jCompany suporta a implementação de validações invariáveis via “programação
declarativa”, através de anotações que podem ser adicionadas como complemento ao processo de
mapeamento Objeto-Relacional. Ao dispensarmos a “programação procedimental” neste nível,
maximizamos o reúso e evitamos perda de qualidade e produtividade.
Veremos ainda que os componentes Apache Trinidad (JSF) ou Tag-Files (Struts) do jCompany
conseguem “herdar” as declarações de restrições invariáveis das Entidades de Domínio, deste modo
executando validações em formulários, sem que seja necessário redundá-las por todas as camadas onde
precisam ser verificadas. Evitando, por exemplo, redundância de verificação em classes de controle ou
em outro framework, como o Apache Validator!
- Gerando Mapeamento para Classes de Lookup/Tabular - Objeto-Relacional I
O próximo passo para nossa implementação é gerar uma primeira versão do mapeamento Objeto-
Relacional para nossa Entidade “Uf”.
Para tanto, iremos utilizar o plugin apropriado do jCompany Artifact Generator, de número “01”,
acessível a partir da tecla de atalho “control+N”, tendo-se a classe alvo editada.
1. Acione “control+N” para que o diálogo de assistentes padrões do Eclipse se abra, com uma relação
de categorias.
136
Implementando o Padrão “Manter Classe”
Figura B6.5. Acionando control+N sobre a classe Uf, e assistente para Mapeamento Objeto-Relacional.
3. A primeira página do Assistente provê todas as informações essenciais que iremos utilizar neste
momento, não somente para realizar o mapeamento Objeto-Relacional em si, mas também para
produzir uma versão “recomendada” para Entidades que considere Padrões de Projeto e otimizações
possíveis.
A Figura B6.6 mostra o diálogo e suas principais seções são descritas a seguir:
#1. A primeira marcação “Gerar Entidades descendentes se não existirem” faz com que o gerador
produza uma nova classe, com nome padrão <Entidade>Entity ou utilizando o sufixo padrão
para entidades definível no framework via anotações. Ex: Para Uf.java, será produzida uma
classe adicional UfEntity.java, concreta e descendente de Uf.java.
O default é utilizar este Padrão de Projeto, que nos ajudará a manter a parte abstrata da
classe, com informações de domínio separadas de códigos de implementação tais como
“hashCode”, “equals”, “toString” ou outros que se façam necessários.
#2. A marcação “Gerar mapeamento nos métodos” indica para que mapeamentos no padrão JPA
sejam gerados em métodos “getters”, e não sobre as propriedades. Este último é o default, por
ser mais legível.
#3. A opção “EJB x POJO” é reservada para uso futuro. Espera-se que ocorram diferenças no
futuro, entre anotações de POJOs simples e EJBs. Atualmente, no entanto, não há diferenças,
ao menos em nível das Entidades (ou seja, entre o EJB Entity Bean 3.0 x POJO persistidos via
JPA).
#4. A marcação de “Versão” indica para o plugin gerar uma propriedade adicional na classe
declarada como “private Long versao” e com mapeamento JPA @Version. Com isto, pode-se
reutilizar o tratamento de concorrência otimista padrão do JPA. Como nossa classe herda de
AppBaseEntity, o default deste campo é assumido para “não gerar”.
137
Capítulo B6
#5. A marcação “Auditoria”, indica para o plugin gerar as propriedades “private String
usuarioUltAlteracao” e “private java.util.Date dataUltAlteracao”, nomes padrões e reservados
no jCompany, utilizados pelo framework para manter o login do usuário que produziu a última
modificação em um objeto (registro no SGBD) e a data/hora desta modificação.
Obs.: Neste e no caso anterior, o jCompany supõe que estes tipos de atributos são herdados
(reutilizados), ao perceber a herança de AppBaseEntity. Com isso, altera o default para evitar
gerá-los novamente.
#6. A marcação “Informações Adicionais” faz com que uma segunda janela do Assistente seja
apresentada, com informações adicionais que possibilitam a geração de outras anotações do
jCompany. Se desmarcarmos esta opção, o botão de “Next” irá sumir. Deixe-a marcada,
apenas para conhecer a segunda janela. Não iremos, porém, alterar os seus valores padrões,
para nosso caso específico.
No caso de Uf, deve-se selecionar estereótipo “tabular”, mas o desenvolvedor não perceberá
diferenças funcionais se não fizer esta opção. Esta marcação irá levar à geração de uma
anotação a mais na Entidade, @PlcTabular, que será utilizada para otimizações*.
#8. O campo “Classe” traz a classe para mapeamento em si. Caso tenha-se utilizado o “control+N”
com a classe selecionada, ela já virá preenchida neste campo. Caso tenha-se entrado por outro
caminho, deve-se selecionar uma classe de Entidade para mapeamento.
#9. No campo “Tabela” o jCompany gera uma proposta para o nome da Tabela relacional (Table)
do SGBD, basicamente colocando nomes em maiúsculas e utilizando sublinhados como
separadores. Pode-se modificar o nome e deve-se fazê-lo para coincidir com nomes de tabelas
existentes, se for o caso.
#10. A lista “Identificador” traz diferentes estratégias para identificação de objetos, sendo OID-Auto
a preferível. Neste caso, o framework irá gerar mapeamento para uso do padrão recomendado
“Object-ID”, cuja identificação é realizada via a propriedade padrão “private Long id”, com
valores gerados automaticamente, pelo SGBD-R†.
#11. O campo “Sequence” permite que se informe o nome para criação de uma estrutura de
“Sequence” utilizada em alguns SGBDs relacionais, tais como Oracle, para geração de valores
de identificação. O Padrão do jCompany é utilizar um “Sequence” por “Tabela”, e com nome
“SE_<nome tabela>”. Novamente, pode-se modificar o nome para coincidir com “Sequences”
existentes ou para se mudar esta estratégia (Ex.: um único sequence para várias tabelas). Para
SGBDs que não usem o conceito de “Sequence”, este campo é desprezado.
#12. O campo “Propriedade” somente é utilizado para gerações de chave natural, que não estão no
escopo deste livro.
#13. O campo “CASE” permite que se informe o DataSource ODBC-JDBC para conexão com
repositório do CASE Enterprise Architect, que permite recuperação de dados de tamanho e
nulidade de propriedades.
#14. A coluna “Propriedade” traz propriedades da classe candidatas a serem persistidas, com
exceção das propriedades “transientes” (transient).
*
Em linhas gerais: o jCompany irá utilizar algumas anotações como esta para realizar interceptações em implementações JPA
baseadas no Hibernate, via Hibernate Listener, procurando interceptar e evitar recuperações automáticas a este tipo de classe, já que
são mantidas em caching na camada de Controle.
†
As demais estratégias de identificação, com chave composta (natural), não serão abordadas neste livro, mas somente no “Volume II
– Tópicos Avançados”, desta série. Consulte também a documentação do produto na Ajuda On-Line, para apoio em mapeamento de
chaves naturais.
138
Implementando o Padrão “Manter Classe”
Podem-se alterar mapeamentos para outros tipos, utilizando plugins como os do projeto Dali
e/ou fazendo edição simples das anotações geradas, se preciso for, para cenários diferenciados.
#16. A coluna “Coluna” apresenta nomes sugeridos para as propriedades das classes que, tal como
no caso da Tabela, podem ser modificados, e o deverão ser caso estejamos acessando uma
base já existente.
#17. A coluna “Obrigatório” permite que se marque se a Coluna gerada na Tabela relacional será
gerada com “NOT NULL” (Obrigatório = Sim) ou “NULL” (Obrigatório = Não).
#18. A coluna “Lookup” permite que se selecione uma ou mais colunas para comporem a cláusula do
método padrão “toString”, que será gerado pelo jCompany concatenando-se estas colunas, na
ordem em que aparecem (pode depois ser editado, como desejado). O jCompany marca como
padrão a primeira coluna do tipo “String” que encontrar. Como pedido na especificação,
usaremos nome e sigla e, portanto, devemos marcar ambas.
#20. A coluna “Tabela FK” exibe um nome que será utilizado durante a geração de DDL
automatizada do jCompany, especificamente para nomear Chaves Estrangeiras (Foreign
Keys), quando mapeando relacionamentos. O JPA assume um nome com base em “hashcode”
interno, mas é recomendável que se informe um nome legível, no padrão exigido pelo DBA.
#21. A coluna “Tipo SGBD” exibe o tipo que será utilizado para a geração da DDL (Data Definition
Language), código que define tabelas para um SGBD relacional. Normalmente, não deve ser
editado, já que os tipos assumidos são adequados.
#22. A coluna “Tamanho” exige que se definam os tamanhos limite (tamanho máximo) de cada
coluna, conforme exigido pelo esquema relacional. Para tamanhos com decimais deve ser
utilizado o formato [inteiro],[decimais] (Ex.: 11,2 para onze casas no total e duas casas
decimais). No nosso exemplo inicial, nome terá 40 caracteres e sigla terá 2, conforme vemos
no modelo da Figura B6.6.
4. Após preencher todos os campos conforme o exemplo da Figura B6.6, vá para o próximo passo, com
“Next”, e conclua o Assistente, sem modificar nenhuma informação.
Após a conclusão, o jCompany irá gerar a classe UfEntity (concreta) descendente de Uf (abstrata),
conforme pedimos, e complementar ambas com diversas anotações, métodos getters e setters
(padrões da especificação JavaBean), dentre outros.
Se realizarmos uma engenharia reversa (sincronização) das classes Java obtidas para a ferramenta
CASE após esta geração, veríamos que o Modelo de Classes obtido ficaria como o da Figura B6.7*.
*
Dica: Ao contrário do que fizemos, para explanação, é recomendado que o projetista evite manter os níveis concretos (UfEntity) e do
framework (PlcBaseMapEntity) em seus diagramas, deste modo mantendo-se no seu foco, abstrato.
139
Capítulo B6
Figura B6.8. Classe de Domínio Uf, após geração de Mapeamento Objeto-Relacional com Plugin jCompany.
#2. A anotação de herança do JPA é gerada, já que a declaração de Entidade @Entity fica no nível
descendente.
#3. A propriedade que implementa o Object-Id “id”, com mapeamentos correspondentes é gerada.
Nota: o jCompany faz manipulações de entidades utilizando o método “getId”, para Object-ID,
140
Implementando o Padrão “Manter Classe”
ou “getIdNatural”, para chaves naturais. É, portanto, um uso padrão. Caso se opte por alterar o
nome da propriedade para outro que não “id”, deve-se prover getters e setters auxiliares, de
adaptação *.
#4. As anotações para mapeamento de cada propriedade são geradas, também segundo o padrão
JPA do Java EE 5, utilizando os critérios de tamanho e obrigatoriedade informados.
#5. Finalmente, os getters e setters padrões da especificação JavaBean são gerados, para cada
propriedade.
Figura B6.9. Classe descendente UfEntity, gerada para separar implementações do Desenvolvedor das
informações de Domínio.
#2. As anotações que definem um Entity Bean no JPA, bem como tabela de mapeamento são
geradas.
#3. O AcessType é anotação Hibernate, para indicar que anotações estão nas propriedades (field) e
não em métodos†.
#4. Estas anotações iniciadas com o prefixo reservado “Plc” (Powerlogic) são do jCompany, e
utilizadas para lógicas de otimização via especializações de Listeners. Em resumo, podem evitar
a produção de queries desnecessárias para estas classes, já que são mantidas em caching na
camada Controle, pelo jCompany.
*
O Object-Id ou OID, é um identificador numérico interno e auto-gerado pelo SGBD, mapeado como a “Primary-Key” no SGBD,
implementa o conceito de chave fictícia ou substituta, que é a estratégia de identificação mais recomendada pelos DBAs modernos, do
ponto de vista relacional (evita informações na chave e sua redundância, precavendo contra problemas graves tais como no caso do
Ano 2000). Além disso, esta estratégia é também essencial para uma implementação OO mais pura e produtiva, advinda da
“generalização da identificação de objetos” – com diversas vantagens que serão discutidas no Volume II deste livro.
†
O JPA consegue identificar esta diferença automaticamente e ignora esta anotação.
141
Capítulo B6
#5. As NamedQueries são um recurso altamente recomendado pelo JPA e utilizado pelo jCompany
para maximizar os benefícios da “programação declarativa”. A NamedQuery com nome padrão
“[Entidade].querySelLookup” é utilizada pelo jCompany para recuperar objetos referenciados, e
traz unicamente as propriedades de identificação e marcadas como lookup (presentes também
no toString). Deste modo, o jCompany evita recuperações perigosas e dispensa programação
manual para preenchimento de formulários e suas referências*.
#6. A Classe concreta “UfEntity” sempre herda propriedades e métodos de domínio de “Uf”, e deste
modo separa programações de baixo nível das programações de domínio†.
#7. Um construtor é gerado para cada NamedQuery padrão, de modo a viabilizar a recuperação
otimizada somente das propriedades necessárias. Deste modo, evita-se o risco de recuperações
de grafos de objetos maiores que os necessários, e também aprimora-se o padrão de
programação (para mais detalhes, veremos exemplos no capítulo 17, sobre programação de
regras de negócio).
#8. Método padrão Java “toString” é gerado automaticamente, utilizando-se as duas propriedades
de “lookup” marcadas e com separação por hífen. Este método é utilizado pelo jCompany para
exposição de valores da classe em objetos gráficos tais como “combos” e “radio”, bem como
títulos dinâmicos de páginas, em alguns Casos de Uso Padrões que não editem coleções, mas
uma agregação de objetos por vez. O desenvolvedor pode alterá-lo para a formatação
desejada.
6. Para finalizar, o jCompany também gera uma entrada da Entidade no arquivo “hibernate.cfg.xml”‡.
Figura B6.10. Arquivo hibernate.cfg.xml, gerado com configurações padrões e acrescido da Entidade recém-
mapeada.
*
As NamedQueries, assim como o mapeamento em si, ficam nas Entidades de Domínio, mas somente são utilizadas pela camada de
Persistência (DAO).
†
O interessante é que esta separação, apesar de nítida, é realizada no mesmo “plano de abstração”. Ou seja, é um tipo de separação
de conceitos mais OO, que dispensa transformações de modelo em vários “planos de abstração” – é um tipo de separação de conceitos
que tende a se preservar com maior eficácia, ao longo do tempo.
‡
Este registro é desnecessário para o JPA, que consegue identificar as classes mapeadas, sem que estas precisem ser declaradas no
arquivo “persistence.xml”, correspondentes ao “hibernate.cfg.xml”.
142
Implementando o Padrão “Manter Classe”
143
Capítulo B6
Figura B6.12. Validações via Anotações do jCompany (a anotação está deslocada para exibir a propriedade.
Cada validação é exibida com sua documentação “javadoc”, o que facilita a rápida inspeção.
2. Após selecionar a validação desejada, conheça as suas opções de declaração (propriedades da
anotação) pressionando a tecla “shift” e sobrepondo o mouse sobre a anotação, conforme a Figura
B6.13.
Figura B6.13. Apertar shift com o cursor do mouse sobre a Anotação exibe suas propriedades.
Veja que é possível utilizar a propriedade “tam” para indicar o tamanho exato que desejamos.
3. Informe “tam=2” para encerrar o trabalho.
4. Em seguida, procure pela anotação @PlcValFormatoSimples, que iremos utilizar para garantir que os
valores informados serão em letras maiúsculas. Esta segunda anotação fica de exercício para o
leitor, que deverá então obter o resultado exibido na Figura B6.14. Repare que usamos uma
Enumeração “FormatoSimples”, definida dentro da anotação @PlcValFormatoSimples.
Até aqui resolvermos a restrição “Siglas devem ser alfanuméricas e maiúsculas” e também a restrição de
tamanho mínimo de 2 para sigla (além de 1 para nome, implicitamente, já que é nullable=false). Estas
são validações são em nível de propriedade.
Mas e quanto às validações de duplicidade para nome e sigla? Elas são validações que consideramos em
nível de classe, já que devem percorrer vários objetos da classe para serem averiguadas. Como iremos
resolvê-las?
No caso da propriedade “nome”, o jCompany já irá cuidar para que não tenha valores duplicados,
graças à anotação @PlcTabular(propReferenciaDesprezar=”nome”). Esta anotação define uma
propriedade como “padrão para desprezo de objetos”. Neste caso, se “nome” não for informado, os
144
Implementando o Padrão “Manter Classe”
demais valores do objeto serão desprezados, e ele não será persistido*. Como aprimoramento prático,
esta anotação @PlcTabular também assume um teste de duplicata, já que tipicamente esta “propriedade
de referência” costuma ser também um “identificador natural” do objeto, e não aceitar duplicada (Este
default pode ser alterado, mas não é o nosso caso).
Na Figura B6.15, explicitamos a propriedade e também o indicador para teste de duplicata.
Figura B6.15. Anotação PlcTabular com propriedade nome como referência de desprezo e teste de duplicata
explícito (apesar de ser default)
Prosseguir para programações de Caso de Uso antes de estarmos certos de explorar todo o
potencial de modelagem OO, mapeamento Objeto-Relacional e programação declarativa é um erro
que cobra seu preço na forma de queda de qualidade e produtividade.
Uma vez que estamos certos de ter esgotado o potencial de solução no nível da Entidade, passaremos a
contar com um novo aliado para a confecção do Caso de Uso em si: os Cheat-Sheets ou Folhas de
Apontamentos.
Este recurso é utilizado pelo jCompany para prover roteiros que conduzem o desenvolvedor do início até
o fim da implementação de um Caso de Uso Padrão, utilizando arquitetura MVC2-P. Neste cenário, os
Cheat-Sheet são utilizados como “orquestradores” do processo de construção, guiando o desenvolvedor
por passos e plugins apropriados, em cada um deles.
Tipicamente, um roteiro em Cheat-Sheet do jCompany irá seguir a seguinte estrutura:
*
Esta anotação de metadados é também herdada por componentes visuais de formulário, que usam a
mesma propriedade como um “flag” para facilitar o descarte de linhas não preenchidas. Em suma, para o
nosso caso: se o usuário não preencher “nome” em uma instância (linha de formulário correspondente),
componentes de validação irão desprezar esta linha (Lembre-se: não há acoplamento com a herança de
metadados e a camada de Domínio é ortogonal, visível por todas as camadas do MVC. Em restando
dúvidas, retorne ao capítulo IV do módulo A).
145
Capítulo B6
o Passo 1: Apresentar o Caso de Uso Padrão brevemente, com hiperlinks para definição mais
extensa na documentação.
o Passo 2: Chamar um “plugin de processo” específico do jCompany, que irá criar uma primeira
versão gerando todos os artefatos “não-Java” (JSPs, XML, Properties, etc.) envolvidos. Lembre-se
que classes Java são generalizadas. O jCompany não gera código Java procedimental, o que
preserva a produtividade durante as manutenções!
o Passos 3, 4, 5 e 6: Em cada um destes passos, o jCompany abrirá os artefatos gerados ou
alterados pela geração no passo 2, para as camadas MVC-P, respectivamente “Visão”,
“Controle”, “Modelo” e “Persistência”. Cada passo abre o artefato através de um “plugin de edição”,
homologado para este fim.
o Passo 7: O jCompany dispara a construção e liberação do arquivo WAR via Maven, utilizando
a “liberação completa” na primeira chamada (alguns minutos), e a “liberação rápida com
reinicialização”, nas subseqüentes (alguns segundos).
Vamos acionar o nosso primeiro roteiro.
1. Acesse o menu “Help -> Cheat-Sheets...”. Um diálogo com várias categorias de Cheat-Sheets
aparecerá.
Figura B6.16. Relação de opções de roteiros do jCompany, com seleção do “Manter Classe”.
4. O primeiro passo traz uma breve introdução e permite, com o clique no botão de ajuda, que se
recupere a documentação completa para o padrão a ser desenvolvido, conforme destacado na Figura
B6.17.
*
É possível que um Cheat-Sheet abra com o passo inicial expandido, dependendo do estado em que a última utilização deixou o
roteiro. O Eclipse procura “manter o último estado” do Cheat-Sheet.
146
Implementando o Padrão “Manter Classe”
Figura B6.17. Primeiro passo do Cheat-Sheet com destaque para o botão de ajuda.
#1. Opção entre tecnologia de Controle Struts ou JSF: O jCompany investiga o projeto para
assumir um padrão apropriado, mas como é possível se compatibilizar as duas tecnologias em
Casos de Uso diferentes, com alguma programação adicional, é dada a oportunidade para que
o desenvolvedor altere este padrão.
#2. Opção entre a tecnologia de Modelo (Serviços) entre POJO e EJB: Não gera diferenças,
sendo reservada para diferenciações futuras.
#3. Projeto: Pode-se alterar o projeto corrente (assumido por default) para a geração em
módulos, por exemplo.
147
Capítulo B6
#4. Identificador do Caso de Uso (URL): É um texto que será utilizado como prefixo pelo
jCompany para a geração da URL, nome base de JSPs, etc., seguindo convenções de
nomenclatura da Arquitetura. Para o nosso exemplo, utilizaremos “uf”, o que irá gerar uma URL
“/uf” e JSP “ufTabular.jsp”.
#5. Entidade: Este campo permite que se selecione a Entidade raiz da Agregação envolvida, cujas
propriedades serão utilizadas como base para a proposta de um formulário, e cujas instancias
serão persistidas, segundo a arquitetura MVC. Deve-se selecionar uma classe concreta, no
nosso caso “UfEntity”.
#6. Nome do pacote: Assumido. Nesta versão, não deve ser modificado.
#8. Classe de Modelo: Nome de Classe de Modelo (Serviço), caso se preveja a necessidade de
implementação de programações nesta camada, para o Caso de Uso. No nosso caso,
preferimos fazer a programação de validação de duplicidade de “siglas” a partir de eventos da
camada Modelo e, portanto, podemos pedir para que o assistente crie uma classe com nome
padrão “UfManager” (Um Session Bean candidato!).
Obs. 1: O jCompany irá criar somente a estrutura básica destas classes (declaração), no
projeto/pacote padrão. Como já vimos, o jCompany não gera códigos Java procedimentais,
mas trabalha com generalizações OO e programação declarativa, para reutilizá-los.
Obs. 2: Os sufixos padrões para classes de Controle (Action) e serviço de Modelo (Manager)
são definidos em metadados via anotações, e podem ser customizados como veremos mais a
frente.
#10. Permissão de Acesso: (Somente Struts) Pode-se informar nome de “roles” (Atores) que
poderão acessar este Caso de Uso, restringindo este acesso. Estas roles, que podem ser várias,
separadas por vírgulas, serão geradas no Action-Mapping do arquivo struts-config.xml,
segundo o padrão Struts. O faces-config.xml não traz similar para JSF, portanto este problema
deve ser resolvido com declarações padrões Java EE no web.xml ou via produto jCompany
Security, quando utilizando-se esta tecnologia (nosso caso).
#11. Permissão de Manutenção: Neste caso, pode-se declarar “roles” (Atores), inclusive várias
delas, separadas por vírgula, que poderão acessar o Caso de Uso (URLs de implementação)
com privilégio de inclusão, alteração ou exclusão. As demais continuam tendo acesso, somente
de consulta. Esta é uma implementação específica de segurança realizada pelo próprio
jCompany. No nosso caso, informe “Administrador” para permitir somente consulta para
outras “roles”, exceto esta.
2. Após preencher todos os campos como indicado na Figura B6.18, iremos apertar o botão “Next” para
seguir para a página (segunda página do Assistente), onde preencheremos somente o título, com
“UF”, em maiúsculo.
o Título: Título a ser utilizado no Formulário e Item de Menu que serão gerados. Usar “UF”,
“Manter UF” ou “Gerir UF”, conforme desejado. Com recomendação geral, o uso de plural deve
ser evitado (afinal, todos os títulos seriam plurais).
Por hora, não explicaremos as diversas opções desta segunda página, que veremos em detalhe,
nos próximos capítulos.
3. Após informar o título, clique novamente em “Next”, para seguirmos para a terceira página do
Assistente.
148
Implementando o Padrão “Manter Classe”
Figura B6.19. Terceira página do Assistente de Criação do Caso de Uso Padrão “Manter Classe”.
Esta página nos permite personalizar uma primeira versão de página JSP, apropriada para nosso
Caso de Uso Padrão e que poderá ser estendida posteriormente para conter especificidades*.
Em nosso Caso de Uso atual, vamos apenas entender algumas opções básicas deste passo, já que
o padrão assumido nos servirá, sem necessidade de intervenções:
#1. Usar I18n (Internationalization): Indica para o jCompany gerar os rótulos de cada
propriedade no arquivo “ApplicationResources.properties”, e não diretamente na JSP.
#2. Usar borda na tabela: É uma opção somente útil em tempo de visualização, que exibe borda
na tabela HTML que define o contorno do formulário, para auxílio visual apenas. A tabela que
define formulários, nas peles do jCompany, não são exibidas com bordas, como padrão.
#3. Visualizar Pele: Permite que se escolha uma pele distinta para a visualização, eventualmente
uma pele específica da empresa não pré-existente na palheta do combo – motivo pelo qual o
mesmo pode ser modificado.
#5. Exemplo de página sendo visualizada, que utilizaremos em nosso Caso de Uso.
#6. Coluna “Usa?”: Permite que propriedades da classe sejam retiradas da visualização no
formulário. Perceba que o jCompany já assume que propriedades padrões de auditoria “pauta
mínima” não devam aparecer.
4. Para nosso propósito atual, podemos concluir o Assistente de Criação, clicando em “Finish”, e
encerrando o segundo passo do roteiro Cheat-Sheet. Após o alerta de conclusão da geração, o
próximo passo do roteiro Cheat-Sheet se abrirá automaticamente: “Editando Artefatos da Camada
de Visualização”.
5. Ao clicarmos para editar pela primeira vez, um diálogo poderá pedir pela configuração do plugin
Exadel Studio (renomeado para RHDS - Red Hat Developer Studio, mais recentemente), conforme
Figura B6.20.
*
Ela pode apresentar ligeiras diferenças visuais, por estar programada para revisão estética, durante a escrita deste livro
149
Capítulo B6
Os plugins que compõem o RHDS são especializações dos plugins do WTP, que permitem edições
mais inteligentes (e até gráficas) também para arquivos Tiles, Struts e JSF, tais como tiles-
menu.xml, tiles-pagina.xml, struts-config.xml e faces-config.xml.
Importante 1: Estes plugins consomem mais memória, sendo recomendável que se chame o
Eclipse utilizando o disparo padrão do jCompany que reserva 768MB para o Eclipse (em um
máquina com no mínimo 1GB RAM), chamado “start768m.bat”.
Importante 2: Se você não ver o diálogo acima, ao clicar neste passo, é porque sua versão do
jCompany já pré-configurou estes plugins (esta facilidade estava em andamento, no momento
desta escrita). Neste caso, não será preciso seguir as instruções de configuração deste item. Se
não foram pré-configurados, teremos que configurar este plugin somente uma primeira vez, para
cada projeto.
Ao clicarmos em “Add JSF Capabilities Now” para nosso exemplo (para Struts, o comportamento é
similar) e no botão “Ok”, um próximo diálogo de configuração nos pedirá que indiquemos onde se
encontra o arquivo “web.xml” do projeto. Devemos localizar primeiro o diretório do projeto
principal abaixo de meus_projetos, normalmente
“[driver]/Powerlogic/jCompany/meus_projetos/rhtutorial”, e em seguida o “web.xml” em
“src/main/webapp”, conforme a Figura B6.21.
150
Implementando o Padrão “Manter Classe”
Importante: Esta versão do RHDS não reconhece artefatos que se encontram em módulo de
recursos (como JSPs do framework, por exemplo), apresentando um ícone de erro no projeto
principal. É um alerta que não causa problemas mais sérios e que pode ser desligado em “Windows
-> Preferences... -> JBoss Tools -> Web -> Verification”.
151
Capítulo B6
#1. Versão textual da JSP. Possui recursos de “auto-complete” a ajuda on-line sensitiva bastando
que se posicione o cursor sobre um atributo de Tag.
#2. Visualização da barra de títulos. Até a versão atual, ela não fica exatamente alinhada com as
colunas e nem traduz rótulos I18n - estas são limitações das APIs de customização do editor
desde sua origem na Exadel. Estes recursos tendem a ser aprimorados nas próximas versões,
com a aquisição da Red Hat.
Obs.: Repare que, na figura, a seleção de um segmento na parte visual seleciona o segmento
na parte texto, facilitando sobremaneira a edição.
#3. Visualização das ocorrências de campos de entrada. A linha pontilhada em verde indica que
serão exibidas várias ocorrências do trecho circundado.
#4. Visualização de hierarquia de Tag. Ao clicar em “Tag<>”, o editor exibe a hierarquia ancestral
da Tag correntemente selecionada.
o Mensagens I18n: O plugin homologado para a edição de arquivos de Properties é o JInto. Este
plugin permite a edição de mensagens em vários idiomas simultaneamente, bem como emite
alertas de traduções faltantes (chaves que não possuem preenchimento em algum dos idiomas).
Além disso, dá erro quando há duplicidade de chaves e oferece busca via “control+F”.
152
Implementando o Padrão “Manter Classe”
Figura B6.25. Mensagens em vários idiomas editadas simultaneamente, e com mensagens de validação.
#2. Ordenação por chave (Key) ou rótulo em qualquer linguagem, clicando-se nos cabeçalhos de
coluna.
#3. Edição de vários arquivos de idiomas simultaneamente (Os templates “*_ini.zip” do jCompany
vem com exemplos em inglês e espanhol)
#4. Alertas amarelos para chaves que não possui tradução em todos os idiomas
#5. Clique direito em qualquer chave aciona o “Search for Reference”, diálogo que permite buscar
por ocorrências da chave em diversos tipos de arquivos, com diversas opções.
#6. Há uma série de customizações possíveis. Para mais opções, deve-se consultar o Help On-Line
do Eclipse, na seção “JInto User Guide”.
o Entrada de Menu: O plugin homologado para edição de arquivos XML do Tiles é também o RHDS.
O framework Tiles é utilizado pelo jCompany, tanto para versão Struts quanto JSF, para Gerência
de Leiaute, o que inclui os menus, que são um importante leiaute de nível “secundário”.
Menus Tiles são definidos em XML, e podem ser renderizados em vários formatos, como veremos.
O assistente do jCompany gera uma nova chamada para a URL principal do Caso de Uso gerado
(em nosso caso “/f/t/uf”), ao final do último bloco de menu que encontrar no arquivo padrão “app-
tiles-menu1.xml”. No módulo D, iremos discutir Gestão de Leiaute com Tiles, mais a fundo.
153
Capítulo B6
#1. O nome padrão do arquivo para definição da estrutura hierárquica de menus é “app-tiles-
menu1.xml”. Na versão JSF, este arquivo é declarado no web.xml, como initParam do Servlet
TilesServlet. Já na versão Struts, ele é definido no struts-config.xml. Para menus muito
extensos, pode-se subdividir o arquivo em “app-tiles-menu2.xml”, e assim por diante,
bastando que se acrescente o nome arquivo no “web.xml”.
#2. A definição Tiles chamada “app.m” corresponde à primeira “barra de menu”. O projeto que
geramos já vem com uma versão de definição de menu que contém, nesta barra principal,
quatro opções: um primeiro sub-menu “app.m.inicial”, com opções da aplicação e outros três
sub-menus que são definidos dentro do jCompany: “jCompany.m.ajuda.jsf”,
“jCompany.m.personalizar.jsf” e “jCompany.m.area.tecnica.jsf”.
#3. O primeiro sub-menu, chamado “app.m.inicial”, é o único definido localmente (repare o número
3 repetido, indicando o vínculo). Por este motivo, foi onde o jCompany gerou a chamada para
UFs, “/f/t/uf”.
#4. O jCompany tem definições de “sub-menus” padrões que podem ser reutilizadas, basicamente
para permitir acesso à Ajuda On-Line da aplicação, Personalizações de Pele, Leiaute e
Formulário (Preferências de Aparência, mantidas em cookies) pelo usuário; e também um
menu especial, somente acessível por usuários com papel (role) “AreaTecnica”, utilizado
somente em tempo de desenvolvimento.
#5. Todos os blocos que possuem itens de menu herdam de uma definição “app.menu.item”, que
por sua vez herda de “jCompany.menu.item”. Esta arquitetura OO do Tiles permite que o
jCompany generalize a renderização e controles de menus e sua troca dinâmica pelos usuários
(não se preocupe em entender agora como o Tiles utiliza herança na gestão de leiautes, iremos
praticar alguns exercícios neste sentido, nos tutoriais que se seguirão)
#7. Na definição do hiperlink temos o seu rótulo (I18n) e URL a ser chamada. Para JSF, as URLs
irão seguir o padrão “/f/t/[url especifica]”, para ativar o contexto “Faces” + “Tiles”. Em Struts,
a URL é gerada sem prefixo, mas com sufixo “.do” e parâmetro “evento=x”. Ex:
“/uf.do?evento=x”.
#8. O Editor Tiles do Red Hat Studio também permite visualização em modo gráfico e, ainda, do
XML em si.
Figura B6.27. Visualização do Menu em forma de diagrama, mostrando a herança. O item “jCompany.m.item” está
mais opaco, já que sua definição não se encontra no arquivo atual.
154
Implementando o Padrão “Manter Classe”
chamado “package-info.java”*. Uma nova classe de controle também poderá ter sido gerada, caso o
desenvolvedor tivesse modificado o “AppAction”, durante o Assistente de Criação do Caso de Uso.
o Declaração de Fluxo de Navegação: O plugin homologado para edição de arquivos XML de
definição de “fluxos de controle”, tais como o “faces-config.xml” (JSF) ou “struts-config.xml” (Struts)
é também o RHDS, que provê facilidades similares, em ambos os casos. Estes arquivos definem o
fluxo de navegação para JSF ou Struts, que no caso de um Caso de Uso “Manter Classe” é trivial,
mantendo o usuário sempre no mesmo formulário/URL.
Em JSF o jCompany irá gerar entradas no “faces-config.xml”, com URL padrão “/t/[id do caso de
uso]”. No nosso caso específico, ele gerou “/t/uf”. O prefixo “/t/” faz com que o Tiles atue.
Em Struts, o jCompany irá gerar entradas no “struts-config.xml”, sendo uma declaração de form-
bean vazia (pois o jCompany o torna desnecessário), com nome “[id do caso de uso]Form”, e outra
de Action-Mapping com padrão “/[id do caso de uso]”. Ex.: respectivamente, no nosso caso,
“ufForm” e “/uf”.
Figura B6.28. Editor do Red Hat Studio homologado para arquivos faces-config.xml e struts-config.xml.
#1. Arquivo de configuração JSF para a aplicação, em formato XML e com auxílio em todas as
seções.
#2. Uma regra de navegação (navigation rule) de desconexão vem pré-configurada, para atender
ao botão gerado como padrão no rodapé das aplicações
#3. A nossa regra de navegação é gerada, com fluxo simples, que apenas mantém o usuário na
mesma página.
#4. Como nos outros editores RHDS, abas permitem que se comute para visualização em modo de
diagrama ou texto XML.
*
Em Struts, ele irá alterar o “struts-config.xml” e inserir estas informações de metadados no próprio “action-mapping”.
155
Capítulo B6
Figura B6.29. Modo gráfico para exibição de fluxos de navegação, representando inicialmente “Desconexão” e
“Manutenção de UF”.
o Metadados de Controle (Metadados): Em JSF, o jCompany irá gerar um arquivo específico para
conter anotações (Annotation), com nome “package-info.java”. Este arquivo é criado dentro de um
pacote padrão para conter metadados ou programação declarativa:
“src/java/config/com/powerlogic/jcompany/config/app/[url do caso de uso]”. Em nosso
caso, específico, abaixo de: “src/java/config/com/powerlogic/jcompany/config/app/uf”.
Estas anotações servem para dar diretrizes ao framework para acionar comportamentos genéricos
desejáveis, na camada Controle. Não iremos nos aprofundar nos metadados, neste capítulo.
Importante: No momento da escrita deste livro, a Powerlogic estava anunciando um editor visual
para estes metadados, que pode estar presente na sua instalação. Utilizaremos, neste livro, a edição
padrão Java para arquivos de metadados (com auxílio do “auto-complete”), mas você pode
experimentar o novo editor, se possuir uma release recente. Verifique, acionando “clique direito” no
projeto “rhtutorial” (principal), e procurando por “jCompany -> Editor de Metadados”.
o Classe de Controle: Para Struts ou JSF, o Assistente de Criação permite que se defina um nome de
classe de controle para que seja criada dentro do padrão. Precisaremos deste recurso, em próximos
tutoriais.
Neste passo, além dos metadados, o Cheat-Sheet também abrirá as Entidades, em nosso exemplo
“Uf.java” e “UfEntity.java”, utilizando como plugin de edição padrão o JDT, naturalmente.
*
Como vimos no capítulo 5, este grafo é composto da Agregação de Classes sendo mantida e também das classes utilizadas como
consulta, em uma Colaboração (URL).
156
Implementando o Padrão “Manter Classe”
tutorial, ainda não precisamos de nenhuma customização específica, pois o padrão nos atendeu
perfeitamente. Mas nos próximos Casos de Uso, mais complexos, iremos explorar várias customizações
típicas.
O passo de finalização, portanto, se trata simplesmente do disparo de rotina Maven para
“empacotamento seguido de liberação”. Esta rotina irá agrupar nossos projetos em um executável WAR,
apropriado para executar no Application Server correntemente configurado - em nosso caso, o Contêiner
Web Tomcat 6.x (já que não usaremos EJB).
1. Clique no último passo, certificando-se de que o projeto “rhturial” está em foco.
No primeiro acesso será necessário marcar a opção, conforme indicado na Figura B6.31, mas nas
subseqüentes um atalho será criado, facilitando o disparo. Note que o diálogo de External Tools
permite diversas personalizações das rotinas.
Figura B6.31. Diálogo do “External Tools” com diversas tarefas Maven genéricas e opções.
#2. Em “Working Directory” vemos que a variável ${project_loc} indica como alvo o projeto
corrente.
#3. Em argumentos, diversas opções Maven são usadas. Discutiremos variações de uso em outros
capítulos.
157
Capítulo B6
Figura B6.32. Relatório final do Maven sobre a liberação completa (primeira vez, mais demorada).
4. Para compreender o resultado desta tarefa, confira o diretório onde se encontra instalado o Tomcat,
em “[jcompany]\servers\tomcat\”, conforme a Figura B6.33.
Como funciona? Após gerar o arquivo “rhtutorial.war”, a rotina Maven expande seu conteúdo na
pasta “webapps”, e envia um arquivo de definição de contexto (presente no template INI), para a
pasta “conf\Catalina\localhost”. A configuração é a mesma também para ambientes de
desenvolvimento Linux.
158
Implementando o Padrão “Manter Classe”
Figura B6.34. Para liberação, via Cheat-Sheets ou atalho External Tools, o projeto principal deve estar em foco.
Este problema pode ocorrer porque, como descrevemos na Figura B6.31, as rotinas Maven do jCompany
estão configuradas para pegar o projeto correntemente em foco no Eclipse (${project_loc}). Para fugir
deste incômodo, é possível se criar tarefas Maven apontando para cada projeto explicitamente, da
seguinte forma:
1. Selecione, dentro do diálogo do External Tools, a tarefa desejada e clique direito, acionando a opção
“Duplicate”, como exibido na Figura B6.35.
Figura B6.36. Criando tarefas específicas de Liberação, com partes modificadas em amarelo.
Obs.: Esta prática pode levar à proliferação de tarefas, mas é útil para quem trabalha com poucos
projetos simultaneamente.
159
Capítulo B6
2. Em seguida levantar o serviço, utilizando a opção “Apache Derby -> Start Derby Network Server”.
*
Este SGBD-R possui um trajeto curioso: criado pela empresa Cloudscape, detinha o nome de Cloudscape DB. Esta empresa foi
adquirida pela Informix, que por sua vez foi adquirida pela IBM, que doou o produto para o grupo Apache, quando mudou de nome
para Apache Derby. Finalmente, na versão 6.0 do Java, está sendo incorporado como solução embutida de SGBD-R.
160
Implementando o Padrão “Manter Classe”
3. Conferir a ativação do serviço. O indicador de que um serviço de Banco de Dados Derby está
servindo na porta 1527 é uma seta verde que passa a decorar o projeto e uma mensagem (em
português, já que o Derby tem tradução embutida para este idioma!) na janela de console.
4. Conferir o arquivo de conexão de Pool JDBC. O arquivo “rhtutorial.xml”, conhecido como arquivo de
contexto no Tomcat, pré-configurado na aplicação, vem com nome “bancolocal” e opção de “auto-
criação” para que um novo Banco de Dados seja criado, se não existir (o banco é criado na raiz do
projeto “rhtutorial”). Este arquivo deve ter sido liberado para a pasta “conf/Catalina/localhost” do
Tomcat.
Obs.: Pode-se, naturalmente, alterar estas configurações para se utilizar qualquer outro SGBD-R
desejado, apenas cuidando para disponibilizar o driver JDBC de acesso na pasta “common/lib” do
Tomcat.
- Utilizando o Apache Tomcat
Com o Banco de Dados no ar, podemos ativar finalmente o Tomcat, que usaremos durante este livro*.
1. Para iniciar o Tomcat, basta clicar no ícone do “gato Tom”, na barra do Eclipse.
*
Somente no livro “Volume II – Tópicos Avançados”, quando introduziremos Web-Services, JMS e chamadas RMI-IIOP, utilizaremos
EJB3, Glassfish e JBoss.
161
Capítulo B6
2. Para executar a nossa aplicação, como está sendo servida na porta 80, basta digitar no Navegador:
http://localhost/rhtutorial
- Entendendo a Segurança – Controle de Acesso I
Logo que executarmos a chamada da aplicação, seremos apresentados a uma página de autenticação do
jCompany, conforme a Figura B6.43.
Aqui normalmente começam a surgir várias indagações, com relação à customização da aplicação, como
por exemplo:
1. Como está definida a segurança? Que usuário utilizo?
Não iremos responder aos itens 2 e 3 no presente capítulo, mas faremos uma breve introdução sobre o
item 1, para compreendermos o que vem pré-configurado do ponto de vista da aplicação e Application
Server/Contêiner.
o Configuração de restrição de segurança padrão Java EE, no projeto: Os templates INI já vêm
com opções de segurança pré-configuradas no padrão Java EE, declaradas no arquivo “web.xml”.
Basicamente, há uma restrição definida para a página inicial da aplicação, que permite acesso
somente para usuários com papel (role) “Membros”. Este é um papel comumente adotado no
jCompany para representar “Qualquer usuário que possua um login/senha”.
Para mais informações sobre como configurar uma segurança padrão Java EE no arquivo web.xml,
pode-se consultar documentação de tutorial da Sun no hiperlink:
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/ (capitulo 32: Security)
162
Implementando o Padrão “Manter Classe”
* Alguma variação também ocorre caso seja utilizada a opção “htmlFormatoPlc=Strict” como parâmetro inicial (context-param) no
web.xml. Neste caso, o jCompany evitará renderizar opções do framework DOJO utilizadas no rodapé padrão, que não são compatíveis
com formato XHTML Strict do W3C.
163
Capítulo B6
#1. Topo contendo nome da empresa, título do formulário corrente e sigla da aplicação. O título
central muda conforme cada formulário e documento sendo editado.
#2. Barra de menu Pull-Down, utilizada no leiaute “sistema”, com várias opções sugeridas como
padrão.
#4. Barra de “botões de quiosque”, sugerida para destacar funções importantes do negócio (opções
de Caso de Uso mais acessadas).
#5. Área informativa sugerida, devendo ser editada para conter informações globais de operação
da aplicação.
#6. Área customizável da barra de rodapé, contendo nome completo da empresa e da aplicação,
bem como informações de copyright e de controle da aplicação.
#7. Área de rodapé gerida pelo jCompany, sugerida como padrão com diversas opções de
utilitários.
Todas estas áreas podem ser personalizadas. Em até certo nível, inclusive, somente com algumas
anotações de metadados. Para alterações mais profundas, no entanto, será preciso editar XMLs de leiaute
no padrão Tiles e/ou especializar JSPs de componentes.
- Personalização de Pele
Caso as cores apresentadas na página principal da Figura B6.45 não coincidam com as cores de sua
aplicação, não se preocupe: a parte decorativa da aplicação é realizada em peles, que podem inclusive
ser escolhidas de uma palheta e modificadas para o gosto de cada usuário.
Vamos selecionar a “pele itunes”, clicando no menu “Prefs/Language -> Personalizar Pele” (ou através da
aba do Tab-Folder ou opções de rodapé). Experimente variar a seleção por várias peles, e ao final
mantenha a pele de sua preferência – neste livro, iremos utilizar principalmente a pele “itunes”, até o
módulo D, quando aplicaremos um Web-Design próprio.
Figura B6.45. Seleção da pele “iTunes”. Lembre-se de clicar em F12-Gravar para confirmação.
164
Implementando o Padrão “Manter Classe”
- Personalização de Leiaute
Assim como no caso da pele, o próprio leiaute mais abrangente da aplicação pode ser personalizado ao
gosto e necessidade de cada usuário, ficando ambos salvos em cookies, o que não causa sobrecarga na
aplicação.
Para personalizar o leiaute, acesse a opção “Prefs/Language -> Personalizar Layout” (o uso de Layout ou
Leiaute pode ser escolhido e modificado no arquivo de mensagens “ApplicationResources.properties”).
- Personalização de Formulário
Normalmente, formulários de entrada de dados são apresentados na seção de corpo (centro) do leiaute
principal – seção que costuma ser a única a variar, em conformidade com cada Caso de Uso.
Podemos ver esta organização acessando o formulário que produzimos, via a opção “Menu Inicial ->
UF”*. Mas antes, vamos conhecer algumas opções de customização de comportamentos e aparências
ligadas a formulários, utilizando a opção “Prefs/Language -> Personalizar Formulários”.
Figura B6.46. Seleção de formulário “Elegante”. Selecionar e clicar em F12-Gravar para confirmar.
Nas imagens deste livro, usaremos a opção “Elegante” para formulários, que exibe “fieldsets” HTML em
lugar de tabelas, para delimitar formulários. Se também preferir, selecione esta opção.
- Gerando Esquema Relacional (DDL) - Geração de DDL I
Para conseguirmos operar nosso Caso de Uso inicial, precisaremos criar o esquema relacional no nosso
SGBD Apache Derby, que atualmente possui apenas um banco de dados com nome “bancolocal”,
totalmente vazio. Este esquema é definido em linguagem padrão conhecida como DDL (Data Definition
Language).
Felizemente, o jCompany traz algumas opções de menu, abaixo de “Área de TI”, especialmente
disponíveis para usuários com papel (role) “AreaTecnica” – e uma delas irá nos apoiar em gerar DDLs
automaticamente, a partir do mapeamento Objeto-Relacional da aplicação.
1. Acesse a opção “Área de TI -> Esquema DDL – Geração” e selecione “Atualização” no combo com
rótulo “Tipo de Esquema”.
Em nosso estágio, isso significa criar não somente a tabela “UF”, como também sua “Primary Key”
e tabelas auxiliares que o Hibernate utiliza (em SGBD Derby) para geração automática de
identificadores†.
*
O formulário se abrirá com mensagens de erro, porque não temos ainda tabelas para que funcione adequadamente. Se clicarmos no
botão F7-Novo iremos criar linhas de entrada que nos permitirão ver o seu leiaute interno.
†
Em Oracle, por exemplo, esta segunda tabela não é necessária, sendo utilizados “Sequences”, como padrão.
165
Capítulo B6
Figura B6.47. Utilitário especialista em geração de DDL. Obtenção do esquema relacional a partir do mapeamento
O-R.
#1. Opções para geração do esquema DDL de “Criação” (independente da existência ou não de
estruturas), “Atualização” (criação ou alteração de esquemas, apenas se necessário e em
função de análise do esquema atual no SGBD) ou “Exclusão” (geração do esquema para
exclusão de todas as estruturas existentes).
#3. Opções complementares, para quando se utiliza “owner” ou para trocar delimitador padrão.
#4. O esquema pode ser gerado com o comando “Gerar Esquema”. Importante: Este botão não
executa o esquema – apenas o gera no campo 5, para conferência e edição!
#5. Campo que contém a DDL gerada. Pode ser editado antes de submetido. Pode-se também
cortar seu conteúdo e colar para envio a um DBA, para organizações que não dêem permissão
de criação de esquemas DDL em SGBDs de desenvolvimento.
#6. O botão “Executar Esquema” é o que submete o esquema efetivamente ao SGBD. Neste caso,
a submissão irá funcionar porque o usuário pré-configurado no “pool de conexões” do Tomcat
(DBCP) tem privilégios de administrador do Apache Derby. (usuário: APP, senha: APP) e,
portanto, é autorizado a submeter DDLs.
3. Clique em “Executar Esquema” para submeter a DDL gerada e, em seguida, confira se não há nada
mais a sincronizar (mera confirmação), clicando novamente em “Gerar Esquema”. Desta vez, nada
deverá ser gerado, já que o mapeamento Objeto-Relacional estará síncrono com o esquema do
banco de dados.
Figura B6.48. Conferência de “Atualização” de esquema. Após a execução, nada mais é gerado.
166
Implementando o Padrão “Manter Classe”
Repare que uma marca ao lado do campo “Sigla” o indica como obrigatório, mas não no campo
”Nome”. Este é um padrão que indica que o campo Sigla deve ser informado, mas somente quando
“Nome” o for. Linhas com nomes não preenchidos serão desprezadas, para conforto do usuário,
que não precisa se preocupar em excluí-las antes de transmitir.
2. Preencha então o formulário, inclusive saltando algumas linhas, como na figura 46.
3. Clique em F12-Gravar. Em uma única submissão à rede e transação do Application Server e SGBD,
todos os registros (objetos) são gravados, e uma mensagem “Registro gravado com sucesso”, em
azul, é exibida.
Figura B6.51. Todos os objetos persistidos em uma única requisição HTTP e transação de SGBD.
Figura B6.52. Uma inserção, uma exclusão e duas alterações realizadas em uma única transmissão!
167
Capítulo B6
Conseguimos obter um leiaute bastante razoável para impressão, inclusive com campos de entrada
substituídos por textos simples de forma dinâmica (DHTML), conforme exibido na figura 50. O topo
do leiaute de impressão pode ser customizado genericamente, para conter logotipo e formatação
específicos, de cada empresa.
Dica: Clique no título do leiaute de impressão, para substituir o texto padrão, antes de imprimi-lo!
168
Implementando o Padrão “Manter Classe”
Sumário
Neste capítulo, fizemos o desenvolvimento de nosso primeiro Caso de Uso, utilizando o padrão “Manter
Classe”, para prover um formulário que permita aos usuários incluir, alterar, excluir e imprimir dados de
Unidades da Federação.
Apesar de simples, utilizamos este nosso primeiro Caso de Uso para explorar cada passo do processo de
construção de um Caso de Uso MVC, utilizando plugins diversos e folhas de apontamentos (Cheat-
Sheets) para nos auxiliar desde a confecção do mapeamento Objeto-Relacional, passando por obtenção
de uma primeira versão de artefatos visuais e de configuração necessários.
Introduzimos também os utilitários de construção e liberação do Maven especializados no jCompany,
bem como recursos de infra-estrutura para desenvolvimento e testes, tais como o SGBD Apache Derby o
Apache Tomcat.
Nos próximos capítulos, iremos explorar novos padrões de Caso de Uso, expandindo também nosso
conhecimento em cada área introduzida neste capítulo.
169
Capítulo B6
170
7
Capítulo
Implementando o Padrão
7
B
“Manter Agregação
Simples”
Implementando “UC001.2 Manter Unidade Organizacional-”
- Analisando a especificação
A segunda especificação de Caso de Uso que iremos implementar está definida no diagrama da Figura
B7.1. Especificação para “UC001.2 Manter Unidade Organizacional“..
Este diagrama, tal como o do capítulo anterior, também é suficiente para nos dizer tudo o que
precisamos saber para implementar este Caso de Uso, com precisão. Isso porque também se trata de um
Caso de Uso Padrão chamado “Manter Agregação Simples”, definido no módulo jCompany Patterns &
Methods e automatizado pelos módulos jCompany FS Framework (generalizações da arquitetura) e
jCompany IDE (gerações de artefatos específicos).
171
Capítulo B7
Figura B7.2. Grafo do Modelo de Domínio incluindo Agregação a ser Mantida e Classe referenciada.
As classes correspondentes em Java são listadas abaixo e podem ser criadas pelo Eclipse, seguindo-se o
mesmo roteiro descrito no capítulo anterior.
Veremos que a classe “Endereco: não herda as propriedades de auditoria e versão de “AppBaseEntity”
porque ela foi modelada para ser um “componente” de “UnidadeOrganizacional”, o que significa que não
terá “vida própria, independente”. Suas propriedades serão persistidas na tabela de
UNIDADE_ORGANIZACIONAL, inclusive. Portanto, veremos um primeiro caso em que uma classe não irá,
necessariamente, ser mapeada para uma tabela relacional.
Dica: É uma boa prática realizar o mapeamento de classes na ordem inversa de suas
dependências. Ou seja, devem-se mapear primeiro as classes de estereótipo “tabular”,
“componente” e “detalhe”, chegando por último nas classes raízes das agregações.
172
Implementando o Padrão “Manter Agregação Simples”
1. Para mapear “Endereco”, edite esta classe e aperte a tecla de atalho “control+N”, selecionando em
seguida o plugin “01” da lista de geradores do jCompany Artifact Generator, tal como fizemos
para mapeamento da classe Uf.
A Figura B7.5 mostra o diálogo de mapeamento preenchido para “Endereco”, somente com as
partes modificadas em destaque.
2. Ao clicar em “Finish”, o Assistente irá decorar a classe “Endereco”, com o resultado descrito na
Figura B7.6. Repare que, para componentes, não há a criação de descendentes concretos. Perceba
que, na verdade, a classe foi “corrigida” para concreta, já que não funcionaria apropriadamente com
“abstract”.
#1. A anotação padrão JPA “@Embeddable” indica um componente, e não uma Entidade (@Entity).
#3. A associação manyToOne com Uf já foi mapeada apropriadamente, inclusive com nome de
Foreign Key significativo, com base no nome das tabelas envolvidas, e estratégia de fetch
“Lazy”. Como os dados de “Uf” ficam em cache mantido pelo jCompany na camada Controle,
esta estratégia é a mais apropriada.
#4. A exibição de endereço quando se fizer necessária, será realizada com exibição de
“Logradouro”, já que foi a propriedade de “Lookup” marcada.
173
Capítulo B7
Figura B7.7. Classe Java mapeada para componente UnidadeOrganizacional, com partes importantes em destaque.
Esta classe deve ser mapeada com estereótipo de raiz da agregação (normal) e a única
propriedade que exige tamanho é nome. Não devemos esquecer também que a referência
recursiva deverá aceitar nulo, de modo que seja possível se criar o primeiro nível.
Repare que as referências e o tipo de mapeamento para elas já são assumidas apropriadamente,
tanto para o componente quanto para a recursividade.
4. Prossiga, clicando em “Next”. Vamos adentrar pela primeira vez no segundo passo do Assistente de
Criação de Mapeamentos, exibido na Figura B7.8.
#1. O segmento de cima, bem como a primeira opção “Usa em Explorer”, são opções de ativação
de uma “TreeView” chamada “Explorador de Dados”, que é ativada em nível de leiaute, ou
seja, dispensando o uso de componentes em formulários específicos e qualquer outro tipo de
programação procedimental.
Iremos utilizar o Explorer de forma mais extensiva, no terceiro bloco deste livro, e ver em
detalhe suas outras opções. Para nosso caso específico, as três declarações que usamos são
suficientes:
174
Implementando o Padrão “Manter Agregação Simples”
URL Manutenção: O nome de uma URL a ser utilizada como hiperlink em nós da TreeView. No
caso, queremos editar a Unidade Organizacional especifica, então colocamos a URL com a
convenção padrão do jCompany (nome da classe em minúsculas, com sufixo “man”). Não
esquecer a barra inicial.
#2. Em “Usa fonética” indicamos para o jCompay gerar propriedade auxiliar padrão para armazenar
dados em formato que permite buscas fonéticas (que considerem como iguais, por exemplo,
diferenças entre “Ottoni” e “Otoni”), para casos onde se faça necessário.
#3. A indicação de “Utilizada como Lookup” é assumida como padrão para mapeamento de classes
com estereótipo “Tabular”. A marcação implica na geração de uma anotação do jCompany em
nível da Entidade, que será utilizada por rotinas de otimização para se evitar recuperações
desnecessárias.
#5. O indicador de “Validação Unificada” indica que desejamos fazer a validação “Invariável” (de
Domínio), juntamente com a validação “Variável” (de Caso de Uso), em uma mesma passada.
Isso dispensa a necessidade de se declarar “obrigatoriedade” e “tamanho” em campos de JSPs
correspondentes a propriedades de classes, pois estas informações passam a ser “herdadas”!
#7. A opção de “Criar Auxiliares” cria métodos com sufixo “Aux” para getters e setters de
propriedades cujo tipo não sejam “String”. Esta é a opção padrão para classes com estereótipo
“detalhe” e “subdetalhe”, quando utilizando Struts, uma vez que este framework não é “type-
safety” como o JSF, não aceitando entrada de dados em tipos que não sejam String.
Normalmente, não precisa ser marcado em JSF.
Ao clicar em “Finish”, o Assistente irá gerar mapeamentos e ajustes seguindos “melhores práticas”
incorporadas pelo jCompany, tal como no caso anterior, para “Uf”. Irá gerar um descendente
concreto com nome “UnidadeOrganizacionalEntity” e mapeamentos descritos nas Figura B7.9 e
Figura B7.10.
Figura B7.9. Classe Abstrata (do Projetista) para UnidadeOrganizacional, com mapeamentos.
#1. Segundo o JPA, componentes devem ser mapeados, em classes que os referenciam, com a
anotação “@Embedded”
#2. A anotação “@Valid” indica que desejamos incluir a validação “Invariável” do componente
juntamente com a validação da classe raiz da agregação. Este é o padrão, pois normalmente
toda a agregação deve ser íntegra para ser persistida.
175
Capítulo B7
Figura B7.10. Classe Concreta (do Desenvolvedor) para UnidadeOrganizacional, com mapeamentos.
#2. Os “sequences” são gerados como estratégia de obtenção de OID automática, para SGBDs que
o suportam, tais como Oracle, porém são desprezados em outros como o Apache Derby.
#4. O jCompany gera uma Named Query com nome padrão <Entidade>.querySelLookup, utilizada
por rotinas genéricas para recuperar referências a esta Entidade quando se fizerem
necessárias, caso participem em um grafo de classes controlado pelo jCompany. Repare que a
cláusula gerada sempre inclui o identificador (Object-ID ou OID), e as colunas marcadas como
“Lookup”. Um construtor apropriado também precisa existir em conformidade com a parte
“select” da cláusula padrão JPA.
5. Vamos agora complementar a anotação “@PlcEntidade” para indicar que, por hora, queremos exibir
somente uma TreeView que inclua dados da Entidade corrente, recursivos. Para isso, adicione os
atributos “recursividadeUsa=true” e 'recursividadeNomeProp="departamentoPai”'.
Dica: abra um espaço entre os atributos da anotação e inicie a digitação com “rec” e
“Control+Space”. Uma lista de propriedades com estas iniciais aparece, exatamente as duas que
queremos, conforme a Figura B7.11.
Figura B7.11. Control+Space após digitar as iniciais do atributo, traz lista de opções (auto-complete do Eclipse)
Outra dica: ao se esquecer dos atributos possíveis para qualquer anotação, utilize
“Control+Clique” no nome da anotação para entrar em sua definição ou “Shift + mouse
Sobreposto” no nome para vê-la em um balão amarelo, sem sair do contexto de edição.
Figura B7.12. Anotação finalizada para exibir TreeView de leiaute com hierarquia organizacional.
176
Implementando o Padrão “Manter Agregação Simples”
o {cep deve ser um CEP Válido} em “Endereco”. Neste caso precisaremos garantir que o CEP tenha
8 números, basicamente*. Mas note que teremos de aceitar um CEP não informado como correto, já
que é um valor opcional.
Estas duas validações são ligeiramente mais sofisticadas do que a validação em “Uf”, que fizemos
anteriormente.
Para implementarmos a primeira, vamos utilizar o recurso de “Named Queries Padrões naoDeveExistir”
do jCompany, que funciona basicamente da seguinte forma:
o Primeiro, declaramos cláusulas com “select count(*)”, nomeadas com o padrão
“[Entidade].naoDeveExistir[Sufixo Livre]”, especiais para resolverem este tipo de restrições.
o Em cada transação de inclusão ou alteração, as classes de camada Modelo do jCompany procuram
“Named Queries” JPA com esta convenção nas Entidades. Se existirem, elas irão submetê-las
(quantas existirem, uma após a outra) e exigir um resultado 0 (zero), de cada uma, para prosseguir
na inclusão ou alteração.
o Exceções são disparadas com uma chave de mensagem padrão para cada cláusula OQL, que pode
então simplesmente ser definida no arquivo “ApplicationResources,properties”.
Vamos implementar em nosso caso específico.
1. Crie a Named Query “naoDeveExistir” copiando-se a existente, como na Figura B7.13, e em seguida
altere seu nome e cláusula, como exibido na Figura B7.14.
Figura B7.14. Definição apropriada da Named Query “naoDeveExistir”, com partes importantes em destaque.
*
Não iremos validar o CEP em base de valores em função de logradouros, bairros, etc., neste caso. O cliente hipotético julga não ser
suficiente, em um cadastro de endereços internos, que um CEP tenha 8 posições e seja composto apenas de números.
177
Capítulo B7
Figura B7.16. Acionamento do roteiro de criação de Caso de Uso Padrão “Manter Agregação Simples”.
2. Prossiga no roteiro. A Figura B7.17 exibe a primeira tela do Assistente de Criação, aberta no
segundo passo do roteiro Cheat-Sheet.
Figura B7.17. Página inicial do Assistente de Criação para Caso de Uso Padrão “Manter Agregação Simples”.
Não há nada de especial no preenchimento desta primeira janela, que já não tenhamos discutido
na criação do Caso de Uso “UC001 Manter Uf-”.
Perceba a convenção para identificador do Caso de Uso, utilizando o nome da Entidade raiz, sem
sufixo, totalmente em minúsculos. Ou seja, para a classe chamada “UnidadeOrganizacionalEntity”,
o identificador é “unidadeorganizacional”. Este prefixo foi informado também em “Subdiretório”,
de modo que será utilizado como raiz de nomes de URLs, JSPs, diretório e mensagens
correlacionados, provendo uma unidade de nomenclatura que nos auxiliará bastante, em
manutenções futuras.
3. Informe somente o título “Unidade Organizacional”, na segunda janela do Assistente, também para
este Caso de Uso.
178
Implementando o Padrão “Manter Agregação Simples”
Figura B7.18. Terceira página do Assistente de Criação do Caso de Uso Padrão “Manter Agregação Simples”.
Vamos começar por definir a Colaboração de “Seleção”. Ela exigirá uma JSP de “argumento” e outra
para a “lista de seleção”.
o Selecione por quais propriedades da agregação pretendemos filtrar coleções de Unidades
Organizacionais, e através de quais operadores.
Se analisarmos a especificação, veremos no artefato visual “unidadeorganizacionalArg”, a
definição dos argumentos e operadores a serem utilizados para recuperação dos dados. Ela diz
que devemos utilizar as propriedades “nome” e “logradouro”, com operadores “like *%”. O
símbolo “like *%” indica busca por parte do texto digitado, neste caso pelas iniciais, já que o
“*” se encontra antes do “%”.
Na figura 21 encontramos a definição correspondente dos argumentos grifadas, na coluna
“Usa?” (3), e uma visualização prévia da página de “argumento e seleção”. Perceba que, ao
assumirmos certas propriedades como argumentos, elas são automaticamente selecionadas
para a lista de seleção, definida na coluna “Usa?” (7).
São as seguintes as novas opções ainda não apresentadas da Figura B7.18:
#1. Define para que o trecho de formulários que define propriedades de componentes ou classes
em associação “um-para-um” com a raiz seja gerado em uma JSP diferente, o que melhora a
legibilidade e possibilita o reuso. No caso vamos deixar o padrão marcado, pois a especificação
da figura 1 indica para que endereço seja renderizado em JSP distinta.
#2. As propriedades de componentes são geradas com o nome da propriedade que representa o
Componente na agregação (no caso, “endereco”), como prefixo, e um sublinhado como
separador. Isso evita possíveis conflitos de nomes.
#3. Nesta coluna, podem-se selecionar propriedades que serão utilizadas como argumento para
recuperação da lista parcial de objetos.
#4. Esta coluna define a linha, dentro do componente visual de “argumento” (JSP que permite a
entrada dos valores), na qual a propriedade será gerada.
#5. Esta coluna define a coluna, dentro da linha do componente visual de “argumento”, na qual a
propriedade será gerada. Os valores de linha e coluna não precisam ser alterados em nosso
caso, pois a posição dos campos já atende à especificação.
#6. Operadores lógicos utilizados na montagem do critério de seleção, que correspondem aos
operadores mais comuns utilizados tanto em linguagens OQL (Object Query-Language) quanto
em SQL. No nosso caso os valores assumidos pelo jCompany, que são “like *%” para
propriedades String, “igual” para números e “maiorOuIgual” para datas, atende à especificação.
Obs.: Esta lista de operadores, bem como das propriedades, não tem a pretensão de esgotar
as possibilidades, mas resolver de forma produtiva os casos mais freqüentes de seleção.
Veremos como programar ajustes mais avançados, no módulo C deste livro.
#7. Nesta coluna marcamos as propriedades que desejamos que sejam exibidas na parte de
seleção do Caso de Uso. Teremos que fazer um ajuste aqui, pois a especificação pede que seja
incluída a propriedade “numero” na lista.
179
Capítulo B7
#8. Nesta coluna pode-se alterar a ordem em que aparecem os valores resultantes da pesquisa,
que chamamos de lista de seleção. Para se trazer listas com mais de uma linha em cada
objeto, deve-se alterar a JSP após a geração.
#9. O botão “Visualiza Argumento/Seleção” dispara uma visão prévia da página de argumento e
seleção que será gerada, incluindo JSPs de argumento e seleção.
#10. Uma JSP separada somente para argumento com nome padrão “[id do caso de uso]Arg.jsp”
será criada, e uma visualização prévia é exibida.
#11. Uma segunda JSP separada somente para a lista de seleção com nome padrão “[id do caso de
uso]Sel.jsp” também será criada, e uma visualização prévia é exibida, abaixo da de argumento,
como são montadas pelo leiaute Tiles Universal, padrão para este tipo de Colaboração.
* Em minha opinião, a exibição do “id” pode ser de auxílio no dia a dia para usuários, por exemplo, referenciarem de forma mais direta,
qualquer documento. Porém, é muito comum que Analistas de Negócio queiram “esconder” a chave substituta – por isso escolhemos
exemplificar a implementação deste hábito.
180
Implementando o Padrão “Manter Agregação Simples”
#2. Vários rótulos estão com acentuação faltando, bem como requerendo outros ajustes de
português.
#3. A propriedade “unidadePai” deveria estar ao lado de “nome”, e utilizar seleção “popup” (na
especificação, simbolizada com três pontos ‘...’). Este componente do tipo “diálogo de seleção
popup” é chamado de “Vinculado”, e pode ser selecionado na lista de “Formatos”.
#4. A propriedade “bairro” deveria estar na linha de baixo, antes de “cep” e “uf”, segundo a
especificação.
Na Figura B7.21, vemos um resultado de edição que aprimora todos os pontos acima, bem como a
visualização do resultado final. Fica como exercício para o leitor aplicar as modificações até a
obtenção de resultado similar ao da figura.
Figura B7.21. Modificações para atender à especificação, com pontos modificados em destaque.
6. Vamos finalizar o Assistente de Criação, clicando em “Finish”, já que ainda não iremos utilizar o seu
último passo.
181
Capítulo B7
Na camada Visão, para este Caso de Uso Padrão, foram gerados 4 (quatro) arquivos de JSP* e
modificados 1 (um) arquivo de formato XML Tiles e 1 (um) arquivo de formato Properties, para
mensagens.
o Página “unidadeorganizacionalArg.jsp”: Gerada com a “parte” (markup) de argumentos, que
comporá a página de “argumento e seleção”.
o Página “unidadeorganizacionalSel.jsp”: Gerada com a “parte” (markup) de seleção, que
comporá a página de “argumento e seleção”.
o Página “unidadeorganizacionalMan.jsp”: Gerada com a “parte” (markup) de manutenção,
relativo à Entidade Raiz da agregação, que comporá o formulário de manutenção.
o Página “unidadeorganizacionalMan2.jsp”: Gerada com a “parte” (markup) de manutenção
complementar, relativo ao componente, que comporá o formulário de manutenção.
o Arquivo “app-tiles-menu1.xml”: Alterado para conter uma nova entrada de “menu”, gerada no
último bloco encontrado, com chamada padrão para a URL de manutenção
“f/t/unidadeorganizacionalman”.
o Arquivo “ApplicationResources.properties”: Alterado para conter mensagens deste Caso de
Uso. Lembre-se: se a opção “I18n” do assistente foi desmarcada, muitos rótulos foram gerados na
JSP, diretamente, e não neste arquivo.
o O arquivo “app-tiles-pagina1.xml” não é modificado, já que o jCompany possui leiautes Tiles
totalmente generalizados, chamados de “Universais”, que ainda nos atenderão neste caso.
Por fim, o uso de um prefixo e sufixo padrão em todas as JSPs é suficiente para que o leiaute Universal
saiba montá-las da forma apropriada. Deste modo, ganhamos duas vezes: dispensando a criação de
leiautes Tiles específicos, em XML; e reforçando a padronização de nomes, já que “não seguir a
convenção” acabará exigindo um trabalho adicional, de definir um leiaute específico.
Neste passo, vamos alterar somente o arquivo de menu, basicamente para passar um parâmetro via
URL. Veja esta alteração indicada na Figura B7.22.
Figura B7.22. Modificações na chamada de menu para acionar Explorador de Dados na abertura.
Este parâmetro indica para que o nosso “Explorador de Dados” seja renderizado, tão logo seja aberto o
formulário. Como padrão, veremos, ele somente seria exibidp quando o usuário comandasse uma opção
de painel específica.
*
Perceba que a separação das JSPs em quatro partes especializadas mantém as páginas individualmente simples de se entender,
emulando as boas práticas de coesão utilizadas em programação OO. Desta forma, promove-se o reúso de JSPs como as de
argumentos ou lista.
†
Como já discutimos antes, estes arquivos de “package-info.java” são um ponto chave de produtividade no jCompany, pois contêm
declarações (“metadados) na forma de anotações para cada Colaboração, um para a “manutenção” (unidadeorganizacionalman) e outro
para a “seleção” (unidadeorganizacionalsel), respectivamente. Através de simples declarações nestes arquivos, podem-se acionar
variações importantes de comportamento genérico em cada caso, maximizando o reúso e evitando erros que intervenções
procedimentais poderiam causar.
182
Implementando o Padrão “Manter Agregação Simples”
Como exemplo, para localizar o arquivo de metadados (anotações) para uma colaboração com
URL “/testesel”, o jCompany irá procurá-lo com nome “package-info.java” (padrão Java para
anotação de pacotes), debaixo de “com.powerlogic.jcompany.config.app.testesel”, onde:
#3. A classe definida em “action” será utilizada como Classe Java de Controle, neste caso sendo
utilizada a classe padrão (vazia, gerada na criação do projeto) para a aplicação, “AppAction”. A
lógica de controle genérica é herdada e para JSF se encontra em “PlcBaseJsfAction”. No caso de
Struts, se encontra em “PlcBaseAction”. Não iremos precisar programar nenhuma linha de
código Java em nosso Caso de Uso Padrão, mas o faremos em momento oportuno.
#4. A opção de “layoutUniversal” fala para o jCompany tentar reusar um leiaute Tiles, que irá
inserir as páginas de JSP com base no nome padrão, considerando o padrão de Colaboração
utilizado.
Além disso, o leiaute irá procurar estas páginas abaixo do diretório “WEB-
INF/jsps/unidadeorganizacional”, como indicado na anotação. Confira a localização dos
artefatos, para compreender todo o mecanismo.
Dica: se for desejável fazer qualquer variação com relação ao leiaute Universal, basta que se
retire a anotação “layoutUniversal” deste arquivo de metadados e que se declare um leiaute
Tiles no arquivo “app-tiles-pagina1.xml”, com nome “unidadeorganizacionalsel”. Faremos
isso em um dos próximos tutoriais.
183
Capítulo B7
#1. O pacote segue a mesma convenção da seleção. Apenas o sufixo “man” diferencia os
metadados de “manutenção” daqueles de “seleção”.
#2. Os demais trechos são idênticos ao arquivo de metadados da seleção, com exceção do atributo
“mestreTotalComponentes”, que indica para o leiaute Universal que existem duas JSPs de
manutenção.
Obs.: O algoritmo utilizado para inserção de JSPs do leiaute Universal, para manutenções no
padrão “Manter Agregação Simples” e tendo uma URL “/testeman”, será: buscar primeiro por
uma JSP “testeMan.jsp”; em seguida por adicionais, conforme o número em
“mestreTotalComponentes”, seguindo no padrão “testeMan2.jsp”, “testeMan3.jsp”, etc..
O diretório “dirBaseJSPs”, da mesma forma, indica o diretório base onde procurar as JSPs, neste caso o
mesmo diretório onde se encontram as JSPs de argumento e seleção.
2. No caso da Colaboração de Manutenção, iremos acrescentar uma nova anotação, último quesito
para “ativarmos” o nosso “Explorador de Dados” genérico.
Dica: Utilize “Control+Space” (auto-complete) após digitar “@PlcConfig” quando trabalhando com
metadados, já que este é um prefixo padrão para estas anotações.
184
Implementando o Padrão “Manter Agregação Simples”
3. Ainda com relação à camada Controle, não precisamos realizar nenhuma intervenção no arquivo
padrão JSF “faces-config.xml”, mas é importante entendermos o que foi modificado no mesmo.
Um pequeno fluxo de navegação entre as duas Colaborações geradas foi criado, e pode ser visto
pelo diagrama da Figura B7.27.
#2. Fluxo criado anteriormente, para Caso de Uso Padrão “Manter Classe”, que não possui
navegação entre URLs, resolvendo todo o Caso de Uso em uma única URL/Formulário.
#3. Fluxo que acabamos de criar, que inclui duas Colaborações, diferenciadas por sufixos “sel” e
“man”, que interagem entre si conforme o usuário queira selecionar objetos para edição. Os
casos de navegação (Navigation Cases) do JSF (correspondentes aos “action-forwards” do
Struts), representados no diagrama, ilustram bem esta interação:
185
Capítulo B7
Além das classes participantes da Agregação principal em si, são também definidas referências
que pertencem ao Grafo como um todo, tais como “UfEntity”.
#3. padrao: O Padrão da Colaboração de manutenção é definido com a constante “CRUD”, neste
caso. A complexidade é meramente documentacional, não alterando comportamentos do
framework.
#6. componentes: Classes com estereótipo “Componente” (padrão JPA) devem ser indicadas
nesta lista, para serem gerenciadas automaticamente pelo jCompany, em todas as camadas
MVC.
No caso da Colaboração de Seleção, o arquivo de metadados gerado é bastante similar, mas não
traz classes do grafo que não são utilizados neste caso.
Obs.: Caso o jCompany tenha gerado a referência a “Uf” nos metadados da Colaboração de
“Seleção” (apesar de não usarmos “Uf” como argumentos ou itens de seleção), remova-a. Apesar
de não trazer nenhuma implicação funcional, esta geração é incorreta e marcada para ajuste em
novas versões.
Lembre-se: caso ocorra algum erro ao final da rotina Maven, confira se o projeto principal está em
186
Implementando o Padrão “Manter Agregação Simples”
foco. Se não estiver, clique nele e acione novamente esta opção, reabrindo o último passo do roteiro
Cheat-Sheet. Confira na Figura B7.30.
2. Alternativamente, para acionar esta rotina Maven fora do roteiro do Cheat-Sheet, procure por
“Liberação Rápida Reinicio Tomcat”, na barra de “External Tools”.
Figura B7.31. Procurar “Liberação Rápida Reinicialização Tomcat”, em atalho ou dentro do diálogo “External
Tools”.
3. Após o disparo, por qualquer dos dois meios citados, observe o resultado na janela “Console”. O
resultado final da liberação deve durar cerca alguns segundos e ter mensagens de “SUCESS”.
Figura B7.32. Relatório final do Maven sobre a liberação completa (primeira vez mais demorada).
4. A rotina de liberação Maven, ao final, aciona um reinício da aplicação “rhtutorial” no Tomcat. Por este
motivo, logo após o encerramento da liberação em si, a janela Console irá comutar para exibição da
console do Tomcat, exibindo os procedimentos desta rotina de reinício.
Perceba que existirão duas “consoles” a serem monitoradas: a da tarefa Maven e a do Tomcat.
Comute entre elas, clicando no botão “Display Selected Console”, em destaque na Figura B7.33.
187
Capítulo B7
Figura B7.33. Mensagem final do Tomcat após reinício e botão para comutação da Console.
3. Selecionar “Atualização”, na lista com rótulo “Tipo de Esquema”, e clique em “Gerar Esquema”.
Este utilitário irá exibir o esquema DDL necessário para “sincronizarmos” nosso mapeamento com
o esquema atual do SGBD, contendo somente as diferenças que produzimos em nosso novo Caso
de Uso “UC001.2 Manter Unidade Organizacional-“.
Figura B7.34. Esquema de DDL produzido a partir do mapeamento Objeto-Relacional da nova Agregação.
Obs.: Note que as Colunas (relacionais) correspondentes às Propriedades (OO) das Classes do tipo
“componente” são geradas na Tabela (relacional) correspondente à Classe Raiz da Agregação (OO).
Reforçando: “Componentes” são classes que não geram novas Tabelas, muito embora devam ser
utilizados para refinar o encapsulamento no mundo OO, aumentando as chances de reúso e
preservando a simplicidade dos artefatos.
As declarações de Chave Primária (PK - PRIMARY KEY) e Estrangeiras (FK - FOREIGN KEY) também
são geradas apropriadamente. A PK é gerada para a propriedade “id” (Object-Id) e as duas FKs
para a associação recursiva e com a Tabela “UF”.
4. Após conferir, clique em “Executar Esquema”, para submeter as modificações ao SGBD.
188
Implementando o Padrão “Manter Agregação Simples”
#2. O espaço vazio à esquerda é exibido porque incluímos na URL um comando para exibição
imediata do “Explorador de Dados” automatizado do jCompany (TreeView), que por hora está
vazio. Este explorador pode ser ativado ou desativado, com o uso do painel acionável através
do ícone, ao lado da impressora.
#3. Uma seção diferenciada é delineada para os dados de endereço. Este Web-Design é assumido
como padrão, agrupando em uma subseção de “field-set” ou de “table”, as propriedades de
componentes (pode-se alterar este corte, mas normalmente é desejável).
Obs.: Perceba que o nome da seção para Endereço está repetido com o da Unidade
Organizacional. Iremos corrigir este detalhe em próximos passos de ajuste.
#4. O vínculo à Unidade Organizacional superior, como foi definido, será feito através de um
“vinculado”, recurso visual que envolve a chamada de uma Colaboração de Seleção, em modo
“popup”.
Aqui também teremos que fazer uma adaptação, já que a especificação pede que os Object-IDs
não sejam expostos ao usuário (o que ocorreria nesta exibição padrão do componente
vinculado, no primeiro campo).
#5. Um combo com a relação de UFs já foi disponibilizado, conforme assumido pelo Assistente de
Criação. Iremos discutir a técnica de disponibilização destes dados mais a frente.
3. Vamos testar nossa implementação de restrição para CEP. Tente digitar letras ou caracteres não
numéricos. Perceba que uma função Javascript impede que se dê entrada nestes valores. Ao
preencher parcialmente e tentar gravar, o número de caracteres também é verificado, como mostra
a Figura B7.37
189
Capítulo B7
#2. Novas opções de ação surgem em conformidade com o “modo” do formulário! Perceba que o
jCompany entende que o formulário passou para “modo de edição” (ou de “alteração”) e
habilita alguns novos botões, automaticamente.
#3. A lista de UFs que cadastramos aparece para exibição em conformidade com o método
“toString” da Entidade Uf, podendo ser facilmente alterada.
Para preencher os próximos registros, podemos nos valer de um interessante recurso de usabilidade
generalizado pelo jCompany: a clonagem de Agregações.
Imagine que temos três Diretorias principais abaixo da Presidência, no mesmo endereço (mas em outra
sala/andar, por exemplo). Neste caso, agregações diferentes irão compartilhar de uma boa dose de
valores em comum, e uma boa estratégia de produtividade seria cadastrar as similares “a partir de cópia
dos dados de uma agregação base”.
5. Clique no botão “Clonar”, para realizar esta cópia de todo o “documento” (neste caso, do formulário
com dados da Agregação). Em seguida, altere o nome conforme a Figura B7.39.
6. Vamos continuar o ajuste do novo cadastro, selecionando a Presidência como Unidade Superior. Use
o botão de seleção do componente “Unidade Superior”. Ao acioná-lo, um diálogo de seleção de
190
Implementando o Padrão “Manter Agregação Simples”
Unidades Organizacionais será exibido, contendo exatamente as opções de busca e seleção que
definimos durante a criação.
#1. O botão que aciona o diálogo Popup também pode ser acionado com Hot-Key, pressionando-se
“seta para baixo”, com o foco estando em algum dos campos do vinculado. Deste modo,
consegue-se uma operação que independa do uso do mouse, um inimigo quando o assunto
são entradas de dados massivas.
#2. Os diálogos Popup padrões do jCompany já são apresentados em janelas com leiaute
apropriado, sem topo, menus ou rodapés, já que são transientes e requerem o máximo de
espaço. Perceba que o posicionamento inicial da janela irá depender da configuração do
Navegador do usuário, mas é possível customizar a chamada da janela para fixá-la, quando
desejado.
#3. A parte de argumentos foi deixada em branco, nesta primeira pesquisa, já que a especificação
não ditou restrições à pesquisa. É possível incluir validações de obrigatoriedade em argumentos
de pesquisa também, para se evitar resultados muito grandes. Outra possibilidade seria o uso
de paginação, mas o projetista não julgou necessário, neste Caso de Uso.
#4. Outros detalhes de acabamento de podemos melhorar são também os rótulos das seções do
formulário.
7. Selecione uma Unidade Organizacional, posicionando o mouse sobre uma linha e clicando nela; ou
andando com setas (para cima e para baixo) e digitando “Enter” na linha em foco. Em ambos os
casos, uma referência ao objeto selecionado será retornada para o formulário principal, conforme
ilustrado na Figura B7.41.
Figura B7.41. Identificador e valores de exibição (toString) da Unidade Organizacional, exibidos em vinculado.
8. Faça como exercício duas novas clonagens para criação das outras duas diretorias que faltam, como
mesmo endereço e subordinação: “Diretoria de RH” e “Diretoria Administrativa”. Agora é ainda mais
fácil, já que a referência de subordinação à Presidência será também clonada.
2. Clique em “F12-Gravar”. Deverá surgir uma mensagem de erro apresentando uma chave ainda não
traduzida (lembre-se que não a declaramos propositalmente, quando fizemos a “Named Query” para
o padrão “naoDeveExistir”).
191
Capítulo B7
3. Selecione a mensagem apresentada e copie com “control+C”, como na Figura B7.42. Os símbolos
“???”, presentes no início e no final da mensagem, são caracteres reservados, utilizados para indicar
claramente ao desenvolvedor que o texto exibido não é uma mensagem, mas uma “chave da
mensagem” cuja tradução não foi encontrada, no arquivo de idiomas corrente.
Figura B7.42. Mensagem de erro enviada, e seleção da parte que começa com “jcompany.”, sem incluir os “???”,
para registro da mensagem.
4. Retorne ao Eclipse com “Control+Tab” e utilize a Hot-Key “Control+R” para seleção de recursos.
5. Digite as iniciais “Appl” para filtrar os recursos apresentados e, em seguida, selecione o arquivo de
idioma Português, “ApplicationResources.properties”, conforme ilustrado na Figura B7.43.
6. Após a seleção, o arquivo já deverá vir editado, no plugin padrão, homologado para este fim. Clique
então no botão “+” e cole a mensagem copiada na linha que se abre.
Note que as mensagens para este tipo de validação são padronizadas da seguinte forma:
jcompany.aplicacao.[nome da Named Query naoDeveExistir]
onde
jcompany.aplicacao.: prefixo que indica que é uma mensagem disparada pelo jCompany,
mas especifica da aplicação (as genéricas utilizadas começam com jcompany e ficam no
arquivo “jCompanyResources.properties”).
192
Implementando o Padrão “Manter Agregação Simples”
1. Chame nossa Colaboração novamente, pelo item de menu, para ativar a recuperação inicial do
Explorador de Dados. O resultado deve ser similar ao da Figura B7.45.
O resultado não é exatamente o que planejávamos, pois os dados não estão hierarquizados. Isto
porque nós nos esquecemos de definir uma “Named Query” para indicar, ao Explorador de Dados,
qual o critério para recuperar o “primeiro nível da árvore”*.
2. Para tanto, volte ao Eclipse, clique em “Control+T” e selecione “UnidadeOrganizacionalEntity.java”,
de forma similar ao que fizemos para o recurso “ApplicationResources.properties”.
Figura B7.46. Relação de Named Queries para UnidadeOrganizacional, com destaque para a última codificada.
*
Os níveis subseqüentes irão funcionar perfeitamente (experimente clicar em “Presidência”), porque já declaramos a propriedade de
elo da recursividade para o jCompany. O primeiro nível, no entanto, ao ser recuperado como uma “Named Query” padrão, permite
maior flexibilidade ao desenvolvedor.
193
Capítulo B7
7. Os itens da árvore exibida pelo Explorador de Dados utilizam o hiperlink definido na anotação
“urlManutencao” e incluem também o Object-ID como chave de recuperação. Utilize este recurso,
clicando em “Diretoria de RH” (não no botão de + e -, mas no texto).
8. Em seguida, clone e altere o nome para “Presidência”, para repetir o nosso teste de duplicidade. O
resultado final deve aparecer como na Figura B7.49.
Figura B7.49. Explorador de Dados funcionando (item selecionado em destaque) e mensagem de duplicidade.
* Note que continuamos 100% MVC e utilizando o DP DAO (Data Access Object). Apenas a camada de Persistência é capaz de conhecer
e executar uma NamedQuery JPA/Hibernate, apesar destes metadados estarem – como as anotações de mapeamento - anotados nas
Entidades. Na prática, como vimos na arquitetura discutida no capítulo 4, isto é possível porque o Modelo de Domínio é ortogonal,
visível por todas as camadas MVC.
194
Implementando o Padrão “Manter Agregação Simples”
Figura B7.52. Clique em um dos itens da lista de seleção, ou no botão F7-Novo, comutam para a manutenção.
*
A metáfora aqui com o mundo físico é a de que estamos “abrindo uma pasta de documentos”, ou seja, tirando-a de um arquivo para
análise ou alteração. Esta é a metáfora tradicionalmente utilizada - definida nos laboratórios Xerox Sparc e popularizada em Sistemas
Operacionais com interfaces gráficas, tais como Mac e Windows.
195
Capítulo B7
2. Após editar, clique em “Excluir” e verifique o alerta em Javascript emitido para esta operação, como
na Figura B7.53.
Figura B7.55. Definição de mensagem com a chave criada, com rótulo como “Endereço”.
196
Implementando o Padrão “Manter Agregação Simples”
Figura B7.56. Definição de mensagem diretamente em JSP de argumento, trocando-se “tituloChave” por “titulo”.
Figura B7.57. Definição de mensagem diretamente em JSP de seleção, trocando-se “tituloChave” por “titulo”.
3. Agora vamos fazer um último ajuste que percebemos: esconder, no componente vinculado, o
“Object-Id”.
Um diálogo com todas as propriedades do componente JSF será exibido, contendo alguns termos
em inglês (originais do componente Apache Trinidad especializado pelo jCompany) e outros em
português (extensões e aprimoramentos realizados no componente, pelo jCompany). Uma ajuda
on-line está disponível para ambos os casos, que pode inclusive ser exibida com a simples
passagem do mouse sobre os atributos. Recomenda-se uma leitura geral e exploração práticas das
variações possíveis, ao longo do tempo.
Para o nosso caso, existe uma propriedade específica chamada “idExibe”, que inclusive já foi
gerada e está com ajuda disponível exibida na Figura B7.58. Basta trocá-la para “N” e também
remover a propriedade “idSomenteLeitura=’N’” (que não faz mais sentido), para conseguirmos o
efeito desejado.
Figura B7.58. Propriedade exibindo ajuda bastando-se passar o mouse sobre ela.
- Realizando Liberação Rápida via Maven e Hot Deploy – Construção e Liberação III
Neste tópico, conheceremos uma terceira variação de tarefa Maven utilizada pelo jCompany, que não
dispara o reinício da aplicação: a “Liberação Rápida para Tomcat”. Ela é possível porque alterações
em artefatos como JSP, Javascript, CSS e mídia não exigem reinício da aplicação para terem sua nova
versão reconhecida pelos Application Servers.
O funcionamento desta liberação é similar ao da “Liberação Rápida com Reinício”, porém não há o
acionamento para reinício da aplicação, ao final.
Muito embora esta liberação dure apenas alguns segundos, nós a utilizaremos somente uma única vez
neste livro, neste tutorial, basicamente para anunciar sua existência. Veremos que o jCompany IDE
oferece uma alternativa melhor para este cenário específico, que dispensa o acionamento de tarefas, e
realiza liberação instantânea: o jCompany Hot Deploy.
Vamos, uma única vez, utilizar esta rotina Maven.
197
Capítulo B7
1. Para acionar o terceiro tipo de liberação Maven, procure pela tarefa “Liberação Rápida para Tomcat”,
em “External Tools” (antes se certifique de que possui o projeto “rhtutorial” selecionado, como
sempre).
2. Clique em “Run”. Como vimos, isso não somente irá executar a liberação rápida, como também
disponibilizará um atalho para facilitar disparos subseqüentes.
Agora vamos configurar o “jCompany Hot Deploy”, de modo que não precisaremos mais acionar tarefas
Maven, para testar edições em recursos do tipo JSP, CSS, Javascript e mídia (JPG, GIF, PNG, etc.).
1. Selecione o projeto “rhtutorial” (é o único que contém este tipo de artefato, em nossa configuração,
do contrário teríamos que acionar para os demais também), e acione “clique direito -> jCompany ->
Ativar jCompany Hot Deploy”.
2. Com este recurso ativado, arquivos modificados no Eclipse são imediatamente propagados para o
Application Server. Se for necessário desativá-lo, utilize a mesma opção.
Figura B7.60. Vinculado sem Object-Id e título de seção de Endereço alterado (falta reinício para texto I18n
aparecer).
Figura B7.61. Títulos de seção na seleção alterados (já ativos, pois neste caso não usamos I18n).
198
Implementando o Padrão “Manter Agregação Simples”
199
Capítulo B7
Sumário
Neste capítulo, fizemos o desenvolvimento de nosso segundo Caso de Uso “UC001.2 Manter Unidade
Organizacional-“, utilizando o padrão “Manter Agregação Simples” e a extensão padrão “Explorador de
Dados”.
Neste padrão, provemos formulário e reutilizamos implementações MVC padronizadas para que usuários
possam incluir, alterar, excluir, clonar e imprimir dados de Unidades Organizacionais, bem como buscá-
los e consultá-los de forma hierárquica, através de uma Treeview padrão.
Com este Caso de Uso somado ao primeiro “UC001.1 Manter UF-“, encerramos um primeiro Caso de Uso
em nível de Objetivo do Usuário, chamado “UC001 Manter Estrutura Organizacional!”.
Neste Caso de Uso exploramos mais edições de artefatos, vimos alternativas adicionais de Liberação
Maven e entendemos um fluxo de navegação entre duas Colaborações.
No próximo capítulo, iremos explorar o padrão “Manter Agregação Mestre/Detalhe”, que é uma extensão
do padrão que utilizamos aqui.
200
8
Capítulo
Implementando o Padrão
8
B
"Manter Agregação
Mestre/Detalhe"
Implementando “UC002 Manter Funcionário!”
- Analisando a especificação
A terceira especificação de Caso de Uso que iremos implementar está definida no diagrama da Figura
B8.1.
Este diagrama ainda é bem sucinto porque se trata de um terceiro Caso de Uso Padrão com nome
“Manter Agregação Mestre/Detalhe”, definido no módulo jCompany Patterns & Methods e
automatizado pelos módulos jCompany FS Framework (generalizações da arquitetura) e jCompany
IDE (geradores de artefato)*.
O Modelo de Classes e Projeto de Interfaces com o Usuário (GUI) são agora de uma dimensão
inapropriada para serem diagramados juntamente com a visão estrutural do Caso de Uso. Por este
motivo, foram representados em pacotes diferentes, na ferramenta CASE. O conteúdo do pacote “Grafo
Funcionário” pode ser visto abaixo.
* Nota de especificação: É o primeiro dos Casos de Uso que implementamos até agora, do “nível do mar”, ou seja, de um nível que
representa um interesse direto do usuário/cliente, o que podemos notar pelo símbolo de exclamação (!) e cor azul clara (caso
estejamos visualizando colorido). Somente para rememorar o capítulo 5, os outros dois Casos de Uso anteriores, somados,
representavam um único “objetivo do usuário”.
201
Capítulo B8
Figura B8.2. Grafo do Modelo de Domínio incluindo Agregação a ser Mantida e Classe referenciada
202
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Figura B8.5. Classes Java para prosseguir no “rhtutorial”, disponíveis no diretório de instalação.
* Na verdade, em aplicações reais o número de classes em geral costuma ser maior, bem como o número de propriedades. Porém, isso
não interfere na complexidade da estrutura “sintática” do Grafo, o que significa que o Caso de Uso Padrão que utilizaremos
permanecerá útil, e continuará provendo excepcional produtividade, mesmo se escalarmos o tamanho do modelo.
†
Obs.: Como não temos um outro uso previsto para Sexo neste projeto (ao contrário do componente Endereco, por exemplo, que
previmos usar em “UnidadeOrganizacional” e “Funcionario”), alguns irão preferir mantê-lo inicialmente em “funcionario",
posteriormente efetuando uma refatoração, se e quando necessário for.
203
Capítulo B8
3. Na página de definição, digite o nome da Enumeração e uma relação de valores do tipo “Código e
Descrição”, que irão representar os valores discretos possíveis. Para adicionar valores à lista, clique
em “Adicionar Item”, como exemplificado na Figura B8.9.
Figura B8.9. Clicando em “Adicionar Item” após digitar “M” em código e “Masculino” em Descrição
*
É possível que agora os plugins do jCompany Artifact Generator sejam apresentados como default pelo Eclipse (senão forem,
abra-os na lista).
204
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#2. Campo para se informar o código, que no caso de Entidades persistentes, será o valor
armazenado no SGBD*.
#3. Campo para se informar a descrição, em idioma “português” (idioma default, na verdade).
Como funciona?
- Esta descrição será gerada na Enumeração como um comentário padrão, ao lado de cada
valor da Enumeração†.
- Quando um Assistente de Caso de Uso notar uma referência a esta Enumeração, este
comentário será acrescido ao arquivo “ApplicationResources.properties”, com a convenção de
chave apropriada:
- Enumerações que seguem esta convenção podem ser diretamente utilizadas, de forma
internacionalizada, por componentes JSF ou Tag-Files para Struts do jCompany.
#4. Botões para se adicionar itens à lista ou para se remover. Para o segundo caso, posicione na
linha desejada e em seguida clique no botão “Remover Item”.
*
Portanto, ao contrário da “boa prática” recomendada para Enumerações transientes, no caso das persistentes mantenha estes códigos
pequenos, para não gerar desperdício desnecessário de armazenamento.
†
É importante notar que, para que uma Enumeração definida em ferramenta CASE (tal como o EstadoCivil, por exemplo), funcione de
forma I18n no jCompany, basta declarar o comentário apropriadamente, após cada valor e com a convenção apropriada, como o faz o
gerador.
205
Capítulo B8
#3. Método auxiliar, útil para componentes JSF e Tag-Files Struts exibirem valores.
5. Para finalizar, vamos acertar as importações em “Funcionario” e “Dependente”, uma vez que
criamos Sexo no diretório raiz do pacote de Entidades.
Edite cada uma destas classes e digite “Control+Shift+O” (letra O, não o número Zero), para que as
importações sejam ajustadas pelo Eclipse automaticamente.
Ao final, nenhum erro de compilação nas Entidades deve ser mais exibido.
Figura B8.12. Propriedades que representam associações, geradas por ferramenta CASE.
Perceba que propriedades de associação que não estavam presentes no modelo da Figura B8.2 agora
aparecem na classe, tais como Enumerações, Componentes e outras. Qualquer ferramenta CASE
razoável, tal como o Enterprise Architect©, utilizado neste livro, conseguirá gerar estas propriedades a
partir das associações e agregações modeladas. Caso não se possua nenhuma, naturalmente, deve-se
criá-las manualmente (o que é também um trabalho trivial).
Mas neste caso específico, já que “Funcionario” possui ligação bidirecional com seus detalhes (na
verdade, toda associação com detalhes deve ser bidirecional, para que funcione
apropriadamente), então deveríamos esperar também por uma coleção de “Dependente” e uma de
“HistoricoProfissional” em “Funcionario”, mas elas não existem.
206
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Seria possível gerarmos estas coleções utilizando recursos de nossa ferramenta CASE, mas não o fizemos
em nosso exemplo para expor uma comodidade oferecida pelos plugins do jCompany IDE. Estes plugins
irão realizar este ajuste para o desenvolvedor, e criar as coleções, caso ele as esqueça*.
Compreendendo isso, estamos prontos para iniciar mais uma iteração de mapeamento Objeto-Relacional.
O “targetEntity” é o único inconveniente, afetado pela “ordem” em que se mapeia. Uma vez que
tenha consciência disso, o Desenvolvedor pode gerar mapeamentos Objeto-Relacional em qualquer
ordem - e ajustar o “targetEntity”, em seguida.
Uma outra notável dificuldade para se utilizar a dica de ordem pela “menor dependência” são as
composições Mestre-Detalhe, pois estas possuem referências bidirecionais†... Por qual
lado começar? Neste caso específico, sugerimos que se inicie o mapeamento na ordem
“Raiz/Mestre” primeiro, e “Detalhes” em seguida.
Se analisarmos nosso modelo na Figura B8.2, tirando as Enumerações e as classes já mapeadas,
como “UnidadeOrganizacional” e o componente “Endereco”, restam as classes candidatas
“Funcionario”, “Dependente”, “HistoricoProfissional” e “Foto”.
Pela análise de dependência simplesmente, a classe “Foto” seria a primeira, por ter menos
referências (“Funcionario” é que referencia “Foto”). Poderíamos mapeá-la agora, mas esta classe
tem peculiaridades que serão discutidas com mais detalhes, no próximo capítulo.
Resta então a nossa Agregação Mestre/Detalhe (Composição Bidirecional). Iniciaremos o
mapeamento, neste caso, pela classe Raiz/Mestre, “Funcionario”.
2. Edite esta classe e pressione “Control+N” para iniciar seu mapeamento, selecionando o Assistente de
Criação número “01”. As informações de mapeamento para esta classe se encontram na Figura
B8.13. Basicamente, aplicamos as modificações presentes na especificação.
* Apesar disso, os plugins de mapeamento Objeto-Relacional do jCompany não devem ser utilizados para “corrigir modelagem”. As
classes Java para Entidades já devem, preferencialmente, possuir uma estrutura correta de associações, antes de serem mapeadas ou
utilizadas no jCompany.
No entanto, devido ao pouco costume de desenvolvedores com modelagens bidirecionais com coleções, e sendo estas importantes para
uma Agregação Mestre/Detalhe, os plugins efetuaram este ajuste. Outra opção que o jCompany realiza de forma “complementar” é a
geração de “getters” e “setters”, no padrão JavaBean. Tanto as ferramentas CASE quanto o Eclipse possibilitam esta geração
facilmente, mas o jCompany irá também realizar este complemento se os métodos não existirem, para evitar não-conformidades
básicas.
†
Perceba que explicitamos todas as referências no diagrama UML com as setas de direção das associações, para facilitar a análise de
dependência ou referência. Normalmente omitiríamos bidirecionamentos para composições e direcionamentos simples para agregações
compartilhadas, que podem ser inferidos.
207
Capítulo B8
Figura B8.13. Mapeamento Objeto-Relacional para “Funcionario", com partes modificadas em amarelo.
Este tamanho é dispensável pelo JPA, já que o tipo “Date” é reconhecido por SGBDs e não
utiliza tamanho explicito nas DDLs. Mas informando 11 possibilitamos que os campos de
entrada de data nos formulário “herdem” esta informação declarada na Entidade, como nas
outras propriedades.
o Perceba também que as classes referenciadas já são identificadas pelo jCompany, e associações
apropriadas assumidas como padrão (como para componente diferenciando-se de manyToOne).
O restante do mapeamento já deve ser de compreensão do leitor. O resultado gerado é exibido nas
Figura B8.14 e Figura B8.15, somente com as partes novas em destaque.
*
Como o padrão para campos do tipo “Date” é que sejam exibidos com formato de entrada “dd/mm/aaaa”, inclusive com máscara que
restringe a entrada a estas 10 posições, o tamanho 10 seria suficiente. Mas a experiência conta que 11 posições possibilitam uma
melhor estética.
208
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#2. A precisão do tipo temporal pode ser definida no padrão JPA. A precisão assumida é
TIMESTAMP, que inclui a parte tempo no item de data. Iremos ajustar este padrão a seguir.
#3. As Enumerações são mapeadas com cláusula necessária para que sejam persistidas como
alfanuméricos (STRING), o que significa que os valores “C”, “V”, “D” e “S”, para Estado Civil,
representarão os valores da Enumeração no SGBD.
#2. Para a associação com “Endereco”, que é um Componente, o mapeamento é específico, sendo
que o “@Valid” irá reusar as validações que já fizemos para CEP e outras deste componente,
em nosso novo Caso de Uso!
#3. O mapeamento “manyToOne” com o arquivo de foto também é gerado, e neste caso (como
ainda não mapeamos o arquivo), o “targetEntity” foi gerado com “Foto”. Mas como dissemos os
“arquivos anexados” são um caso especial, que será discutido ainda neste capítulo.
3. Vamos prosseguir agora para nossa primeira classe de Detalhe, “Dependente”. Edite esta classe e
pressione “Control+N” para iniciar seu mapeamento, selecionando o Assistente de Criação número
“01”. Preencha a primeira página do Assistente de Criação para mapeamentos Objeto-Relacional,
como na Figura B8.16.
*
Repare que o jCompany mantém as associações na camada “do projetista” como abstrações, utilizando “UnidadeOrganizacional” (que
é abstract) como propriedade, e “UnidadeOrganizacionalEntity” (que é concreta), no “targetEntity”. Esta prática é mais rica em
possibilidades de flexibilização e refatoração futuras (Veremos um bom uso de novos “descendentes” concretos para Entidades, quando
fizermos a implementação de Auditoria Rígida)
209
Capítulo B8
#1. Perceba que, para mapeamento de detalhe e caso não haja uma coleção para receber o
mapeamento “oneToMany”, o jCompany trará a opção de uso de “List” (recomendado) ou
“Set”. O padrão de acesso pode sempre ser Lazy, pois o jCompany irá “forçar” recuperações no
grafo que controla, quando necessário, especialmente neste caso.
#2. Ao selecionar “Detalhe” no Estereótipo, um novo campo “Classe Mestre” irá requisitar que se
selecione a classe “FuncionarioEntity”, neste caso. Cuidado para não selecionar a classe
abstrata “Funcionario”, erroneamente.
4. Clique em “Finish”.
O resultado obtido dispensa maiores explicações. Perceba os relacionamentos com tipos abstratos
(na camada abstrata, do “Projetista”), utilizandos juntamente com o “targetEntity” nos metadados
(apontando para instância concreta), em destaque na Figura B8.17.
5. Acione “Control+Clique” sobre o tipo “Funcionário”, para navegar diretamente para a classe
“Funcionario”. Confira o outro lado da associação bidirecional, gerada pelo Assistente de Criação.
Figura B8.18. Classe Funcionario alterada para conter mapeamento bidirecional oneToMany para Dependente.
#2. Opção de propagação de atualizações e exclusão (CascadeType.ALL), que deve sempre estar
desta forma para mapeamentos “oneToMany” utilizados em associações do tipo “Composição
Mestre-Detalhe”.
Importante: A cláusula “mappedBy”, se omitida, não causa problemas funcionais, mas irá
210
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
produzir SQLs em excesso, ao menos quando se utiliza o Hibernate como implementação JPA,
que é o nosso caso. Muitas vezes um pequeno detalhe como esse gera transtornos em
produção, causando gargalos de performance desnecessários. Esse tipo de esquecimento é,
aliás, um dos erros freqüentes no uso do Hibernate que o jCompany evita.
#3. A cláusula “@Valid”, tal como no caso do Componente, pede para que validações invariáveis
declaradas no escopo do Detalhe (Dependente, no caso), sejam realizadas juntamente com as
validações invariáveis do Mestre. No caso de uma agregação, como discutido em “Domain
Driven Design” [Evans, Erick 2004], as validações de todos os seus membros devem ser
realizadas em conjunto. Portanto, esta cláusula deve ser utilizada.
#4. A declaração de “@JoinColumn” é necessária para a indicação da(s) coluna(s) que compõe a
Foreign Key utilizada na associação.d
#5. Perceba que foi utilizado “List”, a interface de Coleções que escolhemos e que estamos
utilizando explicitando o conteúdo da coleção, com o tipo abstrato “Dependente”*, mantendo a
nossa “boa prática” de mapear somente abstrações na camada de Entidades do Projetista. Em
“targetEntity” o JPA sabe a instância concreta padrão que deverá ser utilizada, mas isso não
nos tira flexibilidade para adaptações futuras, pois as anotações não geram acoplamento
indesejável.
Figura B8.19. Mapeamento Objeto-Relacional para “HistoricoProfissional”, com partes modificadas em amarelo.
#1. O Assistente de Criação procura sempre assumir a primeira propriedade do tipo “String”, como
implementação para o “toString” (Lookup).
#2. O tamanho para tipos com decimais, como os monetários, devem ser informados separados
por vírgula, com formato “[tamanho total],[precisão da parte decimal]”.
O resultado somente apresenta o mapeamento para o valor monetário como novidade, com relação
ao Dependente, exposto na Figura B8.20.
*
Um dos esquecimentos muito comuns no momento da modelagem, especialmente quando coleções são geradas pela ferramenta
CASE, é a ausência da qualificação do conteúdo da coleção, via “Generics”. Por este motivo, pode-se optar por realizar tais ajustes de
mapeamentos através do jCompany, como fizemos, para em seguida sincronizá-los utilizando engenharia reversa do CASE.
211
Capítulo B8
#1. O mapeamento JPA padrão para “salario" define precisão e escala. O “length” é importante
para “herança” do tamanho pelos componentes de formulário, como no caso de Datas.
Terminamos o mapeamento de toda a Agregação, com a exceção da classe “Foto”, que veremos em
separado. Partiremos agora para acrescentar as anotações de validação invariável, conforme declaradas
na especificação.
o “dataNascimento deve ser menor que atual” e “dataNascimento não deve incluir tempo”
Podemos resolver estas restrições com uma modificação na anotação “@Temporal” do JPA e
acrescentando uma validação padrão do Hibernate Validator, chamada “@Past".
Posicione em seguida após “TemporalType.”, e digite “Control+Space” para ver opções. Selecione
“DATE” para eliminar a possibilidade da gravação da precisão de “tempo”, para esta data*!
o “cpf deve ser válido”
*
Este aparente “detalhe” é um outro caso de erro recorrente de programação, não somente em Java mas em qualquer linguagem que
trabalhe com SGBD-R relacionais. Sem o recurso acima, corre-se o risco de algum Desenvolvedor não informado armazenar a parte
temporal – em determinadas situações – ocasionando como conseqüência vários erros na comparação de datas. Por exemplo, datas
com dias iguais podem ser consideradas diferentes, porque possuem a “parte temporal” diferente.
212
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Figura B8.23. Validação de duplicidade de CPF, com Named Query padrão “naoDeveExistir”.
Vamos definir um índice único (unique index) em nível do mapeamento Objeto-Relacional, de modo
que este nos sirva a um duplo propósito: acelerar a consulta por cpf, que utilizaremos para
verificar a duplicidade; e garantir duplamente, em nível de SGBD, a questão da unicidade.
Para tanto, declare a cláusula específica do Hibernate “@Index” na propriedade “cpf”†, como na
Figura B8.24.
Mas e se nossa implementação JPA não for o Hibernate? E se formos portar esta aplicação para
várias implementações JPA distintas? Neste caso, a anotação será simplesmente desprezada, e
teremos de cuidar para que o esquema de índices seja corretamente submetido pelo DBA, como é
tradicionalmente feito nas empresas.
o “email deve ser válido”
O Hibernate Validator traz a validação “@Email”, para esta finalidade.
Figura B8.25. Definição de validação de formato de email (neste caso, somente se informado)
2. Com isso, terminamos as restrições definidas para “Funcionario", que podem ser resolvidas de forma
declarativa, mas não para toda a Agregação. Temos ainda três outras definidas em nível do
“HistoricoProfissional”.
*
A Powerlogic não julga apropriado modificar os padrões de nomenclatura de frameworks reutilizados. Por isso, validações como o
“@Past” e outras do Hibernate Validator são disponibilizadas “como estão”, ou seja, infelizmente sem nenhuma convenção específica.
†
Declarações de índices que envolvem múltiplas propriedades podem ser feitas em nível da classe.
213
Capítulo B8
o “salario não deve ser negativo”, “dataInicio deve ser menor que atual” e “dataInicio não
deve incluir tempo”
Somente a primeira é uma novidade. As demais estão ilustradas na Figura B8.26, de forma similar
a outras que fizemos.
#1. A validação “@Min” do Hibernate Validator permite que se valide intervalo de valores
numéricos.
Este tipo de método é chamado de “assertiva”, por devolver um “boolean” e não conter
argumentos (trabalha somente com valores internos à agregação). Ele deverá ainda conter a
anotação “@AssertTrue”, conforme a implementação exemplificada na Figura B8.27.
#2. Declaração para que este método seja considerado uma “assertiva” de validação. Fará com que
seja executado juntamente com as demais validações declarativas invariáveis. No padrão do
Hibernate Validator, a mensagem pode ser especificada entre chaves, para que seja entendida
como I18n.
#3. A assinatura de um método de assertiva deve retornar “boolean” e não pode conter
argumentos.
#5. A extração de valores constantes presentes nas regras de negócio para variáveis de classe não
somente é mais elegante por tornar a regra mais legível, como permite o reúso destes valores
214
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
por diversas regras e ainda otimiza a execução, evitando instanciar objetos constantes por
diversas execuções.
Figura B8.28. Método de serviço em nível de classe e protegido para acesso somente pela Agregação.
#1. Método em nível de classe, pois percorre coleção de todos os objetos, e protegido para acesso
somente interno à agregação.
#2. Esta classe somente sabe lidar com coleções de “HistoricoProfissional”, o que já é amarrado no
contrato do método.
#4. A implementação deve também levar em conta a possibilidade de nulos, pois estaremos
realizando-a durante uma entrada de dados, que pode conter salários não preenchidos.
Lembre-se que o jCompany “deixa linhas em branco e sabe desprezá-las” – também temos
que ter este cuidado em nossas programações invariáveis.
A classe Raiz da Agregação, “Funcionário”, pode então implementar a validação final, reutilizando
este serviço, em uma segunda assertiva muito semelhante à primeira.
215
Capítulo B8
2. Prossiga no roteiro para o segundo passo, “Utilizando o Assistente”. Vemos na Figura B8.31, a
primeira janela do Assistente de Criação do jCompany, preenchida para nosso Caso de Uso.
Figura B8.31. Tela inicial do Assistente de Criação para Padrão “Manter Agregação Mestre/Detalhe”.
Todas as modificações que tivemos de realizar manualmente estão grifadas, e nesta altura já não
devem ser novidade. Mas note que, para este padrão, informamos o número de classes de
detalhe envolvidas na Agregação, em “Número de detalhes”. No nosso caso são duas:
“Dependente” e “HistoricoProfissional”.
3. Vamos agora, pela primeira vez, entender em detalhes a segunda janela do Assistente de Criação.
216
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#2. Opção para uso de Ajax na Colaboração de Manutenção. Somente deve ser desmarcada
caso seja identificado algum impedimento específico, nesta Colaboração, que impeça a
otimização via Ajax (renderização parcial do formulário, durante a interação do usuário com os
botões de seleção, como F9-Pesquisar).
#3. A opção de Entrada em Lote influi no comportamento generalizado dos formulários, resolvido
na camada Controle. Marcar esta opção produzirá uma variação no comportamento que o
formulário seguirá, após uma gravação com sucesso, e esta variação dependerá do padrão
utilizado:
- Nas Colaborações que mantêm uma Agregação de Objetos por vez, como “plcCrud”,
“plcMestreDetalhe”, etc., o padrão após a gravação com sucesso é manter os dados recém
gravados disponíveis, para alterações, conferências ou clonagens. Com “Entrada em Lote”
marcado, ao invés disso, um formulário em branco será exibido, para uma nova inclusão.
- Na Colaboração “plcTabular”, o padrão após a gravação com sucesso é fazer uma nova
recuperação de todos os objetos da classe. Com a variação da “Entrada em Lote”, a
recuperação não é realizada e são adicionados novos objetos em branco, para novas inclusões.
Como achamos remota a possibilidade de clonar dados de funcionários, vamos marcar a opção
de “Entrada em Lote”, neste caso.
#4. A opção de “Exclusão Lógica” indica para o jCompany não excluir fisicamente objetos
da agregação (ou seja, não remover as Tuplas correspondentes, das Tabelas do SGBD-R).
Caso seja marcada como “lógica”, o jCompany irá utilizar transformar exclusões por uma
alteração padrão, de valor da propriedade “sitHistoricoPlc”, de “A” (Ativo) para “I” (Inativo).
Esta propriedade é reconhecida pelo framework, que então passa a tratar objetos com situação
“Inativo” como excluídos, do ponto de vista dos usuários.
*
Veremos esta Colaboração, no módulo C (Casos de Uso de Manutenção Secundários).
217
Capítulo B8
Em nosso Caso de Uso, observando a especificação, veremos que foi modelada a “Inclusão
Padrão para Caso de Uso”, de “Exclusão Lógica”. Portanto, iremos marcar a exclusão como
“Lógica”.
#5. Neste campo podemos indicar para que o formulário de seleção utilize paginação. Se
informarmos um número maior que zero nesta opção, vários comportamentos genéricos serão
alterados para a seleção, em todas as camadas MVC: As classes genéricas de DAO somente
recuperam do SGBD, no máximo, o número de objetos informados, de cada vez; Barras de
navegadores, na camada Visão e controladores serão renderizados, para permitir ao usuário
“paginar” uma consulta, e também dar saltos para páginas específicas, além da primeira e da
última.
Informaremos o número 5, apenas para facilitar nossos testes. Números mais apropriados para
situações de produção estariam entre 15 e 50, dependendo de cada caso.
#6. Opção para geração ou não da Colaboração de Seleção. Pode-se gerar uma nova,
reutilizar alguma existente (uma mesma Colaboração de Seleção pode servir a edições em
mais de um Caso de Uso) ou não gerar, situação em que se deve prover alguma forma de
seleção de objetos para edição, por conta própria, podendo muitas vezes ser através de
“hiperlinks” de outras Colaborações ou Explorador de Dados.
#8. Opção para incluir a geração de metadados, (arquivos “package-info.java”). Como o Caso
de Uso não funcionará sem esta parte declarativa, esta opção somente deve ser utilizada
quando for desejado produzir artefatos isolados, tais como uma JSP apenas.
#9. Opção para incluir a geração de chamadas de menu para o Caso de Uso. Registra a
chamada, no arquivo “plc-tiles-menu1.xml”, chamando a colaboração de “manutenção”,
inicialmente.
#10. Opção para incluir a geração de JSPs para o Caso de Uso. Em situações de desenvolvimento
para outras tecnologias de Cliente, que não pretendam utilizar JSPs, esta opção pode ser
utilizada.
#12. Opção para se utilizar ou não o framework Apache Validator. Este framework permite a
declaração de validações “variantes” em XML, atuando na camada de Controle (e não na de
Domínio, como é o caso do Hibernate Validator). Usado apenas para Struts.
4. O próximo diálogo já nos foi apresentado, mas algumas poucas novas opções serão utilizadas. A
Figura B8.33 exibe em amarelo as partes modificadas com relação ao padrão assumido pelo
jCompany, para obtermos o resultado especificado, e numeração nas novidades.
*
Caso se desabilite o uso de Ajax globalmente, estas opções podem ser desprezadas. É importante lembrar também que o jCompany
traz opção para que cada usuário possa desabilitar para si esta otimização, o que é útil na eventualidade de uma parcela mínima do
universo de usuários estar usando Navegadores antigos, que produzam problemas com Ajax.
218
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
- Já as propriedades das classes de Detalhe, como serão exibidas com várias ocorrências, são
organizadas como padrão em “uma aba de Tab-Folder por Classe de Detalhe”.
- Já no caso da opção “Assistente”, podermos fazer “cortes” que nos possibilitarão apresentar o
formulário de forma fragmentada, linha a linha se preciso, como um “Assistente de Entrada de
Dados”. É um recurso de usabilidade interessante, que apoiará os usuários durante períodos de
treinamento ou uso inicial.
Vamos marcar esta opção em nosso caso, já que há uma especificação para uso da “Extensão
Padrão de Assistente”.
#3. Se analisarmos o projeto de GUI para a parte de seleção da Figura B8.4, veremos que foi
solicitado uma pesquisa por “intervalo de idade” do Funcionário. Como este dado não existe
pronto na Entidade, esta exigência exigirá que realizemos não somente uma programação de
controle complementar, mas também uma customização na parte visual, de argumentos. Para
atendermos a este caso, deixamos uma “lacuna” (Coluna 2 da Linha 2) no formulário,
disponível para alteração e incluímos a data como argumento, provisoriamente.
*
Os Assistentes de Criação, como “plugins de Processo”, fazem um esforço para obter uma primeira versão de Interfaces com o
Usuário com qualidade de produção e que sigam “melhores práticas” de O&M, Usabilidade em Geral e Web-Design, tendo como base de
referência os Padrões da Arquitetura. Eles não pretendem ser “editores artesanais genéricos, de Interfaces com o Usuário”, o que deve
ser obtido com editores WTP/Red Hat Studio, Tiles, JSP e JSF.
219
Capítulo B8
#4. Algumas outras formatações e ajustes ainda estão pendentes, tais como o “formato” exato
para exibir “UnidadeOrganizacional” (assumida como “combo” mas devemos alterar para
“vinculado”) e de rótulos tais como “Cpf”, que deve ser “CPF”. Iremos ajustar estes itens
durante a confecção da parte de manutenção.
A maior parte dos ajustes em coordenadas de campos é conseqüência de termos que remover o
Object-Id do formulário, para atender à especificação. O que temos de mais interessante, neste
caso, são oportunidades de uso de formatações mais interessantes para campos, relacionadas
abaixo:
#1. As propriedades cujo tipo seja Enumeração são assumidas em formulários como “Combo
Estático”, ou seja, “listas de valores” cujos dados não podem ser modificados pelos usuários.
Este padrão é apropriado para a propriedade “estadoCivil”.
#2. No caso da propriedade “sexo”, como são apenas dois valores, o formato “Radio” é mais
interessante, pois não ocupa mais espaço que o “Combo”, e já permite a visualização das
opções existentes. Normalmente, indicamos “Radio” para Enumerações que contenham dois ou
três valores, no máximo, dependendo do tamanho da descrição destes valores, e “Combo
Estático” para três ou mais.
#3. O formato “Caixa Marcação” (Checkbox), é assumido para propriedades com valor “Boolean”,
que são persistidas como “S” ou “N” em SGBDs, pelo padrão automatizado no framework. Ele é
apropriado para “temCursoSuperior”.
#4. O formato “Vinculado”, que já vimos antes para implementar a recursividade com
“UnidadeOrganizacional”, será aqui mais uma vez utilizado, oferecendo um diálogo Popup que
permite seleções sofisticadas, paginadas em com diversos argumentos, com objetivo de
facilitar ao usuário a análise e escolha do objeto que deseja “vincular” ao formulário principal*.
*
Perceba que os “Vinculados” reusam Colaborações de Seleção pré-criadas! Um vinculado não funcionará caso sua Entidade já não
tenha sido utilizada anteriormente, como raiz em uma Colaboração de Seleção.
220
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#5. O campo “observacao”, por ter um tamanho grande, pode ser mais bem apresentado através
do formato “Área”, que oferece várias linhas de entrada de texto. Neste caso, altere o tamanho
para conter o número de linhas e de caracteres por linha desejados, no formato: [Número de
Linhas],[Número de Caracteres].
#6. O campo “uf” foi corretamente assumido como “Combo Dinâmico”, já que seu tipo é uma
classe Raiz de agregação. Este é o formato apropriado, para classes mantidas em caching, pelo
padrão “Manter Classe”.
#7. Por último, vamos remover a propriedade “foto” do formulário, já que exigirá um tratamento
especial, no próximo capítulo.
Figura B8.35. Tela para definição de formulário e metadados para Detalhe “Dependente”.
#1. Classe de Detalhe. Deve-se selecionar a classe concreta que represente o primeiro detalhe.
#2. A visualização do trecho de formulário (markup) que representa o Detalhe será realizada
apenas mostrando-o abaixo da parte principal, do “mestre”, já que esta é uma visualização
local e que não possui gestão de leiaute atuante. A visualização do uso de “Tab-Folder”, por
exemplo, somente será possível após a liberação para teste.
#3. Em “Título”, o título do Detalhe deve ser informado, conforme irá aparecer no topo de seu
componente (subseção do formulário) ou na aba do “Tab-Folder”, caso a opção de Tab-Folder
tenha sido marcada.
#4. Em “Flag de Detalhe (Prop. Referência)”, devemos selecionar uma das propriedades da Classe
que servirá de referência para que o framework considere a linha como preenchida. Em outras
palavras: caso o usuário não forneça um valor para a propriedade aqui informada, toda a linha
(objeto) será desconsiderada.
Normalmente, esta propriedade representa uma “chave alternativa” do negócio, ou parte dela,
e é a primeira propriedade a aparecer em cada linha, no formulário. O Assistente
habitualmente assume um bom padrão, mas este deve sempre ser conferido.
221
Capítulo B8
Para o caso do Dependente, os valores devem ser “0..2”, pois foi especificado desta forma no
Modelo de Classes, conforme pode ser conferido na Figura B8.2*.
#6. Em “Num. Novos”, podem-se informar o tamanho do bloco de objetos “em branco” que será
criado no formulário para este detalhe, no momento da criação do formulário; blocos de
mesmo tamanho também serão criados, a cada clique no botão “F7-Novo”, se este detalhe
estiver com foco. O padrão são 4 (quatro) mas, em nosso caso, podemos diminuir para dois.
#7. Em “Pos. Título”, é possível optar por gerar os rótulos de título de cada coluna no “topo”, ou
seja, uma única vez, acima de todas as linhas de detalhe; ou em “linha”, de maneira
entremeada, acima dos campos de cada linha. Em geral, o padrão “topo” é o mais adequado, a
não ser que a quantidade de propriedades exija mais do que uma linha por registro.
#8. Em “Por Demanda” é possível se retardar a recuperação de objetos desta classe de Detalhe,
que passam a não ser mais recuperados juntamente com a recuperação do objeto Mestre, raiz
da Agregação.
Esta opção deve ser utilizada com cautela, somente em situações que exijam otimizações
decisivas de performance, pois dificulta lógicas de programação, que não podem contar mais
com “todos os dados da agregação representados em memória”.
Por exemplo, nossa validação de “Salário Mínimo para Curso Superior” não funcionaria se o
Detalhe “Histórico Profissional” fosse declarado como “Por Demanda”, e nem a validação de
cardinalidade automatizada do jCompany, que se baseia em verificações em memória! O
desenvolvedor deve estar consciente e ter conhecimentos suficientes sobre como fazer lógicas
de programação como estas, neste cenário. Por outro lado, quando o número de classes de
detalhe for muito grande e não for possível se “subdividir o padrão” em mais Colaborações,
então o uso do “Por Demanda” pode ser um fator de otimização importante.
As demais informações desta Tela são similares às que conhecemos, para o ajuste de coordenadas
e formato para propriedades do Detalhe.
7. O próximo passo do Assistente de Criação exibe a mesma tela para definição de formulário e opções
para o próximo detalhe, e também dispensa mais explicações. Perceba o ajuste da multiplicidade
mínima e alinhamento de todas as propriedades na mesma linha.
*
Obviamente, uma restrição de um máximo de “dois” dependentes é bem hipotética e pouco provável no mundo real, apenas usada
para forçar a demonstração tecnológica que precisamos.
222
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Figura B8.36. Tela para definição de formulário e metadados para Detalhe “HistoricoProfissional”.
8. Seguindo para o último passo, iremos definir opções de geração que nos possibilitará atender a
Extensão Padrão “UC002.1 Assistente”, de nossa especificação.
A definição dos passos é realizada através de “recortes” do nosso formulário, sendo cada “recorte”
equivalente a “um passo do Assistente”.
Assistentes “passo a passo” são uma excelente opção para promover o uso da aplicação. Quando
bem utilizados, mostram-se o meio mais eficaz de se capacitar usuários no sistema, economizando
em treinamento e tornando-o bastante eficaz do ponto de vista de usabilidade.
Figura B8.37. Tela final para definição do “corte” que será exibido para o usuário, em cada passo do Assistente.
#1. A granularidade mínima de apresentação em cada passo é “uma linha do formulário”. Veja que
a primeira coluna já apresenta, quais propriedades estão sendo exibidas, em cada linha, com a
exceção dos componentes de Detalhe, que não podem ser divididos - cada Detalhe deverá ser
apresentando, integralmente, em um único passo do Assistente.
#2. Em “Objeto”, vemos a descrição do estereótipo Mestre ou nome dos detalhes presentes na
Agregação sendo mantida.
#3. O “Corte Componente” pode-se alterar a distribuição das linhas pelas “Abas de Tab-Folder”, se
esta opção foi marcada, ou por seções de formulário, caso não tenha sido marcada. Cada grupo
de linhas com mesmo “número de corte” é gerado em uma mesma “aba ou seção” de
formulário, distintas das demais. Não iremos alterar estes valores.
#4. O gerador assume como padrão colocar todas as linhas da classe Mestre em um único passo,
mas em nosso caso desejamos oferecer explicação minuciosa, linha a linha. Portanto,
alteraremos o “Corte Assistente” da forma exemplificada. Cada “número de corte” distinto será
“um passo do Assistente”.
#5. Em “Descrição Assistente”, pode-se definir a introdução do texto que será exibido em cada
passo do assistente (a primeira de cada número de corte é utilizada).
Dica: Não é necessário se informar todo o texto neste momento. Informe apenas o suficiente
223
Capítulo B8
*
Perceba a modificação do padrão de sufixo, de “Man” para “Mestre”, para este padrão, com relação ao “Manter Agregação Simples”.
†
No caso de rótulos, somente se foi utilizada a opção “I18n”, caso contrário os rótulos são gerados na JSP, diretamente.
224
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#2. A única importação da página JSP é da Tag-Lib “plcf.tld” do jCompany, que por sua vez
especializa os componentes JSF do Apache Trinidad*.
Este desacoplamento das JSPs de tecnologias específicas de cliente (Apache Trinidad, Struts,
etc.) é um benefício muito importante da arquitetura, pois possibilita ao jCompany evoluir,
readaptar e substituir implementações atuais por outras que possam surgir no futuro,
preservando grande parte do código das JSPs, produzido pelos clientes†. Além disso, esta
simplicidade advinda do baixo acoplamento ainda aumenta a estabilidade e facilita a
manutenção, como vimos no capítulo 4, sobre arquitetura.
#5. Componentes “celula” envolvem os rótulos e os campos. Este agrupamento facilita variações
em leiautes do formulário, como alinhamentos verticais (rótulos à esquerda de campos). Este
componente irá renderizar uma trama com elementos HTML “span” e “td”§.
*
No caso da tecnologia Struts, são Tag-Files que especializam Tag-Libs Struts, bastante similares.
†
Vale aqui uma observação: Somente a biblioteca de componentes Apache Trinidad que vem com o jCompany traz mais de uma
centena de componentes JSF, fora outras bibliotecas JSF que se possa utilizar concomitantemente! Portanto, o desacoplamento do
jCompany é restrito a algumas dezenas de componentes mais comuns, tais como “inputText, Radio, Combo, etc.”. Não é desencorajado
ao desenvolvedor utilizar outros componentes JSF quaisquer, quando se faça necessário, e isso não invalida o benefício de
desacoplamento, em 99% dos casos.
‡
Muito embora os leiautes privilegiem o uso de CSS e tags HTML “div”, sempre que possível, tags HTML “table” são mais apropriadas
para uso em formulários, se comportando melhor em redimensionamento de janelas dos Navegadores, e em variações de resolução de
vídeo.
§
Note que o jCompany não modifica o padrão básico de renderização dos componentes reutilizados do Apache Trinidad.
225
Capítulo B8
#8. Todos os componentes são gerados com a propriedade “id”, deste modo facilitando sua
identificação, em programações Javascript*.
#9. A expressão para o valor de campos de argumento deve ser informada como
“#{plcLogicaItens.argumentos.[propriedade de argumento].valor}”. A seqüência de
comunicação dos componentes JSF com o Backing Bean (Action), envolvendo lógica de
Controle genérica e o JBoss Seam, será explicada mais a fundo, no módulo E.
#10. Todos os componentes de entrada de dados são gerados com a propriedade “ajudaChave”†,
que por sua vez renderiza um elemento HTML “title”. Este é um elemento obrigatório, que além
de prover ajuda sensitiva em nível de campo (balões amarelos na sobreposição do
mouse), também é chave para prover acessibilidade, pois contém o texto lido por dispositivos
de apoio à operação por deficientes visuais, quando o campo entra em foco.
#11. O componente “comboEstatico” renderiza um elemento HTML “select”, contendo uma lista de
opções exibida de forma “Pull-Down”. É um componente muito interessante por não ocupar
espaço em demasiado no formulário, porém não aplicável quando o número de itens a ser
exibido for crescente ou muito grande (por exemplo, acima de 100 objetos).
#12. O atributo “domínio” permite que se informe uma classe de Enumeração, cujos valores serão
utilizados pelo componente JSF para renderizar as opções do “comboEstatico” (funciona
também de forma similar, para componentes “radio”)‡.
Importante: Para funcionar, a classe de domínio utilizada deve estar declarada no arquivo de
metadados em nível da aplicação, na relação de classes de domínio discreto (os geradores já
fazem esta declaração, na maior parte dos casos). Exemplo, em
“com.powerlogic.jcompany.config.app/package.info.java”:
Figura B8.39. Classes de domínio discreto (Enumerações) e de lookup (Estereótipo “plcTabular”), declaradas
em metadados da aplicação.
#13. O atributo “exibeBranco” exibe uma linha adicional na lista de opções do “comboEstatico”,
que quando escolhida seleciona o valor “null”. Deve ser utilizada sempre que a propriedade
aceitar nulos§.
#14. Ao contrário dos demais componentes até aqui, o “vinculado” não possui um correspondente
muito próximo, no Apache Trinidad. Ele renderiza dois campos em HTML: um de “código”
(opcional) e outro de “descrição”, além de um botão que aciona (via Javascript) um diálogo
*
Para se pegar o valor de um campo de qualquer formulário do jCompany via Javascript, em JSF, deve-se utilizar o prefixo “corpo:”,
antes do identificador definido em “id”. Por exemplo, para pegar o valor informado no campo “e-mail”, em uma seção Javascript, pode-
se codificar: var email = get('corpo:email');
Este prefixo é assumido pelo Apache Trinidad, uma vez que todo o formulário é gerado dentro de um “div HTML” com identificação
id=”corpo”, que por sua vez está definido abaixo de um elemento “f:view”.
†
Se a geração ocorresse sem a opção “I18n” ligada, o valor seria gerado utilizando a propriedade “ajuda”, com texto direto em
português.
‡
Como já vimos, as descrições em I18n serão utilizadas para exibição ao usuário, de acordo com a convenção (Ex.:
sexo.M=Masculino) – e os valores da Enumeração gravados como código alfanuméricos (ex: ‘M’) no SGBD-R. Em Struts, o
funcionamento é similar.
§
Se esta opção não for usada, a lista do comboEstatico irá aparecer com o primeiro valor selecionado. Nestes casos, o recomendável é
incluir um valor inicial para a propriedade explicitamente, na Entidade.
226
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Popup. Este diálogo reutiliza uma página de seleção, permitindo ao usuário selecionar valores
de outros objetos, e vinculá-los ao formulário principal.
#15. Para que a devolução do valor selecionado no diálogo Popup retorne corretamente, o atributo
“propSelPop” deve coincidir com o atributo “propAgregada” da Tag “linhaSelecao”,
presente na página de seleção reutilizada. Isto é necessário para que as funções
Javascript genéricas do jCompany consigam copiar os valores selecionados, do diálogo Popup
para o formulário, sem necessidade de codificação pelo Desenvolvedor.
Figura B8.40. Valor correspondente para retorno de valores selecionados, do diálogo de seleção para o
formulário.
Obs.: Repare também que já utilizamos ‘idExibe=”N”’, para que o campo de “id” não seja
exibido pelo componente “vinculado”, como já fizemos no Caso de Uso anterior.
Após as modificações, este trecho da Figura B8.38. Anatomia de uma JSP de argumento típica.
deve ficar alterado conforme a figura abaixo.
#16. O atributo “autoRecuperacaoClasse” indica a classe que será utilizada para a busca pelo
campo de código (“id”), se ele estiver exibido e não protegido. Pode-se acrescentar a
propriedade “autoRecuperacaoPropriedade”, para utilizar outra propriedade diferente de
“id” (Ex.: uma chave de negócio) para a recuperação de objetos vinculados. Iremos utilizar este
recurso em tutoriais do módulo C.
#17. O atributo “actionSel” indica o nome da Colaboração de Seleção a ser reutilizada pelo diálogo
Popup. Esta Colaboração deve ter sido previamente desenvolvida. Em nosso caso, a
desenvolvemos para permitir a seleção para edição, de objetos de “UnidadeOrganizacional”,
bem como vínculos recursivos. Da forma em que são concebidas na arquitetura, o ideal é que
Colaborações de Seleção se tornem padrões para busca de determinadas Entidades,
reutilizadas por toda a organização.
É possível, inclusive, reutilizar esta Colaboração, mesmo que esteja embalada em outra
aplicação - preferencialmente configurada com alguma estratégia de unificação de logins
(single-signon), para evitar uma nova janela de login, ao chamar o diálogo! Para este caso,
bastaria definir o contexto de base para formação do hiperlink para outras aplicações, como no
exemplo da Figura B8.42, reutilizando a seleção de outra aplicação com nome de contexto
“outraapl”:
Ao analisarmos a página de um modo geral, podemos observar que está em um estágio minimalista,
contendo o mínimo necessário de informações: Não contém nenhum atributo decorativo (cor, fonte) e
nem referências a estilos; nenhum código HTML; nada a respeito de leiaute externo (nem includes); nada
sobre tamanho e obrigatoriedade dos campos; nada sobre valores de Enumerações; nada de um idioma
específico e ainda com o mínimo de dependências e nome padronizado, por exigência dos leiautes
universais.
Tudo isso gera inúmeras vantagens, tais como:
o Internacionalização (I18n)
o Uso possível de outras tecnologias de cliente (WML, XML, etc.), bastando que se crie “Renders
JSF” diferentes (em Struts, especializar Tag-Files).
227
Capítulo B8
Figura B8.43. Tamanhos “especializados”. Os demais campos continuam assumindo o tamanho da Entidade de
Domínio.
2. Veja na opção “Visual” ou “Visual/Source” do editor, que a visualização destes campos reage ao
novo tamanho. Já os demais são exibidos em tamanho 5 (cinco), sempre, pois em tempo de
desenvolvimento o plugin do RHDS não reconhece os valores do domínio, como o jCompany.
3. Outra modificação, bem mais importante, diz respeito à recuperação por argumentos, de intervalo
de “idade”. Lembre-se que geramos um argumento por “dataNascimento”, somente para nos prover
“espaço” na página para fazermos a adaptação.
o Uma primeira coisa a notar na JSP gerada, é o valor 2 (dois) no atributo “columnSpan”, para os
componentes “celula” de “dataNascimento” e “unidadeOrganizacional”. Este atributo renderiza
uma Tag HTML “td” com atributo “colSpan”. Este atributo tem o efeito de “mesclar” colunas,
que foi exatamente o que desejávamos, durante o Assistente de Criação.
o Uma segunda é a convenção de sufixo “_ArgINI”, utilizada somente em campos transientes de
argumento, utilizados em intervalos. Os dois valores possíveis são “_ArgINI” e “_ArgFIM”.
No caso do intervalo de “idade”, divida o conteúdo da célula por duas, retirando o
“columnSpan=’2’”, e alterando o seu conteúdo, conforme o exemplo da Figura B8.44 .
228
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Perceba que alteramos rótulos e texto de ajuda, mantendo a convenção em I18n. Neste caso,
explicitamos ainda o tamanho, pois não há uma propriedade correspondente na Entidade de
Domínio, para que o tamanho seja “herdado”. Por fim, acrescentamos uma restrição de formato
nos componentes para aceitarem “somente números”.
Figura B8.45. Mensagens criadas para intervalo de “idade”, seguindo a convenção de nomenclatura.
*
Dica 1: Esteja certo de tabular após realizar a digitação do último campo no editor de mensagens. Um erro comum é salvar sem a
tabulação, situação em que o valor não será inserido por este editor, ficando nulo.
Dica 2: Os alertas em amarelo na coluna esquerda do editor são porque não cadastramos valores para os rótulos em outros idiomas.
Informe-os, para testar, ou exclua os arquivos de outros idiomas, se quiser se livrar destas advertências.
229
Capítulo B8
#1. Para o correto funcionamento da lógica de “Assistente”, a Tag-Lib “Core” (c) do JSTL é
também importada, nesta página. A Tag “c:if” é utilizada para “filtrar” linhas para cada passo
do Assistente, caso o usuário esteja em “Modo de Assistente” (ficará mais claro quando
operarmos o formulário)*.
Neste caso, o jCompany IDE gera uma chamada à função “comutaAba”, que irá
automaticamente acionar a próxima “aba” do leiaute, na medida em que o usuário encerre o
preenchimento de uma anterior. Este recurso contribui para uma operação de entrada de dados
“massiva” - que não deve forçar o usuário a recorrer ao mouse, para comutar de abas.
#4. Datas possuem um componente específico, chamado “data”, similar ao componente “texto”
(também renderiza uma Tag HTML “input type=’text’”), mas que introduz máscaras
Javascript de entrada de dados†, opção de calendário Popup, dentre outras pequenas
especializações para este tipo específico.
*
Para este caso, poderíamos inicialmente tentar o atributo “rendered” do JSF aplicado em linhas do formulário, como alternativa ao
“c:if”. O “rendered” é a forma preferencial, na maior parte dos casos. Porém, na prática, nem sempre o resultado é o esperado,
especialmente devido à complexa cadeia de renderização e caching do JSF, para cada componente, e sua relação com a tecnologia JSP.
Neste caso, como em algumas raras exceções, somente o “c:if” nos proverá o comportamento desejado.
†
“dd/MM/yyyy” é default. Opções são “dd/MM/yy”, “MM/yy” ou “MM/yyyy”, definidas no atributo “mascara”.
230
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#2. Já modificamos o componente “vinculado” para o nosso caso, que não queremos o “Object-
Id” exibido. Não se esqueça de aplicar esta modificação.
#3. O componente “área” renderiza a Tag HTML “input text=’area’”, que permite múltiplas linhas
de entrada de dado. Ele exige a declaração do tamanho e número de linhas (conforme já foi
gerado).
Veja o conteúdo deste arquivo na Figura B8.48, com as partes que temos editado em destaque.
Pode-se acrescentar ou remover propriedades e alterar valores, tendo apenas o cuidado de não modificar
inadvertidamente, as partes envoltas com o token “###”. Estas são as partes variáveis em função do
Caso de Uso, substituídas pelo jCompany Artifact Generator (em situações especiais é possível,
inclusive, fazer geradores sob medida utilizando-se estes mesmos templates).
Importante 1: Salve uma cópia dos templates modificados, porque uma atualização de versão do
jCompany poderá sobrepô-los. Após cada atualização retorne com as modificações ou as reaplique, caso
o template tenha sido alterado.
Importante 2: Os templates para geração de artefatos são uma parte não documentada, por ser pouco
usada, mas seu entendimento é, na maior parte do tempo, intuitivo. Entre em contato com a
Powerlogic se precisar de mais informações para personalizações nesta área.
*
O nome agregado era anteriormente utilizado em lugar do atual vinculado. Alguns arquivos ainda guardam esta nomenclatura.
231
Capítulo B8
Figura B8.49. Modificação da chamada para “/f/t/funcionariosel”, com a URL de manutenção como parâmetro.
Neste ponto encerramos todas as modificações necessárias nos artefatos da camada Visão, e podemos
passar para a camada Controle.
Figura B8.50. Modificações em metadados de controle, para alterar argumentos na Colaboração “funcionariosel”.
#1. A classe de controle que estará atuando, em nosso caso, será “FuncionarioAction”, criada
(vazia) pelo Assistente de Criação do jCompany Artifact Generator, conforme requisitamos.
#2. As opções de navegação paginada em dados de seleção também são geradas aqui. Após
nossos testes, temos que nos lembrar de alterar o número de objetos por página, de 5 para um
número apropriado para uso em produção, como 25 ou 50.
232
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
poderá modificar o número de registros por página dinamicamente, dar saltos de página ou
outras opções.
#4. Os argumentos são definidos com nome da propriedade, operador e formato, em propriedades
com nomes correspondentes. Clique após as Enumerações “Operador.” ou “Formato.” e digite
“Control+Space”, para obter ajuda, com as opções disponíveis.
1. Aplique as modificações em destaque na Figura B8.50, para indicar o uso do novo argumento
baseado em “idade”.
Vamos agora entender as diferenças geradas nos metadados para “funcionarioman”, em adição ao que já
vimos na manutenção “unidadeorganizacionalman”.
#1. A classe de controle (Backing Bean) que atuará também foi assumida como a nova que
indicamos, “FuncionarioAction”. Não precisaríamos dela porque não temos necessidade de
nenhuma programação de Controle para a Colaboração de Manutenção, neste Caso de Uso.
Porém, vamos deixá-la atuando para implementações futuras.
#2. Um grupo de metadados “@PlcConfigAssistente” nos permite definir para o leiaute Universal
utilizar o leiaute de Assistente. Em sua ergonomia padrão, um novo botão será exibido na barra
de ações, permitindo ao usuário acionar o “Modo de Assistente”. Em “totalPassos”, explicitamos
ao leiaute Universal o número total de passos de assistente que serão usados, para facilitar a
generalização.
#4. Um grupo de metadados “@PlcConfigTabFolder” nos permite definir para o Leiaute Universal
para utilizar o subleiaute genérico de Tab-Folder. Em “tabFolderUsa” deve-se definir “true”.
#5. Em “tabFolderLayout”, pode-se definir um nome de leiaute Tiles (definition a ser declarada em
“app-tiles-pagina1.xml”) para a parte de Tab-Folder, de modo a oferecer total flexibilidade. Na
forma “automatico” (default) o Leiaute Universal irá reutilizar um leiaute de Tab-Folder que
dispensa codificação de JSPs ou XML Tiles.
*
Não poderíamos usar componentes JSF para Tab-Folder ou para fazer o Assistente, por exemplo? É sempre possível, ao
desenvolvedor, utilizar quaisquer componentes JSF que deseje, até porque o jCompany disponibiliza mais de uma centena deles
através do Apache Trinidad. Mas veremos que os “componentes de leiaute” Tiles são assim concebidos para serem mais “invisíveis” ao
desenvolvedor, externos aos formulários de negócio. Deste modo, eles atendem a um grande número de interações com os leiautes
gerenciados pelo jCompany, que não seriam triviais para componentes mais “refinados”, que deixamos para uso interno aos
formulários.
233
Capítulo B8
Mas como funciona a lógica de programação generalizada, tipo QBE (Query by Example), implementada
pelo jCompany nas seleções?
o Nas camadas de Visão e Controle, o jCompany apenas captura cada valor de argumento informado,
e o encapsula em POJOs do tipo PlcArgVO, que contém também o operador a ser utilizado e outros
valores necessários.
o Em seguida, o jCompany envia uma coleção com estes POJOs para a camada Modelo.
o Serviços da camada Modelo irão abrir a transação e delegar para a camada de Persistência, o
tratamento final do tipo QBE.
o As implementações genéricas de DAO, seja para Hibernate (Session), seja para JPA (EntityManager),
irão produzir cláusulas de filtro “where” dinamicamente, em função do que foi informado, e devolver
coleções com resultados, utilizando “NamedQueries” declaradas, como base para a cláusula “select”
e as demais.
Recapitulando: se o usuário informou somente um valor para o argumento “nome”, então um objeto
transiente PlcArgVO, contendo a propriedade, operador e valor informado são enviados como argumento,
para que a camada Modelo/Persistência faça o restante do serviço.
Após entender esta mecânica, concluímos que precisaremos programar apenas, na camada Controle, a
conversão do valor informado para o argumento transiente “idade”, informado pelo usuário, para o
argumento reconhecido, “dataNascimento”.
*
Com um bom uso da camada Bridge para especialização nos leiautes universais, estas taxas podem subir para 80% a 100% dos
casos!
†
Não precisamos, neste capítulo, saber como isso acontece, em detalhes. Veremos detalhes no capítulo 16.
234
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
2. No jCompany, cada um destes métodos de controle contém programações genéricas que variam
em conformidade com os metadados definidos para as Colaborações, concebidos para diferenciações
típicas (programação declarativa).
O método principal chama outros, vazios, destinados a “programação por exceção”, em classes
descendentes.
/**
* 1. Método de Controle com programações generalizadas
*/
public String metodoControle() throws PlcException {
// 2
metodoControleAntes(<argumentos>);
/*
* 7. Métodos vazios para especializações.
*/
public void metodoControleAntes(<argumentos>) throws PlcException {
// Vazio
}
public void metodoControleApi(<argumentos>)throws PlcException {
// Vazio
}
public String metodoControleApos(<argumentos>)throws PlcException {
// 8
return “mesmaPagina”;
}
#2. Chamada a um primeiro método “de extensão”. Quando é chamado antes das programações
genéricas principais, ele é batizado com a convenção “[nome do método principal]Antes”.
#4. Chamada a um segundo método “de extensão”. Se for necessário um ponto de extensão no
meio do algoritmo genérico, ele é batizado com a convenção “[nome do método
principal]Api”. Note que este tipo de método é opcional – nem sempre é necessário, em
todos os métodos de controle.
#6. Chamada a um terceiro método “de extensão”. Quando é chamado após as programações
genéricas principais, ele é batizado com a convenção “[nome do método principal]Apos".
Obs.: Este último método, no caso da camada Controle, irá devolver uma String que define o
fluxo de apresentação para a interação corrente, segundo a arquitetura de controle do JSF
(idem para Struts). Esta String identifica uma nova visão para apresentação, definida no
arquivo “faces-config.xml” (ou “struts-config.xml)*. Nas Colaborações padrões do jCompany, a
maior parte das ações mantêm o usuário na mesma página (String “mesmaPagina”). Mas o
*
Para aprofundamento nesta área, pode ser necessário um estudo do funcionamento básico de fluxo de controle destes frameworks,
para quem não os conhece.
235
Capítulo B8
desenvolvedor pode especializar este método e alterar o seu “fluxo de execução”, mudando o
valor de retorno.
#8. O método “Apos" possui apenas o desvio padrão de fluxo, sem nenhuma outra implementação.
Deste modo, pode ser especializado sem risco de sobreposição dos algoritmos genéricos.
Mas como são concebidos os argumentos e pontos exatos de extensão, dos Template Methods? Em seu
livro “Test Driven-Design” [Beck, Kent 2003], Kent Beck, um dos maiores desenvolvedores de software
da atualidade, explica assim esta questão:
“Um Template Method é mais bem identificado através da experiência do que projetado
antecipadamente. Toda vez que digo para mim mesmo: ‘Ah, esta é a seqüência e aqui estão os
seus detalhes’, eu sempre me pego depois copiando o código para métodos descendentes e
tornando a extrair as partes verdadeiramente variáveis.”
Ref. B8.1. Kent Beck em “Test Driven-Design”. Págs. 170 e 171.
Assim, note que esta é uma questão que evolui com a experimentação, com a exploração
prática.
Quando surgem necessidades em pontos chave de algoritmos que ainda não possuem “pontos de
extensão”, os desenvolvedores ainda podem sobrepor o método principal, de visibilidade “public”,
eventualmente copiando seu conteúdo para o descendente e modificando-o. Feito como exceção, isto não
é nada demais, mas se houver uma necessidade recorrente, possivelmente é o caso de se criar
um novo método de extensão – e é assim que eles vem sendo criados pela Powerlogic,
mediante identificação de demandas de uso.
2. Vamos agora utilizar algumas funções do Eclipse que nos apoiarão na descoberta dos “Template
Methods”. Posicione no corpo da classe e acione “Clique-Direito -> Source -> Override/Implement
Methods...”.
*
Como se fossem abstratos. Na verdade, a classe PlcBaseJsfAction somente não é definida como abstrata porque pode atender de
forma direta a 80% dos casos de controle.
236
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
3. Após acionar a opção, toda a hierarquia ancestral será exibida, sendo que os métodos com
implementação serão facilmente identificáveis por terem a visibilidade “public”, exibidos com
“bolinhas em cor verde”.
#2. São os métodos para extensão, vazios e com sufixo padrão, para programações de
diferenciação.
#3. Outros métodos com prefixo igual ao do principal podem existir, mas se não possuem os
sufixos padrões é porque foram criados para maior coesão de determinados trechos do
algoritmo principal. .
237
Capítulo B8
Figura B8.54. Método de extensão da Classe de Controle, conforme gerado pelo Eclipse.
#2. Perceba que, no caso deste método, deve-se retornar como resultado uma coleção de objetos
“List<PlcArgVO>”. Cada PlcArgVO encapsula um argumento declarado para a lógica. Pode-se,
portanto, alterar esta coleção programaticamente, para obtenção de comportamento dinâmico
ou quaisquer exceções ao algoritmo padrão, como é o nosso caso.
#4. Uma lista pré-montada com POJOs contendo argumentos é passada como argumento,
facilitando nosso trabalho*. Podemos utilizá-la como base, apenas realizando nossos ajustes.
#5. O método vem com chamada ao método ancestral, que retorna o conteúdo da coleção, sem
interferências.
5. Vamos finalmente implementar o nosso algoritmo, atentos aqui a uma boa prática: devemos evitar a
implementação de nossas regras, logo nos “métodos de extensão”. Isso tende a diminuir o
encapsulamento e depreciar a qualidade do código, ao longo do tempo, na medida em que surgirem
outras possíveis implementações, para o mesmo método.
Troque, portanto, a chamada ao ancestral pela chamada a outro método (que ainda não existe),
com nome de “modificaIdadeParaDatas”. Este novo método receberá a coleção de PlcArgVO e a
devolverá, modificada.
6. Perceba que ocorrerá um erro imediatamente após digitarmos o nome do novo método, pois este
ainda não existe. Mas podemos utilizar, neste momento, um outro recurso bastante interessante do
Eclipse, o “Quick Fix”, exibido na Figura B8.55.
Figura B8.55. Alteração de chamada para novo método, ainda não existente, e acionamento do “Quick Fix” do
Eclipse.
*
Perceba que, apesar de ser o primeiro método de extensão do Template Method “pesquisa”, algum processamento genérico já o
precedeu. Portanto, as chamadas aos métodos com sufixo “Antes” não são necessariamente “antes de se executar qualquer outra
coisa”, mas “antes de se executar o algoritmo principal”, que neste caso é a chamada à camada Modelo/Persistência, para recuperação
da lista segundo os argumentos informados.
Como dissemos, a concepção dos pontos de extensão é feita experimentalmente. Em um caso típico de “pesquisa”, quase nenhuma
utilidade prática teria um método antes do momento da montagem dos argumentos.
238
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
#2. Em seguida, clique no ícone de erro, à esquerda da linha com problemas, para acionar o “Quick
Fix” (Acerto Rápido) do Eclipse.
#3. O Eclipse exibirá uma quantidade de ações corretivas que consegue inferir, dentre elas a ação
que desejamos, “Create method ‘modificaIdadeParaDatas (...)’”.
#4. Perceba que, no balão amarelo para nossa opção, uma imagem do método que será produzido
é exibida em negrito, para conferência.
Basta digitar enter ou clicar na nossa opção para disparar a criação do método, que aparecerá
como na Figura B8.56.
#2. O tratamento generalizado de exceções será discutido em próximos capítulos. Por enquanto,
lembre-se de incluir a cláusula “throws PlcException”, conforme a figura.
#3. Não codifique a varredura pela coleção na mão. Digite “for + Control+Space” para opções do
Eclipse, que já reconhecem a única coleção em escopo e geram o trecho de laço (loop).
Somente tivemos que incluir “<PlcArgVO>” no “Iterator”, para evitar um “casting" logo abaixo,
pois esta é a forma mais elegante de se fazer, em Java 5.
Importante: Note que o jCompany não irá montar um “PlcArgVO”, para argumentos não
informados.
239
Capítulo B8
#5. Troca dos nomes das propriedades de argumento: Nesta linha, trocamos a raiz do nome
dos dois argumentos (ArgINI e ArgFIM), de “idade” para “dataNascimento”†.
#6. Troca dos valores informados para os argumentos: A implementação da substituição dos
valores em si nos é extremamente facilitada por utilitários de ajuda para datas, disponível em
“PlcDateHelper”. Na prática, o desenvolvedor poderia utilizar qualquer biblioteca de utilitários
para “datas” que lhe conviesse, mas o jCompany traz um conjunto de funções úteis em
“PlcDateHelper”‡.
#7. Troca dos tipos da propriedade de argumento: O Precisamos dizer, em cada PlcArgVO,
qual é o tipo do argumento encapsulado. No nosso caso, uma data. Ela poderia ser incluída
como String diretamente (“DATE”), mas da forma realizada, através da Enumeração, é mais
seguro e elegante. Lembre-se de acionar “Control+Shift+O” (letra O), para importar
referências.
Isso encerra nossa primeira “programação por exceção”, de camada Controle. Iremos explorar mais
alguns casos típicos nos tutoriais do módulo B, mas o módulo E está voltado para explicações
arquiteturais mais profundas, nesta área.
*
O pacote da classe “NumberUtils” utilizado é “org.apache.commons.lang.math”. Existe outra opção em “org.apache.commons.lang”,
mas a primeira é mais atual e deve ser selecionada.
†
Lembre-se que o primeiro argumento de “replaceAll” é uma “expressão regular”. Em nosso caso não faz diferença, mas é um
problema recorrente quando realizamos trocas de cadeias de String mais complexas. Poderíamos usar “StringUtils.replace”, também
das bibliotecas “Commons” do Apache, como alternativa.
‡
PlcDateHelper, assim como todas as bibliotecas de utilitários, são “stateless” e usam o DP de Criação Singleton (GoF). Sua “única
instancia em memória” deve ser obtida com o método “PlcDateHelper.getInstance()”.Além de códigos “arquiteturais” do framework, em
muitas situações de programação em granularidade mais fina, precisaremos reutilizar códigos “de bibliotecas de utilitários”.
Note que o jCompany vem com algumas classes de utilitários próprias, sempre disponíveis como Singleton, iniciadas com “Plc” e
terminadas com “Helper”. Ex.: “PlcDateHelper”, “PlcCacheHelper”, “PlcAnotacaoHelper” e assim por diante. Pode-se pesquisar por todas
utilizando-se “Control+Shift+T” no Eclipse e digitando-se “Plc*Helper”.
Mas o jCompany traz, homologadas, diversas bibliotecas de utilitários do mercado, sendo a principal delas o Apache Commons. O
Apache Commons vem com classes tipicamente contendo métodos estáticos e sufixo padrão terminado em “Utils”, tais como
“NumberUtils”, “StringUtils”, “DateUtils”, “BeanUtils”, “CollectionUtils”, etc.
240
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
A Figura B8.58 explica as novidades nos metadados comuns, para a Colaboração de Manutenção.
Já apresentamos a maioria das anotações deste arquivo no Caso de Uso anterior. As diferenças
importantes estão numeradas.
#1. O padrão da Colaboração agora é “MESTRE_DETALHE” (nos estereótipos de modelagem,
usamos “plcMestreDetalhe”), e alteramos a complexidade deste nosso Caso de Uso para
“MEDIA” (muito embora este segundo seja meramente cadastral, sem influencia sobre nenhum
comportamento).
#2. Se a propriedade que representa uma classe do tipo “Componente” não tiver a nomenclatura
padrão (o mesmo nome da classe com inicial minúscula), seu nome deve ser declarado em
“propriedade”. O mesmo padrão é exigido para associações “um-para-um”. Neste caso,
tivemos então que explicitar o nome “enderecoResidencia”.
#3. Cada classe do tipo “Detalhe” que pertencente ao grafo de classes utilizado pela Colaboração é
declarada, com propriedades que definem preferências para sua manipulação, geradas em
conformidade com opções que informamos nas telas do Assistente de Criação. Para modificar
alguma opção após a geração, portanto, basta editá-las diretamente neste arquivo*.
2. Em seguida gere os métodos “getter” e “setter” pelo Eclipse, e informe um mapeamento padrão
@Column, conforme a Figura B8.59.
*
Uma expectativa comum em iniciantes em jCompany é esperar muito dos plugins de criação do jCompany IDE (eventualmente, que
funcionem como editores genéricos, também para manutenção). Porém, com o tempo e prática, percebe-se que também é bem
produtivo editar metadados e arquivos diretamente, o que oferece uma flexibilidade impossível de se obter, com Assistentes de
Criação. Portanto, não utilize os geradores de código em excesso – os melhores resultados advém da compreensão mais profunda da
arquitetura do jCompany FS Framework e de seus metadados.
241
Capítulo B8
Perceba que o nome “sitHistoricoPlc” é fortemente estabelecido pelo jCompany. Pode-se variar
o nome da coluna no SGBD-R (no exemplo, foi usado “SITUACAO”), mas não este nome*. Esta é
uma boa prática, que padroniza esta nomenclatura de modo que projetistas e desenvolvedores
logo reconheçam uma classe com estas variações padronizadas de ciclo de vida.
Os valores padrões que esta propriedade pode possuir são gerenciados pelo framework, e podem
ser:
“A” – Ativo
“I” – Inativo (excluído logicamente)
Obs. 1: O sufixo “Plc” é reservado para diferenciar propriedades como padrão da arquitetura de
base (um nível acima de abstração).
Obs. 2: Normalmente, não é necessária a criação desta propriedade nas demais classes de uma
Agregação, já que uma Agregação deve ser sempre recuperada a partir de sua classe Raiz/Mestre
(usando junções com a raiz, se preciso for).
3. Para finalizar nosso Caso de Uso, temos também que ajustar a NamedQuery declarada para
“seleção”, nomeada com sufixo padrão “querySel”, e disponível em “FuncionarioEntity”. Esta
modificação garantirá que somente funcionários com situação “Ativo” sejam visíveis para o usuário.
Figura B8.60. Named Query utilizada para “Seleção”, alterada para trazer somente “Ativos”.
*
Na verdade, é até possível, mas não desejável.
242
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
Faça isso, utilizando a opção “Liberação Rápida para Tomcat com Reinicio”, ou clicando ao final do
Assistente Cheat-Sheet.
2. Autentique-se na aplicação (admin – senha), e acesse a opção “Área de TI -> Esquema DDL –
Geração”
Novamente, o jCompany irá exibir o esquema DDL necessário para “sincronizarmos” nosso mapeamento
com o esquema atual do SGBD, contendo somente as diferenças que produzimos, com os novos
mapeamentos realizados para o Caso de Uso “UC002 Manter Funcionário!“.
Desta vez a complexidade da DDL gerada é bem maior que das anteriores. Teremos, inclusive, que
efetuar alguns ajustes no esquema gerado, antes de submetê-lo com sucesso.
4. Um primeiro ajuste é remover todas as restrições (“check constraint”) que se referem a
“current_date”.
Figura B8.62. Esquema de DDL produzido a partir do mapeamento da nova Agregação Mestre-Detalhe.
*
É possível que o padrão gerado funcione para outros SGBDs.
243
Capítulo B8
Obs.: Perceba que uma restrição similar, para a coluna “SALARIO”, também foi gerada. Mas neste
caso a sintaxe é válida, e pode ser mantida se desejado.
Figura B8.63. Somente a restrição em DATA_INICIO foi removida. A de salário pode ser mantida.
Já existe uma FK com este nome, criada no capítulo anterior, entre a tabela
“UNIDADE_ORGANIZACIONAL” e “UF”. Ao se tentar submeter este esquema, uma mensagem será
exibida, como na Figura B8.64.
Figura B8.64. Foreign Key declaradas em Componentes exigem ajuste nos nomes, em nível de DDL.
A geração deste nome idêntico deve-se ao fato de termos reutilizado o Componente “Endereco”
tanto para “UnidadeOrganizacional” quanto para “Funcionario”. Como a associação com declaração
do nome da FK (“@ForeignKey”) fica dentro do Componente, ocorre a colisão.
O JPA possui uma anotação que permite a modificar nomes de colunas, em classes que reusam
Componentes, chamada “@AttributeOverride”. Mas ainda não possui para nomes de FK, como é o
nosso caso.
Uma outra saída seria simplesmente eliminarmos a definição do nome, mas deste modo apenas
trocaríamos de problema: as FKs passariam a ser identificadas através de um número de “hash”,
não significativo.
Por hora, vamos apenas alterar o nome neste diálogo, para FK_FUNCIONARIO_UF, antes de
submeter a DDL. Esta mudança de nome não traz efeitos colaterais*.
6. Após fazer os dois ajustes, clique em “Executar Esquema” para efetuar as modificações no SGBD. Se
receber uma mensagem de confirmação, torne a clicar em “Gerar Esquema”, para conferir o que foi
submetido.
Importante: Desta vez, como mostra a Figura B8.65, em lugar de um esquema vazio será gerada
*
Esta situação não costuma ser um problema muito grande, para o estágio atual da maior parte das empresas, que ainda produzem o
esquema DDL inteiramente na mão (Infelizmente, por vezes, antes da Modelagem de Classes!).
244
Implementando o Padrão "Manter Agregação Mestre/Detalhe"
apenas uma cláusula, sugerindo a criação da FK novamente, com o nome duplicado. Desprezaremos
este caso, daqui para a frente.
Não iremos testar a aplicação ainda. Vamos prosseguir para o próximo capítulo, para codificar a parte de
arquivo anexado, antes disso.
245
Capítulo B8
Sumário
Neste capítulo, fizemos o desenvolvimento parcial de nosso terceiro Caso de Uso “UC002 Manter
Funcionário!“, utilizando o padrão “Manter Agregação Mestre/Detalhe”, a extensão padrão “Assistente” e
a inclusão “Exclusão Lógica”.
Pela primeira vez, fomos introduzidos a três requisitos que exigiram programação procedimental em
Java, para duas regras de restrição invariáveis, em nível de Domínio, e para uma regra da camada
Controle, para transformar argumentos de “idade” em “datas” dinamicamente.
Existem dois pontos centrais importantes, discutidos neste capítulo:
o O jCompany IDE não elimina a necessidade de programação Java, e nem defende esta tese como
viável. Simplesmente, diminui a maior parte do código repetitivo (boiler-plate) de nossas aplicações
de negócio, fatorando estes códigos via OO, programação declarativa e Design Patterns. Isso deixa
nossas classes específicas não somente mais enxutas, padronizadas e fáceis de manter, como
também menos suscetíveis a ciladas de programação: “menos código = menos erros”.
o Apesar de não “gerar códigos procedimentais específicos” (o que seria possível com uma estratégia
MDA complementar, por exemplo), o jCompany apóia decisivamente uma boa codificação OO,
indicando caminhos em sua Metodologia de Construção, que se manifestam como “Padrões de
Solução”, roteiros e documentação geral.
Do ponto de vista de produtividade, um desenvolvedor experiente deve levar em torno de 3 (três) horas
para produzir um resultado de implementação de Caso de Uso do tamanho exposto neste capítulo,
incluindo testes.
No próximo capítulo, iremos fechar o Caso de Uso com a parte do Arquivo Foto.
246
9
Capítulo
Implementando a Inclusão
9
B
- Introdução
No capítulo anterior, implementamos a manutenção de toda a Agregação de Funcionário, representada
na Figura B9.1, com exceção da classe “Foto”. Iremos tratá-la separadamente, porque possui
características especiais que o justificam.
Figura B9.1. Grafo do Modelo de Domínio. Faltando apenas a parte da classe Foto, com estereótipo
“arquivoAnexado”.
Neste capítulo, iremos conhecer e implementar a “Inclusão Padrão de Arquivo Anexado”, sugerida e
automatizada, em grande parte, pelo jCompany.
São algumas características deste padrão:
1. (Otimização) Evita usar mapeamentos “manyToOne” para classes com estereótipo
“arquivoAnexado”, que podem causar downloads não desejáveis, “invisíveis” ao desenvolvedor.
2. (Otimização) Provê um ajuste dinâmico de declaração do formulário HTML, para que funcione como
“multipart” apenas no momento do uploads, e como “text/plain” nos demais momentos. O uso
inapropriado de “multipart” degrada considerável a performance de transmissão e
recepção dos dados de formulários.
247
Capítulo B9
3. (Usabilidade) Provê componente visual padrão para upload/download, que permite também a
exclusão do arquivo, de forma independente do restante do documento.
4. (Robustez) Provê gravação do arquivo na mesma transação JPA dos dados da Agregação. Qualquer
exceção na gravação dos dados da classe Raiz/Mestre ou Detalhe irá implicar em “rollback” de todas
as informações*.
#2. A cláusula “@SequenceGenerator” deve ser mantida exatamente como no exemplo, com nome
“SE_ARQUIVO_PLC”, para evitar incompatibilidades com a herança de mapeamentos†.
Isto porque o ancestral traz mapeado o Object-Id com este mesmo valor em “generator”,
Ambos devem ser iguais. Exemplo:
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator = "SE_ARQUIVO_PLC")
@Column (name = "ID")
public Long getId() {
return id;
}
Vamos entender um pouco mais sobre a herança de classes pré-mapeadas, antes de prosseguir.
*
Obs.: Muito embora seja interessante, este recurso pode tornar as Unidades Lógicas de Transação do SGBD mais longas, devido ao
tempo de se gravar conteúdos de maior tamanho. Isso pode ser crítico se há alto índice de concorrência na manipulação dos dados da
Agregação, mas costuma ser aceitável na maior parte dos casos. Veremos mais sobre otimizações diversas em capítulos específicos
†
Se for compulsório trocar o nome do Sequence, então deve-se especializar também o mapeamento do “getter” para esta classe, e
trocá-lo em conformidade com o “@SequenceGenerator”.
248
Implementando a Inclusão Padrão "Arquivo Anexado"
3. Acione “Control+Clique” sobre o nome “PlcBaseMapArquivo”. Desta forma, será aberto o código
fonte desta classe, para conferirmos o que estamos herdando (graças ao mundo Open-Source):
Figura B9.3. Classe ancestral com mapeamentos padrões para arquivos anexados.
#1. As propriedades em si são ainda definidas em um outro ancestral, que não contém
mapeamentos e é mantido assim para compatibilidades com versões anteriores ao JPA.
#2. Perceba que esta classe possui mapeamentos em “getters”, e valores de generator definidos
para a propriedade “id”.
#4. Na propriedade “nome”, o jCompany irá registrar o nome do arquivo, como existia no
momento do upload.
#5. Na propriedade “imagem”, o jCompany irá registrar o conteúdo do arquivo em si, como um
“Blob” (Binary Large Object), formato relacional mapeado como “@Lob” no padrão JPA.
#6. Na propriedade “tipo”, o jCompany irá registrar o “MimeType” do arquivo, obtendo-o através
de seu sufixo. É importante armazenar este tipo separadamente, para facilitar manipulações
(como explicitação de tipo em cabeçalhos HTTP, para download).
4. Após finalizar o entendimento, faça alguns pequenos ajustes na classe Raiz Funcionário, para que
referencie corretamente este arquivo, conforme a Figura B9.4.
249
Capítulo B9
#1. Comente o relacionamento manyToOne (já sem o getFoto e setFoto, removidos no capítulo
anterior), e torne-o “deprecated”.
#3. Além de termos removido o “getFoto” e “setFoto” no capítulo anterior, inclua as cláusulas de
mapeamento “insertable=false” e “updatable=false”, para finalizar.
250
Implementando a Inclusão Padrão "Arquivo Anexado"
2. Declare o uso da Tag-Lib (Biblioteca de Tags) do Tiles, conforme ilustrado na Figura B9.6.
3. Após importar as Tag-Libs do Tiles, utilize a Tag “insert” para incluir uma definição, ao final da JSP,
como na Figura B9.7.
Lembre-se de copiar também o teste do passo do Assistente, para que a exibição do arquivo
anexado somente apareça, em modo de Assistente, no passo 4.
4. Defina rótulos (dois) para o componente, no arquivo “ApplicationResources.properties”. Para isso, é
importante entender a sua ergonomia.
Este componente visual aparece em três “estados”, exigindo dois rótulos em um padrão
determinado:
o Estado Inativo - quando não há arquivo anexado: Apenas apresenta um botão para
mudança de “modo”, mantendo o formulário principal com ‘encType=”text/plain”’. Exemplo
para uma Colaboração com nome “funcionarioman”:
Figura B9.9. Campo que permite upload (com form HTML em multipart).
251
Capítulo B9
Figura B9.12. Declaração de “componenteVisualFinal”, para inserir componente Tiles ou JSP ao final do leiaute.
3. Será preciso, para finalizar esta segunda alternativa, incluir o título para a nova aba de Tab-Folder,
com rótulo “def.componente.arquivo.ancestral.jsf.titulo.tab” no arquivo
“ApplicationResources.properties”.
2. Declare a classe “FotoEntity” no grafo controlado pelo jCompany, conforme a Figura B9.13.
Figura B9.13. Classe de arquivo declarada com estereótipo especial, no Grafo de Classes.
252
Implementando a Inclusão Padrão "Arquivo Anexado"
Dica: Ao digitar uma nova anotação nos arquivos de metadados, no Eclipse, pode-se precisar, em
algumas circunstancias, utilizar “Control+Shift+O” duas vezes, para atualizar as importações
corretamente. Isso é ocasionado por conta da característica especial destes arquivos, que exige as
anotações acima da declaração de pacote e da importações.
Figura B9.14. Problema conhecido que exige reinício em desenvolvimento, após certo número de liberações.
Este é um problema clássico na lista do Tomcat. Após uma liberação “a quente” (hot-deploy), sem parada
do servidor, em alguns casos o Tomcat/JVM não consegue liberar toda a área de memória de código
(PermGen), ocorrendo um “leak” (perda de memória que não retorna) a cada liberação. Em nossa
experiência, de cerca de 5 a 10 MBytes, por “hot-deploy”.
Em tempo de desenvolvimento, o jCompany já configura o Tomcat com um aumento na área de PermGen
para 128MBytes, conforme ilustra a Figura B9.15, o que deve permitir cerca de 10 (dez) ou mais
liberações, sem que seja preciso reiniciar o Tomcat*.
Ao receber esta mensagem, simplesmente pare o Tomcat e em seguida o reinicie. A parada pode ser
realizada através do botão vermelho na janela de Console ou do ícone na barra de ferramentas, indicados
na Figura B9.16.
*
Este é um problema na área de caching de código (JSPs, Singletons, etc.), e não traz nenhum risco para a área de dados da
aplicação, a memória HEAP (o que seria mais preocupante). Mas se pretender usar o Tomcat em produção, consulte um especialista,
que poderá dar sugestões de contorno para esta situação.
253
Capítulo B9
2. Acesse novamente a opção “Área de TI -> Esquema DDL – Geração”. Em seguida selecione
“Atualização” na lista “Tipo de Esquema” e clique em “Gerar Esquema”.
Agora o jCompany irá exibir o esquema DDL necessário para “sincronizarmos” nosso mapeamento,
tendo como novidades o uso do tipo “blob” e da cláusula “Alter Table”, para acrescentar nova
coluna a “FUNCIONARIO”. Veja em destaque na Figura B9.17.
254
Implementando a Inclusão Padrão "Arquivo Anexado"
Sumário
Neste capítulo, desenvolvemos a Inclusão Padrão “UC002.2 Anexar Foto”, o que finaliza a implementação
do nosso terceiro Caso de Uso “UC002 Manter Funcionário!“.
Discutimos peculiaridades importantes a respeito de manipulação de arquivos e implementamos um
primeiro caso de herança total do mapeamento Objeto-Relacional e de reúso de componente Tiles, com
algumas variações.
No próximo capítulo, iremos testar tudo o que desenvolvemos neste e no capítulo anterior, explicando em
detalhes as características de usabilidade que produzimos para a manutenção de Funcionários.
255
Capítulo B9
256
Capítulo
10
Testando e Aprimorando
0
1
B
A o clicarmos na opção “Menu Inicial -> Funcionário” do menu da nossa aplicação “rhtutorial”, iremos
cair inicialmente, desta vez, na página de seleção, uma vez que alteramos a URL da chamada de menu,
conforme especificado.
Figura B10.1. Página de Seleção, como entrada para “UC002 Manter Funcionário!”.
Figura B10.2. Página de manutenção. Aba principal com dados da classe Raiz.
#2. O Leiaute Universal já oferece uma organização padrão em Abas, conforme o “corte de
componentes que fizemos”.
#3. Um primeiro campo para entrada de datas é exibido (não tivemos datas nos Casos de Uso
anteriores). Podemos conferir que ele já oferece Javascript com máscaras e barras automáticas
(no padrão dd/MM/yyyy) e calendário para seleção Popup.
#4. Um primeiro campo do tipo “Lista de Valores” (Combo Estático), com domínio baseado na
Enumeração “EstadoCivil” também é exibido, similar ao dinâmico que exibimos anteriormente,
para “Uf”.
257
Capítulo B10
#5. Um primeiro campo do tipo “Botões de Rádio” (Radio Button) também aparece, utilizando como
domínio a Enumeração “Sexo”.
#7. Um primeiro campo do tipo “Área”, com três linhas disponíveis para preenchimento, conforme
especificado.
#8. Finalmente, vemos também um botão do componente de arquivo anexado, que permite ao
usuário comutar para o “modo de anexar arquivos” é exibido, na posição da página em que o
incluímos.
Perceba que agora nossos “componentes de leiaute” foram organizados dentro de Abas de um Tab-
Folder renderizado pelo Leiaute Universal, que permite comutação entre as abas via DHTML, ou
seja, dispensando transmissão ao servidor.
2. Experimente comutar as abas com o mouse. Em seguida utilize “Control+Seta para Direita” e
“Control+Seta para Esquerda”. Ao fazer isso, confira como os componentes foram organizados.
Veja, por exemplo, que os dados do Componente “Endereco” ficaram em uma Aba própria, assim
como cada Detalhe.
3. Note também que cada Detalhe iniciou com o número de registros que estipulamos.
Figura B10.4. Aba do Detalhe “Dependente”, iniciada com dois objetos, como solicitado.
4. Com a aba de “Dependentes” selecionada, como na figura anterior, preencha “Dependente Teste” no
primeiro nome e em seguida clique no botão “F7-Novo”. O resultado deve aparecer como na Figura
B10.5.
Figura B10.5. Aba do Detalhe “Dependente”, com mais itens para preenchimento, após clique em F7-Novo.
Perceba que um novo bloco com dois de objetos foi adicionado à lista inicial. O usuário pode clicar
indefinidamente em “F7-Novo”, para criar mais linhas em branco para preenchimento, mas o ideal
é que o Projetista preveja um número que evite isso, suficiente para a maior parte dos casos.
Mas aqui há um outro ponto chave, que deve também ser entendido: O botão “F7-Novo” tem
funcionamento sensível ao contexto:
o Quando o foco está na parte principal do formulário (Raiz/Mestre/Componente), seu
funcionamento é de “inicializar a Agregação, apresentando um novo formulário em branco”.
o Quando o foco está nos Detalhes, ele simplesmente cria mais linhas para entrada de dados
neste Detalhe, como acabamos de ver.
258
Testando e Aprimorando Interfaces com o Usuário
Como comprovação deste funcionamento, experimente clicar em alguma das Abas principais,
“Funcionário” ou “Endereco”, e em seguida em “F7-Novo”. Veja que o valor “Dependente Teste”
antes informado, desta vez será limpo, uma vez que todo o formulário foi reiniciado.
Figura B10.6. Formulário de manutenção, com partes modificadas em amarelo e após tentativa de gravação.
Para eliminar este problema, um valor inicial “false” sempre é assumido pelo jCompany (caso true
não tenha sido explicitamente informado), para garantir que o componente sempre “aparenta” o
que é de verdade – neste caso, uma indicação de que o Funcionário não tem curso superior
(false ou ‘N”, no SGBD).
Apesar desta ajuda, é recomendável que o valor padrão de propriedades Boolean seja sempre
explicitamente definido pelo Projetista – pelo menos para aquelas que não aceitem nulos e
vão ser utilizadas em “Caixas de Marcação”. Isso não é uma obrigatoriedade, mas uma
manifestação de que o Projetista tem consciência deste problema.
*
Existem caixas deste tipo que apresentam três estados, mas esta variação não é muito recomendada, pois não é intuitiva e nem
padronizada.
259
Capítulo B10
Figura B10.7. Inicialização explicita e em tempo de modelagem, para propriedades com tipo Boolean
2. Vamos agora incrementar um pouco mais o nosso teste de verificação das validações de entrada de
dados (Restrições), digitando somente o nome de dois Dependentes (sem informar o sexo) e dados
de Histórico Profissional, conforme destaque na Figura B10.8. Preencha e, em seguida, grave com
F12.
Figura B10.8. Erros de toda a Agregação exibidos em conjunto, de uma única vez.
Veja que a mensagem não está apropriada – ela deve ser trocada. Se desejar fazer agora, corte
parte da mensagem e procure-a com “Control+F” no arquivo “ApplicationResources.properties”. Em
seguida redefina seu texto como, por exemplo: “Um funcionário pode ter no máximo dois
dependentes”.
2. Agora apague o nome do terceiro Dependente (como sabemos, toda a linha será desprezada) e
retire a marca de “Tem Curso Superior”, se estiver marcado. Em seguida, tente gravar. Desta vez, a
“multiplicidade” entre Funcionário e Histórico Profissional será averiguada, conforme a Figura
B10.10.
260
Testando e Aprimorando Interfaces com o Usuário
Figura B10.10. Validação das regras invariáveis, anotadas e programadas, ocorrem antes da multiplicidade (1..*)
Troque também esta mensagem, para “Um funcionário deve possuir pelo menos um registro
de Histórico Profissional”, seguindo a mesma dica anterior.
Uma boa idéia, então, é aprimorar nossa explicação para o usuário. Simplesmente troque a
mensagem para “Funcionário com curso superior deve possuir pelo menos um histórico
profissional, e seu salário atual não pode ser inferior a R$ 1.000,00”.
2. Já vimos que, se não há nenhum registro de histórico profissional informado, nossa regra de salário
funciona. Mas vamos tentar com novos cenários. Tente inserir um item no histórico profissional com
salário menor de R$ 999,99. A mesma mensagem da Figura B10.11 deve aparecer.
Figura B10.11. Validação codificada de piso salarial para quem tem curso superior.
3. Agora tente incluir um funcionário com data de nascimento próxima da atual e gravar.
261
Capítulo B10
Porém, agora um novo formulário é apresentado após a gravação, devido ao uso da opção “Entrada
em Lote”, utilizada para este Caso de Uso. Esta opção é útil quando não se julga necessário conferir
dados após a gravação e a digitação é realizada em grande volume, no que chamamos de “entrada
de dados em lote ou massiva”.
2. Digite novamente os dados, informando o nome, data, CPF e e-mail, utilizando tabulação
apenas.
3. Em “Estado Civil”, digite a primeira letra do estado civil desejado, para selecionar sem um valor sem
o mouse.
4. Em “Sexo”, utilize as seta “para cima e para baixo”, para comutar de valor entre masculino e
feminino.
262
Testando e Aprimorando Interfaces com o Usuário
#1. Aperte “seta para baixo”. Em campos de vínculo, esta tecla abre o diálogo Popup para seleção.
#2. Se quiser preencher algum argumento, como iniciais da Unidade Organizacional, faça-o,
lembrando de não usar o mouse. Em seguida aperte F9 para disparar a pesquisa.
#3. Após a o resultado ter retornado, percorra a lista com as “setas para baixo e para cima”,
apertando “enter” para selecionar a linha desejada. Os valores necessários são então copiados
para o formulário principal, “vinculando” este a uma Unidade Organizacional específica.
6. Prossiga para o campo de “Observação”, informando valores em pelo menos duas linhas. Ao tabular
neste que é o último campo da Aba de Funcionário, note que a segunda Aba de Tab-Folder será
selecionada automaticamente; e que o primeiro campo da próxima Aba receberá o foco.
Este comportamento é fundamental para operações de entrada de dados em lote que usam leiaute
de Tab-Folder.
Como funciona? Ele é implementado através da chamada à função Javascript “comutaAba”,
chamada esta gerada na propriedade “aoSair” do componente “tabela”, de cada JSP de
manutenção.
#1. O primeiro argumento é o número da aba, iniciando em zero. Portanto, 1 (um) indica a
próxima Aba com relação à Aba de “Funcionário”.
#2. O segundo argumento é o identificador em HTML do primeiro campo da próxima aba, para
possibilitar que o jCompany force o foco para ele, após a comutação automática da Aba -
deste modo evitando tabulações excessivas ou acesso ao mouse*.
Obs.: Os nomes são identificados com o prefixo “corpo”, no padrão “corpo:[id do campo]”.
Quando a próxima JSP (da próxima Aba) for de Detalhe, o nome do campo para foco segue uma
convenção um pouco diferente:
“corpo:[nome da propriedade de detalhe]:[índice (0)]:[id no campo]”
*
Desenvolvedores acostumados ao desenvolvimento Cliente/Servidor podem achar um tanto quanto estranho este esforço, pois muitos
ambientes de GUI desktop já liberam este resultando, como padrão. Até por este motivo é comum, em desenvolvimento para Web sem
o jCompany, que estes detalhes sejam esquecidos, e as interfaces terminem pouco produtivas para o usuário.
263
Capítulo B10
Apesar do jCompany gerar estas configurações através dos plugins do jCompany IDE, seu
entendimento permitirá ao desenvolvedor customizar ajustes com foco, em quaisquer variações
que se façam necessárias.
7. Preencha o formulário até o fim. Ao tabular para fora do último campo da lista do último
componente do Tab-Folder (ou seja, da última Aba, o Histórico Profissional), o modo de
“Visualização de Formulário” será automaticamente ativado, para conferência final pelo usuário,
conforme mostra a Figura B10.20.
Como funciona? O que produz esta visualização é uma chamada Javascript diferenciada, gerada
como padrão pelo jCompany IDE somente para a última JSP que compõe o formulário:
“visualizaFormulario()”.
8. Após uma conferida geral, acione F12 para a gravação. O formulário deverá voltar para o modo
padrão, com Tab-Folder, totalmente em branco e com o foco no primeiro campo da primeira Aba,
para prosseguimento do próximo cadastro.
Por este motivo, o Assistente de Entrada de Dados que produzimos nos será de grande auxílio. Ele
orientará os usuários, linha por linha, no preenchimento de todo o formulário, substituindo ou
264
Testando e Aprimorando Interfaces com o Usuário
O acionamento do Assistente aparece para os usuários como um novo botão na barra de ações. Feito
assim, em nível de arquitetura, este botão logo se torna conhecido dos usuários internos, treinados na
operação do sistema. Ao vê-lo, já sabem que este recurso está disponível para o formulário corrente. Mas
para o caso de usuários esporádicos, não treinados, o recomendado é alterar o hiperlink de
chamada à manutenção, para que ela já abra no modo Assistente.
Vamos realizar uma operação básica no Assistente, para conhecer seus recursos.
1. Clique no botão Assistente. O primeiro passo do leiaute de Assistente será exibido, conforme a
Figura B10.23.
Figura B10.23. Primeira página do leiaute de Assistente de Entrada de Dados para usuários finais.
#2. Boneco do Assistente: o jCompany traz quatro “mídias” prontas de bonecos e permite que se
declare em anotação qualquer outra mídia para aparecer neste local. (gif, jpg ou png).
#3. Texto do Assistente: parte mais importante, contendo a explicação em si. O balão se expande
conforme o tamanho do texto, que é definido no arquivo ApplicationResources em formato
HTML, portanto podendo conter negritos, parágrafos, hiperlinks e outros recursos HTML.
#6. Corte do formulário. Cada passo é apresentado, somente com a seção do formulário que
definimos com o “Corte de Assistente”.
*
O jCompany também apóia a confecção de Ajuda On-Line, trazendo padrões de uso e painéis de leiaute prontos para chamada. Mas
é um recurso complementar, que não compete com o Assistente.
265
Capítulo B10
Dissemos que os Detalhes são indivisíveis em termos do Assistente, sendo apresentados “um
Detalhe por passo”. Também não é possível para o usuário acrescentar novas linhas em branco no
Detalhe, em modo de Assistente. Se o Projetista já previu um número suficiente, isto não será
problema. Também é possível se realizar implementações de Controle que acrescentam mais linhas
no(s) Detalhe(s), antes de se entrar em modo de Assistente*.
Figura B10.25. Confirmação final aparece com todos os dados informados e botão para gravação
o Use as Tags <b> para negritos, <br> e <p> para quebras de linha e parágrafo, para formatar
melhor o texto.
Figura B10.26. Mensagens editadas no editor homologado. Markups HTML podem ser incluídos.
o Use um editor HTML do Eclipse para fazer as mensagens e depois cole o resultado no arquivo
“ApplicationResources.properties”. Esta é, na verdade, a única forma viável de se digitar
grandes mensagens, já que o editor JInto, homologado para edição do
“ApplicationResources.properties”, exibe cada mensagem em uma linha†.
*
Na prática, quando precisam, usuários internos utilizam o modo normal. Esta programação adicional somente faz sentido para
usuários esporádicos, sem treinamento.
†
Não há limitação de tamanho, apesar disso.
266
Testando e Aprimorando Interfaces com o Usuário
o Não fique limitado à geração inicial dos plugins - ajuste o número de passos, se julgar mais
apropriado. Para isso, basta alterar de posição os comandos “c:if” (para mudar cortes internos
às JSPs) e/ou, eventualmente, subdividir ou mesclar as JSPs geradas, conforme desejado. Para
alterar o número de passos em si, edite os metadados, via anotação “@PlcConfigAssistente”.
/plc/jsps/geralTopoAssistentePlc.jsp
/plc/jsps/geralTopoPassoAssistentePlc.jsp
- Utilizando o Quantum DB
Para os próximos testes que faremos, precisaremos conhecer um novo plugin homologado no jCompany
IDE: o Quantum DB. Ele nos permitirá investigar (ou alterar, se preciso for), informações diretamente
no banco de dados, qualquer que seja o SGBD utilizado†.
Investigar o conteúdo do SGBD não somente é uma boa prática em tempo de teste, como deve ser
feita juntamente com a conferência dos SQLs que estão sendo gerados pelo JPA, exibidos na
console de execução no Eclipse.
Vamos aprender a configurar o acesso para o Apache Derby, o que poderá ser feito de maneira similar,
para qualquer outro SGBD.
1. Acesse a perspectiva do Quantum DB no Eclipse, via “Window -> Open Perspective -> Other...”, e
então selecionando “Quantum DB”.
2. Com a janela de “Database Bookmarks” disponível, acrescente uma nova entrada de conexão,
conforme a Figura B10.29 e Figura B10.30‡.
*
Como veremos em capítulo específico sobre customização, basta procurar por estas páginas nos projetos do jCompany, copiá-las
para o projeto específico e alterar o seu código. Como o jCompany utiliza “cortes” finos (Tiles) em JSPs de leiautes e exterioriza a
parte decorativa para as peles (CSS), as sobreposições bem feitas habitualmente não redundam muita informação.
†
Bastando que tenha um driver JDBC disponível.
‡
No momento desta escrita, a Powerlogic planejava incluir uma pré-configuração deste bookmark automaticamente, com a instalação
do jCompany. Se você ver uma entrada com nome de “bancolocal” já criada, pode dispensar esta parte inicial do roteiro de
configuração.
267
Capítulo B10
Figura B10.30. Configurando novo Driver JDBC para Acesso ao Apache Derby.
#2. Clique, em seguida, em “Add driver...” (porque ainda não temos um Driver JDBC para Apache
Derby configurado).
#3. Clique em “Add External Jar...” e busque pelo JAR “derbyclient.jar”, no diretório
“[jcompany]/meus_projetos/jcompany_apoio/jdbc/Derby” (cópias oficiais do
jCompany*) ou “[jcompany]/servers/tomcat/lib” (cópias de avaliação). Este arquivo
contém as implementações chamadas de “driver JDBC”, para Apache Derby.
#4. Após a seleção do “derby_client.jar”, clique em “Browse...”, logo abaixo, para selecionar a
classe de implementação em si. Uma única opção irá aparecer e deverá ser selecionada. Clique
então em “Finish”.
*
O projeto “jcompany_apoio” contém uma série de bibliotecas de utilitários homologados, não utilizadas especificamente para
“construção e compilação” de projetos, mas para uso em tempo de desenvolvimento ou de produção somente, com finalidades
diversas. O diretório “jdbc” traz Drivers JDBC homologados para diversos SGBD-Rs do mercado. A homologação significa que estas são
as versões de Drivers JDBC utilizadas pela Powerlogic, ao testar a solução jCompany. Pode ser que outros Drivers também funcionem
bem, mas o uso das versões homologadas traz sempre uma dupla garantia.
268
Testando e Aprimorando Interfaces com o Usuário
Figura B10.31. Driver JDBC para Apache Derby configurado, aparecendo na lista.
3. Após a configuração do driver, vamos criar os “bookmarks” em si, que apontam para uma instância
de banco de dados específica.
Clique em “Next >”, já com o Driver JDBC selecionado, e preencha conforme a Figura B10.32.
#1. Informe usuário “APP” e senha “APP”, que são o mesmo usuário e senha configurados no
arquivo de contexto do Tomcat, que o jCompany gera juntamente com a aplicação.
#2. Informe a URL JDBC exatamente como na Figura B10.33. O nome do banco que o jCompany
configura é “bancolocal”.
4. Para finalizar a configuração, informe um nome qualquer, podendo ser o mesmo do banco de dados.
Note que este Bookmark servirá para qualquer banco ativo no momento, de qualquer projeto, não
somente para o nosso “Rh Tutorial”.
269
Capítulo B10
5. Após estes procedimentos, acione com um “Duplo Clique” a entrada que criamos em “Database
Bookmarks”. Este comando irá disparar a abertura de uma conexão direta com o SGBD, que
apresentará uma árvore como a da Figura B10.34.
#1. Relação de “owners” (esquemas de usuários), sendo apenas o “APP” o que nos interessa. Os
demais são de sistema do Apache Derby.
#2. Clicando em “APP” + “Tables”, vemos a relação de Tabelas relacionais existentes no SGBD, que
temos atualizado até aqui.
#3. Podemos expandir uma Tabela para ver suas Colunas, Primary Key, Foreign Keys, Indexes,
etc., mas ao dar um “Duplo Clique” sobre “FUNCIONARIO”, uma janela à direita exibe uma
relação com o conteúdo atual desta Tabela, que nos interessa.
#4. Na nova janela “Quantum Table View”, podemos consultar os valores de três colunas que não
tínhamos ainda conferido, pois são mantidas internamente pelo jCompany e pelo JPA.
o A estratégia de geração de Object-Id para o Derby, por não usar Sequences (como no caso do
Oracle, por exemplo) e nem “autoincrement” (como no caso de um MS SQL Server, por
exemplo), deixa saltos nos valores de ID_FUNCIONARIO. Mas como estes são valores internos,
não causam problema.
o O campo “VERSAO”, como esperado, contém um valor numérico, incrementado a cada
atualização.
o Os campos “DATA_ULT_ALTERACAO” e “USUARIO_ULT_ALTERACAO” foram preenchidos pelo
jCompany, significando que nossa “Auditoria Pauta Mínima” está funcionando.
2. Após a edição, clique em “Excluir”, e guarde o número do CPF do funcionário que está sendo
excluído.
270
Testando e Aprimorando Interfaces com o Usuário
Uma mensagem de “Registro Excluído com Sucesso” deverá aparecer, com o formulário agora em
branco, em modo de inclusão.
3. Retorne agora para a seleção, clicando novamente em “F8-Abrir -> F9-Pesquisar”. Confira se o
funcionário foi efetivamente removido - a pesquisa não deverá exibi-lo, desde que não se tenha
esquecido de alterar a “querySel” declarada em FuncionarioEntity para incluir
“sitHistoricoPlc=’A’”, como instruído.
Mas será que nosso registro teve apenas o campo situação modificado para “I” (o que queremos),
ou foi excluído fisicamente do SGBD (como não queremos)?
A única forma de termos a certeza é conferindo como anda a situação, diretamente no SGBD.
Com a conexão cliente com o Apache Derby agora disponível via Quantum DB, ficará mais fácil
investigarmos funcionamentos como o da “Exclusão Lógica”, invisível aos olhos do usuário.
4. Para conferir, busque pelo funcionário que excluímos. Ele ainda deve existir na relação de
funcionários com valor de SITUACAO = “I” (Inativo). Nos demais registros - os que estão visíveis ao
usuário - este valor deve constar como SITUACAO = “A”.
Resumindo o mecanismo: Vimos que a “Exclusão Lógica” é uma alteração que funciona como exclusão,
do ponto de vista do usuário. É um procedimento muito comum em aplicações corporativas, seja para
prover auditoria, seja para preservar associações passadas, para determinadas consultas legais; ou
mesmo para possibilitar reativações em algumas situações de negócio.
O mais interessante é que não somente padronizamos este hábito, normalmente resolvido de forma
artesanal, por cada Projetista/Desenvolvedor, em cada aplicação - como ainda o fizemos de forma
altamente produtiva, com três simples configurações:
o Declaramos a propriedade padrão “sitHistoricoPlc”;
o Incluímos uma anotação “@PlcExclusaoLogica”;
o E adicionamos um filtro na cláusula “querySel”, para não trazer inativos.
Mas vale à pena destacar que a histórica não acaba ai: o jCompany FS Framework tratará
genericamente desta questão, não somente na simulação da exclusão para usuários, mas em diversos
momentos onde a exclusão lógica deve ser considerada. Vejamos um exemplo:
5. Tente registrar um novo funcionário, utilizando o mesmo CPF do funcionário anteriormente excluído.
Será possível gravá-lo, apesar de termos declarado uma restrição de NamedQuery “naoDeveExistir”,
replicada na Figura B10.37.
Figura B10.37. Declaração “naoDeveExistir”, que não explicita o teste de exclusão lógica.
271
Capítulo B10
Note que o esperado seria um erro de “CPF já existente”. Mas se consultarmos a cláusula
SQL submetida, via janela de Console do Tomcat no Eclipse (reproduzida na Figura B10.38),
constataremos que o jCompany acrescentou a cláusula “sitHistoricoPlc=’A’” à cláusula “where” do
teste, automaticamente.
Figura B10.38. Relação de SQLs enviados para inclusão de Funcionário, sem Dependentes.
#1. Cláusula SQL de “select count(*)” para “naoDeveExistir”, com acréscimo automatizado de teste
de sitHistoricoPlc=’A’.
Importante: No caso de “querySel”, vimos que o padrão é não automatizar este teste. Tanto que,
somente neste caso, tivemos que explicitar o “sitHistoricoPlc=’A’”. O motivo para esta exceção é que
estas cláusulas costumam ser mais complexas, exigindo um tratamento mais cuidadoso por
parte do desenvolvedor. Além disso, eventualmente vai-se desejar realizar seleções sobre
objetos inativos, para reativação ou consulta apenas.
2. Após a edição, clique em “Clonar”. Confira os dados copiados – eles incluem não somente os valores
da parte Mestre do formulário, mas também de todos os Detalhes.
3. Altere alguma informação como no nome, por exemplo, e tente gravar. A mensagem de validação
de duplicidade de CPF deve ser emitida, agora corretamente (como não alteramos o CPF, estamos
tentando incluir um novo funcionário ativo, com o mesmo CPF).
272
Testando e Aprimorando Interfaces com o Usuário
4. O recurso de clonagem é útil para cadastro de informações com muita similaridade. Em nosso caso,
será também para criarmos uma boa base de testes rapidamente.
Altere o CPF (se desejado, o nome também) para um valor inexistente e grave agora com F12.
Repita este procedimento, editando um registro, utilizando a clonagem e trocando o CPF para uma
série de valores válidos e não repetidos (Ex.: ‘11111111111’, ‘22222222222’, ‘33333333333’, etc.).
Mas qual será a real utilidade da clonagem, no dia a dia dos usuários finais? Isso dependerá de três fator:
o Arquitetura de GUI (Interface com o Usuário) utilizada na aplicação. A clonagem, como veremos,
funcionará melhor aliada ao recurso de “Preferidos” (Bookmark) do Navegador, que por sua vez
exige URLs únicas para endereçar cada documento (ou seja, arquitetura Restful [Richardson,
Leonard 2007]).
o Treinamento em Navegadores Web para os usuários finais. Apesar da popularização dos
Navegadores, muitos usuários ainda subutilizam certos recursos interessantes, como a “História do
Usuário” e os “Preferidos”.
o Características do cadastro em questão. Os ganhos, naturalmente, irão variar conforme o caso.
Cadastrar muitas Notas Fiscais para o mesmo Cliente/Produto, por exemplo, seria um exemplo de
caso que traria excelentes ganhos.
O primeiro fator é casuístico. Vamos discutir então os dois primeiros.
No que diz respeito à arquitetura de Interfaces com o Usuário para Navegadores Web, o ponto chave é
que seja utilizado um padrão de endereçamento de páginas compatível com a natureza do protocolo
HTTP e o conceito de “recursos” da Web. De forma mais direta, devemos recuperar documentos através
de URLs únicas, utilizando protocolo HTTP GET.
O jCompany utiliza este padrão para todos os formulários. Por exemplo, para editar um funcionário
específico basta se utilizar a URL “http://www.[contexto do servidor]/[contexto da
aplicação]/f/t/funcionarioman?chPlc=[Object-Id]”*. Somente deste modo, com as informações
para recuperação de um documento específico expostas na URL, torna-se viável para o usuário:
o Enviar qualquer documento da empresa por e-mail, na forma de hiperlink, utilizando a opção
do Navegador “Enviar -> Link por e-mail”.
o Registrar um documento importante - base para clonagem, por exemplo, em seus "Favoritos”!
o Utilizar sem problemas os botões de “Anterior” e “Próximo” do Navegador (Desde que a
Arquitetura também preveja o uso apropriado do Ajax).
*
Aliado ao uso do padrão de segurança Java EE utilizado pelo jCompany, inclusive, o login será requisitado se um usuário anônimo
tentar acessar. O esquema de “redirect” para o login e, em seguida, exibição do documento originalmente procurado, é realizado pelo
App Server, sem qualquer esforço de programação.
273
Capítulo B10
Figura B10.41. Control+H para ver a historia de uso dos últimos tempos (Mozilla).
2. Para uma melhor simulação, limpe todo o acesso do dia até aqui, clicando em “Today” ou “Hoje”, e
acionando “Clique direito -> delete”.
3. Em seguida edite diversos registros diferentes, um após o outro. O resultado deve ser similar ao da
Figura B10.42, agora no IE 7.x:
#1. O diálogo de “História do Usuário” exibe acessos segmentados por servidor (no caso,
“localhost”), listando os vários títulos das páginas acessadas.
#2. A Arquitetura de Interface com o Usuário prevista no jCompany não somente diferencia cada
instância de documento por uma URL única, como também diferencia títulos para cada
uma delas em modo de edição, usando como padrão a concatenação do título em I18n...
274
Testando e Aprimorando Interfaces com o Usuário
Deste modo, fica viável para o usuário, identificar instâncias de documentos editados no
histórico.
A dica é para que o usuário, sempre que julgar um determinado documento como “modelo para
dados recorrentes”, marque-o Favorito, como na Figura B10.43.
Figura B10.43. Quaisquer documentos podem ser “preferidos” (bookmarked), acessíveis a um clique de distância.
Com todos estes recursos em mãos, os usuários podem ter um ambiente de trabalho “a um clique de
distância” de quaisquer documentos que julguem importantes, estejam eles em quaisquer aplicações da
empresa! Com o tempo, certamente vários “modelos clonáveis” estarão nos “Favoritos” ou “História do
Usuário”, para facilitar cadastros produtivos.
#2. O botão “F7-Novo” comuta para a manutenção, permitindo a inclusão de um novo documento.
#3. O botão “F9-Pesquisar” dispara a pesquisa, considerando os argumentos informados. Dica: Ele
é também o botão com foco padrão da página, podendo ser disparado com a tecla “Enter”,
além da tecla F9 e o mouse.
275
Capítulo B10
#4. Permite que se informe parâmetros tais como “iniciais do nome”, “CPF”, etc., antes de se
efetuar o disparo da pesquisa.
#6. Botões para navegação tipo “DVD” incluindo “página inicial”, “página anterior”, “próxima
página” e “ultima página”, na ordem em que aparecem.
#7. Numeração incluindo número de ordem do primeiro e último objeto exibidos na página atual, e
total de objetos.
Note que, em se havendo foco em um registro selecionado, o “Enter” passa então a funcionar
como seleção (ao invés de acionar o botão padrão, F9-Pesquisar).
4. Faça exploração de uso de todos os argumentos, inclusive do Intervalo de Idade, onde nossa regra
de Controle deverá estar atuando.
Quando interagindo com SGBD, não se contente em ver o resultado esperado. É importante
compreender o que ocorre por trás dos bastidores, para evitar problemas grosseiros causados por
cláusulas SQL mal otimizadas. Estes são quase invisíveis em tempo de desenvolvimento, mas
podem produzir problemas graves de performance e escalabilidade, quando usando volumes de
dados de produção, em ambiente multi-usuário.
Para facilitar ao desenvolvedor conferir as cláusulas SQL que o JPA ou Hibernate estão gerando, a
partir das queries no padrão JPA-QL ou HQL, o jCompany Configuration Management já traz a
opção “show-sql=true” configurada no arquivo “hibernate.cfg.xml”, conforme ilustra a Figura
B10.45.
Figura B10.45. Opção “show_sql” configurada para desenvolvimento, para conferência dos SQLs gerados.
5. Faça uma nova pesquisa pelas iniciais do nome do funcionário, e em seguida analise os SQL
gerados, na console do Tomcat, no Eclipse. Devem ser submetidas duas cláusulas SQL, exibidas nas
Figura B10.46 e Figura B10.47.
*
Além das listadas, é possível definir metadados para permitir ao usuário alterar o número de “itens por página” exibidos.
276
Testando e Aprimorando Interfaces com o Usuário
Figura B10.46. Primeiro SQL produzido pelo Hibernate, para Seleção Paginada, por inicial do nome.
#1. A primeira cláusula é um “select count(*)”, utilizando a mesma “where condition” da cláusula
principal, somente para recuperar o total geral de registros. Este total é necessário, para gerar
todo o controle do componente de paginação*.
#2. Perceba que todas as associações são feitas com junção “OUTER” (“left join”, em OQL) em
relação à Tabela principal. O jCompany utiliza critérios importantes nesta hora, para que a
lógica de funcionamento QBE funcione adequadamente†.
#3. Para UF, associação poderia ser realizada através de uma junção “INNER” (o padrão, em OQL),
mas o “OUTER” não trará problemas funcionais.
#4. A cláusula “where” foi montada dinamicamente pelo jCompany FS Framework, em função
dos argumentos informados (somente eles) e utilizando “Prepared Statement”‡.
*
Ele não é gerado, em seleções que não utilizem paginação.
†
Todas as informações que advêm de associações possivelmente opcionais devem utilizar “junções OUTER”, do contrário não se veria
objetos que não possuem a associação, na lista de seleção. Por exemplo, funcionários ainda não associados a Unidades
Organizacionais, não apareceriam!
‡
Prática de se passar os argumentos em separado da cláusula SQL, e não concatenados a ela. Deste modo, otimiza-se a execução e
obtém-se maior segurança (contra, por exemplo, argumentos contendo subqueries).
277
Capítulo B10
Figura B10.47. Segundo SQL produzido pelo Hibernate, para Seleção Paginada, por inicial do nome.
#3. A cláusula “order by” somente é utilizada na segunda submissão, pois não faz sentido para a
primeira*.
Obs.: No segundo caso, o JPA/Hibernate irá garantir, de alguma forma que pode variar para cada
implementação de SGBD, que irá recuperar somente o número de registros que pode ser
apresentado em uma única página, de cada vez. Deste modo, evita recuperações excessivamente
grandes, e até uma varredura completa na base, anomalia conhecida como Full Scan.
Importante: Para mudar os SQLs resultantes, para eventuais† otimizações, precisaremos fazê-lo
indiretamente, editando a NamedQuery padrão “querySel” em sintaxe JPA-QL ou HQL.
Em nosso caso, não precisaremos editar a “querySel” para otimizações, mas existe um ajuste
desejável na visualização da página de seleção.
6. Perceba, pela Figura B10.44, que a descrição de UF está com o texto “null” sendo concatenado ao
nome da UF, indevidamente. O gerador do jCompany IDE inclui na NamedQuery somente uma
propriedade para classes referenciadas (a primeira encontrada, do tipo String), a menos que outras
sejam utilizadas em argumentos, o que não é o caso de “Uf”.
*
A ordenação não alteraria o total de objetos resultantes da primeira query.
†
Esta é uma eventualidade provável – não acredite em cláusulas SQL “defaults” de nenhuma implementação OQL, sem antes conferir
seu resultado. Especialmente em aplicações de missão crítica, com grandes volumes de dados envolvidos.
278
Testando e Aprimorando Interfaces com o Usuário
Figura B10.48. Ajuste que alteraria a exibição do “toString” da classe Uf, para apenas nome.
Mas neste caso não exibiríamos “sigla”, que afinal de contas foi projetada para exibição, na classe
“Uf”. Portanto, o mais apropriado é alterarmos a “querySel”, para também trazer sigla.
7. Faça este acréscimo como demonstrado na Figura B10.49, para a cláusula “select” do OQL.
Figura B10.50. Ajuste no construtor correspondente, para “acomodar” o dado no grafo de classes.
Quando realizarmos a liberação, ao final dos testes, veremos o resultado corrigido, apresentando
também a sigla de UF.
Figura B10.51. Componente visual padrão para Arquivo Anexado, em modo Inativo.
o Upload: Quando o usuário clica na opção “Anexar Foto”, o componente altera para modo “Upload”.
Nesta situação, os leiautes do jCompany também alteram a declaração do formulário para
279
Capítulo B10
Figura B10.52. Componente visual padrão para Arquivo Anexado, em modo Upload.
Nota: No modo de Upload, o texto “Browse...” é renderizado pelo Navegador, em sua linguagem
de instalação. No exemplo da Figura B10.52, o exemplo é para um Navegador instalado em idioma
“inglês”. O texto em português poderia ser “Procurar...” ou “Anexar...”, dependendo do Navegador.
o Download: Se o usuário edita um documento que já possua um arquivo anexado, o componente
exibirá uma caixa para marcação de exclusão do Arquivo e um botão para baixá-lo, no modo de
“Download”.
Figura B10.53. Componente visual padrão para Arquivo Anexado, em modo Download.
1. Experimente variações de cenário, editando um funcionário somente para incluir sua foto, ou
excluindo um arquivo, marcando-o e clicando em F12-Gravar, etc..
Perceba que o jCompany também irá garantir a integridade de exclusão, ou seja. Quando excluindo
um funcionário, o arquivo anexado também será excluído junto, na mesma transação do SGBD.
Importante: Existe grande número de variações de necessidades para se lidar com arquivos. Muitas,
obviamente, divergirão do padrão acima adotado, apesar de atender a um cenário muito comum. Com
conhecimento mais profundo do jCompany FS Framework, porém, é possível criar novos padrões
corporativos, seguindo estruturas similares.
*
Tanto o envio pelo Navegador, quanto a recepção pelo servidor, deverão tratar cada componente (campos) do formulário em partes
separadas, em lugar de enviar um único texto, no formato padrão.
280
Testando e Aprimorando Interfaces com o Usuário
Perceba que editamos o documento fazendo duas alterações, uma exclusão e duas inclusões de objetos,
operando sempre na máquina do cliente, em caching. Ao final, comandamos uma única submissão ao
Application Server*, que usou uma única transação do SGBD†!
E por que isso é relevante? Porque normalmente os projetos de GUI para Navegadores Web não são
condizentes com o uso corporativo, mas inspirados pelas metáforas de “carrinho de compra” dos
eCommerces de primeira geração - trazendo grandes prejuízos nesta área, para todos os lados. E ainda,
o que é pior, estes projetos costumam até ser ditados pelos próprios usuários finais (que,
embora não sabem que pode existir alternativa ainda melhor) ou por Web-Designs, sem formação
adequada para considerarem a arquitetura, como um todo.
Estes projetos de GUI que batizamos de projetos “carrinho de compra” provocam, em uma simulação
análoga à nossa, cinco ou dez vezes mais submissões ao Application Server para alcançar o
mesmo resultado. Mesmo que ao final, tais aplicações persistam tudo em uma mesma transação do
SGBD‡, ainda assim escalam menos, por produzirem um considerável aumento do consumo de recursos
de rede e Threads HTTP.
Além disso, se não forem amenizados com o uso das tecnologias Ajax, os vários carregamentos
intermediários de páginas do Navegador irão prejudicar também a produtividade do usuário – uma
verdadeira situação “perde-perde”, onde os usuários perdem em performance e também em usabilidade§.
Felizmente, com um trabalho adequado em nível da arquitetura, é possível invertermos o jogo para uma
situação “ganha-ganha”, oferecendo aos usuários melhor performance/escalabilidade, aliadas a uma
operação mais simples e produtiva.
*
O que significa uma única ida à rede, uma única requisição ao pool de Threads HTTP (mantido pelo App Server) e uma única
seqüência de atendimento processada pela aplicação!
†
O que significa uma única abertura de sessão de persistência, uma única requisição ao pool de conexões JDBC (mantido pelo App
Server) e uma única transação com o SGBD, terminada em COMMIT.
‡
Acumulando as alterações em objetos “de sessão”.
§
A versão “carrinho de compra” se pareceria com o nosso “Assistente de Entrada de Dados”. Em um mundo corporativo, ela somente
faria sentido em momentos especiais de aprendizado ou para aplicações visando usuários esporádicos, não treinados (como o
eCommerce em si). Quando este é o caso, como já sugerimos, o recomendado é inclusive que o “modo Assistente” seja o padrão,
acionado logo após o clique no menu. Mas nos casos em contrário, o acionamento somente no momento da necessidade é mais
apropriado.
281
Capítulo B10
Figura B10.55. Estilo CSS diminuindo a largura do componente “radio”, para JSP Mestre.
Edite a página “funcionarioDet.jsp” e acrescente desta vez, além do “inlineStyle” com valor
“width:160px;”, a propriedade “layout” com valor “horizontal”. Neste caso, esta opção de
alinhamento será melhor.
Figura B10.56. Estilo CSS alterando a orientação para horizontal do componente “radio”, para JSP de Dependente.
Estas e centenas de outras opções de ajustes estão disponíveis para customização em aparência
dos componentes Apache Trinidad, inclusive naqueles especializados pelo jCompany FS
Framework.
Como conhecer todas as opções disponíveis?
282
Testando e Aprimorando Interfaces com o Usuário
Figura B10.58. Assistente da parte visual do Editor RHDS, exibindo palheta de opções JSTL
*
Nota do Editor: Veja, nas Referências Bibliográficas ao final deste livro, endereços dos Web-Sites de todos os projetos discutidos.
283
Capítulo B10
Importante: Não percebemos nenhum problema relacionado a este título até agora, em nossos
testes, pois os componentes “tabela”, como padrão, não são renderizados quando estão no contexto
de um Tab-Folder de leiaute do jCompany*!
6. Aproveite para excluir os rótulos antigos iniciados com “ajuda.endereco” e “label.endereco”, que
substituímos no passo 4, após esta modificação.
Dica: Para o componente de “Endereco”, a melhor abordagem seria tentar a reutilização de uma
mesma JSP, tanto para “Mantém Funcionários” quando para “Manter Unidade Organizacional”. Esta
deve sempre ser a primeira hipótese. Para tanto, bastaria fazermos a seguinte refatoração, após a
geração pelo jCompany IDE:
o “Extrair” o conteúdo das duas páginas “funcionarioMan2.jsp” e
“unidadeOrganizacionalMan2.jsp” para uma nova, em diretório raiz, chamada “endereco.jsp”.
o Em seguida substituir o conteúdo das duas, originais, por somente uma cláusula ‘<jsp:include
page=”/WEB-INF/jsps/endereco.jsp”/>’, que poderia inclusive passar argumentos para
ajustar pequenas diferenças.
Esta deve sempre ser a técnica preferida para JSPs que representam componentes, maximizando o
reuso. Porém, algumas vezes, as exigências visuais de rótulos e disposição são bem diferentes ou,
como é o nosso caso, temos um nome de propriedade distinto (enderecoResidencial) e ainda testes
condicionais do Assistente e registro de tabulação, específicos somente para o caso de Funcionário.
Por este motivo, neste caso, não julgamos compensador o reúso – à exceção dos rótulos.
Feitas estas considerações, julgamos finalizado o nosso terceiro Caso de Uso, agora com “qualidade de
produção”.
*
Se for necessário exibir, contrariando este padrão, deve-se utilizar a propriedade exibeEmTabFolder=”S”.
284
Testando e Aprimorando Interfaces com o Usuário
Sumário
Neste capítulo, finalizamos o desenvolvimento de nosso terceiro Caso de Uso “UC002 Manter
Funcionário!“, realizando testes em todas as funcionalidades especificadas e implementando pequenos
ajustes finais. Aproveitamos para compreender em um pouco mais de detalhe um bom número de
padrões de usabilidade em nível de arquitetura, providos automaticamente pelo jCompany FS
Framework, dentre eles:
o Recursos de produtividade para preenchimento de formulários complexos, tais como a Entrada em
Lote (sem mouse e com tabulação inteligente), o Assistente de Entrada de Dados, a Clonagem de
documentos (Agregações de Objetos completas), o uso de “Preferidos” e da “História do Usuário”,
viabilizados pela identificação de instâncias de documentos através de URLs únicas, e titulação
apropriada.
o Recursos de produtividade para seleção de documentos, tais como recuperação por amostragem de
valores (QBE) via pesquisa paginada, incluindo saltos diretos e seleção via teclado.
Por fim, iniciamos algumas tarefas de customizações nesta área, como uma introdução às customizações
mais avançadas que veremos no modulo D.
No próximo capítulo, iremos realizar o nosso primeiro Caso de Uso de consulta.
285
Capítulo B10
286
Capítulo
11
Disponibilizando
1
B
Formulários para
“Consulta Apenas”
Implementando “UC003 Consultar/Imprimir Ficha Funcional!"
287
Capítulo B11
Em vez de desenvolvermos novos formulários e Colaborações, com alto índice de redundância, podemos
utilizar técnicas de gestão de leiautes para tentar reaproveitar código. E o jCompany FS Framework já
traz uma opção automatizada que irá nos auxiliar muito nestes casos: o “Modo de Visualização de
Documentos”.
Já fomos apresentados a esta facilidade, quando falamos sobre “Entrada de Dados em Lote”, no capítulo
anterior. Vamos conhecer agora algumas extensões que nos permitirão obter uma solução de consulta e
impressão imediatamente funcional, para quaisquer formulários de manutenção, sem esforço.
1. Selecione um funcionário (acesse via Favoritos do Navegador!).
2. Em seguida, clique no botão “Vis. Documento”. Um resultado como o da Figura B11.2 deverá
aparecer.
#4. O componente com o botão para anexar arquivo também não é exibido (somente o nome do
arquivo ou imagem, se houver um anexado).
#5. A imagem, o título e as caixas para marcação de exclusão de Detalhes, também não são
exibidos.
Podemos considerar este como um leiaute já apropriado para consulta... Mas não para a impressão! Se
formos imprimir esta página pelo comando “Arquivo -> Imprimir...” (ou “File -> Print...”) do Navegador,
imprimiríamos junto com o formulário, o topo, a barra de ações com botões e o rodapé do leiaute
principal. Além disso, as setas para seleção das listas de valores (combos), também não fazem sentido
em uma impressão.
288
Disponibilizando Formulários para “Consulta Apenas”
#1. Esta opção exibe um leiaute com topos e rodapés ajustados para impressão, sem barras de
botões, com campos de entrada transformados em textos. Em seguida, aciona
automaticamente a opção de impressão do Navegador.
#2. Esta opção exibe um leiaute com topos e rodapés ajustados para impressão, sem barras de
botões, mas deixa os campos de entrada do formulário como estão originalmente. Também
aciona automaticamente a opção de impressão do Navegador, após a chamada.
#3. Esta opção envia uma versão com leiaute igual ao da opção 2 diretamente para a impressora,
sem visualização. Esta opção é mantida pois, em determinados Navegadores - e para
formulários extremamente grandes, as duas funções de visualização anteriores podem não
funcionar.
289
Capítulo B11
Figura B11.4. Formulário visualizado com a primeira opção de impressão, com leiaute apropriado.
#1. O topo, a barra de botões e os rodapés do leiaute original são substituídos apenas por um topo
de impressão, que pode ser customizado especializando-se a página
“/plc/jsps/geralTopoImpressaoPlc.jsp”*. A imagem apresentada como padrão é declarada nos
metadados globais – e a mesma utilizada na janela de login (se não informada, o default é
“/plc/midia/marca_empresa.gif”).
#3. Somente os componentes do tipo “Botões de Rádio” e “Caixa de Marcação” não são
modificados, pois se comportam bem em impressão.
#4. Os títulos também sofrem adequações incluindo um reforço de negrito, que comporta bem em
todas as peles padrões disponibilizadas com o jCompany.
Antes de imprimir, o usuário pode ainda alterar o título com um simples clique no mesmo, conforme
ilustra a Figura B11.5.
Figura B11.5. Alterando o título via DHTML com um simples clique na área do topo.
*
Mais informações sobre como se pode especializar quaisquer componentes Tiles de leiaute, no módulo D.
290
Disponibilizando Formulários para “Consulta Apenas”
Em algumas situações pode ser necessário imprimir a imagem real do formulário, com os campos de
entrada. Nestes casos, o usuário pode utilizar a segunda opção do painel de impressão, para um
resultado como o da Figura B11.6.
Mas e se quisermos acrescentar algum tipo de informação que exija programação Java, somente em
“Modo de Visualização”?
Neste caso, bastaria especializarmos o método de extensão “editaVisualizaDocumentoApos()”, em nossa
classe de controle “FuncionarioAction”, utilizando um mecanismo similar ao que fizemos para ajustar os
argumentos de idade para data, no último Caso de Uso.
Vamos fazer um exemplo, acrescentando o último pagamento recebido, ao lado do campo “observação”.
Somente conseguiremos finalizar esta programação quando implementarmos o Caso de Uso de “Cálculo
da Folha de Pagamento”, já que não temos salários recebidos ainda (somente os valores nominais de
base). Mas já podemos adiantar a sua fôrma básica, o que já atende ao nosso propósito didático.
1. Edite a classe FuncionarioAction, e implemente um método como o da Figura B11.8.
291
Capítulo B11
#2. Chamada de método específico. Lembre-se: não devemos implementar códigos específicos em
métodos de extensão, para evitar perda de coesão.
#3. Métodos com sufixo “Apos” são executados ao final dos Template Methods e normalmente
trazem uma opção para que o desenvolvedor desvie o fluxo após programações específicas. Em
nosso caso, basta voltar a constante IND_MESMA_PAGINA (“mesmaPagina”).
Vamos nos lembrar como funciona o desvio de fluxo? No arquivo “faces-config.xml” (para
Struts, “struts-config.xml”), estas chaves de desvio são definidas, como “Navigation Case”
(casos de navegação), para cada declaração de requisição principal (Em Struts, se chamam
“Action Forward”). O Desenvolvedor, então, retorna uma das “chaves” declaradas ao final dos
métodos de Controle, de modo a indicar qual a próxima visão a ser exibida para o usuário.
Figura B11.9. Opções de Navigation Case padrões. O “mesmaPagina” mantém o fluxo no formulário atual.
292
Disponibilizando Formulários para “Consulta Apenas”
#4. Métodos devem disparar a exceção “invólucro” PlcException, se for desejado utilizar o
tratamento genérico de exceções*.
#5. Por hora, vamos apenas marcar com uma Tag “TODO” do Eclipse e uma mensagem de
depuração do Log4j, para voltarmos futuramente neste ponto e finalizar.
Se a mensagem não apareceu, pode haver algum problema na configuração do “Source Path” para o
Tomcat Sysdeo. Vamos conferir.
3. Abra a lista de projetos Eclipse que estão marcados para reconhecimento pelo Tomcat Sysdeo, em
“Windows -> Preferences... -> Tomcat -> Source Path”
*
Lembrando a “pauta mínima” utilizada no tratamento de exceções genéricas, do jCompany: para exceções controladas, envia
mensagem para usuário. Para exceções inesperadas (externas), envia logging, mensagem para usuário e e-mail para lista registrada.
†
Também é possível se realizar configurações do WTP 2.0 em projetos jCompany, para permitir “Hot Deploy” para outros App Servers.
Mas este tema somente será abordado em um próximo livro desta série: “Volume II – Tópicos Avançados”.
293
Capítulo B11
Figura B11.11. Projetos marcados no Tomcat Sysdeo, para liberação imediata e reconhecimento em depuração.
Se ela estiver sem marcações nos projetos desejados, marque-os e reinicie o Tomcat, para que
passem a valer nas próximas modificações. Se esta configuração está correta, e a mensagem ainda
não apareceu, um outro ponto importante para conferir são os níveis de logging do Log4j.
5. Perceba para Figura B11.10, que a classe de exibição da mensagem foi [AppAction], já que a
classe de logging utilizada está definida no ancestral de “FuncionarioAction”, como mostra a Figura
B11.12.
294
Disponibilizando Formulários para “Consulta Apenas”
#2. A classe “rootLogger” é a ancestral geral, com nível “INFO”. Mudá-la para “DEBUG” liga o
logging de todas as mensagens contidas em classes cujos pacotes não estão declarados neste
arquivo, mas que se encontram presentes na aplicação.
#3. A classe de log “org.hibernate.type” é especialmente importante, pois se alterada para DEBUG
exibe os argumentos enviados em “Prepared Statements” (?) que aparecem nos SQLs! Por
ser muito útil, é pré-configurada aqui pelo jCompany.
#5. Classes da aplicação são declaradas como DEBUG (do contrário não veríamos a
mensagem que fizemos).
#6. Definição de um dispositivo de saída de logging para arquivo utilizado somente em Struts, para
logging de execução (Profiling).
#7. Definição da saída padrão para todas as mensagens, na Console do Application Server.
295
Capítulo B11
3. Esta pequena página é ultra-leve, realizando somente a inclusão de uma nova JSP para o topo
chamada “/plc/jsps/geralTopoImpressaoPlc.jsp” e executando uma função Javascript que
obtém o corpo (parte entre os tokens) da página que a chamou, localmente.
Este esquema é tremendamente otimizado, comparado a uma nova renderização completa, somente
para obtenção de um novo leiaute. Mas uma conclusão importante é:
o Customizações mais profundas (acréscimos ou retiradas de informações) devem ser realizadas no
“Modo de Visualização” (como fizemos no tópico anterior), e não no de “Modo de Visualização para
Impressão”, já que este não realiza processamento significativo no servidor.
o Programações no “Modo de Visualização para Impressão” são possíveis somente via Javascript.
Em “Modo de Visualização para Impressão”, de uma forma geral, podem ser utilizados os seguintes
recursos para customização:
o Para alterar o topo: Especializar a página “/plc/jsps/geralTopoImpressaoPlc.jsp”, salvando-a
do projeto “jcompany_visao” para a Camada Bridge* ou para um projeto específico.
o Para alterar estilo CSS: Para alterações que devam ocorrer, somente neste modo, deve-se
especializar o arquivo de CSS “/plc/css/PlcImpressao.css”, que também está presente em
“jcompany_visao”. Especializações mais globais utilizam arquivos e esquema arquitetural distinto,
que será discutido em mais detalhes no módulo D.
o Para alterar o leiaute como um todo: Especializar a página
“/plc/jsps/PlcImpressaoLayout.jsp”, também do projeto “jcompany_visao”.
*
A camada Bridge foi introduzida no capítulo 4, sobre arquitetura. É um módulo corporativo que atua em grande parte como uma
camada (layer), servindo para generalizações de arquitetura específicas da empresa, que ocorrem após o jCompany e antes das
aplicações.
296
Disponibilizando Formulários para “Consulta Apenas”
2. Em seguida, clique novamente no item pai da árvore e acione “Clique-Direito -> Paste”. Informe o
nome “def.menu.funcionario.con.titulo” no diálogo que aparecerá, requisitando a alteração.
Figura B11.16. Alterando o hiperlink para realizar chamada para manutenção em modo consulta.
o mfPlc=v (Modo Formulário = Visualiza). Abrir uma seleção passando este parâmetro, ou
diretamente uma manutenção, faz com que o formulário se abra em “Modo de Visualização de
Documento”.
*
Este trecho de parâmetros de URL será renderizado no Navegador como simplesmente “&mfPlc=v&mcPlc=t”. O uso de “&” no
lugar de simplesmente um “&”, deve-se ao fato de estarmos dentro de um arquivo XML, que trata o caractere “&” de forma reservada.
297
Capítulo B11
o mcPlc=t (Modo Componentes = Texto). Abrir uma seleção passando este parâmetro, ou
diretamente uma manutenção, faz com que os componentes do formulário se abram com
componentes convertidos para textos.
Importante: Note que o resultado final deste link deve ser, em XML, “<item
link="/f/t/funcionariosel?fwPlc=funcionarioman&mfPlc=v&mcPlc=t"
value="def.menu.funcionario.con.titulo"/>”. O editor visual do Tiles já corrige o caractere “&”
para “&”, como deve ser informado em XML. Se for informado “&” na parte visual,
ocorrerão duplicações nos tokes “&” – se for o caso, remova-os para que fiquem na forma
acima. Lembre-se: Cada “&” representa um “&”, em XML.
4. Defina o rótulo para a entrada de menu em “ApplicationResources.properties”. Lembrete: Não se
esqueça de tabular após informar o texto neste editor. Se acionar o salvamente sem uma tabulação,
o último texto não será gravado.
5. Salve os arquivos e faça uma nova liberação “Rápida para Tomcat com Reinicio”.
6. Entre na aplicação e clique em nosso novo item de menu. A mesma página de seleção de
funcionários deve aparecer, como na Figura B11.18.
7. Agora selecione em um objeto. Desta vez, ele já aparece apresentado em “Modo de Visualização”.
298
Disponibilizando Formulários para “Consulta Apenas”
#1. Página de consulta aparece logo na entrada da edição e dentro do leiaute normal.
#2. A Barra de Ações é ajustada para consulta apenas, restando somente o botão “F8-Abrir”.
#3. O leiaute do formulário aparece em “Modo de Visualização” e com campos em “Modo Texto”,
uma mistura com o leiaute de impressão.
Perceba que, entrando diretamente neste modo, eventuais programações de ajuste específicas já
são executadas, evitando um clique adicional para o usuário. Constatamos isso pela ausência do
campo observação, que ajustamos para não ser exibido, em tópicos anteriores.
Importante: Quando reutilizando uma mesma Colaboração de Seleção para dois objetivos diferentes
(em nosso caso, para manutenção ou para a consulta), certifique-se de que a chamada de menu para a
seleção da manutenção esteja passando como parâmetro “fwPlc=<urlmanutenção>” (Ex.:
fwPlc=funcionarioman).
Ajustes visuais em aplicações Web não podem ser considerados como “segurança”. Considere-os
sempre como um “conforto visual” bem desejável, mas implemente alguma verificação de
segurança efetiva, necessariamente no servidor.
Vamos agora cuidar da segurança, começando por utilizar o que há disponível no padrão Java EE. E este
padrão oferece recursos declarativos e suficientes para se restringir direitos de gravação e/ou consulta,
para determinados papéis, em determinadas URLs:
1. Edite o arquivo “web.xml” e clique direito em “Security Roles”, como na Figura B11.20.
Figura B11.20. Definindo “Atores” UML como “Roles” Java EE, no web.xml.
2. Cadastre uma entrada em “role-name”, para cada Ator encontrado no diagrama da Figura B11.1.
299
Capítulo B11
Figura B11.21. Atores do negócio em amarelo. Membros e AreaTecnica são utilizados pelo jCompany.
3. Em seguida, defina uma primeira restrição, que irá impedir o acesso de gravação em funcionários,
chamando-a de “Funcionário – Somente Consulta”.
Para tanto, clique direito acima de “Security Constraints” e adicione um “Web Resource Collection”
contendo “/f/t/funcionarioman” como URL pattern e “GET” como protocolo HTTP.
Em seguida, adicione a role “FolhaPagamento” a esta restrição. Confira o resultado com a Figura
B11.22.
Figura B11.22. Restrição para acesso de “somente consulta” para usuários com role “FolhaPagamento”
#3. Padrões de URL que serão protegidas, podendo ter “*” como coringa. Em nosso caso, temos
somente uma URL (apesar de chamada de dois modos diferentes).
#4. Protocolo HTTP permitindo somente GET, utilizado para edição de documentos.
#5. Lista de papéis (roles) de usuários que podem utilizar os recursos protegidos. No nosso caso,
somente “FolhaPagamento”.
4. Defina a restrição para permitir manutenção somente para usuários com papel “RH”, de uma forma
similar, mas agora sem incluir nenhum protocolo definido. Deste modo, a restrição vale tanto para
GET quanto para POST.
Novamente: Em Colaborações de Manutenção, o jCompany utiliza GET para a edição e POST para
gravações.
300
Disponibilizando Formulários para “Consulta Apenas”
Figura B11.23. Restrição para acesso de “consulta e manutenção” (todos os comandos HTTP) role “RH”.
5. Faça, como exercício, a definição da segurança para os dois primeiros Casos de Uso que
desenvolvemos, restritos apenas ao papel “Administrador”.
6. Para teste, precisaremos criar novos usuários, papéis (roles) e associações apropriadas. Para isso,
edite o arquivo “[jcompany]/servers/tomcat/conf/tomcat-users.xml” e altere-o, conforme a Figura
B11.24 .
Figura B11.24. Cadastramento de usuários, papéis (roles) e associação entre ambos, no arquivo Realm de teste.
Experimente autenticar com “joao", que não possui role “RH”, e acessar a manutenção. Perceba que
ainda assim será possível a edição e consulta (já que sua role “FolhaPagamento” lhe dá acesso de
“GET”, para consulta). Porém, ao apertar “F7-Novo”, “F12-Gravar”, “Excluir” ou qualquer outra
ação que envie comandos de “POST” para a URL “/f/t/funcionarioman”, uma mensagem padrão para
restrição de segurança aparece, refletindo a proteção.
301
Capítulo B11
É uma preocupação que, na verdade, serve a dois propósitos: o de facilitar a vida do usuário, que passa
a não ver o que, de qualquer modo, não tem direito de acessar; e o de reforçar ainda mais a segurança,
não dando informações iniciais que possam “despertar” iniciativas ilegais de invasão.
No nosso caso presente, a primeira necessidade óbvia é esconder itens de menu de usuários que não
possuem direitos de acesso a eles. Vamos fazê-lo, aproveitando a edição do menu para melhorar a sua
organização geral, utilizando dois tipos de facilidades do Tiles:
o Programação declarativa em XML.
o Programação Java em classes controladoras em nível de leiaute, chamadas de Tiles Controller.
Vamos começar criando mais blocos de menu de primeiro nível, separando as opções de manutenção da
estrutura organizacional das que lidam com funcionários. Isso irá nos facilitar, por exemplo, a aplicar
restrições de segurança ao primeiro bloco, que somente pode ser utilizado por usuários com papel
“Administrador” (veja Figura B11.1).
1. Edite o arquivo “app-tiles-menu1.xml”.
2. Primeiramente, vamos fazer uma cópia do primeiro bloco do menu. Clique direito no bloco
“app.m.inicial”, para em seguida copiá-lo.
3. Selecione o nível mais superior, e utilize “paste” para colá-lo como um bloco paralelo ao primeiro.
302
Disponibilizando Formulários para “Consulta Apenas”
4. Ao colar, será requisitado um novo nome (para não haver colisão). Denomine o novo bloco de
“app.m.func” e, em seguida, retire os itens de chamada indesejados em cada um dos dois blocos
resultates, conforme ilustra a Figura B11.27.
#2. Alteração do título (rótulo que aparecerá), para “app.m.func” (mesmo nome do definition,
como convenção).
5. Vamos agora incluir a chamada do novo bloco, a partir da barra principal do menu. A melhor forma
de fazê-lo é também com esquema “cópia e colagem”.
Copie entrada da listaPlc “add:app.m.inicial” e cole-a abaixo da mesma lista. O resultado deve ser o
da Figura B11.28. Em seguida, arraste o item recém colado para abaixo do primeiro, de forma a
colocá-lo na segunda posição.
6. Vamos agora modificar textos I18n. O rótulo de “app.m.inicial” pode ser modificado de “Menu Inicial”
para “Unid. Organizacional”. E a nova entrada para “app.m.func” criada como “Funcionário”.
Em seguida, clique no botão de “+” para adicionar uma linha e acrescente o novo rótulo, conferindo
com a Figura B11.29.
303
Capítulo B11
7. Agora com uma melhor reorganização funcional do menu, podemos implementar facilmente nossa
primeira “restrição de conforto visual” para permitir acesso ao primeiro bloco de funções de
Estrutura Organizacional, somente a usuários com papel “Administrador”. Para tanto, o Tiles traz
uma opção declarativa com indicação de roles, em nível de “blocos” de menu. Vamos utilizá-la.
Figura B11.30. Opções diversas para itens de menu, inclusive segurança para blocos.
#1. Deve-se selecionar um bloco e não um item de menu. O Tiles não oferece esta facilidade em
nível de item.
#2. A lista de roles definida no padrão Java EE, no web.xml, aparece para seleção. Perceba que
apenas uma role é permitida, uma outra limitação do Tiles.
*
É muito provável que usuários administradores também sejam funcionários e até responsáveis pelo cálculo da folha com papel “RH”.
Portanto, com estas sobreposições, serão raros ou nulos os usuários com papel unicamente de “Administrador”.
304
Disponibilizando Formulários para “Consulta Apenas”
iremos implementar somente o segundo caso. De qualquer modo, o mecanismo é o mesmo, de forma
que atingiremos o nosso objetivo didático.
Figura B11.31. Blocos de itens de menu herdam de “app.m.item”, que por sua vez herda de “jcompany.m.item”.
Veja que todos os itens de menu herdam de “app.m.item”, que por sua vez herda de
“jcompany.m.item”. Este último bloco é desenhado de forma mais transparente, porque sua
definição não foi encontrada pelo editor, no projeto corrente. Ela se encontra no arquivo “plc-tiles-
menu.xml” no projeto “jcompany_visao”.
Todos os blocos de itens de menu têm também uma classe controladora (Tiles Controller) comum
na aplicação, que pode ser vista clicando-se no hiperlink em “ControllerClass” para “app.m.item”,
conforme mostra a Figura B11.32.
*
Uma melhor explicação sobre a anatomia de seqüências de requisição, incluindo o momento de atuação de classes de controle
JSF/Struts e Tiles, será dada no módulo E.
305
Capítulo B11
Figura B11.32. Bloco ancestral para itens de menu, com classe controladora em destaque.
Esta classe de controle fica no projeto gerado e contém apenas um código de referência, para
auxílio ao tipo mais comum de programação, como a implementação que faremos para alterar
itens de menu dinamicamente.
Figura B11.33. Classe típica de controlador Tiles, com algoritmo sugerido para alteração dinâmica de itens de
menu.
#2. Este método segue o padrão Tiles e deve ter esta assinatura padrão. Ele é executado antes da
renderização de cada bloco de itens de menu declarados no XML e pode modificá-los.
#4. Importante: Deve-se criar uma nova coleção para prover uma variação dinâmica*. Alterar a
coleção capturada no item 3 irá alterar a definição em escopo de aplicação, para todos
os usuários, e é um erro comum em programação Tiles!
#5. Na programação principal, deve-se receber objetos do tipo “MenuItem”, que são os itens
declarados no XML, e testar condições para adicioná-lo ou não na nova coleção.
#6. Ao final, basta colocar no contexto a nova coleção modificada. Otimizações podem ser feitas,
salvando-se o resultado neste momento também em sessão (se, e somente se, a regra for
relacionada a perfil de usuários); e reutilizando-o das próximas vezes, se existir.
*
Para otimização, deve-se salvar a nova coleção em escopo de sessão, para evitar recriá-la a cada requisição. Isto para o caso atual,
pois a personalização não irá variar durante uma mesma sessão, que é associada a um usuário e seu perfil.
306
Disponibilizando Formulários para “Consulta Apenas”
Após este entendimento superficial da arquitetura Tiles, já é possível implementarmos diversas regras
interessantes. Vamos prosseguir na nossa demanda atual.
Como precisamos realizar modificações dinâmicas, somente no bloco de menu “app.m.func”, não seria
apropriado implementar em “AppMenuItemController”, que executaria para todos os blocos de menu da
aplicação! Em lugar disso, o recomendado é criar uma classe de controle para este bloco específico,
descendente de AppMenuItemController, o que pode ser feito da seguinte forma:
1. Salve a classe “AppMenuItemController” com nome “AppMenuItemFuncionarioController”, no
mesmo pacote da primeira.
#2. A implementação da programação específica em si deve ser delegada para método que a
encapsula (Portanto, fora de métodos de evento do Tiles).
3. Registre no “app-tiles-menu1.xml”, esta nova classe como controladora do bloco que conterá opções
dinâmicas. No caso, o “app.m.func”.
Figura B11.35. Definir um controlador para bloco de menu que se tornará dinâmico.
*
O código ancestral do PlcMenuItemController, basicamente, irá registrar no contexto Tiles o total de itens de cada bloco (que é
necessário, mas sujeito a esquecimentos) e chamar rotinas de integração com o jCompany Security, se este produto estiver em uso.
Além disso, mantê-lo atuando permite que a evolução da arquitetura traga inovações, com o tempo.
307
Capítulo B11
Figura B11.36. Método típico que altera dinamicamente um bloco de itens de menu Tiles.
#2. Uso de estratégia de caching em sessão, recomendada para segurança relacionada ao perfil de
usuários.
#4. Teste propriamente dito, podendo considerar o “link” ou o “rotulo” como testes, que são as
informações disponíveis no objeto “MenuItem” do Tiles.
2. Entre com o usuário “maria”, que não tem o papel “RH”, mas tem o de “Administrador”. O resultado
esperado deve ser o da Figura B11.37
Perceba que ela ainda vê o bloco de menu “Funcionários”, mas não tem acesso visual à opção de
manutenção de funcionários, que é um “conforto visual”.
Mas o que acontece se ela tenta “furar a segurança”?
3. Consulte um funcionário e, em seguida, altere a URL da edição, retirando os parâmetros que forçam
a exibição em consulta. Ou seja, deixando somente uma URL com
“.../f/t/funcionarioman?chPlc=[Object-Id]”. Perceba que este funcionário aparece editado para
manutenção, teoricamente “furando a segurança”.
4. Tente agora gravar o registro. Se a política de segurança foi definida corretamente no arquivo
“web.xml”, aparecerá a mensagem da página “/plc/erros/erro403.jsp”, exibida na Figura B11.38.
Esta página é registrada como padrão, também no arquivo “web.xml”, para exibir mensagens de
segurança.
Neste caso, a explicação mais técnica é “Maria tentou dar um POST não permitido para seu perfil, na
URL ‘/f/t/funcionarioman’”.
308
Disponibilizando Formulários para “Consulta Apenas”
Figura B11.38. Mensagem padrão para erro http 403, para segurança averiguada no servidor.
Dica: Para se customizar esta página de erro, bem como todas as páginas para erros padrões
HTTP* deve-se alterar o registro das páginas de erro no “web.xml”, apontando para uma específica.
5. Entre agora com o usuário “jose”, que tem o papel “RH”. O resultado esperado é o da Figura B11.39.
Ele não tem acesso visual à barra de menu de unidade organizacional, mas tem acesso às funções
de funcionário.
Figura B11.39. Acesso para o perfil de “jose”, mais restrito que “maria”.
6. Entre agora com “joao”, que tem o papel “FolhaPagamento” mas não tem “RH” ou “Administrador”.
O acesso visual é o mais restrito. Até agora, a única função que este perfil pode executar na
aplicação é consultar funcionários.
*
Note que o número 403 é um padrão http, para erros de segurança. Existem vários outros códigos para variadas situações, e cada
um deles pode possuir uma página própria de mensagem padrão.
309
Capítulo B11
novas montagens e liberação da aplicação, toda vez que uma política é alterada, está fora de
questão... Mas seria necessário, no esquema utilizado até aqui*!
o Manutenção de políticas de segurança por usuários finais, que devem possuir uma “IDE de
Administração”, já que não é viável alterarem políticas via edições do “web.xml”*.
o Proteção contra hackers (no pior sentido), proibindo programações para implementação de políticas
de segurança – o que por si, já é um importante flanco de segurança.
*
Mesmo que alguma implementação de App Server permita a modificação das declarações de segurança do “web.xml” em tempo de
execução, sem exigir remontagem e reliberação (ou seja, “a quente”), não é razoável que profissionais da área técnica tomem ciência
destas modificações de política. E estas opções via App Server nunca são amigáveis o suficiente para que os devidos responsáveis pela
segurança possam operá-las.
310
Disponibilizando Formulários para “Consulta Apenas”
Sumário
Neste capítulo, encerramos o desenvolvimento do Caso de Uso “UC003 Consultar/Imprimir Ficha
Funcional”, reutilizando totalmente os nossos artefatos desenvolvidos para manutenção de funcionários,
através da utilização de opções dinâmicas do jCompany FS Framework, que permitem variações
dinâmicas em leiautes e formatos de campos.
Vimos como é possível se customizar detalhes corporativos dos leiautes de impressão, tais como o
padrão logotipo e cabeçalho padrão para impressões; e também como customizar detalhes necessários
em cada Caso de Uso, tais como apresentar ou omitir informações, no modo e consulta ou impressão.
Pela primeira vez, implementamos regras de controle de acesso de acordo com o padrão Java EE,
baseado em declarações de políticas de segurança definidas no arquivo “web.xml”. Complementamos
esta implementação com customizações na parte de Interface com o Usuário, escondendo ou exibindo
itens de menu e/ou de formulários, em conformidade com as políticas de segurança estabelecidas.
Um desenvolvedor experiente deve levar em torno de 2 (duas) horas, para produzir uma consulta de
formulário, com qualidade para impressão inclusive, a partir de uma manutenção já existente, como
pequenas customizações como fizemos.
No próximo capítulo, do módulo C, iremos realizar uma manutenção típica, pela primeira vez, e
introdução os Casos de Uso Padrões de nível secundário
311
Capítulo B11
312
C
Módulo
Casos de Uso .
C
Centrados em Dados
(Secundários)
Este é um módulo prático, que traz tutoriais com passos para implementação de
Casos de Uso Padrões de nível Secundário do jCompany Developer Suite, incluindo
manutenções complementares em grandes agregações de objetos
313
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
314
Capítulo
12
Implementando o Padrão
2
1
C
"Consulta Mestre/Mantém
Detalhe"
Implementando o Caso de Uso “UC001.3 Manter Municípios de UF-”
A té agora, nosso desenvolvimento tem seguido o plano anunciado resumidamente no Capítulo 5. Mas
no mundo real as coisas quase nunca ocorrem desta forma. Aliás, nunca ocorrem desta forma!
Mudanças em várias fases de um projeto irão ocorrer pelos mais diversos motivos:
o Erros de comunicação do Usuário/Cliente, do Projetista ou do Desenvolvedor.
o Necessidades conjunturais ou políticas, externas ao controle do projeto.
o Aprendizado de todos os envolvidos, após liberações parciais de software, trazendo novas idéias
importantes de serem acatadas.
o Etc., etc., etc..
Por tudo isso, sabemos hoje que, mais do que “controlar ou gerenciar” mudanças - o que muitas vezes é
confundido com “antever e evitar”, em software é fundamental nos “preparar” para a mudança,
inevitável. Mais ainda, para “abraçar” a mudança, quando isto trouxer diferencial competitivo ou alavanca
para o sucesso.
Temos nos preparado razoavelmente até aqui: Utilizamos arquitetura MVC; procuramos maximizar o
reuso; preocupamo-nos com “alta coesão + baixo acoplamento” e utilizamos OO e Design Patterns,
sempre que possível. Com isso, esperamos atingir a dois objetivos principais, voltados para a
“manutenção*” de aplicações:
o Diminuição do impacto causado por alterações. De modo que um mínimo de objetos seja
afetado, na hipótese provável de alterações, de uma forma geral.
o Melhoria na “comunicação” do código fonte. De modo que um “recém-chegado” demande o
mínimo de tempo possível, para compreender e modificar uma aplicação.
Manutenções em aplicações são normalmente dividas em três categorias:
1. Manutenções Evolutivas: Melhorias em funcionalidades, para atender a novas demandas de
negócio ou incluir novas variações nas existentes.
No capítulo atual, além de introduzirmos um novo Caso de Uso Padrão, vamos simular uma “manutenção
evolutiva”. Apesar de ser uma manutenção “precoce”, descoberta ainda em tempo de desenvolvimento, é
*
No jargão da área, também chamamos de “manutenção” às modificações realizadas nas aplicações, após elas terem entrado em
produção. É um termo que também utilizamos no contexto de “provimento do ciclo de vida (incluir, alterar, excluir, etc.), como o
fizemos até aqui. Ex.: “Manter Funcionários” ou “Colaboração de Manutenção”.
315
Capítulo C12
útil o suficiente para nosso objetivo didático: demonstrar como variam as práticas de desenvolvimento,
durante as manutenções.
Este Subcaso de Uso entra no cenário do Caso de Uso em nível de objetivo do usuário, “UC001 Manter
Estrutura Organizacional!”. Por isso, alteramos o diagrama original para adicioná-lo, conforme exibe a
Figura C12.1.
316
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
Por que, então, não refatoramos a aplicação para utilizar um único padrão “Manter Agregação
Mestre/Detalhe”, para as duas classes?
A decisão de manter esta Agregação em dois Casos de Uso Padrões distintos (e em duas transações
também) foi tomada para aproveitar melhor as generalizações de caching e a entrada de dados tabular
que o padrão "Manter Classe" oferece, para UFs.
Importante: Seria possível customizarmos o padrão “Mestre/Detalhe” para também prover caching ou
qualquer outra variação que desejássemos, mas na verdade podemos “combinar” dois padrões de modo
a atender plenamente aos usuários; e ainda evitar o impacto de alterar a manutenção existente - na
hipótese de um sistema em produção, este fator deve ser considerado.
Combinação de padrões, em qualquer nível, é um desafio de projeto que distingue os iniciantes dos
experientes. Um Desenvolvedor que conheça mais a fundo a arquitetura dos Casos de Uso Padrões
conseguirá combinar vários deles de modo a preservar o reúso de soluções em 30% ou 40% de
casos a mais!
Note que, por “combinar padrões” queremos dizer “integrá-los visualmente”, de modo que não
exponham dificuldades técnicas para usuários finais, na forma de problemas de usabilidade. A regra é
não aumentar o esforço do usuário para alcançar o seu objetivo, pelo fato de estar combinando duas
soluções de padrão distintas.
Em nosso caso – um dos mais simples possíveis, conseguiremos este resultado apenas com um bom
uso de hiperlinks. Mas em outros mais sofisticados, pode-se ter que incluir um Caso de Uso Secundário
em uma Aba de Tab-Folder de um Primário, por exemplo, além de outras inúmeras variações.
Perceba, na Figura C12.2, que não teremos uma Colaboração de Seleção para nosso Caso de Uso atual.
Já que a classe “Raiz/Mestre” é mantida em um padrão “Manter Classe”, proveremos apenas hiperlinks
da manutenção de UFs para a manutenção de seus municípios. Faremos, por via das dúvidas, um estudo
de usabilidade, para verificar se a ergonomia proposta está adequada.
- Solicitações de Mudança
Especificações não previstas são modeladas de forma distinta, como “Solicitações de Mudança” (SM).
Deste modo, facilitam sua análise em separado do “contrato inicial” e evitam um impacto maior na
especificação em si, caso alterássemos modelos e cenários passados.
Nossa primeira SM exige, além da criação do novo Caso de Uso Padrão, adicionarmos a propriedade
“município” no componente “Endereco” e alterarmos as páginas construídas nos dois Casos de Uso que
utilizam este Componente, como representa a Figura C12.3.
317
Capítulo C12
#6. A JSP correspondente de funcionários foi sucintamente indicada para herdar esta modificação.
Leia-se: “Herde todas as modificações feitas em “unidadeOrganizacionalMan2”, para este
artefato também”.
Temos também que ajustar o Componente “Endereco” para conter a referência a “Município”.
318
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
2. Edite “Endereco”, corte e cole a associação com “Uf” como modelo, alterando as partes específicas e
gerando-se “getter” e “setter” via Eclipse. Confira o resultado com a Figura C12.5.
#1. Associação “manyToOne” copiada de “Uf” (logo acima) e modificada de forma correlata.
#2. Com ainda não mapeamos a classe “Município”, por hora o “MunicipioEntity” não existe, pois
não foi ainda gerado.
Não precisamos complementar manualmente a associação entre “Mestre e Detalhe” pois, como já vimos
em tutoriais anteriores, neste único caso o jCompany complementa a modelagem para o Desenvolvedor,
no momento do mapeamento Objeto-Relacional.
Após este último passo, todas as classes devem estar mapeadas e compilando perfeitamente.
319
Capítulo C12
2. Prosseguindo no roteiro para o segundo passo, “Utilizando o Assistente”, preecha a primeira tela do
Assistente de Criação, conforme a Figura C12.7.
Note que, como a classe Raiz é “UfEntity”, a sugestão de “Subdiretório” é “uf”. Pode-se alterar este
valor para “municipio”, opcionalmente, se for desejado distinguir JSPs deste padrão.
3. No próximo passo, além do título, vamos fazer algumas modificações.
Informe o título e marque “Entrada em Lote”, o que nos deixará sempre com alguns registros em
branco nos Detalhes, para facilitar acréscimos de municípios. Indique também para não gerar
página de seleção, uma vez que iremos substituí-la por via hiperlinks em “Manutenção de UFs”.
4. No próximo passo, defina a parte do formulário “Raiz/Mestre”. Somente retire o “Object-Id”, como
sempre, fazendo em seguida ajustes de coordenadas.
Perceba na visualização da Figura C12.9, que a página é gerada como “somente leitura”, como pede
este padrão.
320
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
Figura C12.9. Página JSP para “Mestre”, somente para consulta, sem Object-Id.
5. Na seqüência, defina a página JSP para o(s) componente(s) de Detalhe. Em nosso caso, temos
somente um, para a classe “MunicipioEntity”. Lembre-se de retirar o Object-id e ajustar
coordenadas.
2. Arraste-a para o bloco “app.m.inicial”, e modifique o seu hiperlink como na Figura C12.11. Em
seguida, exclua a entrada arrastada de sua localização original, em “app.m.func”.
Obs.: Note que operações de “arrasto” no editor “Tiles” para blocos distintos irão produzir cópias e
não movimentar o(s) item(ns) copiado(s), como no Windows Explorer, por exemplo.
321
Capítulo C12
Perceba que, como não geramos Colaboração de Seleção neste caso, então iremos modificar a
chamada de menu apontando a URL também para UFs. Outra opção seria removê-la – neste caso,
o usuário entraria sempre por “UF”.
3. Em seguida, edite a JSP “ufTabular.jsp” para inserir o “hiperlink” para nossa manutenção. Para isso,
vamos utilizar pela primeira vez o componente “linkInteligente”.
4. Posicione o mouse ao final da última célula que contém a entrada para o campo “sigla” e acrescente
uma nova célula conforme a Figura C12.12.
Figura C12.12. Ajuste na página “ufTabular.jsp”, para incluir hiperlink para Municípios.
#1. Nova célula para conter o hiperlink. Lembre-se de colocar uma célula vazia na linha de
cabeçalho também, para manter igual o número de colunas, entre as linhas.
#4. Em “link” deve-se informar o literal completo, na forma exemplificada, e uma expressão
“#{item.id}”, que irá ser substituída pelo Object-Id da UF corrente. Obs.: É importante
informar a cláusula “exibeSe”, para que a tag “linkInteligente” funcione apropriadamente.
322
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
Veja como está o fluxo de navegação de toda a nossa aplicação, até este momento, na Figura C12.15.
Figura C12.15. Fluxos de navegação das várias Colaborações desenvolvidas, com a Colaboração atual em
destaque.
Desta vez, para acrescentar uma nova Coluna ”NOT NULL” em uma Tabela existente, teríamos um
trabalho bem maior que antes. Isso porque os SGBDs relacionais não aceitarão um simples “ALTER
TABLE” para esta tarefa, uma vez que as Tabelas de “FUNCIONARIO” e
“UNIDADE_ORGANIZACIONAL” já contém dados.
Digo “teríamos” porque, em nosso caso, julgamos aceitável usar um “Alter Table” acrescentando
esta coluna permitindo nulos. Em nosso caso, esta concessão não chega a ser problemática
porque:
o Quando pedirmos o esquema para produção, ele será gerado corretamente, com NOT NULL.
o Em tempo de teste, o próprio Hibernate/JPA executa validações de “nullable=false” na camada
da aplicação, antes de deixar “seguir para o SGBD”. Assim, possíveis “furos” de programação
em função de testes seriam capturados, apesar da diferença de esquema.
323
Capítulo C12
Figura C12.16. Esquema DDL de atualização para Caso de Uso e Solicitação de Mudança.
2. Se clicarmos em “Executar Esquema” agora, vamos descobrir ainda que teremos o mesmo problema
na FK de “Endereco->Município”, que tivemos na FK de “Endereco->UF”: duplicidade de nomes,
devido ao reúso em “Funcionario” e “UnidadeOrganizacional”.
Por este motivo, edite a FK entre “FUNCIONARIO” e “MUNICIPIO” e altere o seu nome para
FK_FUNC_MUNICIPIO. Em seguida, submeta a DDL utilizando “Executar Esquema”.
3. Por fim, clique novamente em “Gerar Esquema”, para conferirmos a sincronia entre mapeamento e
esquema no SGBD. Duas cláusulas irão aparece, relativas às duas FKs duplicadas. Iremos conviver e
desprezá-las, a partir de agora, sempre que clicarmos em “Gerar Esquema”.
Figura C12.17. Cláusulas com nomes de FK em Componentes, que não podemos sobrepor em Hibernate.
324
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
2. Clique em um dos hiperlinks. Abre-se o formulário que produzimos no novo Caso de Uso.
Perceba que o formulário já abre com linhas de Detalhe em branco. Preencha algumas linhas e
grave com “F12-Gravar”.
3. Agora aperte F8 (ou clique em “F8-Abrir”). Perceba que voltamos para a manutenção de UF, uma
vez que alteramos o fluxo de navegação para obter este comportamento. Com isso, o usuário pode
selecionar um novo hiperlink, e preencher com produtividade os municípios de todas as UFs.
Importante: Perceba que não há perda de produtividade por parte do usuário, pelo fato de termos
utilizado a combinação de dois padrões, “Manter Classe” e “Manter Agregação Consulta Mestre/Mantém
Detalhe”, em lugar de um só, “Mestre/Detalhe”. Como discutimos, este é um quesito de uma boa
combinação de padrões, por sua vez uma estratégia chave para a maximização do reuso.
2. Realize alterações em sua estrutura para conter a lista de municípios (“combo”), conforme ilustra a
Figura C12.20.
325
Capítulo C12
As modificações anteriores seriam suficientes para se ter uma lista de municípios independente, na
página, mas não para “aninhá-la” com a lista de UFs (recuperar somente municípios da UF selecionada).
3. Finalize as modificações para aninhar as listas, em conformidade com a Figura C12.21.
Figura C12.21. Declarações em tags JSP para aninhar dois “combos” dinâmicos.
Dica: Um macete para se lembrar da notação correta é sempre incluir um nome similar ao “id”
do próximo campo (endereco_municipio), mas com pontos no lugar dos sublinhados.
- Trabalhando com listas aninhadas via Ajax – Edição de Camada Controle VII
Para finalizar a programação declarativa para a obtenção de listas ou “combos aninhados”, precisamos
ainda fazer declarações da camada Controle, nos metadados “package-info.java” para a Colaboração
“unidadeorganizacionalman”.
Faça os ajustes, conforme a Figura C12.24.
326
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
#2. A propriedade origem deve ser informada, com caminho completo a partir da classe Raiz da
Agregação, com notação de pontos.
#3. A propriedade de destino também deve ser informada de forma similar à de origem.
Figura C12.25. Declaração de metadados de camada Controle para listas aninhadas, em “funcionarioman”.
327
Capítulo C12
3. Altere uma “UF”. Note que a lista em “Município” se altera, sem que ocorra a recarga de toda a
página pelo Navegador. Isto é possível devido ao uso de tecnologia Ajax internamente, nas
programações genéricas do jCompany FS Framework.
Perceba que a programação genérica também já recupera os valores apropriados na lista de destino,
em conformidade com o valor de origem selecionado.
328
Implementando o Padrão "Consulta Mestre/Mantém Detalhe"
Sumário
Neste capítulo, implementamos um Caso de Uso não previsto inicialmente, “UC001.3 Manter Municípios
de UF-”, e um série que pequenas revisões em Casos de Uso anteriormente desenvolvidos, impactados
pela Solicitação de Mudança “SM001 – Introdução de Municípios”.
Vimos facilidades reunidas no jCompany para se alterar Entidades, seus mapeamentos e DDLs
associadas, bem como modificar JSPs. Utilizamos um exemplo típico Ajax para prover campos contendo
listas aninhadas de valores, que não exigem recarga de páginas do Navegador - utilizando somente
programação declarativa.
Nos próximos capítulos, iremos personalizar a aparência de nossa aplicação, compreendendo mais a
fundo os leiautes e bibliotecas CSS da camada Visão do jCompany FS Framework.
329
Capítulo C12
330
Capítulo
13
Implementando o Padrão
3
1
C
"Manter Coleção"
- Analisando a Especificação
A nalisando o estereótipo do Caso de Uso da especificação da Figura C13.1 vemos que, como no caso
anterior, neste também desenvolveremos uma solução de manutenção de nível secundário, ou seja,
voltada para a manutenção de objetos que participam como Detalhes em uma Agregação, mas não são
persistidos na mesma transação que o objeto Raiz/Mestre.
Neste caso específico, deveremos manter objetos da classe “ProventoDesconto”, que por sua vez
participa da Agregação de “Funcionario”. Esta classe Raiz e outras da sua Agregação foram mantidas pelo
Caso de Uso Padrão primário "Manter Agregação Mestre/Detalhe", no capítulo 8.
Figura C13.1. Diagrama de Casos de Uso para “UC004 Registrar Proventos e Descontos!”.
No caso anterior, optamos por separar a manutenção de “Uf” e “Município” em dois Casos de Uso
Padrões, para reutilizar as vantagens de caching e da entrada tabular do padrão “Manter Classe” - porque
a população da classe Raiz/Mestre “Uf” era pequena e estável.
Neste novo caso, as motivações são outras:
o Os proventos e descontos do Funcionário são eventos registrados por pessoas distintas (Ator
“FolhaPagamento”) e em momentos distintos.
o A entrada de dados de descontos e proventos é realizada em lote, através de digitadores que
partem de um pré-registro em papel, contendo o CPF de um funcionário, o número de dias
trabalhados, valores de proventos e descontos extras, no período (mês) de trabalho.
331
Capítulo C13
Perceba que projetar “ProventoDesconto” como uma composição “Mestre/Detalhe” seria possível, mas
implicaria em uma associação OneToMany perigosa e desnecessária, entre “Funcionario" e
“ProventoDesconto”. Esta associação implicaria em uma navegação que provocaria uma recuperação
progressivamente maior de objetos de “ProventoDesconto”, ao longo do tempo, quando recuperássemos
Funcionário. A especificação de “ProventoDesconto” sem o estereótipo “plcDetalhe” tem objetivo claro de
evitar este risco - ela reforça a característica unidirecional de navegação, de “ProventoDesconto” para
“Funcionario”.
Por todos estes motivos, o projetista optou por indicar o uso de um outro padrão de manutenção também
secundário, mas diferente do anterior, chamado “Manter Coleção”.
#2. O tamanho para nossa data será 8, para incluir os 7 (sete) caracteres MM/AAAA e ainda prover
um espaço que algumas peles terminam por exigir, para uma melhor visualização. (Pode-se
utilizar exatamente 7 e verificar como se comporta, ajustando o nosso estilo se necessário).
#3. O primeiro campo do tipo String é assumido para o campo de referência (toString) da classe.
O “anoMesReferencia” será coletado apenas com a sua parte "mês" e "ano" no formulário, graças
ao componente JSF que utilizaremos. Porém, quando chegar à Entidade, já estará convertido para
uma data válida completa, do tipo "java.util.Date", com "01" assumido no dia.
Ex.: um valor informado “02/2008” chegará como data com valor “01/02/2008
00:00:00.000000”.
332
Implementando o Padrão "Manter Coleção"
Por este motivo, não faria sentido validar máscara para esta data na Entidade - ela sempre seria
correta.
Mas em alguns casos pode-se julgar compensador validar se o dia é realmente "01". Há cenários
onde pode ser importante ter o dia exatamente registrado como "01", e não como um aleatório
qualquer, e esta validação pode ser uma garantia dupla quanto a eventuais erros em componentes
visuais.
Em casos como este, cujos tratamentos são para erros potenciais de programação, é recomendável
que se encapsule a regra na implementação concreta da Entidade (“ProventoDescontoEntity”), e
não na abstração de negócio (“ProventoDesconto”). Veja exemplo na Figura C13.3.
Agora, garanta quanto à validação de "data no passado" e parte temporal, com as anotações que
já vimos anteriormente.
333
Capítulo C13
Figura C13.8. Primeira tela do Assistente de Criação “Manter Classe” para “ProventoDesconto”.
Figura C13.9. Segunda tela do Assistente de Criação “Manter Classe” para “ProventoDesconto”.
*
Verifique se sua versão já não possui este suporte, que estava previsto para 1º. Semestre de 2008, no momento desta escrita.
Porém, mesmo que exista, é recomendável seguir o tutorial para fluência em adaptações manuais.
334
Implementando o Padrão "Manter Coleção"
Figura C13.10. Terceira tela do Assistente de Criação “Manter Classe” para “ProventoDesconto”.
*
Poderíamos usar qualquer nome, mas ao optar por usar a convenção padrão de nomenclatura do leiaute universal evitamos ter de
criar uma definição de leiaute Tiles específica. Inclusive é por este motivo que o projetista já especificou com os nomes padrões...
335
Capítulo C13
#1. Nome com sufixo padrão para página JSP de argumento, em “Manter Coleção”.
Este componente foi utilizado porque possui a facilidade de recuperação de um objeto a partir
da digitação de valor para qualquer propriedade da classe “vinculada”, tal como o “cpf”. Ele nos
atenderá para o caso do “cpf recuperando o funcionário”, bastando que declaremos a
"autoRecuperacaoPropriedade" e também o "idTamanho", conforme a Figura C13.12.
#4. Componente de data de referência, utilizando máscara “MM/yyyy”* e converter especial para o
caso: “converterDataMascaraParaArgumentoPlc”.
Importante: Note que também explicitamos o 'required="true"' nos dois campos. Neste caso, estes
são campos transientes, auxiliares, que não irão "herdar" seus tamanhos e obrigatoriedade de
propriedades de nenhuma entidade.
*
Estaremos utilizando português diretamente em JSPs a partir daqui, para efeito de simplificação dos tutoriais apenas. A sugestão é a
de que títulos e rótulos sejam agrupadas no arquivo “ApplicationResources.properties”, para facilitar revisões, mesmo que não se
necessite de I18n.
336
Implementando o Padrão "Manter Coleção"
#1. (Opcional) Se quisermos manter a facilidade de pesquisa com “URL RESTful” para pesquisas
contendo datas com máscaras diferentes e “DD/MM/YYYY” (nosso caso), teremos que criar
uma classe de Action especifica para realizar um ajuste na montagem deste argumento de
data. Sugerimos que não seja feito no tutorial (apenas confira o código da classe
ProventoDescontoAction, mais adiante)
#3. Uso de entrada em lote, para facilitar digitações massivas de dados, muito comum quando
utilizando o padrão “Manter Coleção”*.
#4. Informe este indicador para desabilitar o recurso de “URL RESTful” para esta Colaboração
(URL). O usuário não poderá colocar a pesquisa em “Favoritos” ou enviá-la por e-mail, mas
este não costuma ser um quesito essencial em Casos de Uso “Manter Coleção”.
(Opcional) Se for desejado preservar o recurso e “URL RESTful”, não adicione este parâmetro e
mantenha a declaração da classe ProventoDescontoAction, conforme indicada em #1.
#5. Argumentos (campos livres, desvinculados do modelo de domínio) que serão utilizados tanto
para recuperação quanto para replicação de valores, para os itens de “ProventoDesconto”
informados.
Quando argumentos são informados aqui, o jCompany mantém um Map interno, criando “campos
dinâmicos” em tempo de formulário somente, que podem ser referenciados em componentes JSF
da forma que vimos na Figura C13.12:
value="#{plcLogicaItens.argumentos.funcionario.valor}"
ou
value="#{plcLogicaItens.argumentos.anoMesReferencia.valor}"
*
Pode-se retirar o “detalheLembra=true”, se gerado para a tabular, para otimização (não mantém em memória imagem anteriormente
recuperada dos itens).
337
Capítulo C13
Importante: Note que a recomendação é que se evite programações deste tipo, já que a funcionalidade
principal deste Caso de Uso funcionará independente deste recurso adicional! Somente implemente este
tipo de código quando tiver certeza de que os usuários precisam e utilizarão este recurso (Gravar
pesquisa em Favoritos ou enviá-la como link por e-mail para outros).
package com.empresa.rhtutorial.controle.jsf;
import java.util.Map;
import com.powerlogic.jcompany.comuns.PlcArgVO;
import com.powerlogic.jcompany.comuns.PlcException;
@Override
value = "01/".concat(value);
value = "01/".concat(value.substring(0,2)).concat("20").concat(value.substring(3,2));
argAnoMesReferencia.setValor(value);
return super.montaMapaArgumentosApos(_argumentos);
Figura C13.15. Declaração de evento Javascript, com chamada para função local.
2. Em seguida declare uma seção “script” local à página (mas fora do laço de “plcf:iteracao”!),
conforme a Figura C13.16.
338
Implementando o Padrão "Manter Coleção"
#3. Uso de função “getValorJsf”, passando “id” do campo e a “linha corrente”. Esta função facilita a
montagem do nome padrão do campo gerado em HTML pelo Apache Trinidad, especialmente
quando usando iterações. Por exemplo, neste caso, o nome em HTML teria a seguinte anatomia
padrão, para o campo ‘naturezaProventoDesconto’ na primeira linha:
“corpo:plcLogicaItens:0:naturezaProventoDesconto”
#4. A função “getObjetoJsf” trabalha de forma similar à anterior, mas devolve uma referência ao
campo de formulário HTML, permitindo alterações de estilo dinamicamente. Em nosso caso,
estamos escondendo os campos “valor” e “descricao". Perceba a possibilidade ilimitada que se
tem em mãos, podendo-se manipular estilos CSS dinamicamente.
#5. A função “setValorJsf” é análoga à “getValorJsf”, mas para alterar um valor de um campo
dinamicamente.
#6. Função Javascript padrão para envio de alertas. Neste caso, definimos uma mensagem
internacionalizada, como exemplo de seu uso em Javascript. Lembre-se de importar a Tag
“fmt” na página e incluir a mensagem abaixo no arquivo “ApplicationResources.properties”:
#7. A última condição é para assumir valores default para “descricao" e “valor”, se o usuário
selecionar natureza “DT”.
339
Capítulo C13
3. Submeta a modificação.
Figura C13.18. Formulário para entrada de Proventos e Descontos, em leiaute padrão para Colaboração
“plcCrudTabular”.
2. O primeiro campo de argumento recebe o CPF e recupera o nome do funcionário, utilizando a nossa
NamedQuery. O segundo argumento recebe o período no formato “MM/yyyy”.
Perceba que, embora o formulário tenha semelhança com o leiaute “cabeçalho e itens” de
formulários “Mestre/Detalhe”, neste caso há algumas diferenças sutis, mas importantes:
o A classe “Raiz” (“Funcionario”, no exemplo) não é mantida, o que é característica dos Casos de
Uso de Manutenção Secundários. Mas ela é recuperada sem que se saia do formulário. Sua
referência é copiada para todos os “itens” (“ProventoDesconto”), automaticamente.
o Outros argumentos que não compõem a classe “Raiz”, mas que são comuns a todos os itens,
podem ser utilizados no cabeçalho e também são replicados automaticamente para estes itens.
É o caso do “anoMesReferencia”.
Note que os valores de Proventos e Descontos, tal como em Detalhes, podem ser entrados em lote,
sem uso de mouse, de forma bastante produtiva para usuários.
3. Altere a “naturezaProventoDesconto” para valores “IR” ou “SF”. Nosso Javascript atua, alterando
dinamicamente e impedindo preenchimento dos demais campos, além de apresentar a mensagem,
como mostra a Figura C13.19.
340
Implementando o Padrão "Manter Coleção"
#2. Ao tentar selecionar "04-Salário Final Calculado" ou "05-Imposto de Renda Calculado", valores
eventualmente preenchidos nos campos à direita são limpos. Os campos em si são escondidos
e uma mensagem também alerta o usuário.
4. Após preencher os dados corretamente e gravar, veja que os dados de cabeçalho são mantidos, mas
novos detalhes são criados, para facilitar entradas de dados para novos argumentos. Este é o
comportamento padrão quando utilizamos a opção “entradaEmLote=true” para a Colaboração. Se
não a tivéssemos utilizado, os dados recém gravados de itens permaneceriam visíveis na página,
após a gravação.
5. Tente agora clicar em “Limpar” e/ou limpe os campos de argumento e clique em "F12-Gravar". Veja
que os campos de argumento estão sendo devidamente validados.
Nos próximos tutoriais, utilizaremos os valores gerados nesta entrada de dados para a rotina de Cálculo
da Folha.
341
Capítulo C13
Sumário
Neste capítulo, implementamos um segundo tipo de Caso de Uso Padrão de Manutenção “Secundário”,
assim considerado por manter objetos de classes que compõem uma Agregação, mas que não são
mantidas juntamente com objetos da classe Raiz.
No caso específico do padrão “Manter Coleção”, vimos que ele se caracteriza por possibilitar a entrada em
lote e em formulário tabular (desnormalizada, para vários objetos simultaneamente), semelhante em
termos de GUI ao padrão “Manter Classe”, porém com foco em classes com grande população de objetos.
342
Implementando o Padrão "Manter Coleção"
343
D
Módulo
Interfaces com o
.
D
Usuário
Este módulo reúne tutoriais para a aplicação de um Web-Design específico na
aplicação “RH Tutorial” e explicações arquiteturais sobre Gestão de Leiaute (“Visão
de Interface com o Usuário”) do jCompany FS Framework.
344
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
345
Capítulo
14
Embelezando Aplicações
4
1
D
jCompany
V amos partir, neste capítulo, de um Web-Design estático, produzido em menos de uma hora por um
Web-Designer amador (este autor), com o uso do software Xara Web-Style
(http://www.xara.com/products/webstyle)*.
A página da Figura D14.1 é um exemplo básico de Web-Design que pode ser realizado em tempo recorde
por produtos de mercado. O Web-Designer somente teve o cuidado de indicar os pontos do projeto visual
onde previu a entrada dos conteúdos dinâmicos, tais como menus e formulários.
Nosso trabalho é aplicar as partes dinâmicas conforme descrito, obedecendo às cores, fontes e tamanhos
definidos pelo Web-Design, além de conferir e otimizar o seu trabalho, no momento da montagem.
Figura D14.1. Web-design livre básico, produzido em uma hora com Web-Style.
#1. Conteúdo estático para o topo, com logotipo e trabalho artístico para a empresa ou aplicação.
Costuma incluir, no mínimo, o logo da empresa, nome ou sigla da aplicação e alguma sentença
opcional. Um comportamento padrão de usabilidade Web é que, ao clicar no topo/logo,
voltemos para a página principal (home-page) – teremos que implementar este recurso.
#2. A área horizontal para o conteúdo de menu foi reduzida pela arte, mas o Web-Design deixou
espaço suficiente para acomodar as opções dinâmicas. Teremos que incluir o nosso menu
dinâmico aqui, pois um menu estático limitaria nossa segurança visual e outros recursos
interessantes. Para isso, temos a cor de fundo e a fonte do texto definidas, que teremos que
seguir.
#5. Na parte da direita, teremos que manter a barra do jCompany, que contém diversas opções
para troca de pele, leiautes, notas de liberação, “quem está on-line?”, etc..
*
O Web-Style não é um produto gratuito (custa cerca de U$ 70,00), mas apenas de minha preferência para prototipações rápidas de
Web-Design. Naturalmente, existem diversas outras opções nesta área, indo desde produtos gratuitos até dispendiosas suítes
profissionais.
346
Embelezando Aplicações jCompany
A Figura D14.2 traz uma segunda arte para ser incluída somente na página de autenticação (login). Além
disso, esta página sofrerá apenas modificações de estilo.
O nosso Web-Designer deixou também um arquivo de CSS com estilos diversos para ajustar tamanhos e
fontes de texto, em situações diversas, estilo de formulários, botões, etc.. Teremos contato com o
restante deste material, ao longo dos tutoriais.
- Sobre o Tiles
O primeiro framework de camada Visão que deveremos conhecer, para efetuar customizações, é o Tiles.
O Tiles é um dos frameworks para “Gestão de Leiautes” mais populares do mundo, desenvolvido pelo
francês Cedric Demoulin e largamente utilizado pela comunidade Struts, desde 2001.
Mesmo com o surgimento do JSF, como alternativa do padrão Java EE ao Struts, o Tiles permaneceu
como um produto diferenciado, especialmente por prover recursos de Orientação a Objetos, tais como
encapsulamento e herança, à problemática de leiaute. Também por advento do JSF, foi promovido para
um projeto principal do portal Apache Jakarta (antes se tratava de um subprojeto dentro do projeto
Struts), pois pode ser utilizado por quaisquer dos frameworks mais tradicionais para camada
Visão/Controle: o Struts 1.x, o Struts 2.0 e o JSF*.
O Tiles não é a solução de “Gestão de Leiautes” mais simples do mercado, mas é uma das mais
poderosas. Sua sofisticação permite ao jCompany, por exemplo, prover uma arquitetura de
Inversão de Controle (IoC) também para a camada Visão. Com este recurso, o jCompany pode
generalizar um controle MVC totalmente, provendo resultados completos, em nível de Caso de Uso.
Não será possível, no escopo deste livro, prover uma introdução minuciosa sobre frameworks de base
como o Tiles, mas uma rápida pesquisa no Google e pelo portal Jakarta trará vários hiperlinks úteis para
este fim, em ranking apropriado. Quaisquer livros sobre Struts ou JSF, alternativamente, também trarão
capítulos dedicados ao Tiles.
Apesar desta limitação, tentaremos prover informações suficientes para que o leitor possa acompanhar o
tutorial com um razoável nível de compreensão, que pode ser melhorado com um aprofundamento
posterior no Tiles em si.
*
Existem outros frameworks alternativos ao Tiles, e muitas vezes a questão de leiaute é resolvida sem nenhuma “gestão”, apenas
como algum mecanismo de “template”. Mas iremos expor os benefícios de se pensar de forma OO, também nesta área.
347
Capítulo D14
- O que é um leiaute?
De uma maneira introdutória, nos referimos ao leiaute de uma aplicação como o corte estrutural da
Interface com o Usuário que delineia áreas distintas, separando as que variam em maior
freqüência (Ex.: corpo) das mais invariáveis (Ex.: topo, menu, rodapé). Muitas vezes, incluímos neste
escopo de definição também os conteúdo para as partes invariáveis em si (Ex.: conteúdo do topo,
conteúdo do rodapé, do menu).
Um corte típico de leiaute de “primeiro nível” segmenta quatro partes: topo, menu, rodapé e corpo. Em
uma aplicação produzida pelo jCompany, esta estrutura de leiaute é destacada na Figura D14.3.
Poderíamos parar por aqui, no primeiro nível, mas ainda teríamos uma visão arquitetural pobre, bem
abaixo do que se pode obter de uma boa “gestão de leiaute”.
Aprofundando mais um nível em cada corte primário, destilamos novos “cortes padrões”, representados
na Figura D14.4.
#4. Finalmente, o corpo do leiaute também é subdivido em dois, um bloco de ações (botões e
hiperlinks principais), e outro bloco contendo o formulário em si, ou seja, a parte mais variável
do leiaute.
348
Embelezando Aplicações jCompany
#1. Área da esquerda, destinada às possíveis ações específicas, complementares (não há nenhuma
no exemplo em questão, mas veremos exemplos mais adiante neste livro).
Para conceber uma arquitetura de leiaute rica, que maximize o reuso, será preciso refinar uma
visão primária de leiaute em mais níveis, de modo a delinear claramente as fronteiras entre
componentes reutilizados, da arquitetura, e específicos, da aplicação.
Obs.: Existem diversas outras seções e componentes opcionais, não visíveis neste exemplo introdutório,
que veremos no desenrolar deste módulo. Além disso, pelo menos sete outras variações principais, além
do leiaute “classico”.
Estas “partes” demarcadas do leiaute dispensam artefatos específicos (redundantes!) em cada aplicação,
diminuindo assim o esforço em mantê-los, ao longo do tempo. Além disso, garantem maior
homogeneidade na aparência e operação entre diversas aplicações, melhorando a usabilidade e, por
conseqüência, produtividade dos usuários finais.
349
Capítulo D14
Customização Ideal
- Práticas esperadas
Para o nosso desafio presente de customização, descrito no início deste capítulo, poderemos trabalhar
com a Customização Ideal, já que a definição do novo Web-Design não conflita com nenhum esquema
pré-definido de arquitetura do jCompany FS Framework. Neste nível de customização, de um modo
geral, iremos:
o Prover conteúdos específicos para pontos de extensão (“partes” previstas para especialização) da
arquitetura de leiaute.
o Customizar conteúdos para partes genéricas do leiaute, previstos para substituição (tais como o
“topo” e o “logotipo” da página de login).
o Criar um novo conjunto de estilos CSS (ou seja, uma nova “pele”), para alterações de cor, fonte,
tamanho, etc..
*
Somente a definição Tiles em XML do leiaute principal é definida na aplicação “rhtutorial”, no arquivo “app-tiles-pagina1.xml” para
facilitar customizações globais. As diversas páginas JSP “PlcGeralLayout.jsp”, que “implementam” a definição de leiaute, em suas várias
variações padrões (“clássico”, “sistema”, “oriental”, etc.), ficam no framework. Note que uma implementação JSP está para uma
definição XML de leiaute Tiles, assim como uma classe de implementação Java está para uma Interface. Esta arquitetura será discutida
em detalhes, no próximo cap
350
Embelezando Aplicações jCompany
2. Digite um texto de teste, conforme a Figura D14.7 (Em um caso real, estaríamos incluindo novos
botões ou outros objetos mais interessantes).
Note que o texto que aparece na parte esquerda dos rodapés está definido de forma específica nesta
página do projeto (e não no framework), exatamente para que seja modificado, seja para toda a
empresa na camada Bridge, seja para cada projeto específico.
4. Se você está com o “jCompany Hot Deploy” ativo, pode testar imediatamente as modificações que
fizemos. Senão, ative-o e utilize desta vez uma “Liberação Rápida para Tomcat” (certifique de estar
com o projeto principal em foco).
5. Confira o resultado com o da Figura D14.9. Importante: Modifique o leiaute para “classico”, para
acompanhar melhor os tutoriais, a partir daqui.
Note que, em uma arquitetura refinada de leiaute, é possível se estender uma solução de base sem
redundar partes que não variam, mantendo a mesma aparência e ergonomia (“look-and-feel”) para o
usuário. É um processo similar ao que conhecemos em Java como “programação por exceção” ou “pela
diferença”, mas aplicado ao leiaute, na camada Visão.
351
Capítulo D14
Mas como aconteceu esta “mágica”? Note que criamos uma nova JSP e ela substituiu a um
“segmento” de nossa página Web, funcionando como um componente de leiaute...
O que fizemos foi sobrepor a página original que compunha aquela parte do leiaute, definida no projeto
“jcompany_visao”, na mesma estrutura de diretório “WEB-INF/jsps” e de mesmo nome,
“geralTopoComponentePlc.jsp”. Graças a uma convenção utilizada na liberação das rotinas Maven,
componentes mais específicos substituem os originais, se existirem em níveis mais refinados de
detalhamento, conforme mostra o diagrama da Figura D14.13.
352
Embelezando Aplicações jCompany
#1. O projeto “jcompany_visao” contém artefatos genéricos da camada Visão, tais como JSPs de
leiaute (que definem a estrutura de leiautes), JSPs de componente (que compõem a estrutura
de leiautes), CSS, mídia, Javascript específicos, Javascript DOJO, XMLs de configuração e
outros, utilizados tanto com a tecnologia JSF quanto com Struts.
#3. O projeto “jcompany_visao_jsf” contém artefatos adicionais específicos somente para JSF,
tais como componentes especializados do Apache Trinidad, arquivo de configuração “faces-
config.xml”, JSPs específicas para JSF, etc..
#4. O projeto “rhtutorial” reutiliza artefatos dos projetos Eclipse citados nos itens 1 e 3 da figura.
Deste modo, evita ao máximo a redundância indesejável.
#5. As rotinas Maven do jCompany mesclam os artefatos de todos estes projetos nas liberações,
priorizando os artefatos mais especializados, que deste modo podem conter sobreposições
refinadas de apenas parte das soluções genéricas, sem reinventá-las por completo.
A Figura D14.14 mostra um cenário mais corporativo, onde a empresa usa a camada Bridge* para
sobrepor e alterar quaisquer padrões do jCompany, para toda a empresa.
*
Relembrando que a camada Bridge é formada por um conjunto de projetos que provêem um espaço arquitetural amplo para a
empresa isolar o jCompany FS Framework e incluir quaisquer generalidades que sejam necessárias para sua própria realidade,
sobrepondo ou especializando o framework.
353
Capítulo D14
- Criando uma nova pele (conjuntos harmônicos de estilos CSS, Javascript e Mídia).
Um terceiro passo típico da Customização Ideal de interfaces com o usuário, é a criação de uma “pele”
própria para a empresa, que reflita suas preferências de cor, tamanho e tipo de fontes de textos,
alinhamentos, sombreamentos, destaques e quaisquer outros quesitos de Web-Design.
A melhor forma de se fazer isso é copiar um dos diretórios das peles, presente no projeto
“jcompany_visao”, escolhendo o que melhor se aproxima das cores e estilos requeridos pelo Web-
Design. No nosso caso, escolheremos a pele “azul”.
1. (Versões Oficiais) Para facilitar, importe para o Eclipse o projeto “jcompany_visao”, utilizando no
Eclipse o menu “File-> Import... -> Existing Projects into Workspace” e selecionando como “root
directory” o projeto “[jcompany_base]\meus_projetos\jcompany_visao”. Este projeto
contém todas as peles pré-definidas do jCompany.
(Versões de Avaliação) Como a versão de avaliação não vem com este projeto, uma cópia do
diretório da pele “azul” é disponibilizado abaixo do diretório
“[jcompany_base]\jcompany_documentacao\rhtutorial\gui\azul” para apoio a este tutorial.
2. Com o projeto configurado no Eclipse em versões oficiais (ou através do Sistema de Arquivos, no
caso de versões de avaliação), abra o diretório para a pela “azul”, conforme ilustrado na Figura
D14.15.
354
Embelezando Aplicações jCompany
#1. Diretório da pele. Cada um encapsula todos os arquivos que definem uma das peles disponíveis
nas paletas do jCompany.
#2. Arquivos de mídia utilizados para compor o topo padrão da pele, implementado pela página JSP
“principalTopoPlc.jsp”. No nosso caso, não serão utilizadas, e poderão ser excluídas após a
cópia.
#3. Arquivo “PlcLogin.css”, contendo estilos CSS utilizados pela página de login.
#4. Arquivo “PlcPele.css” principal, contendo definições dos estilos da aplicação específicos da pele.
#5. O arquivo “PlcPele256.css” é mantido para compatibilidade com versões passadas, sendo uma
opção originalmente existente no jCompany para monitores com baixa resolução de cores
(256). Com a realidade atual, encontra-se em desuso, e pode ser excluído para a nova pele.
#7. Demais imagens específicas da pele, que normalmente incluem botões de expansão e retração,
imagem de fundo do topo, etc.. Obs.: Imagens que não são específicas de uma pele devem
estar no diretório “/plc/midia”*.
3. Agora copie o diretório acima e cole-o no projeto “rhtutorial”, abaixo do diretório “css”. Importante:
Se você está utilizando a cópia de avaliação, copie este diretório de
“[jcompany_base]\jcompany_documentacao\rhtutorial\gui\”
4. Troque seu nome para “acme” (nome de nossa empresa hipotética) e exclua arquivos que não serão
necessários. Confira o resultado com o da Figura D14.16.
5. Atualize a página da aplicação, trocando a pele através do parâmetro de URL “pelePlc”, ou seja,
chamando http://localhost:8080/rhtutorial/f/t/uf?pelePlc=acme. O resultado, por enquanto, será
uma pele no estilo “azul”, como na Figura D14.17*.
*
Como já vimos, estas convenções de diretórios são importantes, pois o jCompany registra filtros de caching para imagens, utilizando
estes diretórios como padrões, no arquivo “web.xml”.
355
Capítulo D14
Figura D14.17. Pele “acme” sendo chamada na URL, por parâmetro padrão “pelePlc”.
Agora vamos modificar um estilo, apenas para verificar se estamos realmente no controle da situação
utilizando Cascade Style Sheet (CSS)†.
Para acharmos um estilo CSS específico, a ser modificado, podemos partir da investigação do HTML
renderizado no Navegador. Por exemplo, para modificar o título de cada subseção de menu, procuramos
pelo termo “Unid. Organizacional” no HTML e verificamos sua marcação de estilo. Vamos fazê-lo, passo a
passo.
6. Clique direito na página renderizada no Navegador e clique em “View Source/Ver Código Fonte” (IE)
ou “View Page Source/Ver Código-Fonte da Página” (Mozilla).
7. Procure no texto por “Unid. Organizacional” (utilizando “Control+F”) e, em seguida, pelos atributos
“class”, “id” ou “style” no bloco de Tags que circunda o texto desejado. No nosso caso, a Tag que
circunda o texto é uma Tag “div” (uma outra comum é a de colunas de tabelas, “td”), e o atributo de
estilo utilizado é o “class”.
*
Se não funcionar, faça uma “Liberação Rápida para Tomcat” e confira se o “jCompany Hot Deploy” está ativo.
†
A área de Web-Design exigirá conhecimentos da tecnologia de CSS, além de HTML e até um pouco de Javascript, para produzir os
resultados mais interessantes. Se for de interesse, pesquise pelo assunto na Internet – há conteúdo vasto e, em geral, de boa
qualidade sobre todas estas tecnologias.
356
Embelezando Aplicações jCompany
Figura D14.19. Código fonte HTML com partes que interessam em destaque.
8. Agora procure no Eclipse, dentro do arquivo “PlcPele.css”, pela definição da classe de estilo
“menu_barra_titulo” (Utilize “Control+F” após editar o arquivo). Repare que os atributos “class”
aparecem no arquivo CSS prefixados com “#”.
9. Em seguida, altere as cores “azul claro” (#C8DEEC) e “azul escuro” (#3D4F57) por “cinza”
(#9FACB4) e “branco” (#FFFFFF)*. Deste modo, modificamos a cor do texto e do fundo,
respectivamente.
Importante: Note que a simples chamada da página via barra de endereços do Navegador não
exibe a atualização do arquivo de CSS. Você precisará utilizar a opção de “Refresh” ou “Reload”
(Atualizar ou Recarregar) para ver a atualização.
Este comportamento também se deve ao caching declarado pelo jCompany no arquivo “web.xml”,
uma otimização bastante considerável, que evita recarga de arquivos CSS a cada requisição!
*
Como Web-Designer, você precisará de algum software que lhe facilite acesso a códigos das cores, permita algumas edições
WYSIWYG, etc.. Mas como Desenvolvedor, estes códigos lhe devem ser passados resolvidos pelo Web-Designer, com instruções de
aplicação.
357
Capítulo D14
#3. Parâmetro que indica que o conteúdo enviado deve ser mantido localmente, durante 3.600
segundos (1 hora). Pode-se variar este valor, naturalmente.
#4. URLs que são “filtradas”. Repare que a mesma estratégia é utilizada para outros conteúdos
“estáticos”, tais como “mídia” e “Javascript”.
Obs.: Este filtro, na prática, pode incluir qualquer parâmetro no “HEADER” de requisições HTTP,
podendo ser reutilizado para propósitos diversos fora do caching.
358
Embelezando Aplicações jCompany
#1. O arquivo de metadados para empresa fica abaixo do subdiretório terminado com o sufixo
“emp”, enquanto o de aplicação fica no terminado com “app”.
#2. Os dados de nome da empresa, domínio, sigla, etc., devem ser modificados (Nos arriscamos a
dar um nome para a empresa ACME :-).
#3. A URL relativa para acesso ao logotipo que aparece nas páginas de autenticação pode ser
modificada aqui, por exemplo, para permitir o uso de formatos “jpg ou png” ou outro nome no
arquivo. Mas, de modo geral, recomenda-se manter o padrão sugerido, para facilitar a
manutenção.
#4. A pele padrão deve ser alterada para nossa nova pele “acme”.
3. Altere também o título (que aparece na página inicial) com chave “inicial.titulo”, editando o arquivo
“ApplicationResources.properties”, para o mesmo nome.
359
Capítulo D14
#2. Cores da pele azul e que, portanto, ainda devem ser modificadas segundo especificado pelo
Web-Designer, para a pele “acme”.
#3. Indicador de memória, que somente deve ser utilizado para aplicações internas - se desejado.
Este indicador expõe informações internas de memória disponível do servidor, para usuários, o
que pode ser útil para efeito de suporte técnico. No nosso caso, a empresa optou por não
utilizar, e teremos que retirá-lo.
3. Vamos agora retirar a cor de fundo do formulário de login e modificar a cor do botão. Edite o arquivo
“PlcLogin.css” e altere os estilos conforme indicado na Figura D14.27. Estas modificações estão
sendo feitas com base na especificação que está no arquivo “form_login.css” definido pelo Web-
Designer, e também disponível no diretório de recursos que já conhecemos.
#1. Para remover as cores de fundo que delineiam o formulário de autenticação, retiramos a borda
e fundo - mas mantivemos o leiaute e tamanho da classe “loginContainer”.
4. Para impedir a visualização do indicador de memória, vamos utilizar o atributo “visibility” na classe
“div.loginInfo”, que é a utilizada para esta seção do design (vide HTML).
Para tanto, localize esta classe no arquivo, remova os atributos atuais, e utilize “Control+Space”
para ativar o “auto-complete” do Eclipse (neste caso, mais especificamente, do WTP). As várias
opções de declaração CSS serão exibidas, para esta classe. Digita “v” antes do “Control+Space”, se
desejar filtrar as possibilidades.
360
Embelezando Aplicações jCompany
Figura D14.28. “Auto-complete” funcionando para arquivos CSS, após digitação de “v” + “Control+Space”.
#2. Início do nome do atributo CSS (não digite nada para uma relação completa).
5. Selecione “visibility” e aperte novamente “Control+Space”. Agora, uma lista de valores possíveis
para o atributo CSS “visibility” aparecem. Selecione “hidden” (escondido), para não exibir a caixa.
6. Confira o resultado, chamando novamente a aplicação. Em nossa hipótese, o resultado agora está
de acordo com o desejado pelo Web-Design.
Obs.: a técnica de esconder via CSS nos atende porque não julgamos esta uma questão de segurança. O
usuário, se desejar e souber como, ainda conseguirá averiguar os indicadores de memória no código
HTML da página, utilizando a opção dos Navegadores que vimos no início deste capítulo*.
*
Para se retirar definitivamente este segmento ou alterar radicalmente o leiaute da página de autenticação, pode-se proceder da
mesma forma que fizemos para a página de topo “principalTopoPlc.jsp”, sobrepondo a página “loginPlc.jsp” e “loginErroPlc.jsp” (versão
alterada que aparece quando o usuário erra o login ou senha).
361
Capítulo D14
- Modificando o topo
Vamos agora aplicar o novo design ao leiaute principal, proposto pelo jCompany FS Framework, a
começar pelo segmento de topo. Vamos substituir nosso teste de sobreposição do topo, realizado
anteriormente neste capítulo, pelo topo definitivo definido pelo Web-Designer.
1. Copie todos os arquivos de mídia do diretório da especificação de Web-Design para o projeto
“rhtutorial”.
Para tanto, copie todo o diretório “acme” (inclusive esta pasta), que se encontra em
“[jcompany]\jcompany_documentacao\rhtutorial\gui\acme”, para o diretório
“/plc/midia/” do projeto “rhtutorial” no Eclipse. O resultado final deve ficar como na Figura
D14.31.
Figura D14.31. Diretório padrão para mídia, quando não é vinculada a pele.
#1. Diretório de base “plc”, abaixo do qual devem estar todos os recursos organizados dentro da
arquitetura do jCompany FS Framework.
#2. Diretório copiado para “plc/midia”, onde devem estar todos os arquivos de mídia utilizados no
Web-Design da empresa*.
#3. O diretório raiz “/plc/midia” deve conter somente mídias específicas somente da aplicação
corrente.
*
Exceto quando forem variar, de pele para pele, caso em que deverão estar em “plc/css/[pele]”, como veremos mais a frente.
362
Embelezando Aplicações jCompany
2. Em seguida, vamos recortar o trecho de leiaute que define o topo, do novo leiaute produzido pelo
Web-Designer. E, em seguida, aplicá-lo na página “principalTopoPlc.jsp”, que já vimos ser o local
apropriado.
A tarefa mais intrincada para a maioria dos desenvolvedores Java - e, portanto, não
necessariamente experts em Web-Design, é fazer cortes de trechos válidos de HTML (“markups
HTML”). Vamos, portanto dar algumas dicas.
Abra o arquivo HTML principal produzido pelo nosso Web-Designer (na verdade, pelo “Web-Style”),
chamado “acme.htm”, disponível no diretório “jcompany_documentacao/rhtutorial/gui”. Veja
que o Web-Designer utilizou tabelas (tag HTML “<table>”) para delinear o leiaute e que o topo
está definido como algumas linhas de tabela (tag HTML “<tr>”).
3. Precisaremos então recortar estas linhas. Marque o texto que vai da primeira declaração <table>
(após o <body>) até o </tr> representando na Figura D14.32.
#1. O leiaute do topo inicia na primeira ocorrência da tabela “<table>” e termina neste “</tr>”,
que encerra a linha do menu. Portanto, copie o trecho de “<table>” até esta linha.
4. Após copiar este trecho, edite a página “principalTopoPlc.jsp” no Eclipse* e cole o trecho recortado,
substituindo nosso conteúdo anterior de teste. Após colar o conteúdo, feche a tabela HTML, incluindo
uma Tag “</table>” ao final da parte colada.
5. Vamos agora ajustar os caminhos das imagens, que estavam relativos ao diretório raiz da página
estática (iniciando com “acme/”). Eles agora devem estar relativos à raiz da aplicação (ou seja,
iniciando com “${pageContext.request.contextPath}/plc/midia/acme/”). Siga as instruções
da Figura D14.33 para realizar a substituição.
*
Atenção ao editar a página “principalTopoPlc.jsp” utilizando “Control+Shift+R” no Eclipse, se o projeto “jcompany_visao” estiver
aberto (deve estar, pois importamos no início deste tutorial). Neste caso, você irá se deparar com as duas versões desta página, com
mesmo nome. Observe atentamente se está editando a página especializada, do projeto “rhtutorial”. E feche o projeto
“jcompany_visao”, para evitar este problema.
363
Capítulo D14
Figura D14.33. Componente de leiaute “principalTopoPlc.jsp”, com o topo e endereços de imagens ajustados.
#1. Endereços de imagens agora relativos ao contexto da aplicação, apontando para o novo
diretório.
#2. Utilize Replace (Menu “Edit -> Find/Replace...”) para trocar os endereços de imagem, de uma
só vez.
6. Vamos agora copiar os estilos CSS produzidos pelo Web-Designer. Faça o mesmo procedimento de
cópia do passo anterior também para a parte de estilos, copiando o código circundado pelas Tags
<style></style>.
Cole este código na página “principalTopoPlc.jsp” no Eclipse, antes da tab “<table>”, como primeiras
informações da página. Altere novamente o endereçamento das imagens que estão definidas em
CSS (note que o Eclipse “lembra” a nossa última troca, então será somente disparar novamente o
“Replace” anterior).
#2. Replace (Menu “Edit -> Find/Replace...”) utilizado para trocar os endereços de imagem, de
uma só vez, de forma análoga à anterior.
364
Embelezando Aplicações jCompany
7. Teste o resultado, forçando uma recarga da página. O resultado deve ser similar ao da Figura
D14.35.
8. Se você estiver utilizando o Navegador Mozilla Firefox, possivelmente não obteve o mesmo resultado
acima. Devido a pequenas diferenças de comportamento deste Navegador com relação ao IE,
especialmente na renderização de Tags “<div>”, neste caso será necessário um ajuste para redefinir
explicitamente a altura da seção de topo (que é envolta por um “div” com classe “topo_secao”*).
Com isso, agora a visão de topo deve estar apropriada e também “cross-Browser”.
- Modificando o rodapé
Vamos agora realizar um procedimento similar ao que fizemos para o topo, para o segmento de rodapé.
*
As seções principais dos leiautes “tableless” (sem tabela) do jCompany FS Framework são delineadas por Tags HTML “div” com
classes “topo_secao”, “menu_secao”, “corpo_secao” e “rodape_secao”, respectivamente. No caso excepcional do leiaute “sistema”, a
seção de menu Pull-Down tem classe chamada “portaMenuSistema”, como veremos maisa frente.
365
Capítulo D14
1. Corte a tabela que circunda o rodapé do arquivo de Web-Design utilizando qualquer editor, de
acordo com a Figura D14.37.
Note que cortamos duas linhas nesta tabela, sendo a primeira desnecessária, somente para
aproveitar a estrutura de tabela já existente.
2. No Eclipse, edite agora o componente “geralRodapeComplemento.jsp”, que também já alteramos
anteriormente, e cole o conteúdo recortado.
3. Em seguida, retire a primeira linha (que possui o texto “O corpo entra aqui”) e realize a troca de
endereçamento de imagens, mais uma vez. Confira o resultado final com a Figura D14.38.
Perceba que não é bem este efeito que desejávamos porque, na forma em que a arquitetura do
leiaute está concebida, a página “geralRodapeComplemento.jsp” atua somente na metade da
esquerda do rodapé. A metade da direita é reutilizada dos projetos do jCompany FS Framework,
para maximizar o reuso, como já vimos.
Se não fosse a necessidade de montarmos uma imagem para representar a borda da direita do
rodapé “arredondada”, esta arquitetura com reúso nos atenderia, pois conseguiríamos
modificar todo o rodapé, apenas com CSS. Mas em nosso caso, para preservar o bonito efeito
366
Embelezando Aplicações jCompany
das bordas arredondadas, precisaremos de outra técnica que nos permita alterar a estrutura de
todo o rodapé – não somente sua banda da esquerda. Precisaremos, apesar disso, manter as
opções de atalho providas genericamente na banda da direita, como foi solicitado por indicação do
Web-Designer.
Para realizar este nível de modificação da estrutura do leiaute teremos que modificar a definição de
leiaute do Tiles, que fica no arquivo “app-tiles-pagina1.xml”, no projeto “rhtutorial”.
5. Edite este arquivo e localize a definição do leiaute principal. É um XML pequeno, mas que nos
permite modificar diversas das estruturas de leiaute padrão.
Figura D14.40. Arquivo de definição de leiaute Tiles, com radiografia do leiaute principal.
Além disso, dois tipos conjuntos de leiautes distintos são disponibilizados, um no projeto
“jcompany_visao” (que usam Tags HTML “table” para delinear o leiaute) e outro no projeto
“jcompany_visao_jsf” (que usam Tags HTML “div” – chamados “tableless”).
Mas não acaba por aí - o mais sofisticado recurso são os leiautes universais, que criam
“descendentes dinâmicos” de definições de leiautes para formulários do negócio, seguindo
convenções de nomenclatura, o que dispensa os desenvolvedores de codificarem definições
XML de leiaute para cada um de seus formulários.
Esta mesma engenharia pode ser utilizada pela empresa, através da camada “Bridge”, para
criar “leiautes e formulários” genéricos para a empresa, utilizando o arquivo “emp-tiles-
pagina.xml” e as mesmas técnicas do jCompany.
367
Capítulo D14
#2. Os “cortes” primários do leiaute são incluídos como “atributos” no corpo da definição. O único
atributo que não define uma “parte” é o item “titulo”, retirado das JSPs e promovido para a
definição de leiaute em XML de forma a facilitar sua modificação, independente da alteração de
JSPs que implementam o leiaute.
#3. O primeiro componente de leiaute pré-definido é o que define a página JSP de topo, a página
“WEB-INF/jsps/principalTopoPlc.jsp”. Agora entendemos como ela é acionada. Se
desejássemos, em lugar de sobrepor esta página com mesmo nome como fizemos, definir
alguma outra, com nome “principalTopoAcme.jsp”, por exemplo, bastaria alterarmos este
nome no leiaute.
#4. O segundo componente de leiaute é o que define o menu. Perceba que, aqui, temos uma
referência não a uma página JSP que implementa um componente, mas a uma outra definição,
ou “corte de segundo nível de leiaute”, o que é permitido pelo Tiles. Esta outra estrutura irá
subdividir o segmento de menu do leiaute principal.
#5. Este componente será o motivo de nossa customização “estrutural”, pois define o “subleiaute”
(corte secundário do leiaute) para o componente “rodape".
#6. A parte de corpo é aquela tipicamente variável em cada Colaboração do jCompany, pois
conterá JSPs de formulário específicos, em cada caso. A definição de “corpo” default do leiaute
principal vem com uma definição secundária de leiaute, “def.tab.app.home”, que define as
seções de “tab-folders” que aparecem na página principal da aplicação.
#7. O leiaute “def.componente.acoes” é um corte de “terceiro nível”, que ilustramos no início deste
capítulo, criando uma área ao lado da área genérica de “ações” (ou barra de botões).
Note que não vemos aqui a definição de segundo nível, que aponta para
“def.componente.acoes”, pois esta se encontra generalizada em nível da arquitetura pelo
jCompany. Trata-se de uma definição genérica para o “corpo” do leiaute principal, que define
“barra de mensagens, barra de ações e formulário”, e que possui controladores Tiles
sofisticados para o leiaute universal e outros recursos.
#8. O nome da JSP que irá “complementar” a barra de ações também pode ser modificado.
Aplique a modificação exemplificada no item #9. Perceba que transformamos a nossa página de
complemento em um leiaute completo. Isto significa que não iremos mais querer, para este trecho
do leiaute, que o mecanismo de “Inversão de Controle” atue. Neste mecanismo, o leiaute
“geralRodapeDojoPlc.jsp” definido no framework era ativado incluindo generalidades e também
a página “geralRodapeComplemento.jsp”.
*
Os numeradores que sufixam os nomes dos arquivos deixam claro que é possível se ter vários destes arquivos (app-tiles-
pagina2.xml, app-tiles-pagina3.xml, etc.). Para tanto, basta criá-los e acrescentar sua definição para o Servlet do Tiles, que fica
declarado no arquivo “web.xml”. Esta prática, porém, caiu em desuso no jCompany, após a liberação dos leiautes universais, que
diminuíram em 70% a necessidade de se definir leiautes em XML.
368
Embelezando Aplicações jCompany
Da forma como ficou, nossa página específica agora atua diretamente – dizemos que estamos,
portanto, no “controle”.
6. Agora que temos controle total sobre a banda de rodapé, precisaremos inserir os atalhos de
utilitários genéricos do jCompany, à nossa página “geralRodapeComplemento.jsp”. Sem IoC,
precisaremos localizar o(s) componente(s) e incluir explicitamente estas opções. Para facilitar o
reúso neste cenário, o jCompany disponibiliza estes atalhos em uma JSP separada
“geralRodapeDojoEstaticoPlc.jsp”*.
Obs.: A “geralRodapeDojoEstaticoPlc.jsp” é uma versão estática sem o efeito “fisheye” obtido com
o uso do framework DOJO. Esta página não utiliza o DOJO, sendo uma substituta para situações
onde o efeito não pode ser usado. No nosso caso, não podemos usar o “fisheye” neste Web-Design
de rodapé pois o mesmo está baseado em tabelas (lembre-se: o nosso Web-Designer é Trainée, e
teve uma hora para produzir tudo!). O uso de “div” e de menos tabelas oferece mais flexibilidade e
possibilitaria o uso da página “geralRodapeDojoFisheyePlc.jsp”, que preservaria o efeito
interessante do “fisheye”, mas iria requerer um perfil mais avançado por parte do Web-Designer.
7. Faça agora uma “Liberação Rápida para Tomcat com Reinício” (pois modificamos arquivos XML, que
ficam em caching no escopo de aplicação) e confira, em seguida, o resultado. Falta apenas um
arremate de acabamento.
Como reusamos a pele “azul”, restam ainda resquícios de fundo azul no rodapé, indesejáveis.
8. Edite o arquivo “PlcPele.css” para nossa pele “acme”†, para trocar a cor de fundo para branco e
retirar borda, conforme indicado na Figura D14.43.
*
Note que o reúso “específico” exige que se conheçam as “peças” em detalhe, ao contrário do reúso “arquitetural” via IoC. Deste
modo, uma vistoria pela estrutura de componentes do jCompany seria necessária para se encontrar a página
“geralRodapeDojoEstaticoPlc.jsp”, que possui os atalhos para tarefas de rodapé necessárias.
†
Cuidado: como existem vários arquivos com este mesmo nome, em diretórios de peles diversas, feche o projeto “jcompany_visao”
para não correr o risco de editar o de outras peles.
369
Capítulo D14
Procure pela classe “rodape_secao”, que define o rodapé, e não modifique “color” (cor de texto
branca), pois seu estilo atende ao nosso novo design.
9. Lembre-se de atualizar a página do Navegador com o Atualizar/Recarregar (Refresh/Reload) para
forçar a limpeza do caching do CSS. Confirme o resultado final, sem o fundo azul.
- Modificando o menu
Até agora, viemos utilizando um menu de “portal clássico”, pertencente ao leiaute padrão “clássico” do
jCompany. É um menu lateral, que exibe claramente todas as opções disponíveis (melhor para usuários
esporádicos) mas que, em compensação, ocupa muito espaço na página.
Nosso Web-Designer especificou um outro tipo de menu, conhecido como Pull-Down, que é o tipo
utilizado no leiaute “sistema” do jCompany. Este menu é menos apropriado para usuários esporádicos,
mas otimiza o espaço disponível na página, sendo bastante utilizado.
Para aplicar um menu Pull-Down ao nosso leiaute “acme”, vamos iniciar comutando para o leiaute
“sistema”, como ponto de partida. O resultado deve ser o ilustrado na Figura D14.44.
#1. O menu Pull-Down do leiaute sistema aparece em sua posição original, já que é flutuante -
gerado em Javascript.
#2. A barra de fundo do menu, conhecida como “porta menu” (definida pela classe de div
“portaMenuSistema”), aparece relativa ao topo, deslocada do menu em si. Esta barra,
normalmente, deve estar posicionada juntamente com o menu, abaixo dele, para dar aparência
de continuidade à barra flutuante. Nós não a ajustamos porque, em nosso caso, usaremos a
barra presente no Web-Design do topo, de coloração mais escura.
#3. O menu deverá estar sobre esta barra desenhada no topo, dando a impressão de ser parte
integrante de toda a solução de design estática do topo.
Percebemos, então, em uma primeira análise, que teremos que realizar três operações básicas de ajuste:
o Retirar a barra de “porta menu”;
o Posicionar o menu na barra do topo;
o Rever tamanhos de fontes, barras e cores dos rótulos e fundo de menu, para se ajustarem ao Web-
Design proposto.
370
Embelezando Aplicações jCompany
1. Para posicionar o menu na barra do topo, precisaremos achar as coordenadas exatas, vertical e
horizontal, alterando-as no arquivo de Javascript “PlcPeleMenu.js”*. Este arquivo fica no diretório
das peles (no nosso caso “acme”).
Altere estas coordenadas conforme a Figura D14.46. Elas foram obtidas com “tentativa e erro”.
Para destacar os valores customizados, lembre-se de fazer um comentário bem nítido, com o nome
da pele em destaque.
*
A biblioteca Javascript reutilizada e homologada no jCompany, para menus Pull-Down, é a HV Menu (http://www.dynamicdrive.com).
Esta biblioteca possui diversas opções de customização disponíveis, e um trabalho de pré-configuração já é realizado no jCompany, que
registra valores default harmônicos com os leiautes padrões.
Porém, alterações criativas de leiaute podem lançar mão de outros comportamentos interessantes, disponíveis através de simples
alterações de valores das propriedades que o jCompany agrupa neste arquivo. Divirta-se, variando cada delas e observando as
possibilidades – grandes idéias de Web-Design podem emergir...
371
Capítulo D14
2. Para ajustar as cores e fontes do menu Pull-Down somente, edite os estilos também no arquivo
“PlcPeleMenu.js”, já que a biblioteca Javascript homologada não utiliza estilos CSS*.
Na modificação de estilos acima, há uma distinção entre cores da barra principal e das secundárias,
separadas para “cor de fundo” e “cor do texto” e também para “normal” e “com mouse sobreposto
(over)”. Retiramos também as bordas do primeiro nível somente, para o efeito desejado pelo Web-
Designer.
Obs.: A biblioteca Javascript reutilizada permite um número ilimitado de níveis de menu. O
jCompany, no entanto, sugere e facilita o uso de até mais dois níveis de menu, além da barra
principal (ou seja, um além do que temos usado até agora) - isso para serem declarados via XML
Tiles e vistos em vários formatos.
Para mais níveis de hierarquia, o padrão recomendado e estimulado pela arquitetura é utilizar
substituição do menu principal por novas árvores de três níveis, o que é bem simples de se
fazer. Desta forma, evita-se lentidão por conta de renderizações pesadas de Javascript nas
máquinas do usuário e também a má prática de se produzir excesso de hierarquização – o que
muitas vezes pode ser evitado.
3. Retire o comentário que o Web-Design deixou no leiaute, para a seção de menu, trocando-o por um
“espaço HTML”, simbolizado por “ ”. É uma boa prática não deixar colunas sem conteúdo, o
que pode afetar os leiautes.
*
Apesar disso, o jCompany realiza um trabalho de arquitetura que “fatora” as configurações de menu, separando-as de sua
implementação e disponibilizando-as em cada pele. Deste modo a produtividade e efeitos são os mesmos de uma edição CSS,
declarativa e simples. Esta técnica também evita alterações intrusivas na biblioteca de base reutilizada.
372
Embelezando Aplicações jCompany
Figura D14.50. Substituir todo o conteúdo a partir do ponto em destaque, pelo novo.
Apesar de já estarmos vendo “a luz no fim do túnel”, ainda há falhas nos estilos. Veja que, ao
passar o mouse sobre os botões, o estilo para o “hover*” não está funcionando muito bem.
Se olharmos para a definição desta classe, no trecho de CSS copiado, veremos que há referência
no estilo copiado à imagem “acme_panel_bg.gif”, esperando-a no mesmo diretório da pele acme.
*
Modo ativado com a passagem do mouse.
373
Capítulo D14
Figura D14.54. Mudança de local das três imagens que compõem o rodapé.
Figura D14.55. Mudança de endereçamento das duas imagens referenciadas pelo rodapé.
374
Embelezando Aplicações jCompany
Figura D14.56. Mudança de endereçamento das duas imagens referenciadas pelo rodapé.
6. Agora atualize a página para verificar o resultado final. O Web-Designer utilizou o mesmo motivo do
rodapé em algumas barras pela aplicação, mas não conseguíamos ver o efeito devido ao problema
de endereçamento da imagem (aliás, erros em endereçamentos relativos são problemas muito
comuns para iniciantes em CSS).
Estilo Efeito
/* GERAL */
body *{ Alteração dos defaults globais para “fonte”
font-family:"Trebuchet MS", Arial, Sans-serif; (estilo dos caracteres) e tamanho. Estes serão
font-size: 12px; utilizados, a menos que sobrepostos em classes
} mais específicas.
#rodape_secao{
margin-left: 9px; Provê um “respiro” à esquerda e à direita dos
margin-right:3px; cortes primários do leiaute, para topo, corpo e
} rodapé.
#topo_secao{
margin-left: 9px;
margin-right:3px;
}
#corpo_secao{
margin-left: 9px;
}
/* BARRA DE ACOES/BOTOES */
.botao_menu { Estilos dos botões, da barra de ação e outros
color: #FFFFFF; que aparecem em componentes de detalhe.
border:none;
background-color: #1088ff;
}
/* quando em hover */
.botao_menu2 { A variação com sufixo2 é utilizada no “hover”,
color: #FFFFFF; quando o mouse sobrepõe um botão.
border:none;
background-image:
url(../../midia/acme/acme_panel_bg.gif);
}
375
Capítulo D14
}
/* secao de titulo do formulario */
th{color: #ffffff;
background-image:
url(acme_panel_bg.gif);
}
/* barra no navegador */
td.topoNavegador { Topo do título e hiperlinks dentro do navegador
color: #ffffff;
font-size: 14px;
background-color: #1088ff;
}
/* links em geral */
a{ Links em geral (fora da treeview)
color: #333333;
font-size: 14px;
}
/* barra da treeview */
td.barraTituloPortlet{ Topo do título e hiperlinks dentro da treeview.
color: #ffffff;
font-size: 14px;
}
376
Embelezando Aplicações jCompany
/* botao de vinculado */
span.bt{ Botão de vinculado
color: #FFFFFF;
background-color: #1088ff;
}
/* TAB-FOLDER */
table.tabs ul.tabs li.ativada a, Tab-Folder
div.tabfolder_abas ul li.ativada a{
background-color: #1088ff;
color: #FFFFFF;
}
table.tabs ul.tabs li.ativada a:hover,
div.tabfolder_abas ul li.ativada a:hover{
color: #ADD8E6;
}
- Ajustando painéis
Um item de leiaute padrão que ainda não analisamos são os painéis de “ajuda”, “impressão” e
“treeview”. Eles são renderizados como um quadro flutuante (div) e pré-configurados para a altura dos
topos padrões.
Veja na Figura D14.58, o conflito de sobreposição de camadas que ocorre com o menu Pull-Down e
também a falha de posicionamento.
377
Capítulo D14
Como já vimos, poderíamos redefinir os ícones de chamadas e alterar completamente os estilos para
ajustes nos painéis - mas nosso Web-Designer decidiu utilizar o padrão que vem no jCompany.
Portanto, precisaremos somente trocar o posicionamento da abertura de todos os três painéis que
estamos utilizando, sem mudar sua aparência.
Isto pode ser feito através de modificação em uma única classe “div.painel”, que delineia todos os
painéis.
1. Altere a coordenada de “margin-top”, conforme a Figura D14.59.
Figura D14.59. Estilo comum a todos os três painéis, com posição relativa ao topo alterada.
2. Atualize a página e observe agora que o posicionamento de abertura dos painéis está apropriado
para o novo topo. Não precisaremos também tratar o conflito de “camadas”, pois o “div” do painel
não sobrepõe mais o do menu Pull-Down.
Obs.: Repare, pela Figura D14.60, que os campos de lista (combos) somem quando acionamos um
painel (e também quando acionamos o menu Pull-Down). Este comportamento é proposital, realizado por
rotinas Javascript genéricas do jCompany, que dinamicamente escondem objetos que poderiam gerar
conflitos com sobreposições de “div”. Deste modo, o jCompany impede problemas similares aos que
vimos, entre o menu e o painel.
o “principalTopoPlc.jsp”
o “geralRodapeComplemento.jsp”
Isto fará com que os alinhamentos “margin-left” e “margin-right”, declarados para as bandas de “topo”,
“corpo” e “rodapé”, alinhem por igual este três componentes do leiaute.
378
Embelezando Aplicações jCompany
Graças ao esquema de IoC na camada Visão disponibilizado pelo jCompany FS Framework, para exibir
o título com destaque no topo do nosso novo leiaute, seguindo este padrão, bastará que recebamos o
“título base” na página “principalTopoPlc.jsp” e que, em seguida, deleguemos sua renderização para
um componente especializado em sua exibição.
Neste esquema, o título já vem montado para cada Colaboração conforme o padrão declarado pelo
Desenvolvedor, por componentes genéricos de leiaute; e o componente que o exibe concatena os valores
específicos de cada instância editada.
379
Capítulo D14
Para receber o título, primeiramente declare o uso da Tag-Lib do Tiles e do atributo “titulo”,
especificamente.
#2. Padrão Tiles para tornar parâmetros passados por definições disponíveis no escopo da página.
Figura D14.64. Código Tiles que insere um componente de leiaute para exibição do título.
Note que, como é um “div” que estará flutuante, a posição desta chamada na página não importa.
Os estilos para a classe “tituloPagina” foram copiados no CSS que o Web-Designer disponibilizou –
por isso o título já terá um alinhamento adequado para o novo caso (como exercício, se desejar,
procure-o no “/css/acme/PlcPele.css”).
3. Teste o resultado do título, editando algum documento. Com isso, obtivemos uma primeira versão
razoável do nosso Web-Design aplicado (muito embora somente testado no Internet Explorer - IE),
exibido em sua totalidade na Figura D14.65.
#1. Áreas de “respiro” incluídas no tópico anterior (alinhamento com topos e rodapés).
380
Embelezando Aplicações jCompany
Customização Intermediária
Ao avançar para customizações de Web-Design muito distantes dos padrões sugeridos pelo
jCompany, questione mais em detalhe as reais motivações para cada mudança radical: ela está
subtraindo funcionalidades, que prejudicam o uso de recursos naturais do Navegador? Elas estão
forçando usuários a emitirem mais submissões e, portanto, prejudicando a performance? Elas são
meras variações laterais do que já existe presente (um jeito paralelo de se fazer a mesma coisa)?
Se sim, o ganho visual justifica o esforço de customização? E assim por diante...
Em nossa experiência, não é raro que customizações radicais retrocedam a arquitetura proposta para
alguns anti-padrões como mistura de conceitos (disponibilizar seleção e manutenção em uma mesma
página/URL), fragmentação excessiva de formulários (interfaces tipo “carrinho de compra”), recuperação
de documentos via POST (não RESTful) e assim vai.
Por este motivo, vamos discutir em “Customização Intermediária” somente algumas amostras de casos
típicos, que podem se justificar em determinados cenários.
Importante: Mesmo assim, não realize os tutoriais desta seção na aplicação “rhtutorial” (ou, se desejar
fazê-lo - desfaça a seguir), pois a maioria das modificações que veremos não chega a ser desejáveis para
o nosso caso específico.
*
Um outro anti-padrão muito comum é utilizar duas barras, uma acima e outra abaixo do formulário. Uma poluição desnecessária,
exceto quando direcionada para usuários esporádicos (não treináveis), em aplicação de “e-commerce”, por exemplo.
381
Capítulo D14
Figura D14.66. Modificações no leiaute Tiles para mudar a barra de ações de posição.
#2. Novo componente similar ao original, porém com nome diferente, específico.
Todos os formulários são definidos no jCompany pelo leiaute “PlcFormJsfLayout.jsp” para JSF e
“PlcFormStrutsLayout.jsp” para Struts. Seria uma opção possível – mas não muito elegante -
editar estas páginas e salvá-las no projeto específico (sobrepô-las). Mas o jCompany provê
“eventos de extensão” nos leiautes, de maneira similar a uma arquitetura de programação, de
modo que se possa evitar esta redundância (e, conseqüentemente, a perda da IoC e de ganhos a
partir de evoluções potenciais das páginas de leiaute de formulário, no nível da arquitetura).
O próximo capítulo discutirá em detalhes estas extensões disponíveis. Para o nosso caso, que
desejamos um “ponto de extensão” no último momento antes do fechamento da Tag “form”, a
sobreposição da página “/plc/layouts/PlcVboxManSelIncludeFimAntesFormLayout.jsp” no
projeto “rhtutorial” será adequada.
Perceba que esta página existe como um “ponto de extensão”: está vazia na camada de
arquitetura, de modo a ser prontamente extensível, sem redundância.
Crie uma página com este nome e neste mesmo pacote, no projeto “rhtutorial”.
3. Para finalizar, codifique apenas um “insert Tiles”, como exemplificado na Figura D14.67.
4. Confira o resultado com o da Figura D14.68 (Se fossemos manter esta opção, seria apropriado
introduzirmos bordas ao final do formulário, para um melhor acabamento). Note que as mensagens
continuam aparecendo na região de cima do formulário – somente os botões foram alterados de
posição.
382
Embelezando Aplicações jCompany
Este subdiretório “/g” (grande) é padrão, e utilizado quando se deseja prover “ícones grandes”
substitutos, para a barra de botões. As imagens abaixo dele devem seguir uma convenção de
nomes, para os botões padrões:
Figura D14.69. Definição de metadados para uso de imagem grande em lugar de botões.
*
Não iremos utilizar definitivamente, em nosso caso, mas mesmo assim o diretório de especificação contém um conjunto de imagens
para exemplo, utilizadas neste tutorial.
383
Capítulo D14
Perceba que, se desejarmos usar internacionalização e possuirmos textos nas imagens, como neste
exemplo, teríamos que fazer versões em vários idiomas das imagens e manipular sua modificação
programaticamente. Prover várias peles também exigiria manter cópias de todas a imagens, em cada
diretório de pele. Apesar disso, o resultado pode ser interessante.
Importante: Note que, mesmo neste caso, não precisamos redundar (sobrepor) a página de ações
“/plc/jsps/geralAcoesJsfPlc.jsp”, mantendo o reúso maximizado. Naturalmente, sobrepondo-se este
componente do leiaute, pode-se obter resultados com largas possibilidades de variação.
384
Embelezando Aplicações jCompany
#2. Atributo que define o número de colunas laterais que o leiaute irá conter
#3. Lista no padrão “lista[número da coluna]”. Perceba que cada coluna pode conter uma lista
(caixas verticais) de componentes Tiles (JSP markups).
#4. Página que entrará em cada coluna. Estamos reutilizando, obviamente, as páginas que
geramos originalmente.
2. Mas não podemos chamar este leiaute diretamente, já que ele ainda não está contido no leiaute
principal. Não possui topos de mensagens e botões e nem ao menos a declaração de formulário -
todos estes componentes Tiles que reutilizamos da arquitetura do jCompany.
Uma opção seria fazer o mais difícil (tanto de criar quanto de manter) e redefinir tudo em includes e
declarações redundantes de formulário. Mas o que faremos irá preservar todo o reúso que fizemos
até aqui, apesar da definição específica.
Crie uma nova definição de leiaute que incluirá a anterior e que herdará de um leiaute “de caixa
vertical” padrão do jCompany, conforme a Figura D14.72.
Figura D14.72. Definição de leiaute de formulário que herda leiaute geral, seções de ações, mensagens, etc..
#2. Título que irá aparecer no topo do formulário (Também estamos reutilizando um título já
existente, gerado quando geramos a Colaboração).
#3. Lista contendo componentes para serem verticalmente alinhados. Em nosso caso, somente
inserimos o componente “de colunas”.
3. Com isso, finalizamos a definição de nosso primeiro leiaute “não generalizado”, do ponto de vista
do Tiles. Mas precisamos dizer ao jCompany que desejamos trabalhar com leiaute específico e não
com o Universal. Localize o arquivo de metadados para a Colaboração “unidadeorganizacionalman” e
retire a cláusula de leiaute Universal. Veja como fica esta definição após a remoção, na Figura
D14.73.
Figura D14.73. Metadados para controle de “unidadeorganizacionalman”, com leiaute universal retirado.
5. Finalmente, faça uma “Liberação Rápida para Tomcat com Reinício” e teste o resultado,
comparando-o com o da Figura D14.74.
385
Capítulo D14
Obs.: Veja que também editamos a página “geralAcoesComplemento.jsp” e retiramos o nosso texto
“Este é um teste”, que aparecia ao lada da barra de ações (já era tempo, não é mesmo?)
As peles que vêm no jCompany já são homologadas para estes dois grupos de Navegadores
principais do mercado, mas customizações como a que fizemos podem exigir algum esforço nesta
área.
Felizmente, em nosso caso, não devemos observar nenhum problema, com nada do que fizemos até aqui
- apenas as distinções de exibições normais de cada navegador.
*
O documento HTML, no padrão Strict, deve ser também um XML válido.
386
Embelezando Aplicações jCompany
Para teste apenas, há uma forma mais ágil: Basta informar o parâmetro “htmlFormatoPlc=Strict”
na URL (em um GET), para que a declaração seja trocada dinamicamente.
Ex.: se digitarmos “.../rhtutorial/f/t/uf?htmlFormatoPlc=Strict” e em seguida olharmos o código fonte do
HTML, veremos a nova declaração como abaixo:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt_BR" lang="pt_BR">
Importante: Esta opção via URL é apenas para facilidade da verificação de compatibilidade com o
padrão “Strict”, dispensando redeploy da aplicação. Ela é transiente - no próximo clique o formato irá
voltar para “Transitional”.
Faça esta modificação via URL, no Firefox. Dependendo da versão, você poderá notar que, somente com
o uso de “Strict”, um pequeno problema de espaçamento é introduzido no topo, como mostra a
Figura D14.76.
Figura D14.76. Problema no Firefox com “Strict” e uma combinação de estilos específica.
Este é um bug reconhecido somente do Mozilla Firefox, pelo menos até a versão 2.0.0.9, que é a
utilizada para os exemplos deste livro (Se desejar, faça o mesmo no IE, para conferir). É um
exemplo do tipo de problema que se pode ter com Strict, apesar de suas vantagens.
Para quem deseja e está disposto a realizar pequenos ajustes de contorno (workarounds), o esforço
compensa - e há uma tendência de estabilidade a partir da popularização deste padrão.
387
Capítulo D14
*
A parte genérica de CSS (comum para todas as peles) fica no arquivo “PlcGeral.css”, localizado no jCompany FS Framework.
388
Embelezando Aplicações jCompany
A Figura D14.78 mostra as três páginas editadas no Eclipse, do projeto “jcompany_visao”, com
destaque para a página do cabeçalho (HEAD).
Figura D14.78. Páginas chave de declarações HTML. Declaração de <head> para todos os leiautes.
#2. O CSS de estilos gerais é inserido primeiramente. O CSS para a pele específica é inserido em
seguida, para inclusive poder redefinir e alterar quaisquer estilos gerais que se façam
necessários, para a pele específica.
#3. Note que há um terceiro possível arquivo, específico para a Aplicação, mas que somente é
importado se a opção “usaCSSEspecifico” for “S”, nos metadados. Isso para não importar um
arquivo vazio, desnecessariamente. (Deste modo, se pretender modificar algo em escopo de
uma aplicação, o desenvolvedor deve alterar o default “N” para este atributo).
#4. Alguns estilos que não funcionam para as exigências do “Strict”, mas são opcionais, também
são incluídos neste arquivo. Como não é possível se utilizar “c:if” nos CSS, eles são definidos
aqui. Note que, se eles necessitarem de ajustes, esta página deverá ser especializada.
389
Capítulo D14
Figura D14.79. Definição de sub-leiaute com base em tab-folder, para a página principal.
#2. Para produzir Tab-Folder em nível de leiaute (utilizado acima de “formulários”), pode-se herdar
de “def.tab.ancestral”*.
#3. A primeira aba, por sua vez, inclui um leiaute de colunas (o mesmo que utilizamos em
“Unidade Organizacional”, inserindo as páginas “/WEB-INF/jsps/principalMenu.jsp” e
“/WEB-INF/jsps/principalIntroducao.jsp”. Estes componentes Tiles abaixo de “/WEB-
INF/jsps” são considerados de escopo da aplicação, em contraposição aos que existem em
“/plc/jsps”, considerados em escopo da arquitetura (empresa ou grupo de projetos).
#4. As outras abas incluem as opções de personalização de peles, leiautes e formulário, que são
reutilizadas do jCompany FS Framework, definidas no arquivo “plc-tiles-pagina.xml”.
Iremos customizar também estas opções, ainda neste capítulo.
Repetindo uma imagem de capítulos anteriores, a Figura D14.80 mostra o leiaute visto no seu “estado”
inicial (home-page).
*
O leiaute do jCompany especializa o padrão do Tiles, com código que mantém o “estado” das abas, melhora acabamento (estilos),
permite recuperação por demanda, dentre outras melhorias.
390
Embelezando Aplicações jCompany
o #1, #2, #6 e #7. Componentes do leiaute de nível principal e secundário para rodapé, já vistos.
o #3. Subleiaute de segundo nível, contendo segmentação de quatro partes via Tab-Folder.
o #4. Página “/WEB-INF/jsps/principalMenu.jsp”, na coluna da esquerda do sub-leiaute de
terceiro nível em “colunas”. Esta página traz botões tipo “quiosque” com opções de atalho para
operações freqüentes da aplicação. Podemos customizar esta página completamente, alterando
seu código ou, o que é mais recomendado, somente acrescentar nossas opções específicas de
atalho, utilizando programação declarativa.
o #5. Página “/WEB-INF/jsps/principalIntroducao.jsp” de conteúdo para informações
iniciais ao usuário. Esperara-se que esta página seja inteiramente refeita. Ao olhar sua
implementação, inclusive, o desenvolvedor verá que contém textos diretamente em português
(sem I18n), sem a pretensão de servirem em produção.
Para a nossa aplicação, iremos apenas produzir uma customização do texto de introdução, reutilizando o
esquema de atalhos “tipo quiosque” sugerido. Para isso, siga os seguintes passos:
4. Do diretório “[jcompany]/jcompany_documentacao/rhtutorial/gui/homepage”, copie a
página “principalIntroducao.jsp” para sobrepor a página de mesmo nome em “/WEB-
INF/jsps” do projeto “rhtutorial”.
2. Ainda do mesmo diretório, copie a imagem “acme_banner.gif” para o diretório
“/plc/midia/acme”, do mesmo projeto.
3. Os estilos relacionados aos botões de quiosque foram copiados anteriormente. Por isso, somente os
dois passos iniciais nos proporcionarão uma interface adequada, conforme exibe a Figura D14.81.
391
Capítulo D14
Mas não é razoável se ajustar trinta versões de pele e oito de leiautes – três ou quatro peles e
dois leiautes podem bastar para nosso propósito. O ponto chave é escolher aquelas opções, dentre
as existentes, que ofereçam variações úteis para nosso caso específico.
2. Criar variações das imagens utilizadas na pele “acme” para cores/tamanhos que combinem com
cada variação das peles escolhidas. Qualquer software de Web-Design permitirá a exportação das
mesmas criações para várias tonalidades, sendo este eminentemente um trabalho “braçal”.
3. Recriar o diretório destas peles no projeto específico “rhtutorial”, sobrepondo o arquivo "PlcPele.css"
e as imagens distintas (que variam para cada pele).
Note que estas dicas se baseiam na reutilização de peles existentes, pois não costuma compensar, salvo
em raras exceções, criar-se outra pele inteiramente do zero!
#1. Teste para inserir as duas últimas linhas do topo, somente se o leiaute corrente for “sistema”.
Repare que o leiaute, a pele e informações de personalização de formulário correntes podem
ser obtidas do objeto “PlcCacheSessaoVO”, que fica na variável de sessão
“sessionScope.SESSION_CACHE”.
392
Embelezando Aplicações jCompany
#2. Se não for incluir o topo, ajuste altura e margem para uma melhor visualização.
Note que estas dicas se baseiam também na reutilização de leiautes existentes. Para se criar um leiaute
inteiramente do zero, deve-se partir da cópia de um dos diretórios de leiaute - e de conhecimentos
profundos em Tiles e da arquitetura de leiautes do jCompany FS Framework, detalhada no próximo
capitulo.
#1. Opções iniciais para pele, layout e formato, sendo CSS obrigatório para JSF.
#3. Opção para substituição de botões de ação por imagens “grandes”. O jCompany irá pegar as
imagens do diretório “/plc/midia/[formAcaoEstilo]/g”. No caso acima, de
“/plc/midia/acme/g”.
393
Capítulo D14
Deste modo, a personalização de peles, leiautes e formulário ficam restritas àquelas opções
homologadas, conforme exibem as figuras a seguir.
394
Embelezando Aplicações jCompany
Sumário
Neste capítulo, aplicamos um Web-Design inteiramente novo em nossa aplicação “rhtutorial”,
compreendendo diversos aspectos da arquitetura de camada Visão do jCompany FS Framework. Ao
aplicarmos customizações na aparência e ergonomia (look-and-feel) de nossa aplicação, mantivemos
nossa estratégia de reinventar o mínimo de componentes de leiaute, mantendo o reúso maximizado.
No próximo capítulo, discutiremos mais a fundo a arquitetura de gestão de leiautes do jCompany FS
Framework, oferecendo conhecimentos para customizações mais radicais.
395
Capítulo
15
Arquitetura de Leiautes a
5
1
D
Fundo
Introdução
O Espião de Leiaute
396
Arquitetura de Leiautes a Fundo
(eventualmente discutindo com o Analista Projetista ou Arquiteto de Software, se a empresa possuir esta
segmentação de papéis).
Durante a apresentação do espião, alguns componentes de leiaute são eventualmente desformatados,
para viabilizar a exibição da radiografia. Este é o caso, por exemplo, dos menus Pull-Down e do topo. Mas
não se deixe enganar pelo aspecto confuso que inicialmente o espião de leiaute pode passar - após um
primeiro entendimento, ele logo se torna um instrumento de grande valia para, por exemplo:
o Compreensão dos leiautes primários e secundários, componentes reutilizados da arquitetura e
específicos da aplicação.
o Verificação rápida do nome das JSPs de componentes e leiautes a serem especializados,
quando isso se fizer necessário.
o Identificação rápida do nome de componentes específicos da aplicação, com algum
problema de renderização.
Leiautes Primários
397
Capítulo D15
Cada leiaute primário é implementado por JSPs de mesmo nome, porém situadas em diretórios
diferentes, seguindo o padrão:
jcompany_visao/.../plc/layouts/[leiaute]/tl/PlcGeralLayout.jsp
onde [leiaute] é um dos subdiretórios:
“sistema”: menu Pull-Down (Sistema Corporativo).
“classico”: relação à esquerda (Portal Clássico).
“classidoex”: relação à esquerda, expansível (Compacto).
“oriental”: relação à direita (Oriental).
“orientalex”: relação à direita, expansível (Oriental Reduzido).
O jCompany provê facilidade para que usuários possam comutar entre estes leiaute em tempo de
execução, utilizando a página “/plc/layouts/PlcComutaPaginaLayout.jsp” como leiaute da definição
“def.pagina.ancestral”, como vimos no capítulo anterior. Esta página, basicamente, possui o código
encarregado de substituir o diretório da pele corrente, armazenado em escopo de sessão em um
POJO chamado “PlcCacheSessaoVO”. Mas em seguida esta página delega a renderização do leiaute em
si, para uma das páginas “PlcGeralLayout.jsp”, em conformidade com o diretório “corrente”.
Figura D15.3. Definição do leiaute primário na aplicação, com personalização pelos usuários.
Para reforçar nosso entendimento: a forma mais simples de se forçar o uso somente do leiaute “sistema”,
por exemplo, seria declarar a sua JSP “/plc/layouts/sistema/tl/PlcGeralLayout.jsp” no lugar de
“/plc/layouts/PlcComutaPaginaLayout.jsp”, na definição ”def.pagina.ancestral” do arquivo “app-
tiles-pagina1.xml”!
Leiautes Secundários
Uma arquitetura que defina apenas os leiautes primários ainda não estará em seu patamar
adequado de padronização. Ao “recortar” ainda mais as seções, em mais um nível, o jCompany
398
Arquitetura de Leiautes a Fundo
- Leiautes de menu
Os leiautes de menu também são implementados por JSPs de mesmo nome, que ficam nos mesmos
diretórios dos leiautes primários, já que costumam “acompanhar” a variação destes leiautes
"jcompany_visao/.../plc/layouts/[leiaute]/tl/PlcMenuTopoLayout.jsp"
"jcompany_visao/.../plc/layouts/[leiaute]/tl/PlcMenuItemLayout.jsp"
Como os menus são estruturas hierarquizadas, o seu leiaute necessita de duas páginas: a
"PlcMenuTopoLayout.jsp" para definir o primeiro nível (que possui algumas características
diferenciadas) e a "PlcMenuItemLayout.jsp”, que define os dois próximos níveis.
Importante: o Tiles somente disponibiliza dois níveis de hierarquia para menus, mas o jCompany o
expande para até três de cada vez, em uma única renderização. Além disso, disponibiliza menus Pull-
Down e possibilita que se comute entre várias renderizações de menu, inclusive possibilitando a obtenção
de ilimitados níveis reais.
Não é recomendado aumentar o número de hierarquias de menu para acima de 3 níveis, para uma única
visão de menu, porque:
o A renderização de quatro níveis para menus Pull-Down (leiaute “sistema”) degrada a performance,
no lado do Navegador.
o A renderização de quatro níveis dificulta a diagramação dos menus “clássico”, “oriental” ou “clássico
dinâmico”, exigindo endentação em excesso ou miscelâneas com técnicas Javascript que terminam
por confundir o usuário.
o A hierarquização acima de três níveis é comprovadamente mais confusa para usuários - e pode ser
aprimorada pela “modularização dos menus” que podem ser “trocados” por assunto. Se não for
possível aplainar menus para 3 níveis, deve-se então comutar a renderização para níveis mais
detalhados, deste modo expandindo-se a capacidade total para ilimitados níveis, mas somente
apresentando ao usuário, 3 níveis de cada vez.
399
Capítulo D15
o A JSP de “item” renderiza os itens de menu em cada seção, que possuem hiperlink e também
podem possuir ícones.
Pode-se ver um exemplo de ícones e também de renderização de um terceiro nível em um menu
“classico” na Figura D15.5:
/plc/layouts/PlcMenuItemLayoutPlc.jsp
/plc/layouts/PlcMenuItemLayoutPlc.jsp
400
Arquitetura de Leiautes a Fundo
Leiautes de Pastas (tipo Tab-Folder) devem ser utilizados com parcimônia para não substituirem
itens de menu principais por “menus de pastas”, desnecessariamente. Itens de menu são mais
apropriados para exibir hierarquias de funções da aplicação - manter esta função sob a sua única
responsabilidade irá tornar a navegação na aplicação mais intuitiva, na maior parte dos casos.
*
Discutimos no capítulo anterior a página principal gerada pelos templates INI de projeto - ela vem com uma versão de exemplo deste
leiaute, agrupando opções de personalização da aplicação, como alternativa às opções de menu.
401
Capítulo D15
Figura D15.8. No topo, indicação do uso do “PlcTabsLayout.jsp”, leiaute utilizado pela definição
“def.tab.app.home”.
402
Arquitetura de Leiautes a Fundo
Se encontrar a anotação “tabFolder” nos metadados, o leiaute Universal irá prover uma “pasta” para o
Mestre e uma outra para cada Detalhe e/ou Componentes, podendo-se variar o corte da parte do Mestre
e Componentes, mudando estas seções de lugar nas JSPs. A Figura D15.10 mostra uma radiografia de
uma variação de corte para “Manter Funcionário”, onde os dados de endereço ficam na mesma pasta dos
dados básicos de funcionários.
Mas se for necessário realizar quaisquer outras variações na organização das pastas, tais como utilizar
algum Detalhe na mesma pasta do Mestre, deve-se criar um leiaute específico, que herde de
“def.tab.ancestral.agil” (note o “agil" ao final da definição, distinguindo de “def.tab.ancestral”).
- Leiaute de Formulário
Estes leiautes secundários serão utilizados, tipicamente, no segmento “corpo” do leiaute principal,
criando segmentações de áreas típicas para formulários de manutenção e de pesquisa/seleção, incluindo
leiautes de terceiro nível que definem áreas auxiliares de ações (botões de gravação, exclusão, etc.) e
mensagens (de erro ou confirmação), dentre outras.
Para iniciar, uma página JSP chamada “PlcComutaFormLayout.jsp” traz código que comuta entre as
tecnologias Struts e JSF, sendo declarada na definição ancestral “def.corpo.ancestral”, utilizada para
todos os “corpos de formulário”. Esta página atua de forma análoga às páginas
"PlcComutaPaginaLayout.jsp" ou "PlcComutaMenuLayout.jsp"*.
*
Esta convivência, em um mesmo leiaute, das duas tecnologias serve unicamente ao propósito de possibilitar a existência de
Colaborações em ambas as tecnologias, funcionando lado a lado, em uma mesma aplicação. Neste livro, não iremos discutir a
tecnologia Struts em detalhe, já que o foco são tecnologias padrões Java EE 5.
†
Esta distinção é necessária porque a tag HTML “form” será renderizada por um componente diferente, dependendo de cada uma
destas tecnologias.
403
Capítulo D15
Deste modo, esta página é reutilizada para prover o subleiaute de formulário em si, incluindo a
subdivisão de mensagens, ações e as seções de formulário. Seu nome pode parecer confuso em uma
primeira leiatura, mas segue a seguinte convenção:
o “Plc”: Prefixo padrão da arquitetura em nível do jCompany.
o “VBox”: Nomenclatura padrão do Tiles, significando “Vertical Box” ou caixas verticais (as seções do
formulário são dispostas uma sobre a outra, verticalmente).
o “ManSel”: Indica a utilização tanto em formulários de manutenção quanto de seleção.
o “Tab”: Indica a utilização, opcionalmente via declaração de metadados, de sub-leiaute de Tab-
Folder no formulário (inserção desta seção conforme metadados).
o “Layout”: Sufixo padrão para JSPs que implementam leiautes Tiles no jCompany.
O leiaute da página “PlcVboxManSelTabLayout.jsp” é exibido no Esquema D15.1.
mensagensAcoes
/plc/jsps/geralLinkRapidoPlc.jsp
/plc/jsps/geralMensagemPlc.jsp
def.componente.acoes
lista
def.tab.ancestral.agil
componente específico 1
componente específico 2
...
componente específico 3
Esquema D15.2. Esquema do leiaute de “PlcVboxManSelTabLayout.jsp”.
Visto de maneira mais abrangente, inserido no leiaute nível definido por “PlcFormJsfLayout.jsp”, o
esquema final fica como no Esquema D15.3*.
/plc/jsps/PlcVboxManSelIncludeInicioAntesFormLayout.jsp (1)
<tr:form>
/plc/layouts/PlcVboxManSelIncludeInicioAposFormLayout.jsp (2)
/plc/layouts/PlcVboxManSelIncludeInicioAposFormJsfLayout.jsp (3)
mensagensAcoes
/plc/jsps/geralLinkRapidoPlc.jsp
/plc/jsps/geralMensagemPlc.jsp
def.componente.acoes
lista
def.tab.ancestral.agil
componente específico 1
componente específico 2
...
componente específico 3
/plc/layouts/PlcVboxManSelIncludeFimAntesFormLayout.jsp (4)
</tr:form>
/plc/layouts/PlcVboxManSelIncludeFimAposFormLayout.jsp (5)
Esquema D15.3. Definition: “def.corpo.ancestral”. Path: “/plc/layouts/PlcFormJsfLayout.jsp”.
#1. Ponto de extensão antes da declaração de formulário. Contém início de declarações Ajax
somente para Struts. Quem utiliza JSF pode sobrepor esta página se desejado.
*
Os componentes principais não numerados são explicados nos próximos tópicos, caso a caso.
404
Arquitetura de Leiautes a Fundo
#2. Ponto de extensão imediatamente após a declaração do formulário. Possui código que deve ser
replicado para o projeto específico, se for desejado inserir especializações neste ponto.
#3. Ponto de extensão idêntico ao anterior, porém esta página contém somente implementações
pertinentes ao JSF (a anterior compartilha partes comuns com a tecnologia Struts)
Importante: Note que somente a página inserida em (3) é específica de JSF. As demais possuem
estrutura idêntica à utilizada em tecnologia Struts e códigos reutilizáveis para os dois casos.
WEB-INF/jsps/geralAcoesComplemento.jsp /plc/jsps/geralAcoesPlc.jsp
*
Esquema D15.4. Definition: “def.componente.acoes”. Path: “/plc/jsps/geralAcoesPlc.jsp” .
*
Esta definição de leiaute não está perfeita. A página “/plc/jsps/geralAcoesPlc.jsp” não é um leiaute somente, como deveria, pois já
contém eventos (botões) e, portanto, implementações além da preocupação do leiaute em si! Por este motivo, inclusive, é mantida no
pacote “/plc/jsps”, com nomenclatura de componentes, iniciando com minúsculas e terminando com sufixo “Plc”.
Um ajuste pendente é transformá-la em um leiaute “puro”, renomeando-a para algo como “PlcGeralAcoes.jsp” e alterando-a para o
pacote “/plc/layouts”. Mas esta definição tem sido mantida pela Powerlogic deste modo por questões de compatibilidade com versões
anteriores – já que existe desde a versão 1.0!
Este refactoring tem sido postergado para versões futuras por ter baixa prioridade, não trazendo problemas funcionais. Além disso, se
necessário, ele pode ser trivialmente resolvido na própria aplicação, já que a definição fica em “app-tiles-pagina1.xml”.
405
Capítulo D15
Figura D15.11. Componentes de leiaute “VBox – vertical box” montados em “lista” do “def.corpo.ancestral”.
- Leiaute de Assistente
Outra facilidade que traz grande benefício para facilitar a operação inicial de aplicações produzidas em
jCompany (e, consequentemente, para economizar em treinamentos e promover o uso em produção)
são os Assistentes de Entrada de Dados para usuários finais.
A página de leiaute do assistente é definida no projeto “jcompany_visao”, em:
o “/plc/layouts/PlcAssistenteLayout.jsp”.
A definição fica em “plc-tiles-pagina.xml”, com nome “def.assistente.ancestral”, e sua estrutura
inclui componentes para exibição de passo (Ex.: “Passo 2 de 7”) e também para inserção da descrição de
ajuda.
406
Arquitetura de Leiautes a Fundo
topo: /WEB-INF/jsps/principalTopoPlc.jsp
/jsps/geralLinkRapidoPlc.jsp
/jsps/geralMensagemPlc.jsp
/jsps/geralAcoesPlc.jsp
/WEB-INF/jsps/ /jsps/geralAcoesPlc.jsp
geralAcoesComplemento.jsp
Lista
...
rodape: /jsps/geralRodapePlc.jsp
/WEB-INF/jsps/geralRodapeComplemento.jsp /jsps/geralRodapePlc.jsp
.
Esquema D15.5. Definition: “def.pagina.ancestral”. Path: “PlcComutaPaginaLayout.jsp ->
/classico/PlcGeralLayoutPlc.jsp”.
Importante: Note como chegamos a um alto nível de generalização ao final. Somente os segmentos em
negrito são previstos para especialização e necessários de serem codificados de forma específica, na
maior parte dos casos. Para redefinir partes genéricas, como fizemos no capítulo anterior, podemos fazê-
lo em nível da arquitetura (na camada Bridge), de modo a preservar o ganho em reuso, a partir daí.
407
Capítulo D15
Sumário
Neste capítulo, expusemos a arquitetura interna dos leiautes do jCompany, em três níveis de
profundidade, para possibilitar intervenções mais avançadas do que as que fizemos no capítulo anterior.
Aprendemos como utilizar o espião de leiautes para a obtenção de uma “radiografia” dos leiautes
dinamicamente montados pelo jCompany e apresentamos diagramas esquemáticos para a estrutura de
segmentos de leiaute mais comumente utilizados.
Um bom estudo de Tiles e análise dos leiautes JSP e das classes de controle do Tiles, disponíveis com
seus códigos fontes no jCompany, são os próximos instrumentos de análise, para quem deseja obter
controle total nesta área.
408
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
409
E
Módulo
Regras de Negócio
.
E
410
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
411
Capítulo
16
Programando Java com
6
1
E
jCompany
Introdução
- Convenções de Nomenclatura
Neste capítulo, chamaremos os fluxos de processamentos de resposta da aplicação para eventos
disparados por usuários de “Seqüência de Transação”. Tipicamente, estes eventos são disparados a
partir de cliques em botões e/ou hiperlinks. Já o agrupamento de possíveis eventos em torno de um
único formulário/URL chamaremos de “Colaboração” (como já o temos feito).
Por exemplo, dizemos que a “Colaboração de Manutenção de Clientes” é identificada pela URL
“/clienteman” e tem estereótipo “plcCrud”, sendo composta dos eventos de usuário “F7-Novo”, “F12-
Gravar”, “Excluir”, “Clonar”, etc.. Cada um destes eventos, por sua vez, dispara a sua “Seqüência de
Transação”, basicamente processando o atendimento de forma segmentada por camadas, em respeito à
arquitetura MVC2-P.
412
Programando Java com jCompany
*
Figura E16.1. Categorias de classes/camadas participantes de uma seqüência de atendimento .
#1. Em uma aplicação Web, o processamento principal ocorre no servidor. Por este motivo, o
código Javascript que eventualmente roda em Navegadores, na máquina do usuário (cliente),
não é normalmente considerado, em uma análise de arquitetura MVC. Isto tem mudado, nos
últimos anos, com a popularização das tecnologias Ajax e da Web 2.0 em geral. Por este
motivo, iremos representá-la em nossos diagramas.
#2. A “camada Visão do Servidor” é representada por diversos frameworks de base integrados
pelo jCompany FS Framework, para “tirar o máximo” de uma Interface com o Usuário via
Web. Dentre eles, o JSF via componentes Apache Trinidad, o Tiles, o JSP e o JSTL, dentre
outros.
Não se pode destacar uma única classe ou artefato que represente um papel preponderante
nesta camada. Diversas especializações de componentes Apache Trinidad, JSPs de leiaute e
componentes de leiaute Tiles, Tag-Files e Tag-Libs (Struts e JSF), dentre outros, atuam com
interação, nesta camada.
*
As classes representadas no diagrama são implementações concretas ou interfaces que possuem algum papel de destaque em sua
camada. As implementações reais são bem mais sofisticadas, como veremos, muias vezes envolvendo interações entre dezenas classes
e tecnologias, em uma mesma camada.
413
Capítulo E16
#5. A “subcamada de Serviço” contém a maior parte do código Java que realiza a orquestração
principal de retaguarda dos Casos de Uso Padrões do jCompany, para tratamento dos eventos
de manutenção do ciclo de vida para agregações complexas de objetos de domínio, como
vimos até aqui.
Mais especificamente, a classe “PlcBaseBO” traz 90% das implementações generalizadas para
este fim, nesta subcamada*. Uma descendente "AppBaseManager", gerada de forma
específica em cada aplicação, também atua via IoC, de forma similar a outras camadas, para
prover ponto de extensão e isolamento.
#6. A “camada de Domínio” foi muito utilizada ao longo dos tutoriais, trazendo programações de
decisão no escopo das agregações de classes que representam conceitos do negócio, sem
depender de outras camadas ou orquestrar transações.
*
Além desta categoria de classes que lidam com manutenção de ciclo de vida de documentos (também chamadas de Managers no
jCompany), encontraremos também, nesta subcamada, classes de categorias conhecidas como Application Servers (AS),
orquestradoras de lógicas de programação “batch” ou outros serviços de negócio, não necessariamente vinculados a “ciclos de vida” de
agregações. Neste caso, não há comportamento generalizado, por isto esta categoria não foi representada.
†
O sufixo “VO” é mantido para compatibilidade com versões anteriores, mas isso não implica que estas classes devam seguir o DP
Value Object (VO). Seu funcionamento deve seguir orientações de Domain-Driven Design (DDD), como vimos, e inclusive com sufixos
personalizados nos descendentes.
‡
É importante notar que a classe "PlcBaseDAO", apesar de abstrata, traz códigos comuns entre Hibernate e JPA. Portanto, o DP
Abstract Factory, no jCompany, deve ser utilizado somente para customizações relativas ao uso destas tecnologias de mapeamento
objeto-relacional, tais como adaptações para variações de versão. Para variações mais radicais, para mecanismos de persistência não
relacionais, por exemplo, deve-se reimplementar o contrato “IPlcDao”.
414
Programando Java com jCompany
#8. A subcamada 8 é representada pelo framework que provê os serviços de persistência padrão
para SGBD-R relacionais. Ela é evidenciada no diagrama devido ao papel preponderante que
possui, eliminando códigos de INSERT, UPDATE e DELETE das classes de DAO, bem como
montando grafos de entidades de Domínio na memória a partir de “Result Sets JDBC” (deste
modo, viabilizando programações OO com produtividade).
Analisando as seqüências representadas pelos ítens 9 e 10, podemos nos surpreender com alguns
detalhes: a ordem de processamento pode não ser bem a inicialmente esperado, para quem está
iniciando na arquitetura MVC2.
Na prática, é bem mais fácil compreender uma arquitetura MVC1, na qual uma requisição é recebida por
um artefato específico de camada Visão (como uma “JSP”). Na variação MVC2, um único Servlet
“controlador” (DP Front Controller) é quem recepciona todas as requisições – a camada Controle é,
portanto, a responsável por iniciar o tratamento das requisições.
Vamos acompanhar, por exemplo, nesta numeração alternativa da Figura E16.1, a seqüência de uma
requisição GET, que é a que ocorre quando o usuário clica em algum item de menu, por exemplo. Neste
caso, vamos acompanhar uma Colaboração Padrão “plcTabular”, utilizada para realizar um Caso de Uso
“Manter Classe”.
2. S2. O comando HTTP GET com o endereço da transação digitado (URL) é recepcionado pelo Servlet
Controller “FacesServlet”, que por sua vez utiliza mecanismos declarativos padrões do JSF,
definidos nos arquivos “faces-config.xml”, para despachar a requisição para classes de controle mais
“especializadas”. Nos Casos de Uso padrões do jCompany, quando não há classe de controle
especificamente declarada no metadados da Colaboração, o tratamento é delegado para a classe
“PlcBaseJsfAction” ou “AppAction” (sua descendentes em escopo de aplicações). Isto é realizado
após um trâmite inicial que será detalhado mais a frente.
Este algoritmo, somente na primeira requisição de cada “tipo”, tenta localizar o melhor “serviço”
(classe da hierarquia padrão) da camada Modelo para atender à requisição. Este algoritmo faz a
localização, por default, baseado em amarração automática a partir de padrão de nomenclatura
(Pattern Based Auto-Wiring IoC), que será explicado mais a frente. Se não encontrar nenhuma
classe específica para “atuar” na requisição em questão, utiliza a classe genérica “PlcBaseBO” (ou
alguma descendente, que pode ser declarada como padrão).
4. S4. A classe “PlcBaseBO”, neste caso, somente chama o serviço de recuperação simples de
objetos, chamado “recuperaTodos”, definido no contrato “IPlcDAO”.
415
Capítulo E16
padrão para este contrato utilizada será ‘PlcBaseHibernateDAO”, caso a definição da “tecnologia”
em “PlcConfigModeloTecnologia”, definida em escopo da aplicação, seja “POJO”. Se for “EJB3”,
a implementação padrão utilizada será “PlcBaseJpaDAO”.
Mas aqui também é utilizado IoC com amarração automática, de modo que um DAO específico e
com nomenclatura padrão, se existir, será ativado, facilmente expandindo ou alterando
implementações.
5. S5. Quaisquer das implementações de DAO irá iniciar seu trabalho recuperando uma conexão de um
pool de conexões JDBC via endereço “JNDI” declarado no arquivo “web.xml” ou outro mecanismo
disponibilizado pelo Application Server.
8. S8. Programações de pouca relevância serão feitas no caminho de volta da camada Modelo, mas a
finalização do serviço de fachada merece menção, pois é aqui que a transação com o SGBD-R é
encerrada. Na prática, uma rotina AOP do jCompany implementada na classe
“PlcAOPModeloCallbackService” intercepta chamadas às implementações de interfaces de
fachada, e ao final delas faz uma chamada adicional ao método “dao.rollback” ou “dao.commit”,
métodos disponíveis no contrato da classe “PlcBaseDAO”.
9. S9. A classe de controle costuma trabalhar um pouco mais que as demais no retorno, já que deve
montar uma estrutura de resposta para o usuário. Uma boa parte deste trabalho é feita nesta
camada, mas a maioria é delegada para a camada Visão.
Em linhas gerais: após decidir qual a “visão de retorno” será utilizada, analisando a declaração de
fluxo definida em arquivos como “faces-config.xml” (ou “struts-config.xml”, para tecnologia
Struts), a camada controle delega a responsabilidade de renderizar o documento de resposta para
classes da camada de Visão.
10. S10. As classes da camada Visão, formadas por uma combinado de frameworks e tecnologias
harmonizadas pelo jCompany, cumprem então o seu objetivo final de montar e renderizar um
documento HTML ou XHTML (se o cliente for um Navegador Web), acompanhado por rotinas
Javascript, CSS, mídia, etc., - e com dados relevantes devidamente “preenchidos”, incorporados em
textos ou em valores de campos de formulários HTML.
Perceba que, em uma seqüência típica MVC2, a camada Visão será a última a atuar. Em uma
*
Existem alguns “anti-patterns” de gerenciamento de sessões de persistência, que apregoam deixá-la aberta durante toda a requisição
HTTP (incluindo camada controle!), que chegam a dar arrepios de tantas possibilidades de problemas que podem causar. Infelizmente
mesmo Gavin King, o criado do Hibernate, chegou a aventar esta como uma possível “técnica”, em seu primeiro livro “Hibernate in
Action”. Mas hoje já se compreende os horrores que este alto acoplamento e falta de divisão de responsabilidade pelas camadas MVC
podem trazer, à exceção das mais simples aplicações, de um tipo que não é foco deste livro.
416
Programando Java com jCompany
atualização, componentes JSF de camada Visão entrariam com algum processamento na seqüência
de requisição (Empilhamento), mas 90% do processamento desta camada ainda se daria na
seqüência de resposta (Desempilhamento).
11. S11. Para um estudo convencional de MVC2-P, a seqüência de processamento estaria encerrada.
Porém, sabemos que ainda ocorrerão processamentos importantes relacionados à interface com o
usuário, através de rotinas Javascript que executam após a carga (onload) do HTML, por exemplo,
ajustando foco de campo, redefinindo Hot-Keys, alterando estilos dinamicamente, etc..etc.
Como dissemos, o processamento da camada Visão do Cliente não pode mais ser ignorado. Nos
últimos anos, tem crescido em popularidade e importância.
A Figura E16.2 mostra uma representação completa do Diagrama de Seqüência em discussão, com
alguns pontos adicionais em destaque.
Figura E16.2. Diagrama de seqüência para “Manter Classe”. Eventos “F9-Pesquisar” e “F7-Novo”.
#1. Se o usuário clica em “F9-Pesquisar”, perceba que a seqüência disparada será a mesma da
chamada do menu. Isto é porque esta operação de pesquisa é default para este padrão
“plcTabular”. Mas no segundo caso, do clique no botão, o comando HTTP enviado será um
“POST” e será também enviado via “Ajax”*. Deste modo, evita-se das vezes subseqüentes a
renderização completa da página HTML†.
#2. Um novo fluxo exibido no diagrama de seqüência da Figura E16.2 é o do evento “F7-Novo”.
Perceba que ele também é enviado via Ajax. Uma outra vantagem desta arquitetura de
comunicação do jCompany é a de se não “sujar” a História do Usuário, mantida pelos
Navegadores. Como percebemos em tutoriais passados, nenhuma destas submissões de POST
subseqüentes, por serem utilizadas com Ajax, gera entradas nesta história, tornando-a útil‡.
#3. Tal como no caso da primeira chamada, a requisição é sempre atendida pela camada Controle.
Mais especificamente, como veremos em mais detalhes, por classes do tipo “Filter”
*
O usuário pode desativar esta função, mas este é o esquema padrão proposto de interface.
†
O ganho se dará, principalmente, devido à não renderização do menu Pull-Down, que é normalmente o maior pesado.
‡
Se desligar o uso de Ajax, os POSTs também passam a ser armazenados na história do usuário. O jCompany evita problemas
funcionais como quando o usuário clica no botão “Volta” (Back) dos Navegadores. No entanto, itens inúteis passam a poluir a história
de uso, na prática, tornando-a pouco útil.
417
Capítulo E16
#4. Agora vemos uma segunda situação onde instâncias de objetos de Domínio são criadas. A
primeira ocorreu pelo Hibernate ou JPA, ao recuperar informações a partir a abertura ou
pesquisa explícita pelo usuário. Agora, o próprio jCompany produz instâncias da agregação
desejada, para “gerar entradas vazias correspondentes”, no formulário.
#5. Ao final, o HTML traz mais entradas (linhas ou itens) em branco para o usuário, que é o
propósito do evento “F7-Novo”, neste padrão.
Vejamos agora, complementando, como seria o fluxo de gravação (“F12-Gravar”), também para a
Colaboração “plcTabular”, na Figura E16.3.
#1. A implementação de fachada agora realiza uma pequena tarefa de “adaptação”, interpretando,
em uma coleção, quais são as operações que deverão ser realizadas em cada objeto. Para
tanto, analisa a propriedade padrão “indExcPlc”, que armazena marcações possíveis na caixa
de exclusão do objeto, a presença ou não de Object-Id gerado, dentre outras técnicas para
interpretação do “estado atual de cada objeto”.
Ao final, decide por incluir (se forem novos objetos), alterar (se forem alterações em objetos
pré-recuperados) ou excluir (se forem objetos marcados para exclusão), delegando
individualmente esta tarefa, para a subcamada de serviços.
#2. O serviço de manutenção do ciclo de vida então é reutilizado, em laço, para cada objeto. Deste
modo as mesmas funções “inclui”, “altera” e “exclui” que atuam para manutenções de
apenas uma agregação de objetos são reutilizadas (Ex.: Manter Agregação Simples ou
Mestre/Detalhe)
#3. Serviços de persistência de nome correlato são também acionados e cada um utiliza o
framework base de persistência para gerar os comandos SQL necessários*.
#4. Neste evento, ao final da fachada, o encerramento de transação ocorrerá via chamada
“dao.commit()”, para confirmar as gravações, a menos que uma exceção seja disparada, o
que produziria um “dao.rollback()”†.
*
o jCompany não produz SQLs, delegando esta atividade inteiramente para frameworks de implementações do padrão JPA tais como
o “Hibernate”.
†
Quando utilizando EJB3 e gerenciamento de transação pelo conteiner, ela também se encerrará neste mesmo ponto, conforme a
opção declarada de transação.
418
Programando Java com jCompany
#5. O HTML final traz o conteúdo da lista atualizado (linhas excluídas removidas, alterações,
Object-id preenchido, etc.) e também a mensagem “Registro gravado com sucesso”.
Código E16.1. Código de Controle, decidindo sobre qual serviço utilizar do contrato de fachada.
Note que, além de testar a delegação conforme o padrão corrente seja “plcTabular” (Logica.TABULAR)
ou não, este método de controle também verifica se uma seleção “paginada” está sendo utilizada,
situação em que uma terceira alternativa de serviço de fachada será utilizada. O Diagrama de Seqüência
correspondente para o evento “F9-Pesquisar” nas Colaborações “plcSelecao” ou “plcPesquisa” é
exibido na Figura E16.4.
#2. Por sua vez, a implementação da fachada para “recuperaLista” chave “recuperaListaQBE”, no
serviço de negócio.
419
Capítulo E16
#5. Na camada visão, o HTML gerado que será exibido para o usuário irá variar, naturalmente, em
comparação ao que geramos na pesquisa de “Manter Classe” - até porque, neste último caso, a
lista será para manutenção, e a nossa atual será utilizada para consulta apenas. Porém, em
ambos os casos os dados retornaram na forma homogênea de uma coleção de Entidades
“List<PlcBaseVO>”.
Figura E16.5. Diagrama de seqüência para “plcCrud” ou “plcMestreDetalhe”. Eventos “F7-Novo” e “F12-Gravar”.
#1. A criação de novos objetos ocorre como no caso anterior, sem transações, mas agora não há
“laço” de criação para o objeto raiz, pois trabalhamos com apenas uma agregação por vez.
#2. A gravação é agora delegada para “gravaObjeto” (em vez de “gravaTabular”), e o serviço
de fachada utilizado é o “gravaObjeto” (em lugar de “gravaTabular”).
#3. Na fachada, há uma interpretação, baseada na comparação com a imagem anterior do objeto,
para decidir se ele será alterado ou criado (incluído). Em função disso, métodos distintos do
serviço de negócio serão acionados. Repare que, neste caso, a exclusão não é realizada
simultaneamente com a inclusão e alteração, mas por um evento próprio disparado pelo botão
“Excluir”.
Para o fluxo de exclusão, que neste caso é disparado por evento próprio, há uma seqüência inteiramente
nova.
420
Programando Java com jCompany
#1. A requisição chega ao “PlcBaseJsfAction” no método “exclui”, que por sua vez chama serviço
“excluiObjeto” da fachada.
#2. O “PlcFacadeImpl” verifica se há uma declaração para uso de “exclusão lógica” nos
metadados. Se existir, muda o rumo da transação para uma “alteração” (sitHistoricoPlc=”I”),
em lugar da exclusão física em si.
#3. Os comandos utilizados para comunicação com a camada de persistência são “delete” para
exclusão física e o “save”, para atualização.
#4. A transação é também encerrada no final do método de fachada, via AOP, com comando
“dao.commit()”.
#5. Se tudo transcorre corretamente, uma mensagem “Registro Excluído com Sucesso” é montada
em escopo de requisição (usando a interface “HttpServletRequest”) e a seqüência do evento
“novo” é chamada. Deste modo, o usuário recebe um formulário em branco com a mensagem
de confirmação da exclusão.
Como deixamos claro na introdução deste tópico, estas são visões gerais das seqüências de transação
para alguns eventos, simplificadas para compreensão dos mecanismos primários da arquitetura MVC2-P
generalizada no jCompany FS Framework. Iremos, ainda neste capítulo, colocar uma “lupa” em cada
uma destas camadas, para enxergá-la com um nível adicional de detalhamento.
As vantagens da arquitetura MVC2-P são reais, mas muitas vezes visíveis somente no médio prazo.
É uma arquitetura que nos permite modificar alguma de suas camadas radicalmente, com um
mínimo impacto nas demais – ao que chamamos de arquitetura “feita para durar” ou “à prova de
futuro” (future proof).
Vejamos a alguns exemplos reais de benefícios, postos à prova no próprio projeto do jCompany
Developer Suite, concebido somente com um framework, em 2002/2003.
*
Devido à ausência de classes para lidarem com tecnologias de “remoting” como Business Delegate e Service Locators nas fachadas,
Data Transfer Objects, etc..
421
Capítulo E16
Graças à sua arquitetura MVC, a tecnologia JSF pôde ser incorporada para suportar o padrão Java EE
5 e novas tendências do mercado, apenas com a refatoração de uma parcela dos pacotes das
camadas Controle e Visão (“parcelas” porque, dentro das camadas Controle e Visão, já existiam
pacotes isolados com baixo ou nenhum acoplamento com a tecnologia Struts).
o Flexibilidade da camada de Persistência.
*
Lembrando que o próprio Hibernate também pode ser usado como uma implementação JPA, indiretamente.
†
O uso deste recurso foi depois desestimulado, com a popularização da tecnologia Ajax, pouco tempo depois. E novidades nesta área
estão previstas, para versões superiores à utilizada neste livro.
‡
Méritos sejam dados a Rod Johnson, pioneiro nesta área com seu framework Spring e livros com dicas para substituição apropriada
dos excessos da tecnologias EJB 2.x.
§
Note que a camada ortogonal de Domínio está presente em ambos os empacotamentos, no lugar dos DTOs dos EJBs 2.x.
422
Programando Java com jCompany
uma arquitetura rica, tais refatorações costumam não acontecer - por envolverem um custo que não
oferecem ganhos de escala (para um único projeto).
Mas perceba que, nos exemplos acima, enfocamos vantagens do MVC para fins de flexibilidade. Este
quesito é importante porque provê longevidade para a aplicação (mais tempo de sobrevida, a menores
custos) e também a viabilidade da preservação de um patamar tecnológico que mantenha o potencial de
inovação tecnológica.
Mas a adoção da arquitetura MVC oferece outras vantagens, além da flexibilidade:
o Especialização (Separação de papéis “por camada”).
Do ponto de vista da separação de papéis, a arquitetura MVC permite que perfis diferentes de
profissionais atuem em diversos segmentos, para projetos realmente grandes, que exijam este tipo
de especialização.
Na parcela de requisitos que recaem em Casos de Uso Padrões, esta separação de papéis não será
vantajosa*. Mas, para os demais casos pode ser uma boa idéia especializar Desenvolvedores em
tecnologias de camada Visão (JSF, Ajax), camada de Controle (JBoss Seam), serviços de negócio e
camada Persistência (JPA, Hibernate).
o Escala em complexidade sem perda de controle, ou “produtividade sustentada”.
Mas o benefício mais fundamental (e muitas vezes “subvalorizado”), do uso da arquitetura MVC é a
sua capacidade de encapsular especialidades de forma refinada, preservando um bom
entendimento e controle de aplicações corporativas, mesmo quando estas evoluem em
tamanho e complexidade.
Infelizmente, para os benefícios de uma arquitetura MVC aparecerem, será necessário o bom
uso da Orientação a Objetos† e também o passar do tempo. Em um projeto que irá produzir
a primeira versão de uma aplicação, por exemplo, pode-se não perceber nenhum ganho nítido,
nesta área‡ - por este motivo, vemos muitas vezes fornecedores contratados “por projeto”
produzindo código “espaguete”, altamente acoplado, pressionados para entregarem a “bomba
relógio” no prazo.
*
Devido ao alto nível de automação em todas as camadas, com qualidade final de produção.
†
A arquitetura MVC não é a prova de programação “COBOL” embutida dentro das camadas!
‡
E, infelizmente, muitas empresas buscam ansiosamente diminuir seu déficit de projetos, muitas vezes sacrificando arquitetura em
uma “primeira versão” rápida, que nas fases de manutenção cobram seu preço, com juros e correção monetária.
§
Rapid Application Developement. Sigla utilizada para representar desenvolvimentos rápidos focados na produção de Interfaces com o
Usuário via “arrasta-e-solta” e “WYSIWYG”, onde componentes visuais são normalmente vinculados (binding) à camadas de
persistência.
**
Como sabemos, visando simplificação extrema para concorrer com a Microsoft no mercado “varejo” do “.NET”.
††
Apesar de visivelmente perigosa, alguns argumentam que esta arquitetura ainda respeita o MVC original, conforme definido na
época do Smalltalk. O problema é que uma implementação MVC rasa como esta não reforça a separação de aspectos e confia
demasiadamente na disciplina do Desenvolvedor – no que chamamos de recaída para o desenvolvimento “artesanal”. Esta variação
pode ser uma simplificação interessante para um segmento do mercado, mas não a recomendamos para o corporativo.
423
Capítulo E16
- Visão geral
Há inúmeras possibilidades de se implementar interações sofisticadas com o usuário hoje, através dos
Navegadores Web, com base nas tecnologias DHTML/Javascript e Ajax, para citar algumas. O jCompany
homologa frameworks como o DOJO, especializadas nesta área, bem como recursos do Apache Trinidad,
embutidos em seus componentes JSF, prontamente disponíveis para uso. Além disso, traz bibliotecas
Javascript/Ajax próprias, que realizam tarefas como:
o Tab-Folder DHTML (comuta abas sem transmissão do Navegador);
o Hot-Key dos botões;
o Foco inteligente (posiciona no primeiro campo vazio do formulário, após a carga);
o Envio de comandos POST via AJAX (F12-Gravar, F7-Novo, F9-Pesquisar);
o Mensagens de advertências (“Tem certeza que deseja excluir...”);
o Etc.
Para se realizar variações em Javascript, como vimos para o lançamento de “ProventoDesconto”, o
desafio passará não somente pelo conhecimento desta tecnologia mas, principalmente, por conhecimento
sobre como utilizá-la de uma maneira “cross-Browser”, que se comporte bem com a larga variedade de
modelos e versões destes Navegadores.
Vejamos a arquitetura básica sugerida para a confecção de rotinas Javascript específicas, sejam “puras”
ou através do framework DOJO.
424
Programando Java com jCompany
...
@PlcConfigOtimizacao(javascriptEspecificoUsa=true)
...
Código E16.2. Metadados para declaração de uso de biblioteca Javascript “AppGeral.js”.
2. Edite agora o arquivo “AppGeral.js” (Control+Shift+R) e inclua nossa primeira função Javascript em
nível de biblioteca*, conforme o trecho de Código E16.3.
...
/**
* Javascript também merece documentação!
*/
function minhaPrimeiraFuncao() {
alert('Alerta de Teste');
}
...
Código E16.3. Código de Controle, Primeira função Javascript no AppGeral.js.
3. Para chamar esta função, após a carga da página principal da aplicação, por exemplo, edite a página
“/WEB-INF/jsps/principalIntroducao.jsp” e inclua o código em Código E16.4.
...
<%@ taglib uri="/WEB-INF/fmt.tld" prefix="fmt"%>
<fmt:setBundle basename="ApplicationResources"/>
<script>
// Registra a função Javascript para executar
setFuncaoOnLoad('minhaPrimeiraFuncao()');
</script>
<table width="500" border="0" cellspacing="0" cellpadding="0">
...
Código E16.4. Registro de função Javascript, para execução após a carga (renderização) da página.
Este código Javascript “embutido” chama uma função do jCompany “setFuncaoOnLoad”, que
por sua vez registra a nossa função Javascript para execução ao final da carga da página†.
*
Já fizemos uma função embutida em uma página, para o Caso de Uso “Manter Coleção”, em tutoriais passados. Aquela função, agora
que sabemos, deveria ser externada para o arquivo AppGeral.js, para dar ênfase a otimização.
†
A função “setFuncaoOnLoad” provê um tipo de registro de IoC em Javascript.
425
Capítulo E16
...
<img id="bannerACME" style="-moz-opacity:0;filter:alpha(opacity=0)"
alt="ACME - RH Tutorial"
src="${pageContext.request.contextPath}/plc/midia/acme/acme_banner.gif" />
...
Código E16.6. Imagem “identificável” via Javascript e com estilos de opacidade.
Perceba que há dois códigos CSS diferentes, separados por ponto e vírgula, para fazer a mesma
coisa: um no padrão Mozilla e outro no padrão do Internet Explorer. Neste caso inicial, ambos
podem ser misturados, sem seqüelas.
2. Altere o conteúdo do arquivo “AppGeral.js”, no projeto “rhtutorial”, incluindo a nossa função
“minhaPrimeiraFuncao”, conforme o trecho de Código E16.7.
function minhaPrimeiraFuncao() {
if (NavYes) {
alert('Sou navegador!'); // 1
setInterval("MOZ()",50); // 2
}
if (ExpYes) {
alert('Sou explorador!');
setInterval("IE()",50);
}
if (Opr) {
alert('Não sou suportado - mas me comporto bem!'); // 3
}
}
valor=0; // 4
426
Programando Java com jCompany
function IE(){
if (valor<=95) valor+=5; // 4
document.getElementById("bannerACME").filters[0].opacity=valor; // 5
}
function MOZ() {
if (valor<=95) valor+=5;
document.getElementById("bannerACME").style.MozOpacity=valor/100; // 6
}
...
Código E16.7. Código de Controle, de Nova função Javascript acionada no “onload” da página principal.
#1. As variáveis globais “NavYes” (Navigator / Mozilla), “ExpYes” (Explorer – IE) e “Opr" (Opera)
nos permitem identificar a família do Navegador corrente. Elas foram disponibilizadas pela
biblioteca Javascript jCompany. Um alerta foi incluído somente para depuração inicial*.
#2. A função Javascript “setInterval” irá chamar uma função com código específico de um dos
navegadores suportados, várias vezes, de acordo com o intervalo em milisegundos informado.
#3. O Navegador “Opera” não está exemplificado, pois não foi priorizado por nossa empresa
hipotética. Mas é importante notar que esta facilidade irá “degradar” bem para este caso - ou
seja, não haverá perda funcional, mas apenas estética, caso o usuário esteja utilizando este
Navegador.
#4. Uma variável global deve ser criada, para conter o nível da opacidade que será incrementado a
cada chamada. Note que basta declararmos a variável fora de qualquer função, para que seja
definida.
#5. A cada chamada de alguma das funções, ela incrementa 5% de aumento da opacidade
(diminuição da transparência), até que atinja 100, quando estará totalmente opaca (visível) e a
rotina não mais terá efeito.
#6. No caso do Mozilla, a mudança é feita através de estilos, e a escala é de 0 a 1, e não 0 a 100.
Por este motivo, uma divisão é realizada.
...
<plcf:botaoAcao id="botaoAcaoGravar" acao="grava" partialSubmit="#{requestScope.ajaxUsa}"
label="jcompany.evt.gravar" botaoArrayID="GRAVAR" rendered="#{requestScope.exibeGravarPlc=='S' and empty
requestScope.estiloApresentacaoPlc and requestScope.exibe_jcompany_evt_gravar!='N'}"
hotKey="#{requestScope.gravarHotKey}" alertaExcluirDetalhe="jcompany.alerta.excluir.detalhe.tabular" />
...
Código E16.8. Declaração do componente de botão para “F12-Gravar”, com submissão parcial via Ajax.
*
É sempre bom certificar-se de que sua versão mais nova de Navegador está sendo capturada corretamente, pois esta é uma
categoria de software em franca evolução.
427
Capítulo E16
Perceba, pelo trecho de código em destaque, que uma “submissão parcial” Ajax é ativada, se e somente
se o usuário está com a opção “ajaxUsa” ativa. Esta opção pode ser ativada pelo próprio usuário,
dinamicamente, em “Personalização de Formulário”, e é default nos templates INI*. O jCompany
realiza esta e outras configurações de modo a tornar o uso de Ajax imediatamente funcional para os
casos mais comuns.
Para mais informações sobre todas as possibilidades de uso de Javascript via Apache Trinidad,
recomendamos uma visita ao Web-Site deste projeto, disponível nas referências bibliográficas deste livro.
<td>
<script type="text/javascript">
// 1
if (typeof dojo=='undefined') {
document.write(
"<script type=\"text/javascript\" src=\"${pageContext.request.contextPath}/plc/javascript/dojo/dojo.js\"><\/script>");
}
</script>
// 2
<script type="text/javascript">
dojo.require("dojo.widget.Clock");
</script>
// 3
<div dojoType="Clock" label="Rh Tutorial" />
</td>
</tr>
...
Código E16.9. Código Javascript que introduz uma primeira declaração de importação do DOJO.
#1. No primeiro bloco de declaração Javascript, realizamos o teste padrão para importação
dinâmica do Javascript DOJO, que evita carregá-lo duas vezes (no caso de ele ter sido utilizado
em outros componentes de leiaute).
#2. Em outro bloco de Javascript (é importante que seja outro), indicamos as dependências
que iremos utilizar somente para o nosso caso, equivalentes ao “import” do Java.
*
Também é possível ao Desenvolvedor desativá-la globalmente ou localmente em uma Colaboração, via metadados.
†
Lembre-se que nós o retiramos de nosso exemplo “rhtutorial”, no momento em que aplicamos o Web-Design de rodapé “simplificado”
que fizemos, baseado em tabelas “<table>”. O FishEye naquele ponto iria requerer uso de divisões “<div>”.
428
Programando Java com jCompany
#3. Finalmente, neste ponto, definimos uma nova divisão HTML “<div/>”, com o atributo
“dojoType” indicando o tipo “Clock”, um relógio disponível como Widget no DOJO. Um opção
de rótulo também foi definida em “label”.
3. Como estamos no mundo do Cliente, não há necessidade de liberação Maven quando editamos
somente JSPs e Javascript. Teste imediatamente o resultado de nosso código no Tomcat, que deve
aparecer agora como a Figura E16.8.
Este é um exemplo simplório, mas dá as dicas fundamentais do potencial deste novo mundo. Veja na
Figura E16.9, a relação de pacotes e Widgets do DOJO, indo desde relógios, calendários e utilitários
de animação, até rotinas de gráficos e editores multimídia.
Figura E16.9. Visão geral dos pacotes de bibliotecas Javascript do DOJO, homologados no jCompany.
Obs.: Os Widgets do DOJO são baseados na renderização de divisões “<div/>” com atributos
proprietários dinamicamente interpretados - inexistentes nos esquemas estáticos esperados para um
documento XHTML, conforme definido pelo W3C (tais como as propriedades “dojoType” e “label”, em
nosso exemplo). Este não costuma ser um problema para a grande maioria dos casos, pois estes
atributos são desprezados pelos Navegadores. Mas para empresas que exigem documentos HTML com o
429
Capítulo E16
formato “Strict”, esta será uma área de conflito, pois verificadores de formato rejeitarão documentos
que usam este padrão do DOJO como Strict válidos*.
- Visão geral
Vamos agora nos mudar para o mundo do servidor. Como vimos, é aqui onde os objetos da “camada
Visão do Servidor” renderizam documentos HTML ou XHTML para navegadores Web e, possivelmente,
outros formatos tais como WML para dispositivos móveis ou mesmo XML para integrações diversas.
De um modo geral, um grande objetivo da camada Visão é conter o mínimo possível de lógicas
procedimentais. Para tanto, usamos a camada de Controle para absorver tanto processamento quanto
possível. Porém, algum tipo básico de condicionais e laços serão inevitáveis. Eles poderão aparecer em
componentes JSF do Apache Trinidad ou mesmo em JSTL, ambos sobre a tecnologia JSP†.
Do ponto de vista tecnológico, já vimos que o jCompany usa JSP 2.0, JSF 1.2 e JSTL 1.1, em sua
versão atual (5.1, no momento da escrita deste livro) de forma integrada. Todas estas tecnologias
possuem mecanismos de “programação” possíveis, para a camada Visão‡.
Vejamos, nos tópicos seguintes, exemplos de programações típicas de camada Visão do Servidor, na
arquitetura do jCompany FS Framework.
*
Note que, mesmo assim, os Navegadores interpretarão os Widgets corretamente, mesmo utilizando formato Strict! A ressalva diz
respeito somente a validadores de formatação que visam garantir “boas práticas” no formato Strict.
†
Deve-se evitar a linguagem Java nesta camada. Experimentalmente, esta prática já se comprovou como inadequada.
Desenvolvedores que a utilizam tendem a não respeitar claramente a separação das camadas Controle e Visão, com algoritmos
excessivamente complexos, miscigenados às lógicas de renderização de páginas.
‡
A opção pelo uso do JSF integrado às JSPs preserva um grande leque cultural e ainda possibilita a gestão de leiautes OO com
IoC, via Tiles. O uso de alternativas de leiaute mais recentes como “facelets”, por exemplo, não está descartado pela Powerlogic
(podendo inclusive ser realizado imediatamente, através de customizações), mas estava com prioridade baixa no momento desta
escrita, uma vez que as JSPs no jCompany se encontram em estágio bastante avançado em termos de simplicidade.
430
Programando Java com jCompany
#2. Atributo “rendered”, implementando a regra: “CPF para funcionários que não são solteiros é
confidencial”*.
#3. Como estamos eliminando condicionalmente uma coluna, precisamos de uma alternativa para
que nossa lista não apareça com deslocamentos indevidos. Assim, na condição inversa,
estamos exibindo condicionalmente e em vermelho, o termo “[Confidencial]”.
Obs.: As Tag-files do jCompany, utilizadas nas JSPs para a tecnologia Struts, implementam um
mecanismo similar ao “rendered” do Trinidad, através da propriedade “exibeSe”.
...
<c:if test="${empty requestScope.passoAssistentePlc or requestScope.passoAssistentePlc==3}">
<plcf:linha>
<plcf:celula>
<plcf:titulo tituloChave="label.temCursoSuperior"/>
<plcf:caixaMarcacao id="temCursoSuperior"
value="#{plcEntidade.temCursoSuperior}" />
</plcf:celula>
</plcf:linha>
</c:if>
...
Código E16.10. Programação de camada Visão com JSTL Core “if”
Não iremos descrever todas as possibilidades de “controle de fluxo” das Tag-Libs Core JSTL e nem dos
componentes JSF. De qualquer modo, é uma boa prática manter o uso de tais recursos em seus
níveis básicos. Suspeite da necessidade de programações mais intrincadas neste ponto: elas
não podem ser “movidas” para a camada Controle?
- Visão geral
De uma maneira simplificada, a camada Controle deve conter programações relacionadas à interface com
o usuário, segurança, navegação e validações de entrada, não incluindo regras do negócio e nem de
acesso a bases de dados, por exemplo.
*
Não me perguntem por que, raios, existiria uma regra como essa!
431
Capítulo E16
Muito embora não tenham acesso direto a sessões de Persistência, as classes de Controle devem ser as
únicas com acesso aos objetos Web, tais como HttpSession, HttpServletRequest, etc.) e a certos
frameworks especialistas nesta camada, tais como JSF/Apache Trinidad (ou Struts), JBoss Seam ou Tiles
(parte de Controller).
Para facilitar o estudo das seqüências de atendimento, podemos dividir o trabalho da camada de Controle
em duas metades distintas:
o Fase de Empilhamento (equivale às fases JSF de Requisição e de início da Resposta):
Nesta fase “de ida”, as classes de controle recepcionam requisições advindas dos Navegadores,
validam os dados recebidos e os transformam em estruturas de objetos, com semântica mais rica e
apropriada para o prosseguimento da requisição. Iniciando o processamento da resposta, os
métodos de controle chamam serviços de fachada, que encapsulam regras de negócio e acesso à
persistência.
o Fase de Desempilhamento (equivale à fase JSF de finalização da Resposta): Nesta fase “de
volta”, informações devolvidas da camada Modelo são recebidas e recebem manipulações eventuais,
incluindo tratamento de cenários de exceção e análise de fluxos de desvio declarados. Regras de
programação associadas ao mundo da Interface com o Usuário podem ser realizadas, quando estão
acima do escopo de componentes JSF individuais. Deste modo, ao delegar o processamento de
renderização dos documentos de resposta para a camada Visão, resta a esta última camada
somente um trabalho de programação essencial, realizável através de primitivas simples como
assertivas e laços.
Figura E16.12. Seqüência mais detalhada de requisição GET para colaboração “plcTabular”.
#1. Chamada via menu: Como vimos anteriormente, este tipo de evento envia um comando
HTTP GET para a camada Controle tratar. Nestes diagramas mais detalhado, abstrairemos da
representação Javascript utilizada na introdução.
#2. Os filtros que atuam são agora explicitados. Classes do tipo “Filter” foram introduzidas na
especificação “Servlet 2.3”, para atuarem “em torno de um Servlet”; por isso, são as que
primeiro executam processamento, após a chegada de uma requisição*.
Muito embora estas classes, na maioria dos casos, não requeiram atenção e especialização,
*
No jCompany, classes de filtro são nomeadas com a convenção “Plc[Nome]Filter”.
432
Programando Java com jCompany
haverá situações onde compreender a sua atuação será importante. Os seguintes filtros são
registrados e atuam nesta fase:
“PlcMasterFilter”:
#4. Perceba que, a partir deste ponto, classes descendentes e especificas de cada projeto, em
esquema de Inversão de Controle, passam a atuar, tais como "AppPhaseListener" e
"AppAction". A classe “AppPhaseListener”, descendente de “PlcPhaseListener”, é incluída
mesmo que sem implementações específicas, pelos templates INI, para facilitar e promover
especializações neste ponto, de forma padronizada.
O métodos “beforePhase” e “afterPhase” são disparados pelo Apache Trinidad, que realiza
os trabalhos de recepção e reconstrução do “estado” dos componentes JSF (basicamente, a
reconstrução da árvore de componentes no servidor, conforme estabelece o padrão JSF). O
jCompany atuará, através da classe “PlcPhaseListener”, com implementações genéricas nos
métodos “beforePhase” e “afterPhase” para o evento “RESTORE_VIEW 1”*.
Na prática, como nossa requisição específica é um mero “GET” e não envia mudanças de
estado significativas em componentes JSF, esta fase de “RESTORE VIEW” é bastante trivial.
Para os interessados em maior aprofundamento nesta área, sugerimos o estudo deste ciclo de
vida em literatura específica sobre JSF.
#5. É neste ponto, após a recriação no servidor do estado de componentes JSF, onde se inicia a
fase de renderização da resposta para o usuário. Ou seja, a partir deste ponto já sabemos o
que o usuário quer e validamos sua solicitação – vamos então prosseguir para conseguir
montar um documento com a resposta apropriada. Mas note que, de um ponto de vista de
mais baixo nível, ainda estamos “empilhando” chamadas de métodos de objetos, na
pilha da memória (Heap).
*
Segundo o contrato de interceptação padrão do JSF, os diversos eventos de ciclo de vida de componentes são passados como
argumento, para os mesmos métodos “beforePhase” e “afterPhase”.
433
Capítulo E16
#6. De forma simplificada*, a classe “PlcPhaseListener” termina por delegar para o método
“inicializaManagedBeans” a tarefa de obter instâncias do objeto que encapsula metadados
do jCompany, do objeto que mantém em memória os dados transmitidos (em nosso caso, não
transmitimos nenhum) e também do objeto que irá realizar o processamento de Controle,
específico para a requisição (nossa classe no padrão Action).
#7. Neste método, no momento em que o processamento tenta interpretar uma expressão para
obter referência ao objeto que encapsula os metadados do jCompany, o JBoss Seam entra
em ação. A partir deste ponto, precisamos de conhecimentos básicos sobre este framework†.
Tudo começa porque o objeto de metadados em questão, cuja referência tentamos obter
dinamicamente via o interpretador de expressão EL
“PlcElHelper.getInstance().evaluateExpressionGet” é “gerenciado pelo jBoss Seam”.
Este objeto é declarado como variável de instância da classe "PlcBaseJsfAction", e as
anotações reproduzidas no Código E16.11 declaram este “gerenciamento”.
...
@In(value = PlcJsfConstantes.PLC_CONFIG_URL_COLABORACAO, required = false, scope = ScopeType.EVENT)
@Out(value = PlcJsfConstantes.PLC_CONFIG_URL_COLABORACAO, required = false, scope = ScopeType.EVENT)
protected PlcConfigUrlColaboracao configUrlColaboracaoPlc;
...
Código E16.11. Declaração de objeto de metadados “gerenciado” pelo JBoss Seam, no “PlcBaseJsfAction”.
...
@Factory(PlcJsfConstantes.PLC_CONFIG_URL_COLABORACAO)
public void criaConfigUrlColaboracao() throws PlcException {
...
Código E16.12. Declaração de método “factory” para objeto de metadados no “PlcBaseJsfAction”, para o
jBoss Seam.
#9. Assim, da primeira vez que a aplicação tenta acessar uma Colaboração padrão em uma
conversação‡ e seus “metadados” ainda não existem disponíveis para acesso, o JBoss Seam
aciona este método de factory. Este método, somente uma primeira vez na vida de uma
aplicação§, obtém as anotações de metadados tanto da camada Controle quanto Comuns
(Domínio) para esta Colaboração e as mantém encapsuladas, para facilitar o acesso do
framework.
*
Já que existem várias chamadas do “beforePhase”, até este ponto que nos interessa.
†
A representação da chamada de “AppPhaseListener” para o JBoss Seam no Diagrama de Seqüência está em alto nível de abstração,
apenas para fins didáticos. O mecanismo real é mais intrincado e também poderoso.
‡
Uma escopo de “conversação” do JBoss Seam é formado por um conjunto de requisições HTTP que compartilham de um mesmo
“estado”. Este estado é gerenciado pelo jBoss Seam, de forma equivalente a uma sessão HTTP, porém normalmente de menor duração.
§
Isto somente é realizado uma única vez, já que as informações de metadados não variam a cada requisição e nem mesmo durante a
vida da aplicação. Portanto, elas ficam armazenadas em caching na primeira requisição do usuário e são reutilizadas da memória, daí
por diante.
434
Programando Java com jCompany
...
@In(value = PlcJsfConstantes.PLC_LOGICA_ITENS, required = false, scope = ScopeType.CONVERSATION)
@Out(value = PlcJsfConstantes.PLC_LOGICA_ITENS, required = false, scope = ScopeType.CONVERSATION)
protected PlcBaseLogicaItens logicaItensPlc;
...
Código E16.13. Declaração de objeto que encapsula listas para as Colaborações “plcTabular”,
“plcCrudTabular”, “plcSelecao”, “plcConsulta”, gerenciado pelo jBoss Seam, em “PlcBaseJsfAction”.
#11. Como a colaboração de nosso exemplo é “plcTabular”, o jCompany tenta capturar dados no
objeto “plcLogicaItens”. Se eles não existirem (como no caso da primeira requisição), o
método “criaLogicaItens”, definido como “factory JBoss Seam” para este objeto, é
acionado, iniciando uma conversação.
...
@Factory(PlcJsfConstantes.PLC_LOGICA_ITENS)
@Begin(join = true)
public void criaLogicaItens() throws PlcException {
...
Código E16.14. Método de factory JBoss Seam para “plcLogicaItens”, em “PlcBaseJsfAction”.
#12. A implementação deste método irá variar, dependendo do padrão da Colaboração corrente.
Para o caso do “plcTabular”, como a operação default é a recuperação de todos os objetos, o
processamento de criação será delegado para o método “pesquisa” (o mesmo acionado
quando o usuários clica em “F9-Pesquisar”).
O método “pesquisa” obtém, por fim, uma referência do contrato de fachada padrão
(“IAppFacade” – “AppFacadeImpl”) e chama um serviço da Camada Modelo/Persistência, para
recuperação da lista de Entidades.
435
Capítulo E16
#1. Após o recebimento da coleção recuperada via serviços da camada Modelo, o método
“pesquisa” simplesmente disponibiliza a lista de objetos retornada no objeto “plcLogicaItens”*,
disponível como variável de instância da própria classe†.
#4. Uma nova fase JSF é iniciada e o método “afterPhase” é executado para o evento
“RENDER_RESPONSE”, ainda na classe “PlcPhaseListener”.
#5. A partir deste ponto o processamento é delegado para o Tiles, que através de uma JSP de
Front-Controller “tilesDispatchPlc.jsp”§ começa a etapa de “despacho” de conteúdo HTML. O
uso da JSP é necessário como técnica de integração do Tiles com o JSF e seu código é de
extrema simplicidade, realizando uma de duas coisas:
- Se a Colaboração corrente estiver utilizando o leiaute Universal do jCompany, esta página irá
inserir uma definição Tiles “def.universal.automatico” (utilizando a Tag “tiles:insert”).
- Se a Colaboração corrente estiver utilizando um leiaute específico, ela irá tentar inserir uma
definição Tiles com mesmo nome que a URL (Ex.: “uf”).
#6. Definições de leiaute Tiles são recursivas, como já vimos. A definição principal
“def.universal.automatico”, por sua vez, inclui referências a outras subdefinições de
forma dinâmica, com base em convenções de nomenclatura.
#7. Cada definição, em seu nível, pode declarar o uso de uma classe Java considerada de camada
Controle, chamada “Tiles Controller”**. Este tipo de classe implementa a interface “Controller”
do Tiles, que exige o método “execute”. Este método tem código que roda antes do despacho
de cada trecho de leiaute, permitindo programação dinâmica, em seu contexto.
#8. Cada definição, em seu nível, após a execução da classe Tiles Controller, despacha a execução
de uma JSP de leiaute (path) e outras adicionais representando componentes do segmento de
leiaute. As páginas JSP, por sua vez, podem conter diversos componentes Trinidad,
representados por Tag-Libs JSP.
*
Dependendo do padrão, poderia ser uma Agregação de Objetos, disponibilizada no objeto “plcEntidade”.
†
Note que, em JSF, as classes de Action do jCompany são statefull em escopo de “conversação JBoss Seam”, aceitando objetos que
contém dados como variáveis de instância - ao contrário do Struts, onde são stateless e tais objetos devem ser obtidos da sessão
(HttpSession).
‡
Novamente, existem diversos outros métodos executados nesta fase, não representados. Note que a fase “beforePhase” para o
evento “RENDER_RESPONSE 6” é a de maior duração.
§
Esta JSP atua como um Servlet, sendo inclusive declarada como tal no “web.xml”, em uma das técnicas mais utilizadas para
integração os frameworks JSF e Tiles. Como internamente, toda JSP se torna um Servlet, neste caso ela é efetivamente utilizada como
um Servlet de Front Controller para poder ser valer de Tag-Libs Tiles para inserção de leiautes.
**
Esta é uma classificação que pode ser polêmica. Por ocorrerem já na fase de renderização do documento de resposta, poder-se-ia
classificar as classes de controle do Tiles como de “camada Visão”. Porém, estas classes de controle Tiles são certamente
“controladoras” do ponto de vista do Tiles e podem ser entendidas como complementares as classes de Action, sendo inclusive
independentes do formato do documento – por este motivo, são organizadas como camada Controle, do ponto de vista do jCompany.
436
Programando Java com jCompany
#1. As classes de implementação de “PhaseListener” são stateless, significando que não possuem
propriedades com estado variante (variáveis de instância).
#2. Os métodos requeridos pela interface “PhaseListener” estão disponíveis, para sobreposições
que se possam fazer necessárias.
437
Capítulo E16
#4. Diversos “Template Methods” estão disponíveis. Os métodos que terminam com “Antes”,
“Apos” e “Api”, como já vimos, são convenções que indicam que não possuem código no
ancestral – dedicados a especializações.
#5. O mecanismo de IoC que faz com que “AppPhaseListener” atue é provido pela implementação
JSF. Os templates INI trazem este descedente declarado no “faces-config.xml” para que atue e
facilite implementações específicas.
#1. As classes utilizadas como “Action” no JSF são “Statefull”, ao contrário do Struts, onde são
“Stateless”.
#3. A maior parte do código das classes “Service” da camada Controle são independentes da
tecnologia Struts ou JSF*. Quando há alguma diferenciação específica que necessite de
*
Uma das diferenciações do conceito de Delegação comparado a uma chamada simples é a flexibilidade para se especializar as classes
de serviço utilizada em ancestrais. No jCompany, é possível se declarar especializações destas classes em metadados, alterando
qualquer comportamento envolvido na agregação, não somente da classe principal.
438
Programando Java com jCompany
#1. Classes de utilitários utilizadas com freqüência por toda a classe, são definidas em variáveis de
instância, para maior clareza.
#2. Classes de utilitários são definidas com DP Singleton. Note que este DP exige construtores
“privados” para impedir instanciamentos desnecessários – que como efeito colateral também
impedem a herança. Deste modo, classes utilizada com DP Singleton do jCompany não
são projetadas para serem especializadas. Geralmente contêm métodos simples, que
podem ser substituídos inteiramente por outros, sem produzirem redundância significativa.
*
Este é um bom exemplo de ganhos advindos da Delegação. Muito embora a classe Raiz seja dependente de tecnologia JSF ou Struts,
os códigos comuns a ambas estão fatorados nos serviços.
†
Exemplos são o “perfil do usuário corrente” e alguns metadados que podem ser modificados dinamicamente.
439
Capítulo E16
#1. Os objetos que contêm representações de metadados para uma Colaboração corrente são
injetados como variáveis de instância no “PlcBaseJsfAction” pelo JBoss Seam.
440
Programando Java com jCompany
#1. Os objetos que representam agregações de Domínio e também o POJO que encapsula
informações de contexto* também ficam disponíveis para a classe “PlcBaseJSFAction” como
variáveis de instância, e são gerenciados pelo JBoss Seam.
É importante notar que estes objetos têm importância própria e fazem sentido mesmo que
desvinculados do “PlcBaseJsfAction”. Portanto, não são considerados “agregações” da classe
“PlcBaseJsfAction”.
...
<plcf:iteracao id="plcLogicaItens" value="#{plcLogicaItens.itensPlc}">
(...)
<plcf:celula>
<plcf:texto id="nome" value="#{item.nome}" ajudaChave="ajuda.nome" />
</plcf:celula>
...
Código E16.15. Referência a “itensPlc”, dentro de “plcLogicaItens” (o “Action” corrente é assumido
implicitamente pelos componentes JSF do jCompany).
O componente “iteracao" cria um laço e disponibiliza cada objeto da coleção na variável local
“item”, de modo que todo o “grafo de Domínio” pode ser acessado via notação de pontos tipo
“#{item.objeto.[objeto]}”.
*
Na prática, dados mantidos na sessão HTTP ou em uma conversação JBoss Seam – de interesse dos serviços da camada Modelo.
441
Capítulo E16
#3. Note que a coleção anterior pode não ser mantida durante uma conversação*, o que é inclusive
o default do jCompany para evitar aumento de consumo de memória sem necessidade. O uso
do metadado de controle “detalheLembra=true”, para a Colaboração, faz com que coleções
previamente recuperadas (portanto, antes de eventuais modificações) também sejam mantidos
em memória durante uma conversação.
...
comportamento = @PlcConfigComportamento(detalheLembra = true),
...
Código E16.16. Indica para o framework manter a coleção ‘anteriormente recuperada’ em
“plcLogicaItensAnterior”.
Esta configuração somente deve ser usada quando for necessário implementar lógicas de
programação do tipo “se alterou uma propriedade do valor ‘A’ para o valor ‘B’, então
...”.
#4. Se o padrão da Colaboração for “plcCrud”, “plcMestreDetalhe”, “plcMantemDetalhe”,
“plcManSubDetalhe”, “plcPrefAplicacao” ou “plcPrefUsuario”, ou seja, em padrões onde
se manipula “uma agregação por vez”, então a agregação de domínio é incluída diretamente
em “plcEntidade”, através de referência ao seu objeto Raiz. Neste caso, a versão anterior é
sempre mantida pelo jCompany por default, mas somente do objeto Raiz da agregação.
#5. Além do modelo de Domínio, em seus estados atuais e anteriores a modificações, um POJO
adicional é sempre enviado pelo jCompany, da camada Controle para a camada Modelo,
conforme pode ser investigado pela assinatura do Façade "IPlcFacade". Este objeto
implementa o DP J2EE Context Object, que define padrões para encapsulamento de dados
úteis aos serviços de Modelo, porém mantido somente no contexto da camada Controle†.
*
Indicado pela multiplicidade zero no diagrama UML.
†
Muito embora este objeto seja relativamente extenso, a maior parte das informações não é composta em uma requisição típica - o
envio do perfil do usuário corrente é seu propósito mais fundamental, na maior parte dos casos.
442
Programando Java com jCompany
Figura E16.19. Esquema previsto para especialização dos serviços centrais de controle.
#1. A classe “PlcBaseJsfAction” contém as implementações específicas para cada evento padrão
(disparados, em sua maioria, pelos botões de ação), utilizando DP Template Method. Desta
vez, representamos apenas a parte de operações desta classe, para enfatizar esta
implementação (nos outros diagramas, analisávamos as variáveis de instância).
#2. Uma classe “AppAction” é configurada como default, em cada projeto, através dos templates
INI, pronta para conter especializações genéricas para toda a aplicação. No exemplo acima,
esta classe sobrepõe um método exclui para toda a aplicação (algo mais “radical”, porém
possível) e também acrescenta procedimentos após a edição, para todos os objetos.
#5. Para especializar serviços que recebem delegações da classe “PlcBaseJsfAction”, tais como
"PlcValidacaoJsfService", basta criar um descendente, declará-lo como uma classe
gerenciada pelo Seam e implementar um novo método de “factory”, em “AppServiceFactory”,
classe disponível nos templates INI. Exemplos:
@Name("AppMeuValidationJsfService ")
@Scope(ScopeType.APPLICATION)
public class AppMeuValidationJsfService extends PlcValidacaoJsfService{
@Name("AppServiceFactory")
@Scope(ScopeType.APPLICATION)
@AutoCreate
public class AppServiceFactory {
@Factory(value="serviceValidacaoJsfPlc")
public PlcEntidadeService geraValidacaoJsfService() {
443
Capítulo E16
return (PlcValidacaoJsfService)Component.getInstance("AppMeuValidationJsfService",true);
}
}
#6. Finalmente, para repassar novas informações de contexto para a camada Modelo, deve-se
especializar o POJO “PlcBaseContextVO”, criar a nova informação de contexto (por exemplo,
empresa ou filial corrente, em uma aplicação multi-empresa) e, em seguida, especializar a
classe Action para montar este valor.
2. Antes de editar estas classes, experimente alterar a URL, incluindo três diferentes níveis de detalhe
via parâmetro “logSpyPlc=”, informando valores de 1 a 3. Em cada nível, um maior número de
classes é exibido. O resultado do nível 1 é exibido na Figura E16.21.
444
Programando Java com jCompany
Figura E16.21. Todas as classes de log que possuem pacotes padrões do jCompany.
Obs.: O nível 3 filtra somente classes de logging de JSPs pré-compiladas, que aparecem após uma
“liberação com pré-compilação”, voltada para produção. Por este motivo, em desenvolvimento
pode-se não perceber diferenças significativas entre os níveis 2 e 3.
3. Agora retorne ao Eclipse e procure a janela de console do Tomcat. Clique no botão “Clear Console”
exibido na Figura E16.22.
Figura E16.22. Console do Tomcat no Eclipse. Somente SQLs são exibidos, na configuração padrão.
Dois problemas podem acontecer aqui: se a janela “Console” não estiver visível, você poderá ter
que ativá-la através da opção de menu “Windows -> Show View”; ou se a janela console estiver
exibindo informações do Apache Derby ou Maven, você terá que comutá-la para Tomcat, no botão
“Display Selected Console”.
4. Volte o jCompany Log4j Console para o modo resumido, simplesmente informando “logSpyPlc=0”
na URL. Em seguida, troque o nível da classe de log “jcompany.controle.log” de “INFO” para
“DEBUG” e clique em “Set”.
Figura E16.23. Alteração dinâmica de nível de logging para classe especial do jCompany.
5. Agora retorne para a aplicação e acesse a URL “/f/t/uf”. Após sua execução, comute para o Eclipse e
consulte o resultado na janela de Console. Ele deve estar semelhante ao resultado exibido na Figura
E16.24.
445
Capítulo E16
Figura E16.24. Perfil de execução via logging, destacando classes/métodos fundamentais da camada Controle.
Veja como agora fica fácil identificar a seqüência de empilhamento e desempilhamento das
execuções, através da endentação automatizada que o jCompany provê para estas classes
especiais de logging, nomeadas como “com.powerlogic.jcompany.[camada].log”.
Este recurso, aliado com o bom uso do logging convencional, pode auxiliar na identificação de
gargalos de performance e também na localização de problemas, de forma complementar ao
depurador.
6. Experimente agora ligar também o nível de DEBUG para a classe
“com.powerlogic.jcompany.visao.log”, para ver o fluxo de camada Visão, juntamente com o da
camada Controle. Estude o resultado juntamente com os diagramas de seqüência que estudamos
anteriormente.
*
Em Struts, o jCompany implementa uma solução chamada de “one-click profiling”, que exibe uma pilha de execução também via
Log4j, mas utilizando técnicas de AOP via CGLib, para exibir métodos do Tiles e Struts, dentre outros. Esta é ainda uma visão
intermediária entre o log que vimos para JSF e um profiling completo.
446
Programando Java com jCompany
Nos cenários eventuais quando necessitarmos de conhecimento ainda mais profundo, a recomendação é
para usarmos as ferramentas de depuração (Debug) do Eclipse, o que pode ser feito com os seguintes
passos:
1. Após descobrir um trecho de execução “suspeito”, seja na aplicação, seja no jCompany ou
frameworks de base, navegue via hiperlinks pelos códigos fontes destas classes (“control+Clique”
sobre o nome das referências) e aperte “duplo-Clique” na barra lateral esquerda da linha desejada,
para marcar um ponto de parada.
Figura E16.25. Linha de código de classe do jCompany, com “breakpoint” para depuração.
2. Ao executar a aplicação novamente, o “Debug” do Eclipse irá propiciar os diversos recursos que se
espera dos melhores utilitários para este fim, tais como execução “passo a passo”, investigação e
alteração dos valores de variáveis na memória, inclusão de condicionais (Ex.: “somente parar aqui
se variável a for igual b”) e inclusive alteração de código com efeito imediato – seguida de um “Hot
Deploy”.
#1. Relação de “Threads” em execução no Tomcat. Como trabalhamos com ambientes de execução
multi-thread, existirá um conjunto delas (pool) criadas na memória, mas apenas uma conterá a
nossa execução principal, e esta já se apresentará aberta, com a pilha de execução real
exibida, até o ponto de parada definido.
#2. Uma barra de botões permite opções tais como execução “linha a linha” (botão verde), salto
para o próximo ponto de parada, retrocesso e indicativo para se entrar em uma função (em
lugar de considerá-la apenas uma linha de execução).
#3. Na janela “Variables”, pode-se consultar e alterar valores de variáveis em memória, na medida
em que se avança de forma paulatinamente, na execução.
#4. Em “Breakpoints”, podem-se excluir pontos de paradas existentes ou incluir novos, na medida
em que se executa a depuração, inclusive informando-se condicionais.
#5. Finalmente, com o código fonte disponível, pode-se alterá-lo, para avaliar seu efeito imediato.
Lembre-se de que este “Hot-Deploy” realizado não é perene, e será perdido após um reinício
do Application Server. Após algumas alterações em modo de depuração, deve-se realizar uma
liberação “rápida com reinicio”.
447
Capítulo E16
Para aprender mais sobre a opção de “Debug” do Eclipse, consulte no Ajuda On-Line do Eclipse o tópico
“Java Development User Guide -> Concepts -> Debugger”. Se você não conhece ainda esta ferramenta,
esta é uma leitura obrigatória!
448
Programando Java com jCompany
- Visão geral
O estudo da programação da camada Modelo pode ser segmentado em duas subcamadas, já
desconsiderando a de Persistência:
o Subcamada de Fachada (DP Façade): Realiza a adaptação de requisições da camada Controle
para a subcamada de Serviços ou do Negócio, incluindo o delineamento das transações. Não
implementa os serviços em si, mas delega para a subcamada de Serviços. Esporadicamente, para
casos mais simples, pode chamar a camada de Persistência diretamente*.
o Subcamada de Serviços do Negócio (DP Java EE AS-Application Service ou BO-Business
Object): Realiza os serviços principais do negócio, via delegação das implementações da fachada. É
importante esta separação, para manter os métodos de serviços com assinaturas “de negócio”. Além
disso, por não delinearem transações, os métodos desta camada se tornam mais reutilizáveis.
*
A chamada de serviços da persistência diretamente de implementações de fachada é aceita pelos DPs J2EE, para casos triviais, mas
pouco utilizada pelo jCompany, exceto em recuperações de listas simples para colaborações “plcTabular”. A rigor, esta chamada direta
indicaria que a subcamada de fachada e a subcamada de serviços são laterais mas, na prática, é melhor compreendê-las como
camadas superpostas.
†
Nesta arquitetura, um arquivo EAR contendo arquivos JAR gerados dos projetos “rhtutorial_modelo” e “rhtutorial_comuns” deverá ser
embalado e instalado para funcionamento remoto, em um container EJB3, com seus serviços acessíveis via RMI/IIOP, JMS ou Web-
Services. Já os projetos “rhtutorial (principal)” e “rhtutorial_comuns” (este último residirá nas duas pontas, possivelmente, ao menos
para os Casos de Uso Padrões), devem sem embalados um arquivo WAR, funcionando como “cliente”. Esta arquitetura será analisada
no livro “Volume II – Tópicos Avançados”, desta sérieo.
449
Capítulo E16
#1. Contrato de Fachada Padrão para Manutenção de Ciclo de Vida e Consulta Parametrizada, do
jCompany.
#3. A implementação possui ancestrais com métodos de apoio restritos a esta subcamada.
#5. Descendente do Contrato de Fachada Padrão, na aplicação, para permitir novas “cláusulas
contratuais”, que tenham afinidade com o assunto do contrato.
#6. Versão da interface remota na aplicação. Veja que aqui utilizamos “herança múltipla”, possível
para Interfaces (esta Interface especializa tanto o "IAppFacade" quanto o "IPlcFacadeRemote")
#7. Descendente da Implementação de Fachada Padrão, para implementações padrões das novas
“cláusulas contratuais”.
É importante notar que o uso do esquema padrão de especialização do contrato de fachada deve estar
estritamente relacionado ao seu objetivo (“objeto principal” do contrato), que é a Manutenção e
Consulta Parametrizada em Agregações de Entidades. Para quaisquer outros casos de serviços
necessários, mas não relacionados ao objeto, deve-se definir um contrato e implementações de
fachada “à parte”.
Praticaremos com estas duas situações, em tutoriais dos próximos capítulos.
450
Programando Java com jCompany
o Utiliza, de forma transparente para a classe de controle, um algoritmo para localização de serviços
potencialmente remotos com tecnologia EJB3, utilizando lookups JNDI e DP Business Delegate.
o No caso de não utilizar EJB3, e após localizar a classe adequada a ser utilizada para a
implementação de fachada, o algoritmo de instanciação do jCompany utiliza técnicas de AOP via
Proxy CGLib, de modo a permitir interceptações AOP nos métodos desta classe.
Vejamos, pela Figura E16.28, a seqüência de IoC para obtenção da referência da fachada.
Figura E16.28. Seqüência em maior profundidade, da arquitetura de IoC utilizada para localizar a fachada.
#1. Métodos de controle tais como o “pesquisa” obtém referências à Interface de fachada
“IAppFacade”, através do método “getServiceFacade()”, que encapsula toda a
complexidade envolvida em sua obtenção.
#4. Quando utilizando tecnologia EJB3, esta classe irá delegar a localização da referência para a
classe "PlcEjbHelper", que encapsula o algoritmo de DP Business Delegate, para obter uma
referência possivelmente remota da fachada*.
*
Perceba que, muito embora neste cenário o “AppFacadeImpl” seja um EJB3 Session Bean, ele necessariamente poderá não estar
remoto, sendo também possível acessá-lo localmente, segundo o padrão EJB.
451
Capítulo E16
#5. Quando utilizando POJO será utilizado um algoritmo de IoC via DP “Service Locator” e reflexão,
para pegar uma referência de implementação localmente disponível (camada Modelo no
mesmo WAR).
#6. O retorno de cada um dos métodos irá variar, sendo a Interface potencialmente remota
devolvida no primeiro caso, e a local no segundo. Mas em qualquer dos casos, o uso funcional
permanecerá idêntico.
#7. No primeiro caso a classe de controle, agora de posse de uma referência de Interface remota,
indiretamente pode disparar chamadas remotas, no padrão EJB3.
#8. No segundo caso a classe de controle realiza sempre uma chamada local, indiretamente via
Interface. Note que, indiferentemente da forma e tecnologia de implementação, a
camada Controle opera da mesma forma, nos dois cenários!
Figura E16.29. Seqüência em maior profundidade, da arquitetura de IoC utilizada pela fachada.
#1. A maior parte dos métodos de acionamento são como os iniciados por esta primeira seqüência,
típica da pesquisa quando feita em colaborações “plcTabular” ou “plcConsulta”.
#2. A implementação de Fachada irá realizar procedimentos mínimos e pegar uma referência da
classe de utilitário para localização serviços, através do método “getBO(PlcBaseVO)“ que, a
exemplo do “getServiceFacade”, irá encapsular a lógica de obtenção do serviço de Business
Object apropriado para tratar a requisição.
#4. O algoritmo de localização do melhor serviço, por si, é delegado para a classe
“PlcModeloIoCFactoryService”, que é extensível. Este algoritmo recebe uma classe de
Entidade e procura localizar uma classe de gerenciamento com base em convenção de
nomenclatura (Ex.: "FuncionarioManager" para entidade "FuncionarioEntity") ou com
base em anotações explicitas, na Entidade (Ex.:
452
Programando Java com jCompany
@PlcIoC(nomeClasseBC=”com.empresa.rhtutorial.modelo.MeuServico”)). Se não
encontrar, reutiliza uma instância da classe padrão “PlcBaseBO”.
#5. A partir da segunda chamada, a referência que está em cache para a requisição é reutilizada.
#7. A classe “PlcPersistenciaLocator” executa algoritmo similar ao das classes anteriores para
Modelo e Facade, incluindo a delegação do algoritmo de IoC para a classe
"PlcPersistenciaIoCFactoryService", extensível.
#9. A referência de persistência é então obtida para uso direto do método de fachada
(recomendado somente para casos mais simples, como este).
453
Capítulo E16
#1. Como o “Context Object” é mais utilizado em manutenções, desta vez vamos analisar a
seqüência de transação do ponto de vista de um método de atualização como o “grava”.
Por default, somente informações que o jCompany necessita são montadas, mas novas
informações de contexto podem ser adicionadas via especializações. Importante: este objeto,
quando especializado, deve conter somente metadados e informações de contexto! Parâmetros
“do negócio” devem ser explicitamente enviados como tais, explícitos em novas cláusulas do
contrato de fachada (“IAppFacade” ou outro).
Após sua criação, que ocorre uma vez a cada requisição, o objeto de contexto é armazenado
com escopo de requisição (HttpServletRequest), evitando de ser passado também na
assinatura dos métodos de controle, para não “poluir” todas as assinaturas.
#3. Antes de enviar chamadas à fachada, o métodos de controle obtêm uma instância atual do
objeto de contexto através de “getContext”. Este método recupera do escopo de requisição o
objeto de contexto gerado.
#4. Nas chamadas de fachada, como reza o DP Context Object, este objeto é enviado
explicitamente (Lembre-se de que esta pode ser uma chamada remota). Além disso, como há
restrição ao uso da tecnologia de Servlet na camada de modelo, mesmo com as camadas
embaladas localmente (no mesmo WAR), não haveria como a camada Modelo obter este
objeto.
*
Lembrando que aqui também atua um esquema de IoC. Ou seja, é possível declarar um outro descendente específico de
“PlcBaseContextVO”, para conter valores de “contexto” específicos do negócio, para sempre ser enviado para serviços da camada
Modelo.
454
Programando Java com jCompany
#6. Este trabalho é então delegado para uma classe de gerenciamento de Context Objects
chamada “PlcContextManager”, que armazena o objeto em uma “Thread Local”*.
#7. A “Thread Local” funciona como área globalmente visível durante a seqüência de
processamento da camada modelo, no escopo da requisição, como desejamos. A classe
“PlcContextManager” encapsula uma declaração estática com esta “Thread”.
#8. Métodos da camada de serviço (ou do negócio) não mais necessitam enviar este objeto como
parâmetro, ficando com a assinatura mais sucinta e objetiva, definindo estritamente a sua
necessidade de negócio.
#11. Finalmente, quando se trabalha com Hibernate, seja diretamente, seja como uma
implementação JPA, o jCompany possui interceptadores (Hibernate Listeners) em eventos de
persistência que visam realizar otimizações (evitar queries desnecessárias em diversos
momentos) e também registrar usuário e data da última alteração, para auditoria “pauta
mínima”.
Nesta classe, o objeto de contexto é utilizado para se capturar o padrão corrente (para
otimizações), nomes de classes de Raiz/Mestre e Detalhe – além do perfil do usuário corrente.
*
Para compreender melhor o que são as Thread Locals e a técnica de algoritmo empregada nesta área, sugerimos a busca por este
termo em documentações da Sun e listas em geral. O algoritmo utilizado pelo jCompany é bastante comum sendo inclusive, o mesmo
utilizado internamente pela Hibernate, para manter referência às sessões de persistência.
455
Capítulo E16
Porém, um grande leque de requisitos não exigirá estas sofisticações, e nestes casos o uso do
JTA não trará vantagens consideráveis. Pelo contrário, irá gerar complexidade para uma taxa de
retorno próxima de zero!
Note que benefícios tais como “transação declarativa via anotações/AOP”, providos adicionalmente ao JTA
pela tecnologia EJB3, estão também disponíveis no jCompany com POJOs, bem como IoC e DI. Como
uma eventual evolução de POJO para EJB3 será possível, quando, e se, for necessária – o recomendável
para a ser a utilização da alternativa “mais simples que atenda aos requisitos em jogo”, em geral a
transação local via JDBC.
Vamos analisar os diagramas das Figura E16.31 e Figura E16.32, que explicam a arquitetura de
gerenciamento de transações locais declarativas via AOP, do jCompany.
Figura E16.31. Estrutura das classes envolvidas no AOP para fachadas, utilizando CGLib.
#1. O framework “CGlib” provê AOP (Aspect Oriented Programming), permitindo que instanciemos
classes descendentes (de quaisquer outras) que somente existem em tempo de execução,
conhecidas como “proxies”. O jCompany traz uma classe "PlcAopManager", na camada
“comuns”, que encapsula este processo de instanciação de proxies CGlib via a chamada:
PlcAopManager.createProxy(classe,aopBaseCallback);
onde
- classe: é a classe AppFacadeImpl (ou qualquer outra de fachada, em nosso caso)
- aopBaseCallback: É a classe que implementará métodos de interceptação dos métodos de
‘classe’.
#2. A classe “Proxy”, após ser criada em tempo de execução, funciona como um descendente e
tem sufixo padrão assumido dinamicamente pelo CGLib como “$$EnhancerByCGLib$$”.
456
Programando Java com jCompany
Com isso, o desenvolvedor pode simplesmente criar fachadas, bastando instanciá-las com o serviço
"PlcFacadeLocator". Este serviço cuidará de, neste caso, devolver um “Proxy” CGLib com a arquitetura
acima, pronto para receber anotações de transação, a saber:
“@PlcTransacaoGravacao”: Encerra com um “commit” (default);
“@PlcTransacaoLeitura”: Encerra a transação com um “rollback”;
“@PlcTransacaoNaoAplica”: Não trata transações por anotação (deve então ser
programada, se necessária).
Além disso, qualquer disparo de exceção na camada Modelo implicará em “rollback” de
transações, independente da anotação. Vejamos, na Figura E16.32, a seqüência de gerenciamento
de transações completa:
#1. Ao capturar uma interface de fachada, em tempo de execução, vimos que a implementação
retornada é instanciada via CGLib, sendo na verdade um “Proxy” (descendente dinâmico) da
classe “conhecida” pelo desenvolvedor.
#2. A classe de “Proxy” tem nome igual ao da classe base, sufixada com “$$EnhancedCGlib$$”.
A qualquer tentativa de executar métodos de fachada, em “AppFacadeImpl”, ela irá capturar
a tentativa e passar para a classe de interceptação, “PlcAopModeloCallbackService”.
#3. A classe de interceptação (na verdade, como vimos, seu ancestral), chama o método
“interceptaAntes”, mas não há implementação corrente do jCompany neste ponto.
#4. Em seguida, ela chama o método original, acionando diretamente o “ancestral” do “Proxy”, via
comando: “retValFromSuper = proxy.invokeSuper(obj, args);”.
#5. A seqüência então toma seu rumo original, com chamadas possíveis à camada Modelo e
Persistência.
#6. À primeira tentativa de se pegar uma sessão de persistência, seja via Hibernate (Session) ou
JPA (EntityManager), uma nova transação será iniciada, com o SGBD (BEGIN TRANSACTION).
#8. O comando JPA difere ligeiramente do comando Hibernate, para abertura de transação, mas o
jCompany os torna transparentes do ponto de vista do desenvolvedor.
457
Capítulo E16
#10. Note que, quando programa em pontos de extensão “[metodo]Apos” dos Template Methods da
camada Modelo, o desenvolvedor está codificando “dentro da transação”, significando que
qualquer objeto que venha a ser persistido manualmente, neste ponto, será gravado
na mesma “Unidade Lógica de Transação – ULT” da agregação principal gravada,
genericamente.
*
Envolve a captura de uma conexão JDBC de um conjunto (pool) mantido pelo App Server para uso pela implementação de
persistência e sua devida liberação, após o uso, de forma transparente para o Desenvolvedor.
458
Programando Java com jCompany
...
public interface IAppFacade extends IPlcFacade {
...
public class AppFacadeImpl extends PlcFacadeImpl implements IAppFacade {
@PlcTransacaoLeitura
public Integer calculaTotalCandidatosPorSexo(String sexo) throws PlcException {
Se desejarmos que este serviço seja visível para reúso em outras aplicações, devemos criar um novo
contrato, digamos “IFuncionarioService” (leia-se: serviços associados a funcionários – explicitando a
intenção de reúso corporativo), e disponibilizá-lo em um “módulo”, que no jCompany segue padrões
bem definidos: projeto Eclipse distinto, empacotado em JAR separado, etc.. Os trechos de Código E16.21
e Código E16.22 exemplificam esta opção.
...
public interface IFuncionarioService {
...
public class FuncionarioServiceImpl {
@PlcTransacaoLeitura
public Integer calculaTotalFuncionariosPorSexo(Sexo sexo) throws PlcException {
Neste segundo caso, para instanciação simplificada, é recomendável que se crie a Interface e a Classe de
implementação com padrões de nomenclatura: “I[Nome]” e “[Nome]Impl”, respectivamente. Se
*
O gerenciamento de transações “semi-automatizado”, para casos de programação BATCH será exemplificado em tutorial nos
próximos capítulos.
†
Este contrato de fachada deve ser entendido como um “contrato de fachada para a aplicação corrente”, para operações que não
sejam projetadas para reúso corporativo.
459
Capítulo E16
ambas estiverem no mesmo pacote* e seguindo o padrão de nomenclatura acima, podem-se obter
referências corretamente instanciadas (ou seja, como Proxies com transação gerenciada) a partir das
classes de Action, conforme o trecho de Código E16.23.
...
public class MeuAction {
*
Note que, por “mesmo pacote”, não queremos dizer que estarão no “mesmo projeto” ou nem na “mesma camada MVC”. Ex.: A
Interface “IPlcFacade” do jCompany, está no pacote “com.powerlogic.jcompany.facade”, assim como a implementação “PlcFacadeImpl”.
Mas a Interface fica no projeto Eclipse “comuns” (camada ortogonal, visível por todas as demais do MVC2-P), enquando a Classe fica no
projeto Eclipse “modelo” (em escopo de camada Modelo).
460
Programando Java com jCompany
Ainda com relação à nomenclatura, é recomendável que se utilizem convenções de sufixo diferentes, para
ênfases arquiteturais diferentes:
o BO + VO: O uso de BO como sufixo para classes de serviço da camada Modelo remete aos padrões
de nomenclatura clássicos do J2EE, normalmente utilizados em conjunto com o sufixo VO
(Value Object) para o que seriam nossas Entidades (para as quais temos utilizado Entity). Neste
contexto “J2EE Clássico”, os BOs absorvem todo e qualquer processamento, deixando para as
“Entidades do tipo VO” somente a responsabilidade de transportar dados (similar aos DTOs).
Apesar de ainda ser possível se trabalhar deste modo no jCompany*, recomendamos a abordagem
Domain-Driven Design (DDD), mais interessante e Orientada a Objeto.
o Manager + Entity: Para uma ênfase maior em OO via práticas de Domain-Driven Design (DDD),
nossas próprias Entidades encapsularão métodos que representam regras de negócio de sua alçada.
Os antigos BOs, agora sufixados como “Managers”, irão apenas recepcionar eventos e,
eventualmente, tratar pré-condições e acionar serviços de dados. Em se havendo regras de Domínio,
estas serão delegadas para as Entidades responsáveis.
Importante: Feita a recomendação, é importante frisar que o jCompany não impedirá que se trabalhe
com este ou aquele sufixo. Qualquer outro poderá ser definido em metadados, no escopo de aplicação -
recomenda-se apenas que seja usado um mesmo padrão, para uma mesma organização.
Um exemplo de implementação deste tipo de classe pode ser visto no trecho de Código E16.24.
...
public class FuncionarioManager extends PlcBaseBO {
// 1
FuncionarioDAO funcDAO;
public FuncionarioManager(FuncionarioDAO funcDAO) {
this.funcDAO = funcDAO;
*
Inclusive, em seus ancestrais, o jCompany FS Framework ainda usa estes sufixos, em “PlcBaseVO” e “PlcBaseBO” para Entities e
Managers, respectivamente, por questão de compatibilidade.
461
Capítulo E16
// 2
protected void incluiAntes (PlcBaseVO entidade) throws PlcException {
// 3
Funcionario funcionario = (Funcionario) entidade;
// 4
FichaFuncional ff = funcDAO.recuperaFicha(funcionario.getCpf());
// 5
funcionario.validaMaximoSalario(ff);
}
}
Código E16.24. Classe Manager acessando serviço de dados em DAO e delegando regras para Entidades de
Domínio.
#3. A primeira providência ao especializar Template Methods, é fazer ajuste de tipo (casting) das
Entidades recebidas – se possível, tentando trabalhar com o ancestral abstrato, que encapsula
as informações de negócio (“Funcionario”, e não “FuncionarioEntity”).
#4. Acesso ao serviço de dados. Somente classes de Facade, AS ou BO/Managers podem acessar
DAOs.
#5. Delegação para que a Entidade Funcionário implemente a regra de negócio em si. Ela não foi
representada, por não ser relevante, mas perceba que é de responsabilidade da camada de
Domínio. Os métodos de serviços do tipo “Manager” irão realizar interceptação de eventos,
acionamento de serviços de dados, tratamentos eventuais de pré-condições e outras atividades
de “burocráticas” do serviço, mas delegarão para Entidades de Domínio regras de sua alçada.
462
Programando Java com jCompany
#2. Um ancestral "AppManager" é gerado via template INI por default, como sugestão para
conter extensões para toda a aplicação (e, neste caso, já faz uma “adaptação de nome” para o
sufixo “Manager”). No exemplo, um código foi incluído para executar após a inclusão de
qualquer agregação, mantida dentro desta aplicação.
Note o grande número de dependências desta classe. Ela irá depender de classe de DAO para
serviços de persistência e do modelo de Domínio, para regras de negócio, no mínimo.
#4. Para enfatizar o desacoplamento com a camada DAO, o recomendado é utilizá-la via Interfaces,
mantendo uma fachada (DP Façade) também entre a camada Modelo e a de Persistência.
Deste modo, facilitam-se futuras portabilidades.
#5. Mas é possível utilizar a implementação de DAO diretamente, sem grandes prejuízos na maioria
dos casos. Neste caso, mantém-se o isolamento entre as camadas Modelo e Persistência, mas
sem o rigor de outra “fachada”. Muito embora o jCompany utilize Interfaces, a extensão de
seu uso pelo desenvolvedor é opcional, em função das perspectivas do cliente de manutenções
nesta área. Em ambos os casos, será possível a utilização de DI nas classes Manager.
Importante: Ao escolher uma das duas abordagens, deve-se manter fiel a ela,
preferencialmente em nível da empresa.
#1. A maior parte das implementações de classes Manager serão interceptações de Template
Methods, que mantém o ciclo de vida de agregações, na camada Modelo.
463
Capítulo E16
#2. As implementações principais dos métodos chamam métodos vazios para especialização,
injetando uma instância da agregação a ser mantida, como parâmetro*.
#3. Métodos de extensão serão possivelmente especializados para executar acessos a dados e
tratar pré-condições.
#4. Após recuperar os dados necessários, de forma a prover valores para as “variáveis” a serem
utilizadas em regras de negócio, a classe Manager delega esta incumbência para Entidades de
Domínio. Regras que não sejam claramente encasuláveis, podem ser agrupadas em classes
próprias, transientes, também na camada de Domínio.
#5. A classe de Manager somente aciona regras a partir da classe Raiz da Agregação. Esta, por sua
vez, pode trocar mensagens dentro de seu grafo de alcance, de modo a complementar as
informações necessárias para o resultado esperado.
Existem três regras práticas que devem orientar um bom projeto de classe de AS:
o A classe de Application Service, em si, não deve implementar cálculos do negócio, mas
somente fluxos de delegações, incluindo condições e laços. É o conceito de orquestração,
propriamente dito, em nível do Caso de Uso†.
o Na dúvida sobre implementar em Fachada ou em AS, prefira AS. Haverá uma natural
tentação de ser fazer, na própria implementação de fachada, toda a orquestração de chamadas
necessária, mas haverá algumas desvantagens: para casos complexos, isso impede o reúso de
blocos de processamento de AS, já que estes ficam acoplados a uma transação; não é possível usar
“Constructor Based Dependency Injection” no Façade; algumas tarefas de adaptação da fachada
podem “poluir” as orquestrações de negócio.
o Na dúvida sobre implementar em Manager ou AS, pense nos “imports”: Por ser uma
orquestradora, a classe de AS tenderá, naturalmente, a possuir dependências com um grande
número de classes (em conformidade com o tamanho e extensão de seu algoritmo). Pense: Se estas
importações fossem realizadas no Manager, elas trariam acoplamento com classes que não têm
relação com a agregação gerenciada por esta última classe? Por exemplo, mover importações de
“TabelaIR” para “FuncionarioManager”, sendo a primeira uma classe que não pertence ao grafo de
“Funcionario”, é um sintoma de que métodos apropriados para AS podem estar sendo movidos para
Managers, indevidamente.
Implementações de AS devem herdar de “PlcBaseAS” para obterem recursos de caching, IoC e DI. Um
exemplo de implementação pode ser visto no trecho de Código E16.25.
...
public class CalculoFolhaAS extends PlcBaseAS {
...
// Injeção de Dependência no construtor
....
public Integer calculaFolha(Periodo periodo) throws PlcException {
(...)
*
O método de alteração traz ainda a imagem anterior da agregação também (antes de sofrer modificações), porém somente com a
imagem anterior do seu objeto “raiz” (ex.: Funcionario). Para que “agregados” anteriores sejam também “lembrados”, deve-se
informar o metadado “detalheLembra=true”.
†
Em uma analogia com ferramentas de workflow ou ferramentas de BPM/SOA, esta classe representa de forma programada, o “fluxo
de trabalho” propriamente dito, mas não necessariamente as regras disparadas durante o fluxo.
464
Programando Java com jCompany
}
…
Código E16.25. Classe de Application Service. Nada de regras de negócio – somente chamadas, laços e
condicionais.
#1. Application Services são provavelmente acionados por novos eventos, e não a partir dos
eventos padrões do jCompany.
#2. A implementação de fachada não orquestra a execução. Ela apenas realiza ajustes em
argumentos e delineia a transação*.
#3. O Application Server executa uma varredura por todos os funcionários para os quais deverá ser
executado o cálculo, para o período passado por parâmetro.
#4. Operações de ciclo de vida são utilizadas via “FuncionarioManager”, tais como a recuperação de
um funcionário. Os métodos genéricos são utilizados, desde que complementações ao ciclo de
vida sejam relevantes. Pode-se também utilizar o "FuncionarioDAO" diretamente, exceto se a
empresa quiser estabelecer o rigor de sempre haver “Managers” intermediando (como uma
camada, entre os “Application Servers” e os “Data Access Objects”).
#5. Rotinas de orquestração podem ficam extensas. Deve-se buscar uma segmentação que facilite
a compreensão, preservando a simplicidade do fluxo de execução tanto quanto possível, em
cada método do AS.
#6. Chamada direta de classe DAO, para requerimentos “centrados em dados”, basicamente.
#7. Chamada direta a Entidade. A camada de Domínio é ortogonal, e visível por todas as demais.
*
Neste exemplo, pouco provável no mundo real, estaríamos encerrando um cálculo de folha com apenas um “commit()” ao final! O
mais provável seria termos de gerenciar transações manualmente, chamando os métodos “commit” ou “rollback” da interface DAO,
para gravar ULT menores, em blocos de 100 em 100 funcionários, por exemplo. Faremos um exemplo deste gerenciamento nos
próximos capítulos.
465
Capítulo E16
#8. Para a atualização, o acesso também é feito via Manager, caso os métodos de especialização ao
ciclo de vida sejam relevantes.
466
Programando Java com jCompany
#1. A primeira classe a ser acionada, para devolver uma sessão de persistência, será a
"PlcHibernateManagerLocator", que é um singleton que armazena em caching as
referências aos objetos gerenciadores de sessões de persistência.
O arquivo de configuração define parâmetros globais para uma fábrica, tais como endereço
JNDI para pool de conexões e muitos outros, sendo alguns de maior relevância específica para
o jCompany, discutidos nos itens 5 e 6.
467
Capítulo E16
…
<property name="connection.provider_class">
com.powerlogic.jcompany.persistencia.hibernate.PlcConnectionProvider
</property>
…
Código E16.26. Classe provedora de conexões JDBC do jCompany, configurada no Hibernate.
…
<property name="plc.manyToOneLazyOtimiza">S</property>
<property name="plc.updateOtimiza">S</property>
<property name="plc.autoDetectDialect">S</property>
<property name="plc.auditoriaRigida">S</property>
…
Código E16.27. Parâmetros de configuração especiais do jCompany no “hibernate.cfg.xml”.
Não é necessário nenhuma código Java específico nestas classes, a menos que se queira
modificar alguma programação genérica do jCompany, presente em
“PlcBaseHibernateManager”.
#8. Para cada caso exemplificado acima, deve-se definir um arquivo de configurações a exemplo do
“hibernate.cfg.xml”, com nomes respectivos “pedido.cfg.xml” e “corporativo.cfg.xml”. É
dentro destes que se pode modificar informações específicas, tais como dialeto (SGBD-R),
endereço JNDI do pool de conexões (que o jCompany irá utilizar), etc..
- Auto-Detect Dialect.
O jCompany possui a facilidade de detectar automaticamente o dialeto ideal para o SGBD-R corrente,
sem que o Desenvolvedor precise se preocupar em informá-lo nos arquivos de configuração. Este recurso
é útil para quem deseja fazer produtos portáveis para vários SGBDs e que, desta forma, não
precisam modificar em nada os arquivo WAR ou EAR finais!
A detecção automática investiga e decide qual dialeto utilizar, se baseando na URL declarada para a
conexão pelo driver JDBC, capturada via pool de conexões. Este processamento é delegado da
classe “PlcBaseHibernateManager” para a classe “PlcHibernateHelper”, que executa um código
similar ao Código E16.28.
…
if (url != null && url.toLowerCase().indexOf("derby")>-1) { // CloudScape/Derby
p.put("dialect", DerbyDialect.class.getName());
p.put("hibernate.dialect", DerbyDialect.class.getName());
} else if (driver.toLowerCase().trim().indexOf("ibm db2") > -1) { // DB2
p.put("dialect", DB2Dialect.class.getName());
p.put("hibernate.dialect", DB2Dialect.class.getName());
} else if (driver.toLowerCase().trim().indexOf("oracle") > -1) { // Oracle
p.put("dialect", Oracle9Dialect.class.getName());
p.put("hibernate.dialect", Oracle9Dialect.class.getName());
} else if (driver.toLowerCase().trim().indexOf("sqlserver") > -1){ //SqlServer
p.put("dialect", SQLServerDialect.class.getName());
p.put("hibernate.dialect", SQLServerDialect.class.getName());
} else if (driver.toLowerCase().trim().indexOf("mysql") > -1) { // Mysql
p.put("dialect", MySQLDialect.class.getName());
p.put("hibernate.dialect", MySQLDialect.class.getName());
} else if (driver.toLowerCase().trim().indexOf("postgresql") > -1) { // PostgreSql
p.put("dialect", PostgreSQLDialect.class.getName());
p.put("hibernate.dialect", org.hibernate.dialect.PostgreSQLDialect.class.getName());
} else if (driver.toLowerCase().trim().indexOf("sybase") > -1){ //Sybase
p.put("dialect", SybaseDialect.class.getName());
p.put("hibernate.dialect", SybaseDialect.class.getName());
}
Código E16.28. Algoritmo de definição de dialeto dinamicamente com base na URL do driver JDBC.
468
Programando Java com jCompany
Note que, muito embora interessante, este recurso tem margem de erro e alcance limitado aos SGBDs
acima contemplados. Para situações de exceção, deve-se informar “false” na detecção automática (na
anotação ou no arquivo de configuração), informando-se o dialeto diretamente no arquivo
“hibernate.cfg.xml”.
#1. Contrato principal com a camada de persistência. Uma Interface é exigida por muitas
implementações de JPA, que não aceitam o uso de uma classe abstrata como “PlcBaseDAO”
diretamente. Portanto, a Interface “IPlcDAO” foi introduzida ao DP Abstract Factory
implementado por “PlcBaseDAO”.
#5. Classes DAO específicas podem herdar de alguma das implementações concretas de Hibernate
ou JPA, mas não obrigatoriamente. A herança facilita o acesso a sessões de persistência via
“getSession(“minhaFabrica”)” ou “getEntityManager(“minhaUnidadePersistencia”)”,
mas elas podem ser pegas alternativamente via classes de utilitários.
Em Hibernate, por exemplo, pode-se pegar a sessão corrente, de qualquer POJO, via:
469
Capítulo E16
EntityManager em = PlcJpaManagerLocator.getInstance().
getJpaManagerClasse(“[nomeUnidadePersistencia]”).
getEntityManager();
#6. O contrato entre a camada de negócio e os serviços de persistência pode ser definido de forma
trivial, através de uma Interface.
#7. Para capturar uma implementação de persistência via Interfaces e DI, deve-se declarar a
Interface na classe Manager de alguma das formas abaixo:
// 3
public class QueFactory extends QueAbstractFactory {
private QueFactory() { }
public static QueFactory getInstance(){
return INSTANCE;
}
@Override
public IQuestionario createQuestionario() throws PlcException {
return (IQuestionario) PlcModeloLocator.getInstance().get(QuestionarioMestreManager.class);
}
}
Código E16.29. Injeção de Dependência com uso de Interfaces - estratégia de Factory.
Note que na segunda variação, a classe de implementação é anotada diretamente. Ela dificulta a
modificação de implementações externamente, mas preserva o baixo acoplamento (já que a
anotação é apenas metadado).
...
public class FuncionarioDAO extends PlcBaseHibernateDAO {
try {
// 1
Session sess = getSession();
// 2
return (Integer) sess.createQuery("select count(*) from FuncionarioEntity f " +
470
Programando Java com jCompany
"where f.sexo=:sexo”).setParameter(“sexo”,sexo).uniqueResult();
} catch (Exception e) {
// 3
throw new PlcException("jcompany.erro.generico", new Object[] {
"recuperaTotalPorSexo", e }, e,log);
}
}
…
Código E16.31. Exemplo de implementação de método de DAO com Hibernate.
#1. Captura a sessão corrente de persistência. Todas as sessões devolvida por este método,
durante uma requisição na camada Modelo, retornam a mesma referência (mesma sessão de
persistência).
#2. A execução da cláusula em si deve obedecer à sintaxe HQL para Hibernate ou JPA-QL
para JPA. Pode-se ainda indicar para que mesmo o Hibernate somente aceite sintaxe JPA, em
seu arquivo de configuração “hibernate.cfg.xml”.
Para este caso, basta utilizar o template padrão de tratamento do jCompany, digitando-se
“try” + Control+Space. Uma cláusula de “try – catch” similar à do Código E16.31 será gerada.
Este código padrão realizará um tratamento genérico para exceções externas considerado
“pauta mínima”, incluindo:
...
public class FuncionarioDAO extends PlcBaseJpaDAO {
try {
EntityManager em = getEntityManager();
} catch (Exception e) {
throw new PlcException("jcompany.erro.generico", new Object[] {
"recuperaTotalPorSexo", e }, e,log);
}
}
…
Código E16.32. Exemplo de implementação de método de DAO com JPA.
Neste caso específico, somente a Interface de persistência mudou. Devido à influência que teve Gavin
King, o criador do Hibernate, como líder da especificação que resultou no padrão JPA, o percentual de
similaridade entre as duas implementações chega a 90%.
Do ponto de vista de comunicação entre as camadas, já vimos a Injeção de Dependência em Manager/BO
e AS, via declaração de DAOs ou outros Managers, no construtor das classes:
…
public class CandidatoManager extends PlcBaseBO {
CandidatoDAO candidatoDAO;
AreaProfissionalDAO areaProfissionalDAO;
Importante: Classes DAO não possuem “Template Methods” do jCompany. Não se espera
programações de negócio ou quaisquer outras que requeiram generalizações mesmo parciais, nesta
471
Capítulo E16
categoria de classes. Basicamente, elas devem oferecer métodos reutilizáveis de acessos a dados, sem
inclusive envolver muitas trocas de mensagens entre si (orquestrações na camada de Persistência) - pelo
menos, no que tange a persistências para SGBDs relacionais.
472
Programando Java com jCompany
Sumário
Neste capítulo, discutimos em maior profundidade diversos aspectos da arquitetura Orientada a Objetos
do jCompany, nas várias camadas do MVC2-P, provendo alta flexibilidade e separação de conceitos que
visam preservar a simplicidade em implementações específicas, da aplicação.
Muitas das complexidades arquiteturais que discutimos têm um propósito bem claro: eliminar código
desnecessário em aplicações de negócio, em todas as camadas, generalizando cenários de Casos de Uso
por completo.
Desenvolvedores acostumados com a programação J2EE deverão ter compreendido o suficiente para
inclusive efetuarem ajustes arquiteturais no jCompany, se necessário for (com uma ajuda complementar
das ferramentas de logging e do depurador do Eclipse, apresentados).
Caso você não tenha compreendido por completo todos os Design Patterns e técnicas OO aqui discutidas,
não se preocupe: a maior parte do conhecimento que foi descrito pode ser abstraído, mesmo em estágios
intermediários de uso do jCompany FS Framework. Ao surgirem demandas que exijam maiores
customizações, retorne a este capítulo.
473
Capítulo
17
Regras de Negócio &
7
1
E
Batch
O nosso próximo Caso de Uso não irá se encaixar em nenhum padrão do jCompany Patterns &
Methods, e esta é uma situação de se esperar.
Toda aplicação possuirá algum percentual de demandas deste tipo - não generalizáveis por
frameworks “horizontais”, ou porque são Casos de Uso que não possuem cenários
previsíveis, repetitivos, passíveis de padronização; ou porque são, fundamentalmente,
agrupamentos de regras de negócio (como é o nosso caso).
Ainda assim, reutilizaremos diversos serviços úteis do jCompany FS Framework. Afinal, como vimos no
capítulo 1, o jCompany Developer Suite é muito mais que os geradores do jCompany IDE, utilizados
para Casos de Uso Padrões.
Figura E17.1. Diagrama de Caso de Uso para “UC005 Calcular Folha de Pagamento!”.
Como não é um Caso de Uso Padrão, esta especificação requer maiores explicações. Note que este é um
Caso de Uso disparado por algum mecanismo de “temporização”, ou de “escalonamento”, simbolizado
pelo Ator com a palavra reservada “Tempo”. Nestes casos, a interatividade em si do Ator com o Caso de
Uso é trivial, sendo o cenário basicamente definido por um passo de “disparo” e um segundo de reação
da aplicação. A descrição de cenário para este Caso de Uso “UC005” está, portanto, definida da seguinte
forma no repositório da ferramenta CASE:
O escalonador automático dispara o Cálculo da Folha, todo dia 3 de cada mês, a partir de 01h00min da
madrugada.
2. A aplicação recupera todos os funcionários e executa cálculo para cada um, segundo regras definidas
em “REQ001 - Cálculo de Folha”.
474
Regras de Negócio & Batch
Veja que o cálculo da folha de pagamento em si é definido em um requisito à parte. O cálculo que iremos
exemplificar é bem simplificado e altamente fictício, mas suficiente para nossos propósitos. Ele é
reproduzido abaixo:
“Para cada funcionário com horas trabalhadas informadas para o período de referência,
imediatamente anterior ao corrente (último mês), o cálculo deve ser feito da seguinte forma:
2. Calcular o ‘salário inicial’ tendo como base 22 dias úteis, e realizando cálculo proporcional (regra
de três) com o número de dias efetivamente trabalhados, informados em provento do tipo DT.
3.1. Se o número de dias trabalhados informado for mais que 22, gerar erro 'Numero de dias
ultrapassa o possível para o período'
3.2. Se o salário bruto for negativo, gerar erro 'Cálculo de salário negativo para funcionário
[nome - cpf]'
3.3 Se o cálculo estiver correto gravar ocorrência em ProventoDesconto com natureza SL,
com o valor calculado.
4. Calcular o IR com base no ‘salário bruto’, descontando 15% após deduzir 200,00 para cada
dependente. Ex: Para um funcionário com salário de 1.400,00 com dois dependentes, o IR deverá
ser 15% de 1.000,00, ou seja, 150,00.
5. Calcular ‘salário liquido’ final, subtraindo o IR do ‘salário bruto’, e gravando-o em Provento com
tipo SL.
6. Se alguma exceção ocorrer durante um cálculo especifico, ele deve ser interrompido e o erro
enviado por e-mail para “folha@acme.com.br”, além de gravado em log de erro. O processamento
deve continuar para os demais.
Foi definida uma Colaboração com o estereótipo “plcBatch”, que não nos traz muita informação,
diferentemente das Colaborações Padrões anteriores. A marcação indica apenas que deveremos utilizar
um disparo escalonado para esta rotina, e implementar sua orquestração a partir de uma classe de
Application Service chamada “CalculoFolhaAS”.
O grafo de entidades envolvido costuma ser grande em programações batch. Em nosso exemplo, ele está
representado pela Figura E17.2.
Figura E17.2. Grafo de Entidades, envolvido no Caso de Uso “UC005 Calcular Folha de Pagamento!”.
475
Capítulo E17
Um nova classe “FolhaPagamento” foi definida, para abrigar o valor do último período de fechamento.
Esta classe foi estereotipada como “plcPrefAplicacao”, pois contém somente um objeto e é um padrão
definido pelo jCompany Patterns & Methods*. O jCompany IDE, inclusive, pode gerar um Caso de
Uso Padrão para sua manutenção interativa, se preciso for – não é o nosso caso, já que iremos gravar o
“anoMesUltimoFechamento” programaticamente.
Note que modelamos a referência à classe “FolhaPagamento” em “ProventoDesconto” como uma
“variável de classe” dinâmica. Esta é uma conceituação opcional mas, fazendo deste modo, conseguimos
rastrear a classe “ProventoDesconto” com “FolhaPagamento”†.
Finalmente, uma parte do grafo de Funcionário foi incluída, pois o número de seus dependentes e seu
último salário serão ambos utilizados no cálculo. É uma boa prática de modelagem, explicitar claramente
o grafo de Entidades envolvidas no Caso de Uso.
O formulário a ser utilizado é, também, fora do padrão, apresentando botão de disparo ao lado do campo
de período e as mensagens abaixo do botão de disparo. As mensagens estão em cores distintas,
utilizando verde para o número de calculados com sucesso e vermelho para o número com problemas e
mensagens de erro. As mensagens de erro, além de exibidas para o usuário, também devem ser
enviadas por e-mail e log.
A Colaboração que irá implementar a extensão possui estereótipo “plControle”, conhecido também como
“Controle Simples”, que é na verdade um padrão “livre” do jCompany, se é que se pode dizer assim. É
uma Colaboração utilizada quando se deseja realizar implementações livremente, a partir da camada
Controle, mas ainda utilizando leiautes Tiles e possivelmente anotações de metadados para acionar reúso
de recursos do framework.
Veremos a implementação desta extensão, no próximo capítulo.
*
Somente veremos este tipo de padrão no segundo livro desta série “Volume II – Tópicos Avançados”.
†
Nota sobre a modelagem: Variáveis de Classe dinâmicas não devem ser escritas em maiúsculas e, uma vez que passamos a utilizá-la,
é bom diferenciar as demais que usamos até agora, como “Constantes” (veja o destaque “{readOnly}” que agora aparece para
MAX_DIAS_TRABALHADOS).
476
Regras de Negócio & Batch
477
Capítulo E17
Figura E17.6. Ajustes em FolhaPagamentoEntity – auxiliar para pegar data formatada e consulta padrão nomeada.
Note que o jCompany IDE gera um método auxiliar “getAnoMesUltimoFechamentoStr” para exibição
formatada de datas. Uma NamedQuery buscando o Object-Id e propriedades de lookup também é
sempre gerada, com sufixo padrão “querySelLookup”. Tanto a consulta nomeada quanto o método
auxiliar serão úteis, em tempo de programação, para recuperarmos esta entidade e formatarmos
mensagens de erro com a data.
#4. Digite “PlcBaseAS” e clique em “Browse”. O ancestral apropriado para AS deverá ser o único da
lista. Esta herança irá permitir o uso de Injeção de Dependência e categorizar de forma mais
rigorosa este tipo de classe, para a arquitetura.
478
Regras de Negócio & Batch
#1. Caso não se esteja utilizando um ambiente que proveja “rastreabilidade” entre requisitos e
código (como uma suíte de ALM), a inclusão do identificador no Javadoc é recomendada. Na
camada Modelo, em regras do negócio, o Javadoc é especialmente importante.
#2. Definimos objetos de exceção especiais para encapsular exceções internas, geradas em nosso
Caso de Uso. Vamos discuti-los no próximo tópico. Continuamos utilizando a exceção genérica
“PlcException”, para exceções externas (SGBD fora do ar, erros de programação, etc.), de
modo a continuar utilizando o tratamento genérico “pauta mínima”.
#3. Perceba que definimos o método como “protected”! Como somente iremos acioná-lo via
escalonador, esta é uma restrição útil. Veremos a técnica de disparo mais a frente. Poderíamos
também não receber argumentos, inferindo o mês de referência dentro de nosso método, que
seria o mês anterior ao que estamos. Porém, deste modo o tornamos menos reutilizável.
#4. Vamos adiar a recuperação da lista de funcionários por enquanto, para nos concentrarmos no
algoritmo de orquestração em si. Mas uma coisa é certa: iremos precisar de um serviço de
persistência que traga uma coleção de subgrafos de “Funcionario”, contendo somente aqueles
que possuem “DT” (Dias Trabalhados) informados para o período.
Note que não iremos trabalhar com “Result Set” JDBC ou qualquer outro “conjunto relacional”
como retorno, mas com cortes de nosso modelo de Entidades de Domínio, o que é expresso
pela declaração do tipo de retorno como “List<Funcionario>”. Isso tornará nossas regras
mais legíveis e manuteníveis, e é um dos grandes benefícios do JPA/Hibernate.
#6. Manteremos uma lista de exceções geradas em cálculos individuais de funcionários, para
encapsular as causas de erro, associadas a alguns dados do funcionário.
#7. Os elementos de programação tipicamente encontrados nos Application Services serão laços e
condicionais.
#8. É uma boa prática subdividir métodos de orquestração, para mantê-los compreensíveis e
reutilizáveis. Na seqüência, continuaremos a desenvolver nosso raciocínio procedimental, para
cada um dos métodos faltantes. Neste caso, temos um método em separado para o cálculo de
cada funcionário.
479
Capítulo E17
#9. O método que calcula salário para cada funcionário, caso encontre algum dos erros apontados
na especificação, irá disparar a exceção “CalculoFolhaFuncionarioException”, que neste
tratamento será acumulada, conforme solicitado.
#10. Em nosso caso, como recomendado para lógicas de atualização em lote, não devemos
encerrar todas as gravações em uma única ULT (Unidade Lógica de Transação ou
“commit”). Correríamos o risco, neste caso, de comprometer recursos do SGBD
excessivamente, já que transações muito longas (conhecidas como “long running transactions”)
aumentam perigosamente o tamanho e esforço do SGBD para manutenção de áreas de
“log/redo”, dentre outros problemas. Além disso, um erro ao final do processo nos faria perder
todos os cálculos corretos que fizemos até ali.
#11. Se, ao final do processamento, houver algum erro de cálculo individual, nosso método irá
encerrar disparando uma exceção principal, que irá encapsular as várias exceções individuais e
também o total calculado “ok”. Estas são informações que projetamos para que o método
“chamador” (que chamou o atual) possa tratar o erro e apresentá-lo conforme requisitado.
#12. Precisaremos, também, de uma função que verifique se o total de cálculos efetuados até aqui é
igual ao universo de cálculo potencial. Isso porque, segundo a especificação, neste caso
devemos atualizar a data do último fechamento.
#13. Se a função não disparar uma exceção, ela deve devolver o total de funcionários cujo salário foi
calculado, para exibição da mensagem de confirmação, no padrão solicitado.
480
Regras de Negócio & Batch
#2. Esta classe deve herdar de “AppException”, ancestral genérico para a aplicação (esta, por sua
vez, herda de “PlcException”).
#4. Note que não foram criados “setters” para as novas propriedades. Deste modo, elas somente
podem ser incluídas através de um novo construtor, que também recebe a mensagem do
problema em si. A propriedade para armazenar a mensagem de erro é reutilizada do objeto de
exceção ancestral, de modo que se facilite o reúso de tratamentos genéricos de traduções, por
exemplo.
#1. A segunda classe de Exceção deve ser criada com nome “CalculoFolhaException”, no mesmo
diretório da anterior, e também herdando de “AppException”.
#2. Ela irá encapsular uma coleção de exceções individuais e também o total de calculados ok.
#3. Da mesma forma (é um padrão para classes Exception), as novas variáveis somente são
recebidas em construtores, imutáveis.
O esquema final desta parte de exceções, incluindo elo com a arquitetura de base, pode ser
compreendido na Figura E17.11.
Figura E17.11. Modelos de classes de exceção no padrão sugerido pela arquitetura do jCompany.
481
Capítulo E17
#1. Ancestral para exceções que funciona como invólucro (wrapper) para quaisquer exceções
internas ou externas, encapsulando propriedades para mensagens I18N, argumentos de
mensagens, objetos “raiz” (exceção original), e outros dados. Ele é também tratado
genericamente, como veremos, enviando erros para arquivos de log/console, e-mail e para
apresentação ao usuário.
#2. Classes específicas para casos especiais de tratamento, que não enviem somente mensagens e
argumentos triviais, ou para envio em lote, como o nosso caso.
#3. Os comentários Javadoc são fundamentais para promover o reúso de serviços de persistência.
No caso, inclusive antecipamos a estrutura pela qual pretendemos retornar os valores
(List<Object[]>), que é um dos padrões do JPA/Hibernate.
#4. Métodos de DAO tendem a não precisar de objetos de Exceção especiais. O tratamento padrão
para exceções inesperadas é suficiente, e deve sempre ser exigido no contrato.
*
Repare que, apesar de a camada de Persistência ficar no mesmo projeto Eclipse da camada Modelo, ela está segmentada por um
pacote distinto. Caso exista uma equipe dedicada a somente desenvolver DAOs, pode-se desejar promover estes pacotes de
persistência para um projeto distinto no Eclipse. Para tornar esta prática um padrão corporativo, deve-se implementar este novo
projeto editando os templates INI.
†
Dica: Após criar a Classe e indicar a implementação da Interface, experimente usar o “hot-fix” do Eclipse para criar a declaração dos
métodos “não implementados”, clicando no ícone de erro à esquerda da classe.
482
Regras de Negócio & Batch
Figura E17.13. Classe de implementação FuncionarioDAO. Uso de “hot-fix” (clique no erro), para criação de
método.
3. A primeira coisa que métodos de DAO tipicamente conterão, será uma cláusula “try-catch”, para
garantir tratamento contra problemas externos inesperados. No caso específico destas classes,
presentes em uma camada considerada de “integração”, existem diversos externos possíveis, como
problemas de JDBC, Pool de Conexões, SGBD-R, Rede, etc..
4. Para que este tratamento ocorra corretamente, defina também uma ”classe de log” do Log4j, da
forma indicada na Figura E17.15, já que o tratamento genérico recebe uma referência à classe de
log para gravação de erros em arquivos ou outros appenders Log4j†.
*
Em determinadas versões de demonstração, você pode ter que criar este snippet manualmente, uma primeira vez.
†
Classes de log não “pesam” em processamento. Elas devem ser static e final e serem nomeadas de forma casada com as classes
Java, utilizando “getLogger(MinhaClasse.classe)”, de forma que se possa ligar/desligar logs de forma refinada, para cada classe, em
tempo de depuração.
483
Capítulo E17
Figura E17.15. Tratamento de try-catch padrão gerado via “snippet” e classe de log declarada.
5. Vamos agora obter uma sessão de persistência. Já estudamos a arquitetura interna utilizada pelo
jCompany FS Framework para prover estas conexões de forma segura e performática, no capítulo
anterior.
Como optamos por não utilizar herança aqui (mais a frente, vamos ver o que ganhamos com esta
alternativa), poderemos obter uma sessão de persistência através do utilitário
“PlcHibernateManagerLocator”. Esta classe, por sua vez, é um Singleton (acesso via
getInstance()) que recebe o nome de uma fábrica de persistência e devolve uma referência à
sessão. Se estivermos utilizando somente uma, devemos usar “default” como nome da fábrica.
import org.hibernate.Session;
…
Session sess = PlcHibernateManagerLocator.getInstance().getHibernateManagerClasse("default").getSession();
…
Código E17.1. Obtenção de sessão de persistência.
6. Finalmente, vamos agora para a parte central de nosso primeiro método de persistência, a
confecção da cláusula em HQL (Hibernate Query Language) em si, que na verdade é, tal como o
JPA-QL (Java Persistence Arquitecture Query Language), um dialeto de OQL (Object Query
Language). Estes dialetos são similares ao SQL, mas executam sobre o grafo de classes,
oferecendo portabilidade diferenciada e mais aderência ao mundo OO.
484
Regras de Negócio & Batch
#1. Um primeiro objetivo foi trazer, em uma única cláusula, todas as informações do “grafo de
consulta” que precisamos, incluindo o Object-Id (identificador interno do Funcionário), o
“nome” e “cpf”, além do valor de “Dias Trabalhados” em “ProventoDesconto”, o total de
dependentes e seu salário atual (imaginando, de forma simplificada, que podemos inferir o
salário atual como o “maior”).
Note que funções de agregação, expressões, subqueries e outras técnicas consagradas pelo
SQL estão presentes em OQL.
#2. Nossa classe “pivô” escolhida foi “ProventoDesconto”, pois dela consegue-se partir para todas
as demais! Este é um ponto importante em OQL: Se partíssemos de “Funcionario” não
chegaríamos em “ProventoDesconto” via navegação OO, já que não temos um “OneToMany”
de “Funcionario” para “ProventoDesconto”*.
Veja o grafo percorrido no diagrama da Código E17.15, possibilitado pelas setas de navegação.
O símbolo de composição sempre indica uma navegação possível, no caso de
”ProventoDesconto -> Funcionario”. Mas não temos seta de “Funcionario ->
ProventoDescontoӠ.
Figura E17.16. Grafo percorrido no modelo de classes, por nossa cláusula OQL.
*
Também seria possível, a despeito do mapeamento, realizar “joins” relacionais entre estas classes mas, deste modo, a solução fica
mais extensa e menos elegante.
†
Note que um modelo de classes que também traga as “roles” das associações (propriedades de navegação) explicitadas, podem
facilitar bastante na confecção das OQLs.
485
Capítulo E17
#4. Já a navegação de funcionário para seus dependentes é explicitamente codificada como “left
join”†. Em nosso caso, sabemos que existem funcionários que não possuem dependentes (veja
cardinalidade mínima 0!). Portanto, esta é a estratégia correta - deste modo, funcionários que
não tenham dependentes também serão recuperados.
#5. A navegação de funcionário com seu histórico, por sua vez, é obrigatória novamente, já que a
multiplicidade mínima é também 1 (um).
Importante: Perceba que todas as associações de “join” são definidas utilizando o alias “pd”,
ou seja, partindo da classe “pivô” e navegando com notação de pontos, pelo grafo de objetos.
#7. Como estamos utilizando funções de agregação “count” e “max”, juntamente com valores não
agregados, precisamos colocar as demais propriedades ausentes nas agregações, na cláusula
“group by”, tal como faríamos em SQL.
#9. Um último comando “list”, ao final de todo o comando, retorna uma coleção do tipo
“List<Object[]>”, com cada posição do array interno de objetos trazendo o valor de retorno
de uma propriedade, na ordem em que aparecem na cláusula “select”.
*
Se informado somente “join”, o “inner join” é assumido como default.
†
Se informado “left” ou “right”, um “outer join” é utilizado, mudando apenas a direção do “outer”.
‡
Aliás, como dica geral, deve-se evitar o uso de recuperações de OQL/SQL dentro de laços, sempre que possível. Em casos de
programações batch, como é o nosso caso, vamos ainda utilizar mais uma cláusula, durante o cálculo, mas isto é razoável,
considerando-se que pode não haver memória disponível para se manter tudo em caching, no início dos cálculos.
486
Regras de Negócio & Batch
// 1
List<Object[]> listaComDTInformadoNoPeriodo = funcDAO.recuperaComDTInformado(anoMesReferencia);
#1. Cláusulas OQL que usam “select <propriedades>”, retornam coleções de vetores de objetos,
“List<Object[]>”.
#2. O laço que irá percorrer a coleção deve, portanto, fazer o casting apropriado, de cada atributo
para cada tipo correto (veja que neste pequeno exemplo de OQL, já temos uma mistura de três
tipos distintos).
Este padrão não somente é pouco produtivo para quem reutiliza o serviço de dados, mas também sujeito
a diversos erros e extremamente inflexível. Uma eventual introdução de novas propriedades na cláusula
“select” pode introduzir erros graves no método “cliente”, não detectáveis em tempo de compilação e, o
que é pior, muitas vezes nem em tempo de execução!
Faça uma reflexão: Qual o nível de caos aconteceria se, em uma manutenção futura do método de
DAO, introduzíssemos o retorno de um valor adicional com o total de descontos, antes do salário,
como “select f.id, f.cpf, f.nome, pd.valor, count(d.id), sum(hp.valor), max(hp.salario) ...”?
O cenário do Código E17.4 chega a ser ainda pior - e acontecerá na prática se o serviço de dados
incentivar, especialmente se forem dezenas de atributos de retorno a serem manipulados. É o que
chamamos de manipulação do tipo “result set”. É lamentável ver um Desenvolvedor Java EE (em tese,
OO também) programando regras de negócio com dados estruturados como “tabelas relacionais”, como
no exemplo.
...
List<Object[]> listaComDTInformadoNoPeriodo = funcDAO.recuperaComDTInformado(anoMesReferencia);
Faça uma segunda reflexão: Qual o esforço você tem que fazer, para entender que a fórmula
acima em destaque está “subtraindo R$ 200,00 de seu salário base, para cada dependente”?
Introduzimos este anti-padrão “OQL retornando Result Set” em nosso tutorial apenas para
enfatizarmos a importância da utilização de coleções de Grafos de Entidades de Domínio como retorno de
OQLs, sempre que possível. Vamos refatorar nosso método, então, para retornar valores deste tipo, com
maior semântica para o negócio.
2. Altere a cláusula “select”, introduzindo um “new FuncionarioEntity(<propriedadades>)”, que passa
todos os valores retornados em seu construtor.
2. Neste padrão, assumimos o trabalho que cada método cliente teria para fazer “casting” de Object[]
para variáveis com nomes significativos (se fizesse). Assim, como projetistas de serviços para reuso,
cuidaremos de acomodar os dados em um modelo de Domínio com maior semântica, livrando os
nossos “clientes Desenvolvedores” deste trabalho e, principalmente, da tentação de escreverem
código “relacional” em Java. Note, portanto, que não haverá “aumento de trabalho”, apenas
“fatoração de trabalho” que haveria de ser feito de qualquer modo, em cada método
cliente.
487
Capítulo E17
...
public class Funcionario extends AppBaseEntity {
// 1. Auxiliares transientes
protected transient BigDecimal diasTrabalhados;
protected transient Long totalDependentes;
protected transient BigDecimal salarioAtual;
// 3. Construtor apropriado
public FuncionarioEntity(Long id, String cpf, String nome,
BigDecimal proventoDescontoDiasTrabalhados,Long dependenteTotalDependentes,
BigDecimal historicoProfissionalSalarioAtual) {
setId(id);
setCpf(cpf);
setNome(nome);
this.diasTrabalhados=proventoDescontoDiasTrabalhados;
this.totalDependentes=dependenteTotalDependentes;
this.salarioAtual=historicoProfissionalSalarioAtual;
#1. Propriedades “transientes” são criadas na classe abstrata “Funcionario”, para acomodarem
resultados temporários obtidos de seu grafo, e serem utilizadas em cálculos do negócio. O
padrão é nomear as propriedade transientes de forma a manter a classe de origem de sua
informação bem clara, utilizando “[propriedadeAgregacao][Propriedade]”.
#2. Além da visibilidade “protected”, provemos somente métodos “getters” para estas
propriedades para garantir o uso seguro, apenas via construtor, das propriedades transientes.
#3. Na classe concreta, criamos o construtor que acomoda o “result set” em propriedades de
objetos. Mantendo o construtor na classe concreta, visamos “despoluir” ao máximo da classe
abstrata, para que contenha métodos de negócio somente (além dos inevitáveis “getters” e
“setters”, é claro).
#4. Note que, se um “select” retornasse um objeto ou uma coleção de objetos “OneToMany” (Ex.:
“select new FuncionarioEntity(f.id, f.cpf, f.nome, f.historicoProfissional)...”), o correto seria
recompor a agregação, e não utilizar propriedades novas. O mesmo vale para objetos
“ManyToOne”.
3. Agora assim, podemos indicar que nosso método retorna “List<Funcionario>”, alterando sua
assinatura para “public List<Funcionario> recuperaComDTInformado(Date
anoMesReferencia) throws PlcException“. Nosso método “cliente”, agora, pode trabalhar de
uma forma bem mais elegante, compreensível e estável ao longo do tempo. Compare o Código
E17.3 e o Código E17.4 com o Código E17.7.
...
List<FuncionarioEntity> listaComDTInformadoNoPeriodo = fDAO.recuperaComDTInformado(anoMesReferencia);
BigDecimal salarioLiquido =
funcionario.getSalarioAtual().subtract(
funcionario.getTotalDependentes().multiply(new BigDecimal(200));
...
488
Regras de Negócio & Batch
2. Em seguida, corte a cláusula do método de DAO para a parte “query” da nova cláusula
@NamedQuery, finalizando como no Código E17.8. Não se esqueça de incluir a vírgula separadora,
entre as cláusulas.
...
@NamedQueries({
...
@NamedQuery(name="FuncionarioEntity.querySelLookup",
query="select new FuncionarioEntity (obj.id, obj.nome) from FuncionarioEntity obj where obj.id = ? order by obj.id
asc"),
@NamedQuery(name="FuncionarioEntity.naoDeveExistirCPFDuplicado",
query="select count(*) from FuncionarioEntity obj where obj.cpf = :cpf"),
@NamedQuery(name="FuncionarioEntity.recuperaComDTInformado",
query="select new FuncionarioEntity(f.id,f.cpf,f.nome,pd.valor,count(d.id),max(hp.salario))" +
" from ProventoDescontoEntity pd" +
" join pd.funcionario f" +
" left join pd.funcionario.dependente d" +
" join pd.funcionario.historicoProfissional hp" +
" where pd.naturezaProventoDesconto='DT' and pd.anoMesReferencia=:anoMesReferencia" +
" group by f.id,f.cpf,f.nome,pd.valor")
})
@PlcExclusaoLogica
public class FuncionarioEntity extends Funcionario {
...
Código E17.8. NamedQuery “FuncionarioEntity.recuperaComDTInformado”.
3. Por fim, altere o método de DAO para recuperar a cláusula nomeada, trocando a chamada
“createQuery” para “getNamedQuery” e informando o nome da NamedQuery criada, em lugar da
cláusula OQL em si.
...
return sess.getNamedQuery("FuncionarioEntity.recuperaComDTInformado")
.setParameter("anoMesReferencia", anoMesReferencia)
.list();
...
Código E17.9. Comando de classe DAO, agora utilizando OQL externo em NamedQuery.
*
NamedQueries anotadas em Entidades, ao contrário do que uma análise superficial pode sugerir, não “acoplam” Entidades do negócio
a mecanismos de persistência! Na verdade, são como as próprias anotações de mapeamento nas propriedades: informações de
“metadados” (configuração). Nesta categoria, elas nem sequer precisam ser utilizadas pelas classes que as contêm - como, de fato, não
o serão.
Como exemplo de que estes metadados não trazem seqüelas para estas classes, basta removê-los e perceber que nenhum
comportamento interno destas Entidades é afetado. Por outro lado, assim utilizados, aprimoram a organização.
489
Capítulo E17
Além disso, esta cláusula espera um argumento de Object-Id na parte “where”, por recupera um
objeto por vez - ao contrário da “querySel”, utilizada em lógicas de QBE (Query By Example), onde a
“where” é montada dinamicamente e pode permitir retorno de vários objetos.
...
EntityManager entityManager =
PlcJpaManagerLocator.getInstance().getJpaManagerClasse("default").getEntityManager();
return entityManager.createNamedQuery("FuncionarioEntity.recuperaComDTInformado")
.setParameter("anoMesReferencia", anoMesReferencia)
. getResultList ();
...
Código E17.10. Método de DAO utilizando EntityManager JPA ao invés de Session Hibernate.
Note que há apenas uma mera adequação de nomes, com partes diferentes em negrito – não há
diferença estrutural. Mesmo assim, estes são códigos incompatíveis.
Se estivéssemos recuperando de “Sistemas de Arquivos” ou de “LDAP” ou de “Web-Services”, certamente
necessitaríamos aqui de outra estrutura algorítmica bem distinta. Mas tanto o JPA quanto o Hibernate são
especialistas no mundo dos SGBD-Rs, compartilhando de mesma origem – portanto, muito similares.
O ideal, neste caso, seria que eliminássemos as diferenças estruturais de nosso código, inclusive para
deixá-lo mais “lógico”, já que queremos a mesma coisa em ambas as versões: recuperar uma lista de
objetos “Funcionario” a partir de um mês de referência.
Uma outra alternativa seria utilizar geradores de código Java para, por exemplo, a partir de ferramentas
CASE (MDA), gerar classes com sintaxes distintas para cada tecnologia desejada (JPA, Hibernate, LDAP,
FS, WS, etc.) - mas geração “de código que pode ser generalizado”, como foi visto no módulo A, é uma
solução datada da década de 80!
Podemos utilizar Orientação a Objetos, sempre que possível, para aprimorar questões de
flexibilidade e portabilidade - com muito menos esforço e mais pragmatismo. Basta criarmos
“abstrações” de mais alto nível, em nossa arquitetura.
490
Regras de Negócio & Batch
Para isso, prosseguiremos no esforço de “refatoração” e aprimoramento de nossa classe DAO, agora
utilizando uma abordagem alternativa de implementação, via herança de “PlcBaseHibernateDAO”*.
Este é um primeiro passo, que iremos refinar em seguida, até o ponto onde as técnicas de OO nos
permitirem ir – ou até onde julgarmos compensador.
1. Acrescente a cláusula “extends PlcBaseHibernateDAO” e retire a declaração da classe “logger” de
nossa classe “FuncionarioDAO”, já que agora a primeira será herdada.
2. Retire a linha auxiliar para obtenção da sessão, e troque a referência “sess” pelo acesso direto ao
método “getSession()” (Note que poderíamos utilizar ‘getSession(“default”)’ mas, ao omitirmos a
fábrica, o jCompany já assumirá a padrão). O resultado pode ser conferido no Código E17.11.
...
public class FuncionarioDAO extends PlcBaseHibernateDAO implements IFuncionarioDAO {
try {
return getSession().getNamedQuery("FuncionarioEntity.recuperaComDTInformado")
.setParameter("anoMesReferencia", anoMesReferencia)
.list();
} catch (Exception e) {
throw new PlcException(“jcompany.erro.generico”, new Object[]{“recuperaComDTInformado”,e},e,log);
}
}
...
Código E17.11. Classe de DAO, agora utilizando herança.
...
public class FuncionarioDAO extends PlcBaseHibernateDAO implements IFuncionarioDAO {
return (List<Funcionario>)
recuperaListaComNamedQuery("FuncionarioEntity.recuperaComDTInformado",
*
A simplicidade da herança como técnica OO tem a levado muitas vezes a ser malquista por interessados somente em ultra-
flexibilidade (mesmo quando esta não compensa). Mas é exatamente esta simplicidade que torna o uso da “herança” um excelente
instrumento para padronização e reúso arquitetural , em último nível (herança que substitui o “Object”, mas permite descendentes
livremente).
491
Capítulo E17
}
}
Código E17.12. Classe DAO, “refatorada” até sua maior abstração.
Em arquitetura de software, como na vida, tudo tem seu preço. Implementações sofisticadas para
se defender de possibilidades futuras, de baixa probabilidade, são vícios dos arquitetos “Dom
Quixote” - desperdiçam não somente o tempo e dinheiro do projeto se prevenindo contra inimigos
imaginários (seus “moinhos de vento”), como também o dos Desenvolvedores, obrigados a se
transformarem em seus escudeiros (“Sancho Pança”).
“As melhores soluções advêm da simplicidade – a arte de maximizar o trabalho não feito”.
Ref. E17.1. The Agile Manifesto Principles (www.agilemethodologies.com)
492
Regras de Negócio & Batch
- Utilizando DI em classes de AS
Agora que finalizamos a nossa implementação da classe de persistência, deixando-a tão simples e
abstrata quanto possível, vamos ajustar nossa classe AS.
Altere a classe de AS para receber o serviço de persistência via Injeção de Dependência, em seu
construtor (Constructor Based DI), e para chamá-lo de fato, substituindo nosso comando provisório
inicialmente informado.
...
public class CalculoFolhaAS extends PlcBaseAS {
IFuncionarioDAO funcionarioDAO;
public CalculoFolhaAS (IFuncionarioDAO funcionarioDAO){
this.funcionarioDAO=funcionarioDAO;
}
List<Funcionario> listaComDTInformadoNoPeriodo =
funcionarioDAO.recuperaComDTInformado(anoMesReferencia);
...
Código E17.13 . Chamada de AS para DAO, via DI com “amarração automática via padrão de nomenclatura”.
Perceba que não explicitamos uma classe de implementação, o que é possível conforme explicado no
capítulo anterior. Neste caso o jCompany FS Framework tenta identificar automaticamente uma
implementação válida para a interfaces de DAO declaradas, com o seguinte algoritmo padrão,
implementado (e extensível) em “PlcModeloFactoryIoCService”:
1. Primeiramente, o algoritmo de DI procura pela anotação “PlcImplementacao”, no argumento de
Interface do construtor. Se encontrado, utiliza a “fábrica” ou a classe de implementação indicada.
2. Se não encontrou (caso de nosso exemplo), o algoritmo de DI tenta utilizar a auto-amarração via
nomenclatura, da seguinte forma:
No mundo prático dos projetos corporativos, uma das grandes complexidades de programação é
ter de lidar com imperfeições advindas de limitações tecnológicas. Restrições típicas são memória
disponível, capacidade de comunicação via rede(througput) e de processamento.
Vamos, portanto, necessitar recuperar o saldo de Proventos e Descontos com naturezas “PA” e “DG”,
para cada funcionário/período. Este é um serviço que, basicamente, irá acessar a entidade
493
Capítulo E17
...
/**
* @param anoMesReferencia Período de referência (MM/yyyy)
* @return BigDecimal, contendo o saldo de proventos e descontos gerais, para o funcionário, no
* período.
*/
public BigDecimal recuperaSaldoGeralPorFuncionario(Date anoMesReferencia,Funcionario funcionario) throws PlcException;
...
Código E17.14. Novos métodos para recuperar saldo de “ProventoDesconto”.
...
public BigDecimal recuperaSaldoGeralPorFuncionario(Date anoMesReferencia,Funcionario funcionario) throws PlcException {
return (BigDecimal)
recuperaObjetoViaNamedQuery("ProventoDescontoEntity.recuperaSaldoGeralPorFuncionario",
new String[]{"anoMesReferencia","funcionario"},new Object[]{anoMesReferencia,funcionario});
}
...
Código E17.15. Novos métodos para recuperar saldo de “ProventoDesconto”.
...
@NamedQueries({
...
@NamedQuery(name="ProventoDescontoEntity.recuperaSaldoGeralPorFuncionario",
query="select sum(pd.valor) as saldo" +
" from ProventoDescontoEntity pd" +
" where pd.anoMesReferencia = :anoMesReferencia and pd.funcionario=:funcionario" +
" and (pd.naturezaProventoDesconto='PA' or pd.naturezaProventoDesconto='DG')")
})
public class ProventoDescontoEntity extends ProventoDesconto {
...
Código E17.16. NamedQuery em “ProventoDescontoEntity”.
*
Note que, apesar de termos realizado esta especificação para o modelo de Domínio, é uma boa prática utilizar estes mesmos critérios
para o modelo de classes de Persistência, quando possuir correlação.
494
Regras de Negócio & Batch
...
// 3. Constantes externadas
public static final int TAXA_IR = 15;
public static final BigDecimal DESCONTO_DEPENDENTE = BigDecimal.valueOf(200);
...
/**
* Calcula salário e impostos, para um Funcionário
* @param anoMesReferencia Período de referência
* @param funcionario Funcionário a ser utilizado
*/
private void calculaFolhaUmFuncionario(Date anoMesReferencia,Funcionario funcionario)
throws PlcException,CalculoFolhaFuncionarioException {
// Grava
...
}
...
Código E17.17. Método “calculaFolhaUmFuncionario” em “CalculoFolhaAS”.
#1. Perceba que, para cada funcionário, estamos recuperando o saldo de Proventos e Descontos
gerais - para depois delegar para a Entidade “Funcionario” a realização dos cálculos
em si.
#2. 3, e 4. Como dissemos, classes de AS não devem realizar cálculos ou operações de negócio
atômicos, mas se concentrar no “controle” de todo o algoritmo. Note que fizemos três
chamadas distintas a “Funcionario”, a partir de nosso AS. Se não precisássemos dos valores
de IR e Salário Líquido ao final, para gravarmos entradas em “ProventoDesconto”, uma única
delegação ao “Funcionario” seria suficiente. Obs.: Note também o uso de constantes em
escopo do cálculo, em lugar de valores literais, como boa prática.
...
public abstract class Funcionario extends AppBaseEntity {
// 1
public static final int TOTAL_DIAS_MES_REFERENCIA = 22;
…
// 2
public BigDecimal calculaSalarioBruto(BigDecimal saldoProventosDescontosGerais)
throws CalculoFolhaFuncionarioException {
// 4. Cálculo
BigDecimal salarioBruto = getSalarioAtual().divide(BigDecimal.valueOf(TOTAL_DIAS_MES_REFERENCIA))
.multiply(getDiasTrabalhados());
return salarioBruto;
}
...
Código E17.18. Método “calculaSalarioBruto” em “Funcionario”.
495
Capítulo E17
#1. Constante com valor 22, para “dias totais do mês”, criada para evitar proliferação de uso literal.
#2. Nunca é pouco lembrar: os métodos de negócio, especialmente, devem possuir comentários
Javadoc bem elaborados.
#3. Pré-condição especificada, com exemplo de tratamento utilizando uma exceção customizada e
enviando mensagem internacionalizada, com argumentos em separado.
#4. O cálculo em si reside nesta linha. Utilizamos recursos da classe “java.math.BigDecimal” para
fazer uma “regra de três” entre os dias totais e os efetivamente trabalhados.
#5. Pós-condição especificada, com exemplo de exceção disparada agora sem internacionalizar,
para variar o exemplo somente. O uso do token “#”, no início da mensagem, indica para o
jCompany não tentar traduzir este texto.
...
public BigDecimal calculaIR(BigDecimal salarioBruto,int taxaIR, BigDecimal valorDescontoPorDependente) throws PlcException
{
}
...
Código E17.19. Método “calculaIR” em “Funcionario”.
...
public BigDecimal calculaSalarioLiquido(BigDecimal salarioBruto, BigDecimal ir) {
return salarioBruto.subtract(ir);
}
...
Código E17.20. Método “calculaSalarioLiquido” em “Funcionario”.
...
/**
* Recebe valores discretos e inclui um novo ProventoDesconto, com "batch" como usuário da última
* alteração.
*/
public void incluiProventoDesconto(Funcionario funcionario, Date anoMesReferencia,
NaturezaProventoDesconto naturezaProventoDesconto, BigDecimal valor) throws PlcException;
...
Código E17.21. Nova cláusula de contrato com a persistência, para incluir objetos “ProventoDesconto”.
...
public void incluiProventoDesconto(Funcionario funcionario, Date anoMesReferencia,
NaturezaProventoDesconto naturezaProventoDesconto, BigDecimal valor)
throws PlcException{
// 1
ProventoDescontoEntity proventoDescontoEntity = new ProventoDescontoEntity();
// 2
proventoDescontoEntity.setFuncionario(funcionario);
proventoDescontoEntity.setAnoMesReferencia(anoMesReferencia);
proventoDescontoEntity.setNaturezaProventoDesconto(naturezaProventoDesconto);
proventoDescontoEntity.setValor(valor);
// 3
proventoDescontoEntity.setUsuarioUltAlteracao("batch");
proventoDescontoEntity.setDataUltAlteracao(new Date());
// 4
// getSession().save(proventoDescontoEntity);
496
Regras de Negócio & Batch
inclui(proventoDescontoEntity);
}
...
Código E17.22. Método que realiza inclusões programaticamente.
#1. O método inicia criando uma nova instância da classe a ser persistida.
#2. Em seguida, os valores recebidos como parâmetros são incluídos na classe (um outro modo
mais sucinto poderia ser criar um construtor especial na classe, para este fim).
#3. Valores obrigatórios e não informados são preenchidos. O usuário da auditoria “pauta mínima”
deve ser incluído manualmente, em programações “batch”.
#4. O comando “save” da interface de persistência poderia ser utilizado diretamente, mas repare
que o uso do serviço “inclui”, do ancestral, mantém nossa arquitetura sobre controle e nosso
método mais “em alto nível”, independente de sintaxes específicas de engines de persistência
(a mesma sintaxe para JPA!).
Mas é bem importante entender o que o “save” (ou, indiretamente, o “inclui”) realiza, tanto em JPA
quanto em Hibernate: é um comando que “registra” o objeto em memória para ser persistido -
mas não emite nenhum SQL para o SGBD! Estes SQLs ficam em caching no escopo da sessão
de persistência, até que explicitamente se envie um comando para “descarregar” todos eles (Ex.:
“flush”) ou um “commit”, que também descarrega todo o cache, antes de confirmar a transação.
Em nosso caso, é uma boa idéia deixar que todos os “INSERTs” sejam gerados em conjunto, de
100 em 100 registros, no mesmo momento do “commit”, pois deste modo nossa Unidade Lógica de
Transação dura menos tempo. Por isso, em nosso exemplo, bastaríamos implementar o método
pendente “encerraTransacao()”.
No entanto, para efeitos didáticos, vamos implementar os dois serviços:
o Um que simplesmente descarrega o buffer de persistência, enviando para o SGBD todos os
SQLs em caching desde o último envio (somente para exemplo);
o E outro que realiza um fechamento de transação com “commit”, que implicitamente também
envia os comandos pendentes (o que utilizaremos efetivamente).
3. Defina mais duas “cláusulas contratuais” em IFuncionarioDAO, conforme o Código E17.23.
...
public interface IFuncionarioDAO {
...
/**
* Sinaliza para o despacho imediato de comandos de persistencia. Somente necessário para
* controle manual de transações (Ex.: batch)
*/
public void enviaComandos() throws PlcException;
/**
* Sinaliza para finalização definitiva da transação, com confirmação de dados.
* Somente necessário para controle manual de transações (Ex.: batch).
* Obs.: Se a operação "enviaComandos" não foi chamada, dispara todos os comandos em
*caching, neste momento.
*/
public void encerraTransacao() throws PlcException;
...
}
...
Código E17.23. Cláusulas típicas para gerenciamento manual de transações.
...
public class FuncionarioDAO extends PlcBaseHibernateDAO implements IFuncionarioDAO {
…
public void encerraTransacao() throws PlcException{
super.commit();
}
}
...
Código E17.24. Implementação com reúso em “FuncionarioDAO”.
497
Capítulo E17
5. Troque agora o nosso esboço inicial de fechamento de transação, em “CalculoFolhaAS” para usar o
serviço DAO.
...
for (Iterator i = listaComDTInformadoNoPeriodo.iterator(); i.hasNext();) {
try {
if (calculadoOk==100)
funcionarioDAO.encerraTransacao();
funcionarioDAO.encerraTransacao();
if (feLista.size()>0)
...
Código E17.25. Uso de fechamento de transação “manual”.
6. E, finalmente, inclua no cálculo individual, as linhas finais para inclusão de salário e IR, em
“CalculoFolhaAS”.
...
private void calculaFolhaUmFuncionario(Date anoMesReferencia,Funcionario funcionario)
throws PlcException,CalculoFolhaFuncionarioException {
...
}
...
Código E17.26. Chamada para geração de novos objetos “ProventoDesconto”.
...
public interface IFuncionarioDAO {
...
/**
* Conta o total de funcionários sem salário calculado, no período
*/
public Long contaFuncionarioSemSalario(Date anoMesReferencia) throws PlcException;
}
...
Código E17.27. Última cláusula de persistência, de nosso exemplo atual.
2. Implemente em “FuncionarioDAO”.
...
public Long contaFuncionarioSemSalario(Date anoMesReferencia)
throws PlcException {
498
Regras de Negócio & Batch
...
Código E17.28. Implementação da última cláusula de persistência.
...
@NamedQuery(name="FuncionarioEntity.contaFuncionarioSemSalario",
query="select count(*) from FuncionarioEntity f where f.sitHistoricoPlc='A' and f.id not in" +
" (select pd.funcionario.id from ProventoDescontoEntity pd" +
" where pd.anoMesReferencia = :anoMesReferencia and pd.naturezaProventoDesconto='SL')")
})
@PlcExclusaoLogica
public class FuncionarioEntity extends Funcionario {
...
Código E17.29. Cláusula OQL que utiliza função de agregação “count” e “subquery”.
4. Agora podemos implementar o método que falta em “CalculoFolhaAS”, conforme o Código E17.30.
...
private void verificaFechamento(Date anoMesReferencia) throws PlcException {
funcionarioDAO.encerraTransacao();
}
...
Código E17.30. Método que testa se é para gerar fechamento de folha.
Não iremos finalizar a implementação deste método, deixando a inclusão como exercício. Mas veja que,
se o fizermos através do mesmo DAO “FuncionarioDAO”, como sugerido no comentário, estaremos
compreendendo “FolhaPagamento” como parte da agregação, como ilustrado na Figura E17.17.
O uso de mais uma transação, como sugerido, é também necessário, já que não estamos mais no laço
principal, e realizamos mais uma gravação! A revisão de chamada deste serviço, agora incluindo o
parâmetro “período”, está exemplificada no Código E17.31.
...
protected Long calculaFolha(Date anoMesReferencia) throws PlcException,CalculoFolhaException { …
funcionarioDAO.encerraTransacao();
if (feLista.size()>0)
throw new CalculoFolhaException(feLista,calculadoOk);
else {
verificaFechamento(anoMesReferencia);
return calculadoOk;
}
499
Capítulo E17
...
Código E17.31. Método que testa se é para gerar fechamento de folha.
#1. O jCompany possui um invólucro básico sobre as rotinas de “TimerTask” do Java, de modo a
produzir um isolamento básico que permita evoluções maiores nesta arquitetura. Basicamente,
na versão atual, este ancestral recepciona o método “run” e o delega para o “runApi”,
realizando transação de forma genérica.
#3. Utilizamos uma rotina do utilitário de datas do jCompany que, dado o dia atual, subtrai até 28,
para obter o mês anterior. Desta forma, mesmo com uma boa margem de erro no escalonador,
a rotina funcionará.
#5. A classe de Application Service deve ser obtida via serviço de localização padrão
“PlcModeloLocator”, para que as rotinas de ID funcionem a partir daí, já que o jCompany não
oferece DI em rotinas TimerTask.
500
Regras de Negócio & Batch
...
private void trataErro(CalculoFolhaException cf) {
log.error(fe.toString());
}
}
...
Código E17.32. Método que realiza tratamentos de exceção – neste caso somente exibição de log de erro.
4. Mas para que as linhas de erros individuais apareçam formatadas corretamente, precisamos redefinir
o método “toString”, para as exceções de funcionário, como em Código E17.33.
...
public class CalculoFolhaFuncionarioException extends AppException {
…
public String toString() {
return getMessageKey()+" ["+getNomeFuncionario()+" - "+ getCpfFuncionario()+"]";
}
}
...
Código E17.33. Método que formata exibição de exceções.
5. Somente falta agora implementar a rotina de disparo em si. A subcamada candidata para iniciar
rotinas na camada Modelo é a de fachada. Portanto, vamos implementar nossas rotinas de iniciação
de escalonamento na classe “AppFacadeImpl”.
...
public class AppFacadeImpl extends PlcFacadeImpl implements IAppFacade, IAppFacadeRemote {
// 1
private static long MILISEG_1_DIA = 3600000L * 24;
// 2
private static Timer timerMensal = new Timer(true);
// 3
static {
// 4
timerMensal.schedule(new CalculoFolhaTimerTask(), primeiroDiaUmaHora(), MILISEG_1_DIA);
}
// 5
private static Date primeiroDiaUmaHora() {
#2. Declaração de um Timer (temporizador), que é uma Thread ultraleve, que rodará para fazer
ativações temporais escalonadas.
#3. Esta implementação na cláusula “static” garantirá que, ao primeiro acesso à classe
“AppFacadeImpl” (qualquer transação padrão, portanto), a rotina de escalonamento iniciará.
501
Capítulo E17
#5. Cálculo do primeiro dia para execução (que neste caso será o dia 3 do mês corrente), se o dia
atual for anterior a este dia; ou do próximo mês, se o dia atual for depois.
Note que o Timer não nos dá opções ricas, como é de esperar de um escalonador corporativo.
Conseguimos programar a primeira execução para este dia, mas não temos uma opção de
reescalonamento do tipo “execute dia 3 de cada mês”. Para isso, poderíamos utilizar algum
produto Open-Source como o Quartz.
Em nosso caso, de forma simplificada, vamos contornar esta limitação fazendo nosso escalonador
rodar todo dia, 1:00 hora da madrugada; e fazendo com que a própria rotina verifique se é o dia
correto para execução.
6. Edite o “CalculoFolhaTimerTask”, portanto, e acrescente o teste do Código E17.35.
...
public void runApi() throws PlcException {
// Impede execução se não for dia 3, uma vez que o escalonador programa
// verificação diariamente.
Date diaAtual = new Date();
if (diaAtual.getDate()==3) {
Date periodoCalculo = PlcDateHelper.getInstance().dataNumDias(diaAtual,-28);
…
}
}
...
Código E17.35. Testando o dia correto na rotina “TimerTask”.
#2. Nosso algoritmo não está pronto para trabalhar em “cluster” – precisaríamos criar algum tipo
de semáforo, para isso, marcando em banco de dados o início de um processamento, para que
outro nó não o faça paralelamente.
#3. Precisamos fazer contas e subterfúgios em código, para suprir as limitações da rotina de
escalonamento da classe “java.util.Timer”.
Ainda assim, é uma abordagem imediatamente possível, que resolve situações mais simples. Ela pode ser
utilizada transitoriamente, até que se disponha de um ambiente de escalonamento batch mais
apropriado.
502
Regras de Negócio & Batch
Sumário
Neste capítulo, implementamos regras de negócio disparadas a partir de rotinas de escalonamento batch,
utilizando classes de serviços de negócio, da camada Modelo, do tipo Application Service (AS), além de
Data Access Objects (DAO), tarefas temporais (TimerTask) e temporizadores para escalonamento
(Timers).
Colocamos em prática um pouco das amplas possibilidades que o jCompany FS Framework oferece
para simplificar implementações de negócio e organizá-las de uma maneira Orientada a Objetos, com
gerenciamento de transações flexível.
No próximo capítulo, iremos ver mais implementações de negócio, enfatizando o uso de Template
Methods da camada de Modelo, através das classes de Business Object (BO/Manager), além de
implementar fachadas e disparos da camada Controle.
503
Capítulo
18
Regras de Negócio MVC
8
1
E
Interativas
- Analisando a Especificação
Figura E18.1. Diagrama para Extensão de Casos de Uso para “UC005.1 Calcular Folha Interativo!”.
Apesar de um pouco mais trabalhosa, esta Colaboração será uma grande oportunidade de nos
inteirarmos mais do jCompany FS Framework, em si, de forma desvinculada dos geradores do
jCompany IDE.
504
Regras de Negócio MVC Interativas
Figura E18.2. Página JSP de argumento, criada manualmente no diretório padrão “calculofolha”.
#1. Diretório padrão, abaixo de “WEB-INF/jsps” (portanto, protegido para acesso direto), e
utilizando o “nome da Colaboração” (URL).
#2. Novo título, em português direto, bem como rótulos do campo “anoMesReferencia”. Não
utilizamos I18n apenas didaticamente, para exemplificar o uso alternativo, direto.
#3. Criamos duas células auxiliares com ‘width=”40%”’ cada, para centralizar o corpo do
formulário, sem perder o alinhamento da tabela maior.
#4. Um ponto chave de nossa implementação específica é que agora iremos referenciar o
argumento utilizando o padrão JBoss Seam: “[nome de instância gerenciada pelo JBoss
Seam].[nome de propriedade que conterá o valor da data]”. Note que não criamos, até
agora, a classe de Backing Bean que será instanciada em “calculoFolhaAction” – faremos
isso alguns passos adiante.
#5. Também neste caso, como no caso do “ProventoDesconto”, a data será recebida com
máscara “MM/yyyy” (somente mês e ano), e utilizará o conversor do jCompany
“converterDataMascaraPlc”. Este conversor, no momento da submissão do usuário, recebe
o valor alfanumérico, concatena “01” como dia e gera uma data válida para envio. No momento
da recuperação para edição, faz o trabalho inverso, retirando o “01”.
#7. Nova célula, com componente botão. Note que não precisamos, até o presente momento, criar
botões para nossos formulários, pois os temos reutilizado do jCompany FS Framework, nos
tutoriais passados†.
#8. Recomenda-se que todos os componentes da página recebam “id” único, para referência em
possíveis programações Javascript.
*
Dependendo do Web-Design, pode-se precisar de um tamanho=8 para garantir um melhor espacejamento - não é mais o nosso
caso com o novo Design que aplicamos.
†
Para criar este novo componente, parta da paleta do RHDS ou comece a digitação e utilize o auto-complete do Eclipse.
505
Capítulo F19
#9. A ação corresponde ao método que será disparado, no Backing Bean JSF, que iremos criar mais
adiante.
#1. Leiautes para formulários específicos podem (e devem, sempre que possível!) reutilizar o
padrão do jCompany FS Framework, herdando de “def.corpo.universal”.
#2. O título da página, que irá aparecer na barra de cima da janela do Navegador e também no
topo de nosso leiaute principal deve ser definido aqui, no padrão “[URL da
Colaboração].titulo”.
#3. Este trecho sobrepõe a definição do ancestral para a barra de ações e mensagens, incluindo
uma página vazia em seu lugar (técnica para eliminar trechos de leiaute herdados). Isso foi
feito porque não queremos a barra de ações padrão e nem a de mensagens, onde se
encontram.
#4. Nossa página específica é incluída aqui, como primeira da lista de “caixas verticais” (VBox) do
leiaute Tiles.
#5. Reutilizamos o componente de Leiaute para exibição de mensagens, agora na posição definida
na especificação, abaixo do pequeno formulário.
4. Crie uma chamada de menu para o nosso cálculo, em “app-tiles-menu1.xml”, conforme a Figura
E18.4 e Figura E18.5. .
506
Regras de Negócio MVC Interativas
Repare que o rótulo utilizado em “Value” (rótulo para o texto que será exibido na chamada de
menu) é o mesmo do leiaute.
5. Crie as mensagens I18n para o rótulo do botão no “ApplicationResources.properties” e também
para a chamada de menu e titulo da página.
Figura E18.6. Rótulo para botão de “Calcular”, item de menu e título de página.
Obs.: Como definimos os rótulos com o nome da Colaboração primeiro, suas mensagens ficam
agrupadas, quando ordenadas alfabeticamente, facilitando a edição e manutenção futura.
Aprendemos, então, neste tópico, os passos que precisamos realizar manualmente, quando não
pudermos aplicar uma solução padronizada para um problema especificado. De forma sumarizada,
precisamos:
o Criar uma ou mais páginas JSP, abaixo do diretório “/WEB-INF/jsps”*.
o Definir um novo leiaute Tiles em “app-tiles-pagina1.xml”, que utilize as páginas específicas criadas e
reutilize as definições maiores de leiaute, de primeiro e segundo níveis, do jCompany FS
Framework.
o Criar uma nova entrada de menu, em “app-tiles-menu1.xml”.
o Definir mensagens para todos os rótulos I18n utilizados, em “ApplicationResources.properties”.
*
Em nosso caso, precisamos de apenas uma, mas lembre-se: “recortar” uma grande página JSP em mais páginas de menor tamanho,
separadas por seções “naturais”, é uma boa prática, evitando um único artefato extremamente complexo.
507
Capítulo F19
2. Crie agora a classe “CalculoFolhaAction” conforme as instruções abaixo. Esta classe será o nosso
Backing Bean JSF, gerenciado pelo jBoss Seam.
Figura E18.8. Classe de Controle “Backing Bean”, gerenciada pelo jBoss Seam.
#2. Declarações de metadados do jBoss Seam. O nome da instância aqui declarado deve ser o
mesmo utilizado nas JSPs. Em nosso caso, foi referenciado em
“#{calculoFolhaAction.anoMesReferencia}”. O escopo de conversação garante que o valor de
período previamente informado se mantenha disponível após submissões do usuário.
*
Pode-se, a exemplo das JSPs ou classe de domínio, segmentar-se adicionalmente por pacote com nome da colaboração, por exemplo,
“com.empresa.rhtutorial.controle.jsf.calculofolha”. Mas como nossas regras de controle são triviais e em pouca quantidade na
aplicação, estamos mantendo classes de controle no pacote “raiz”.
†
Classes de Controle gerenciadas pelo jBoss Seam são Statefull (ao contrário de classes de controle Struts, por exemplo), e somente
por isso podem receber valores em variáveis de instância.
508
Regras de Negócio MVC Interativas
#6. Em nosso caso, incluímos um disparo de log de informação, “disfarçado” para nível WARN*,
mas que tem o propósito de notificar em arquivo todas as tentativas de execução interativa do
cálculo.
3. Efetue uma “Liberação Rápida com Reinício”. É uma boa prática testarmos a interface e fluxos de
controle, antes de prosseguirmos para delegar, para serviços da camada Modelo, a responsabilidade
do cálculo em si.
Repare que a barra de ações/mensagens não aparece como nos outros formulários. Ao
preenchermos um mês válido, podemos conferir a console, no Eclipse, para ver se nosso método
foi acionado corretamente.
Se limparmos a data e clicarmos em “Calcular”, perceba que a mensagem agora aparece onde
precisamos (por conta da especificação), abaixo do formulário.
*
Esta é uma técnica para garantir que um log de informação seja enviado, mesmo que o nível INFO para esta classe seja desligado,
acidentalmente.
509
Capítulo F19
@Local
public interface IAppFacade extends IPlcFacade {
}
Código E18.1. Nova cláusula contratual, específica da aplicação.
…
@PlcTransacaoNaoAplica
public Long calculaFolha(Date anoMesReferencia) throws PlcException,
CalculoFolhaException {
CalculoFolhaAS calculoFolhaAS =
(CalculoFolhaAS) PlcModeloLocator.getInstance().getAS(CalculoFolhaAS.class);
return calculoFolhaAS.calculaFolha(anoMesReferencia);
}
...
Código E18.2. Implementação de fachada, sem gerenciamento de transação.
…
public String calcularfolha() throws PlcException {
return NAVEGACAO.IND_MESMA_PAGINA;
}
...
Código E18.3. Código de método de controle, chamando fachada padrão.
#1. Para pegar a implementação de fachada que especializa o contrato padrão, basta utilizar o
método “getServiceFacade()”.
510
Regras de Negócio MVC Interativas
#3. Ao final, se não houve erros e se o salário de todos os funcionários foi calculado, uma
mensagem de confirmação é exibida, neste caso em cor verde
(PlcMensagem.Cor.msgVerdePlc).
Note que a classe auxiliar para envio de mensagens é um DP Singleton*. O mecanismo básico é
o seguinte:
...
private void trataErro(CalculoFolhaException cf) throws PlcException {
// 1
if (cf.getCalculadoOk()>0)
PlcMsgJsfHelper.getInstance().msg("calculofolha.total.ok",new String[]{cf.getCalculadoOk()+""},
PlcMensagem.Cor.msgVerdePlc.toString());
// 2. Cabeçalho da mensagem de erro
if (cf.getFeLista()!=null) {
PlcMsgJsfHelper.getInstance().msgErro("calculofolha.erros",new String[]{cf.getFeLista().size()+""});
CalculoFolhaFuncionarioException fe = iterator.next();
// 3
// Exemplo português
if (fe.toString().startsWith("#"))
PlcMsgJsfHelper.getInstance().msgErro(fe.toString());
else
// Exemplo I18n
PlcMsgJsfHelper.getInstance().msgErro(fe.getMessageKey(),
new String[]{fe.getNomeFuncionario(),fe.getCpfFuncionario()});
}
// 4
if (cf.getFaltaDiasTrabalhados()>0)
PlcMsgJsfHelper.getInstance().msgErro("calculofolha.erros.dias.trabalhados",
new String[]{cf.getFaltaDiasTrabalhados()+""});
}
...
Código E18.4. Código para tratamento de erro na camada Controle.
#1. Se, apesar de haver erros, alguns funcionários foram calculados corretamente, eles serão
exibidos em uma mensagem destacada em cor verde, como requisitado. Lembre-se que, em
nosso serviço, mesmo no caso de exceções, montamos este valor no objeto de Exceção, para
esta finalidade.
#2. Se houver algum erro específico (alguma ocorrência de erro em nível de cálculo para
funcionário), todas as ocorrências serão percorridas e também exibidas como mensagem.
#3. Este trecho de código é meramente didático, mostrando a recepção de erro, tanto de forma
internacionalizada, quanto em português, diretamente. No mundo real, somente uma das duas
*
Portanto, como todos os utilitários simples no jCompany, termina com sufixo “Helper” e deve ser obtida via método estático
“getInstance()”.
511
Capítulo F19
seria utilizada.
#4. Ao final, mesmo que não existam erros de cálculos individuais, uma mensagem de erro
também é emitida, caso o total de funcionários ativos existente não tenha sido calculado. Ou
seja, caso estejam faltando lançamentos de “Dias Trabalhados” para algum funcionário*.
#2. Tokens no padrão {[seqüencial]}, para substituição de variáveis, utilizados nas mensagens.
#3. Nota: Lembrando que as advertências são porque não traduzimos as mensagens. Podemos
eliminá-las com alguma das duas opções: efetivamente traduzindo ou excluindo os arquivos de
outros idiomas, que vem configurados nos templates INI do jCompany.
2. Em nosso caso, lançamos “Dias Trabalhados” somente para 2 de 10 funcionários ativos, existentes
em nossa base. O cálculo para dois deles, portanto, foi realizado com sucesso, mas não para todos.
Por isso um erro também é exibido.
3. Alteramos os Dias Trabalhados diretamente na base de dados para valor negativo, de forma a
simular um teste de erro individual, obtendo o resultado foi o da Figura E18.14.
*
Não custa lembrar que nossas hipóteses são uma simplificação bastante grosseira em regras e políticas reais de Cálculo de Folha ou
RH, meramente para forçar situações didáticas, que não exijam esforço de compreensão na direção errada, em entendimentos do
domínio.
512
Regras de Negócio MVC Interativas
#1. As anotações de EJB3 alternativas poderiam ser removidas, pois não as estamos utilizando em
nosso tutorial corrente, com POJOs apenas*.
*
Iremos abordar EJB3 e estratégias de remoting/SOA em geral, no próximo livro “Volume II – Tópicos Avançados”, desta séria.
513
Capítulo F19
#2. Perceba que, mesmo sendo independente, o jCompany continuará utilizando AOP e
transações declarativas, em nossa fachada específica.
3. Para obter uma referência ao contrato de fachada “de negócio”, utilize o padrão destacado abaixo,
no método de controle.
…
public String calcularfolha() throws PlcException {
…
try {
ICalculoFolhaFacade calculoFolhaFacade = (ICalculoFolhaFacade)
PlcControleLocator.getInstance().getFacadeNegocio(ICalculoFolhaFacade.class);
4. Faça uma nova liberação com reinício. A aplicação deve funcionar de forma idêntica, mas agora com
um contrato de fachada próprio.
514
Regras de Negócio MVC Interativas
Sumário
Neste capítulo, implementamos uma extensão do Caso de Uso “UC005 Calcular Folha de Pagamento!”,
realizando uma implementação MVC manualmente, sem apoio de geradores do jCompany IDE.
Muito embora tenhamos criado mais artefatos manualmente, preservamos os benefícios do jCompany
FS Framework, reutilizando componentes visuais, leiautes, tratamentos de exceção, DI/IoC, utilitários e
padrões arquiteturais em geral.
515
F
Módulo
Relatórios com
.
F
Eclipse BIRT
Este é um módulo prático, que traz tutoriais com passos detalhados para confecção
de relatórios Web com Eclipse BIRT. Além de dicas básicas para a construção de
páginas mestre (cabeçalhos e rodapés), reúso de estilos, agrupamentos,
totalizações e quebras de página, este módulo também provê dicas e exemplos
arquiteturais para uma liberação adequada (segura e eficiente) de relatórios para
usuários finais.
516
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
517
Capítulo
19
Introdução ao Eclipse BIRT
9
1
F
Analisando a Especificação
O nosso próximo Caso de Uso tem por objetivo prover um relatório para usuários com papel
"Administrador" realizarem auditoria em operações sobre o cadastro de funcionários, conforme
especificado na Figura F19.1.
*
No jargão de épocas passadas, "relatórios" emitiam informações impressas diretamente em papel e "consultas" emitiam informações
em um terminal de vídeo. Na medida em que se tornou possível "visualizar relatórios em terminais de vídeo" e/ou "enviar para a
impressora quaisquer consultas", este critério ficou mais difuso. Portanto, como convenção, iremos chamar de relatório saídas
produzidas em tecnologia Eclipse BIRT que possuam formatação (mesmo que alternativa) mais adequada para impressão, em padrão
“PDF” ou “DOC”.
518
Introdução ao Eclipse BIRT
Por este motivo, quando especificamos um "relatório" e não uma "consulta", estamos requerendo uma
saída em formato PDF ou outro que possa ser impresso por um programa que não seja o Navegador
(como o Adobe Acrobat Reader©, por exemplo), mais apropriado para esta finalidade.
No caso do jCompany Developer Suite, utilizaremos preferencialmente o Eclipse BIRT, solução Open-
Source de base, homologada para este fim*.
- O Eclipse BIRT
O Eclipse BIRT é uma solução de Business Intelligence de origem comercial, cedida pela empresa
Actuate Corporation© à comunidade Open-Source, há alguns poucos anos atrás. O Eclipse BIRT traz
plugins no Eclipse que permitem a confecção visual (WYSIWYG) de relatórios incluindo quebras e
totalizações, cubos, consultas tipo "planilha" (Crosstab), sub-relatórios e muitos outros recursos, obtidos
com recursos de "arrasta e solta" e conhecimentos de SQL apenas.
Além dos utilitários de desenvolvimento, o Eclipse BIRT também provê uma arquitetura que facilita a
criação de "frameworks de relatório", que permite a criação de estilos e componentes reutilizáveis entre
relatórios, pela empresa.
Por fim, em tempo de execução, além de componentes de motor (engine) que permitem a execução de
relatórios com produção de informações em múltiplos formatos (PDF, DOC, XLS, PPT, CSV, DOC, etc.), o
Eclipse BIRT também traz uma aplicação que facilita significativamente a tarefa de disponibilizar
relatórios para a WEB: o Eclipse BIRT Viewer.
Muito embora seja uma solução recentemente incorporada, o jCompany agrega valor ao Eclipse BIRT,
com:
o Gerência de Configuração: Instalação e pré-configuração tanto do ambiente de desenvolvimento
quanto do de execução do Eclipse BIRT no Tomcat, garantindo uso imediato sobre uma versão
homologada.
o Framework geral: Framework de base simples, contendo estilos visuais (similares a estilos CSS)
para serem imediatamente aplicados em componentes e seções típicas de relatórios.
o jCompany BIRT Viewer: Especializações ao BIRT Viewer, incluindo traduções básicas para
português e uma arquitetura que possibilita liberação ultra-simplificada e com soluções de reforço na
área de segurança.
No espaço que possuímos neste livro, cobriremos apenas uma pequena parte das inúmeras possibilidades
que traz o Eclipse BIRT. Sugerimos os livros de nossa referência bibliográfica "BIRT - A Field Guide to
Reporting" [Peh, Hannenmann, Reeves, Hague 2006] e "Integrating and Extending BIRT"
[Weathersby, French, Bondur, Tchell, Chatalbasheva 2006] para um aprofundamento certamente
compensador, nesta área.
2. Clique direito sobre o novo diretório e procure a opção "New -> Report" (Se "Report" não aparecer,
clique em "New -> Other... -> Business Intelligence and Reporting Tools -> Report").
*
Uma outra opção seria a dupla Jasper Reports e iReports, recomendadas até a versão 3.1 do jCompany e ainda mantidas em
homologação, em paralelo ao Eclipse BIRT. Mas há, no mercado, uma clara tendência ao uso do Eclipse BIRT, devido à sua melhor
integração com o Eclipse, documentação e acabamento diferenciado - especialmente devido à sua origem comercial.
519
Capítulo F19
Note que existem diversos modelos (templates) padrões do BIRT e dois do jCompany disponíveis.
Basicamente, estes modelos trazem versões iniciadas de relatórios, para facilitar a vida de novatos.
Com a experiência, a tendência é usar os modelos mais simples – ou mesmo novos modelos,
criados sob medida para a empresa ou projeto.
O modelo que utilizaremos se presta ao nosso primeiro relatório, que visa trazer uma lista de
valores, sem quebras e nenhum recurso especial.
5. Clique em "Finish". Perceba que o Eclipse irá mudar de "perspectiva", apresentando as visões
disponibilizadas pelos plugins do Eclipse BIRT, para confecção de relatórios.
520
Introdução ao Eclipse BIRT
#4. A área de "Property Editor - Report" traz propriedades diversas de configuração para
componentes de relatório, sensíveis ao contexto! Clique em objetos na área de "Layout" e
perceba como estas propriedades se modificam.
#5. Diversos painéis agrupam propriedades para cada objeto, com um grande número de opções
de estilos básicos (Fonte, Cor, Tamanho, Cor de Fundo, alinhamento, etc.); formatações para
datas, números, dinheiro; expressões de avaliação dinâmica; eventos para programação; etc..
#1. Note que a parte central oferece outras visões além da principal de "Layout", a saber:
521
Capítulo F19
o "Script": Seção para programação. O BIRT expõe eventos que permitem programação via
"script" utilizando sintaxe Javascript ou até Java, mediante configurações especiais. Com isto, é
possível se obter efeitos de alto dinamismo, com possibilidades ilimitadas.
o "XML Source": Todas as definições que se faz nos diálogos visuais ("Layout" e "Property
Editor") terminam por gerar entradas em XML, que também pode ser editado ou consultado
diretamente, nesta aba.
o "Preview": Permite a visualização do relatório, inclusive conectando-se com o Banco de Dados
e utilizando dados reais de teste.
#2. Janela de captura de argumentos automaticamente gerada pelo BIRT*. Note que o modelo
"Tabular" do jCompany já traz um conjunto de argumentos apenas para exemplo e
referência.
7. Clique em "Ok" para aceitar os valores de argumentos propostos. O modelo "Tabular" do jCompany
pode ser então melhor compreendido, como mostra a Figura F19.6.
#1. Um logotipo "da empresa" já vem configurado no canto esquerdo do topo, definido na aba
"Master Page".
#5. A barra de "argumentos" é destinada a exibir os valores informados como parâmetros pelo
usuário. Ela é incluída em uma grade ("Grid"), que por sua vez fica na primeira linha da tabela
("Table") que é vinculada (Binding) com uma Tabela de Dados do SGBD-R.
#6. Os rótulos que aparecem no cabeçalho da tabela de dados em si utilizam uma variação sutil de
estilos, que exibem sublinhados e cores de fundo cinza.
*
Esta janela aparece traduzida quando utilizamos o jCompany BIRT Viewer, em tempo de teste e produção, no Tomcat. Além disso, ela
é automaticamente omitida quando enviamos os argumentos dos relatórios via URL, técnica que usaremos mais adiante.
522
Introdução ao Eclipse BIRT
#10. Os valores de data são formatados com "dd/MM/yyyy" e centralizados, através do estilo
"tabela1ValorDataPlc".
#11. Os valores de data e hora são formatados com "dd/MM/yyyy HH:mm:ss", através do estilo
"tabela1ValorDataHoraPlc".
#12. Na parte de rodapé da tabela de dados, uma nova grade é inserida com dois objetos:
#13. Por fim, também definido na página mestre está o contador de páginas de rodapé, contendo
uma linha de divisão do corpo.
O uso de estilos como os acima descritos deve ser incentivado para relatórios BIRT, assim
como o uso de CSS para páginas HTML. Com os estilos obtém-se maior produtividade na revisão e
melhor qualidade na padronização. Naturalmente, também é possível especializar e/ou modificar
algumas das propriedades dos estilos.
8. Vamos conferir a arquitetura de framework para relatórios BIRT, para localizar os estilos utilizados.
Clique novamente na aba "Layout" e, na seção da esquerda, na aba de "Library Explorer".
523
Capítulo F19
#1. Na visão da esquerda, além da aba "Palette" também é possível se abrir o "Data Explorer"
(Explorador de Dados) e o "Library Explorer" (Explorador de Bibliotecas). O "Library
Explorer" exibe bibliotecas que o arquivo atual eventualmente reutiliza.
O tema "defaultTheme" contém estilos que sobrepõem os valores default utilizados pelo BIRT.
Deste modo, os objetos "itens de relatório" disponíveis na paleta já são introduzidos nos
relatórios com alguns dos tipos "primitivos" (como "Table","Grid", etc.) já recebendo
customizações do jCompany.
#4. O tema "jCompanyDefaultTheme" define novos estilos não existentes no BIRT, como os
citados no passo 7.
Assim, recapitulando até aqui, tivemos contato com os três tipos de arquivos principais do BIRT: o
“rptdesign”, o “rpttemplate” e o “rptlibrary”.
Criamos um novo relatório "funcionarioAuditoria.rptdesign" a partir de um modelo de relatório do
jCompany (existe com nome "jCompanyTabular.rpttemplate", pré-configurado nos diretórios dos
plugins BIRT). Este novo relatório, por sua vez, graças ao modelo, já vem com os estilos da biblioteca
"jCompanyGeneral.rptlibrary" disponíveis.
Importante: Note que, para os maiores ganhos, deve-se realizar um trabalho preliminar de
padronização de topos, rodapés, estilos, etc., para toda a empresa ou ao menos para um projeto. Novos
arquivos dos tipos ".rpttemplate" e ".rptlibrary", contendo generalidades do negócio, podem então ser
disponibilizados em nível da arquitetura para facilitar os relatórios do dia a dia, a partir daí.
2. Clique na raiz da Treeview, em "Relatório Tabular", e localize a aba de "Property Editor - Report"
no painel mais central. Altere os valores conforme os descritos na Figura F19.8.
524
Introdução ao Eclipse BIRT
1. Clique direito no Data Source que veio pré-configurado, "BancoLocal" e, em seguida, em "Edit".
Este é um Data Source que traz configurações para conexão com o Apache Derby, SGBD-R que
utilizamos como padrão até aqui.
Figura F19.9. Data Source BIRT com dados de conexões para Banco Local padrão do jCompany.
#1. Classe do Driver JDBC específico. Note que, como veio pré-configurado, o Data Source já traz o
Driver do Apache Derby selecionado, homologado para acesso ao nosso SGBD local. Para
alterar a configuração para qualquer outro SGBD (ou mesmo se houver algum problema nesta
configuração), basta utilizar o botão "Manage Drivers..." para configurar um novo Driver.
#2. URL de acesso, específica para o Driver. Esta URL pode ser obtida do arquivo "rhtutorial.xml"
(arquivo de contexto do Tomcat, ou do manual de cada Driver JDBC utilizado). Esta URL nos
atende, já que o jCompany utiliza sempre o nome "bancolocal" como nome do banco de
dados local.
#3. Usuário "APP" e senha "APP", conforme vêm pré-configurados pelo jCompany.
525
Capítulo F19
#4. O campo "JNDI URL" é um dos mais importantes desta configuração. Apesar de não ter efeito
no desenvolvimento do relatório em si (se não alterar este campo, ainda assim a conexão em
desenvolvimento irá funcionar), se não informarmos um endereço de pool de conexões que
seja válido em tempo de produção, em produção o Apache Derby irá tentar criar uma nova
conexão (com o usuário e senha "APP"/"APP") a cada execução para cada usuário, o
que degrada consideravelmente a performance!
Felizmente, é mais provável que o relatório não execute, pois o usuário e senha de
desenvolvimento utilizados provavelmente não terão sucesso em conexão no ambiente de
produção. Mas note que, se tiver sucesso, este problema pode ser mascarado e, apesar da
baixa performance, o relatório executar de forma sofrível para os usuários – o que pode ser
ainda pior do que uma falha, que logo é corrigida.
3. Clique em "Test Connection..." para ver se uma mensagem "Connection Sucessfull" aparece. Se
não aparecer, certifique-se de que o banco de dados foi ativado no projeto "rhtutorial" e/ou
reconfira os parâmetros informados para conexão.
*
Por este motivo, quando você estiver mais fluente em Eclipse BIRT, o correto será definir o Data Source em uma biblioteca de escopo
do Projeto, para que não fique redundado em vários relatórios, mas seja reutilizado.
†
Note que o Eclipse BIRT não trabalha somente com bases relacionais (SGBD-R). Ele pode produzir relatórios tendo arquivos
convencionais como Data Source, por exemplo. Neste livro iremos focar somente em acesso a bancos de dados relacionais.
526
Introdução ao Eclipse BIRT
2. No segundo passo, perceba que nossas tabelas e colunas estão disponíveis em painel da esquerda,
para auxiliarem na confecção do SQL. Posicione na cláusula "from", dê um espaço e dê um duplo
clique na tabela "Funcionario" para preencher a cláusula.
3. Posicione o cursor agora na parte "select" e abra uma linha para cada coluna que vamos selecionar.
Procure a coluna na relação à esquerda e, com duplo clique, selecione cada uma que precisaremos,
conforme a Figura F19.12.
Importante: Lembre-se de dar espaço após a última coluna, para separá-la do "from". Um erro
comum é esquecer de dar espaços entre as linhas, quando editando SQLs neste diálogo, quando
não há vírgulas.
4. Crie agora uma cláusula "where", sempre lembrando de dar espaços ao final das linhas. Preencha a
cláusula conforme a Figura F19.13.
#1. Intervalo de datas verificado utilizando uma interrogação "?" em lugar de argumentos do
relatório (que veremos a seguir).
527
Capítulo F19
#2. Para que determinados argumentos tenham o efeito de QBE (Query By Example), ou seja, de
não filtrarem quando não informados, podemos utilizar esta técnica. No caso, se o usuário for
informado iremos recuperar apenas modificações realizadas pelo mesmo. Do contrário,
recuperaremos de todos ("? is null").
Importante: Note que se mantemos o dono ("owner") "APP", esperamos que ele também exista
em produção - do contrário devemos omiti-lo.
5. Clique em "Finish". O próximo diálogo se abrirá, permitindo que se informe nomes mais
significativos para as colunas e também rótulos que serão utilizados como default. Informe os
valores conforme a figura abaixo.
#1. Em "Name" fica o nome da coluna, incluindo todas que definimos na cláusula "select" do SQL.
#2. Em "Type" fica o tipo BIRT assumido para a representação da coluna no relatório.
#3. Em "Alias" pode-se definir um valor alternativo para cada coluna, apresentado em diálogos
com o Desenvolvedor durante a confecção do relatório - mas também em alguns utilitários
do BIRT que podem ser utilizados pelos usuários finais, como "para exportação de
dados". Portanto, vale à pena informar um nome significativo para cada coluna aqui.
#4. Em "Display Name", pode-se definir um rótulo padrão para a coluna, utilizado pelo BIRT como
default, em algumas situações.
#5. Em "Display Name Key" pode-se utilizar I18n no relatório, colocando chaves para arquivos de
mensagens (como fizemos em HTML), em lugar dos rótulos em português diretamente. Não
utilizaremos este recurso neste livro, mas o Desenvolvedor não encontrará problemas em
entender como funciona, da própria documentação do Eclipse BIRT.
#6. Ao acionar um "duplo clique" ou o botão "Edit..." um diálogo se abrirá, permitindo informar os
valores, para cada coluna.
Importante: É um erro saltar este diálogo sem preenchê-lo cuidadosamente, para "queimar
etapas". Ao informarmos bons valores nestas colunas, já estamos avançando em nosso objetivo e
ganharemos tempo mais adiante, com os valores e rótulos já bem definidos.
6. Clique agora, na lista da esquerda, em "Parameters"*. Note que aparecem quatro valores já
preenchidos, ou seja, quatro "argumentos" ou "parâmetros" do Conjunto de Dados (Data Set).
*
Iremos saltar "Computed Columns", mas seu uso pode ser experimentado pelo Desenvolvedor - é um diálogo que, como o nome
sugere, permite que criemos "colunas" com valores derivados das demais através de fórmulas diversas.
528
Introdução ao Eclipse BIRT
O Eclipse BIRT já inclui um parâmetro para cada interrogação "?" que definimos em nossa cláusula
SQL.
Note que, na arquitetura flexível do BIRT, um relatório pode requisitar, digamos, dois
parâmetros do usuário (Report Parameters) que, por sua vez, podem ser vinculados a
vários parâmetros de conjuntos de dados (Data Set Parameters), inclusive de vários Data
Sets diferentes.
Este relatório modelo já possui, por exemplo, três parâmetros definidos para o relatório, como
vimos no "Preview", requisitando "data de início", "data de fim" e "usuário" - exatamente os
argumentos que precisaremos em nosso Caso de Uso*.
Assim, edite cada um dos quatro valores de argumentos para o Data Set conforme exemplifica a
Figura F19.15.
#1. Diálogo de "Data Set Parameters", que nos permite definir melhor cada parâmetro "?"
incluído na cláusula SQL e vinculá-lo a um Report Parameter.
#5. Em "Default Value", também não modifique. O valor será assumido dos parâmetros do
relatório.
*
Neste livro, propusemos uma primeira especificação de relatório próxima do modelo que vem no jCompany, para facilitar o primeiro
caso.
529
Capítulo F19
7. Agora clique na opção "Preview Results". Se existirem atualizações realizadas com o usuário
"admin", no intervalo de datas que vem no modelo como default (ou o último informado no
"Preview"), aparecerão resultados como na figura abaixo.
Figura F19.16. Valores retornados pela cláusula SQL utilizando valores de argumentos.
#1. Definição de parâmetros para o relatório como um todo. São os parâmetros aqui definidos que
serão requisitados aos usuários.
#2. Podem-se agrupar parâmetros para que apareçam em uma caixa segmentada no diálogo com
o usuário e/ou para vinculá-los (como no caso de listas encadeadas de valores. Ex.: Unidades
da Federação -> Municípios -> Bairro"). No caso do projeto modelo "Tabular", um grupo vem
pré-configurado para agrupar o intervalo de datas.
#3. Um terceiro argumento é definido fora do grupo, no modelo, que é o usuário responsável pelas
alterações.
#5. Em "Prompt Text:" informe o texto que se deseja exibir para usuários, no diálogo que
requisita os parâmetros para o usuário.
#7. Em "Display Type", pode-se definir para que um valor seja exibido em formatos tais como
"Combos", "Listas", "Radio", etc..
#8. Em "Display As -> Help Text", informe um texto que aparecerá como um balão de ajuda no
campo de parâmetro.
530
Introdução ao Eclipse BIRT
#9. Em "Display As -> Format As", é possível definir um formato para exibição dos parâmetros.
No caso de datas, o formato sugerido, por hora, é dd/MM/yyyy ou "Medium Date".
#10. Existem outras opções que podem ser informadas, para cada argumento. A principal é "Is
Required" para obrigatório e "Hidden"/"Do not echo input" para não requisitar ao usuário
(assumindo um valor default como constante, por exemplo).
#11. Em "Default Value" pode-se informar um valor default que será exibido para o usuário. Vimos
estes valores em ação, quando clicamos em "Preview" e a janela de argumento se abriu com
valores já preenchidos.
2. Acione um duplo clique agora no parâmetro de usuário. Perceba que neste caso o parâmetro vem
como opcional. O valor default é "admin" (mas seria pouco provável deixar um valor default neste
campo, em um caso real).
3. Se tornarmos agora a conferir a janela padrão de coleta de parâmetros de relatório do Eclipse BIRT
(também chamamos de janela de argumento), compreenderemos um pouco melhor seu
funcionamento. Confira com a Figura F19.19.
#1. Para chamar novamente o diálogo, clique na aba "Preview" e no botão "Show Report
Parameters".
#2. O título da janela pode aparecer em inglês, mas em produção virá traduzido.
531
Capítulo F19
#7. Campos opcionais aparecem com uma opção adicional de valor nulo.
2. Clique em "Table" abaixo de "Body" e, na visão "Property Editor - Table". Selecione a pasta
"Binding". Em seguida, selecione "FuncionarioAuditoria" (Data Set recém-criado) na lista "Data
Set".
#1. A Treeview do outline exibe a estrutura do arquivo XML que contém toda a definição do
relatório (inclusive Data Sources, Data Sets e Libraries), facilitando a seleção de determinados
elementos.
#3. A visão "Property Editor" é dinâmica, como já vimos, e exibe informações complementares
(propriedades) para o elemento selecionado, seja no Outline, seja na visão de Design principal.
Em nosso caso, exibe propriedades para "Table".
#4. A pasta "Binding" permite que se vincule um objeto "tabela" a um "conjunto de dados".
#5. Ao vincular, perceba que o nome que definimos é utilizado, tanto em "Name" quanto em
"Expression".
3. Agora vamos seguir para a visão principal de "Layout” WYSIWYG. Clique nos campos de amostra na
linha "Detail Row" e remova-os. Note que é possível marcar vários objetos simultaneamente com
as técnicas de edição convencionais de "Control+Clique".
4. Em seguida, selecione a pasta "Data Explorer", expanda a relação de "Data-Sets" e o nosso Data
Set "FuncionarioAuditoria". Clique na coluna "Cód." e a arraste para a coluna do Design, conforme a
Figura F19.20.
532
Introdução ao Eclipse BIRT
Figura F19.20. Arrasta e solta do Data Set para a tabela na visão de Design WYSIWYG.
#2. Objeto "Cód." Criado a partir da coluna do Data Set. Note que somente é possível arrastar
porque o objeto Table está vinculado ao Data Set.
5. Arraste as demais colunas que possuem uma correspondência para a coluna respectiva da tabela do
Design. Troque o rótulo de “Salário” para “CPF” e deixe em branco as colunas sem correspondência,
conferindo com a Figura F19.21.
#1. Se não vierem dados, altere os valores dos parâmetros conforme sua amostragem (utilize o
plugin Quantum DB se for preciso, para ver datas das últimas alterações e usuários).
#2. Agora vemos dados reais, recuperados do banco de dados de teste local, configurado no Data
Source.
#3. Note que os alinhamentos de números deveriam estar à direita e de data centralizado, segundo
recomenda o modelo. Além disso, a fonte não é a mesma. Em suma, os novos objetos ainda
não estão seguindo a formatação padrão.
533
Capítulo F19
#4. O objeto "Aggretation" pré-definido agora não é renderizado, pois excluímos objetos por ele
utilizados. O Eclipse BIRT gera então uma mensagem de erro, que aparece de vermelho, logo
abaixo do relatório.
7. Vamos melhorar a formatação do nosso relatório, para nos adequarmos à especificação. Comece por
excluir a coluna que contém "Nascido em", retornando para a visão "Layout" e seguindo as
instruções abaixo.
#1. Clique nas caixas cinza superiores ou laterais, para selecionar uma coluna ou linhas inteiras do
objeto Table.
#2. Clique direito para opções de edição básicas como exclusão ou alteração de estilo. Utilize
"Delete" para excluir a coluna.
8. Agora vamos inserir uma nova linha na seção de cabeçalho, para conter os totais de incluídos,
alterados e excluídos, conforme a especificação da Figura F19.1. Note que temos duas linhas de
cabeçalho e que, para o efeito especificado, devemos incluir uma nova, entre as existentes.
#1. Linhas de cabeçalho. Clique direito na primeira e seleciona "Insert -> Row -> Below" para
incluir uma nova linha entre as duas existentes.
#2. Perceba o ícone diferenciado para linha de detalhe. Também é possível criar quantas linhas de
detalhes forem necessárias - e todas as criadas se repetirão conforme o número de linhas do
conjunto de dados.
#3. Ao final, há uma linha de rodapé preenchida por default com uma totalização. Foi solicitado que
os totais ficassem acima - portanto, iremos retirá-la daqui, logo adiante.
9. Selecione todas as colunas da nova linha criada e clique direito para acessar a opção "Merge Cells".
Acione-a para que possamos mesclar estas células em uma única.
534
Introdução ao Eclipse BIRT
10. Agora clique na linha que possui o rótulo "Total de Registros". Repare que, ao fazê-lo, uma aba
com indicador "Grid" aparece dinamicamente, revelando o contêiner do rótulo. Esta aba permite que
se selecione o contêiner em si (e não algum dos objetos contidos) - seja para edição de suas
propriedades, seja para redimensioná-lo ou arrastá-lo, como é o nosso caso. Com este recurso, o
Eclipse BIRT evita aquelas chatas alterações de camadas "para baixo" ou "para cima" de editores
visuais.
Clique na aba "Grid" e arraste este objeto todo (contendo o Total de Registros e a Agregação) para
a nossa linha recém criada.
Por que nós não incluímos os totais nas próprias colunas da tabela principal, em vez de criar um
Grid?
Incluir um Grid permite que possamos definir um subleiaute independente das seções principais da
tabela para cabeçalhos, rodapés ou mesmo outras linhas especiais de detalhe. Na maioria das
vezes esta prática se mostra mais apropriada. Quando, porém, precisamos apenas de um total,
perfeitamente alinhado com a coluna que está totalizando, o uso das próprias colunas da tabela
pode ser mais prático.
11. Crie mais quatro colunas no Grid original. Precisaremos para os rótulos e totalizadores que constam
na especificação. Para tanto, clique direito na coluna e selecione "Insert -> Column to the Right".
535
Capítulo F19
12. Crie os rótulos de totais para incluídos, alterados e excluídos, deixando colunas vazias para os
valores de totalização que faremos mais adiante. Para tanto, copie o rótulo existente e cole nas
novas colunas, em seguida editando o texto dos rótulos em si.
13. Exclua, também, a primeira coluna da tabela principal, antes de código (se não lembrou de fazer
juntamente com "Data de Nascimento"). Confira o resultado com a Figura F19.28.
#2. Primeira coluna removida para finalização da estrutura do relatório, de acordo com a
especificação.
#1. A aba "Master Page" permite edição WYSIWYG mas também de propriedades na visão
"Property Editor - Master Page -> Properties".
#3. Várias opções de configuração estão disponíveis, que dizem respeito ao relatório como um
todo, ou ao conjunto de páginas que usam uma Master Page específica.
#4. Diversas propriedades permitem a formatação das páginas do relatório como um todo,
incluindo margens, bordas, leiaute (carta, legal, A4, etc.), orientação, etc.etc..
536
Introdução ao Eclipse BIRT
Vamos agora alterar o cabeçalho, para conter o logotipo de nossa empresa e o título apropriado. Clique
no texto do título principal e digite "Relatório de Auditoria" e no subtítulo "Relatório de Auditoria de
Manutenção de Funcionários"*.
2. Agora clique no logotipo e com clique direito acione "Edit". Siga as instruções da Figura F19.30.
#3. Vamos adicionar uma imagem embutida, além da que existe do jCompany†. Ela foi
disponibilizada pelo Web-Designer especificamente para fins de impressão contendo o logotipo
da empresa ACME. Clique em "Add Image..." e procure pela imagem
"marca_empresa_imp.gif" na pasta
"[jCompany]\jcompany_documentacao\rhtutorial\gui".
3. Execute um novo "Preview" e confira o resultado com a especificação. Estamos quase lá - faltam os
totais e um embelezamento final!
*
A especificação não pede os dois, mas gostamos de sugerir melhorias.
†
Note que esta imagem aparece no projeto, mas não pode ser removida, pois se encontra no framework
"jCompanyGeneral.rptlibrary".
537
Capítulo F19
Importante: Não funcionará arrastar o componente diretamente para os espaços corretos do Grid,
pelo menos até a versão "2.2.0 v20070625" do Eclipse BIRT, utilizada neste livro. Será necessário
arrastá-lo para um espaço do Table, diretamente. Em seguida, após a definição da fórmula,
poderemos arrastá-lo para o local definitivo.
2. Um diálogo irá se abrir chamado "Aggregation Builder". Preencha-o como na Figura F19.32.
538
Introdução ao Eclipse BIRT
#1. A paleta é rica em componentes. Veremos uma boa parte deles em nossos tutoriais.
#2. Usaremos o componente "Aggregation" para realizar computações em nível do relatório. Note
que seria também possível utilizar SQL e recursos do servidor SGBD-R para tal.
#4. Altere o valor de "Function" para "COUNT". Ao fazê-lo, percorra todas as funções disponíveis
para conhecer as demais possibilidades oferecidas por este componente.
#5. Em “Data Field”, selecione o campo "Código" (algum que dê unicidade a cada linha,
preferencialmente).
3. Deixando desta forma, nosso componente já apresentará o total de linhas recuperadas, pois o
componente Aggregation assume suas operações sobre o contêiner Table. Mas como queremos
contar incluídos, alterados e excluídos em separado, teremos que adicionar um "filtro".
Acione o botão "fx" em "Filter Condition". O diálogo genérico "Expression Builder" aparecerá,
como mostra a Figura F19.33. Este diálogo é utilizado em diversos contextos onde uma expressão
pode ser inserida, e é um recurso chave a ser dominado para obtenção de fluência em Eclipse BIRT.
#1. A expressão que montaremos pode ser informada manualmente neste campo, mas as janelas
abaixo auxiliam na sua montagem.
#2. Em "Category" estão as categorias de recursos que podem ser utilizados em expressões BIRT,
desde Data Sets até funções e operadores. Em "Avaliable Column Bindings" são exibidos os
539
Capítulo F19
objetos gerados para o relatório, quando vinculamos o Data Set ao Table. Estes objetos podem
possuir formatações e programações adicionais às colunas disponíveis no Data Set.
#3. Em "Avaliable Data Sets" pode utilizar uma coluna do Data Set diretamente, que não seja
através dos "Column Bindings". É importante notar a distinção dos dois: O Aggregation que
criaremos, por exemplo, passará a existir no "Avaliable Column Bindings", mas não em
"Avaliable Data Sets"!
Acione duplo clique nesta opção e clique na única "Sub-Category", para selecionar a coluna
"Versão", como na Figura F19.33.
#4. Em "Reports Parameters", podemos usar os valores informados pelo usuário (ou parâmetros
constantes!) definidos para o relatório, nas fórmulas.
#5. As três últimas opções trazem duas categorias de funções e operadores que podem ser
utilizados nas expressões. A quantidade de opções é impressionante - somente com o tempo
será possível compreendê-las em toda a sua abrangência.
#7. Conforme a categoria e subcategoria selecionadas, uma lista diferente será exibida à direita. No
caso da figura são exibidas as colunas do Data Set selecionado. Altere para "Operators ->
Primeira Sub-Categoria" e acione duplo clique em "==" para incluir uma igualdade na
expressão.
4. Finalize a expressão e a agregação, e arraste-a agora para seu local definitivo, no cabeçalho do
relatório.
Figura F19.34. Objeto Aggregation reposicionado para o Grid, após sua criação em Table.
5. Faça um novo "Preview". Talvez você precise incluir novos registros para ter uma boa amostragem
para teste.
540
Introdução ao Eclipse BIRT
8. Arraste os Aggregations para suas posições definitivas e confira o resultado final com mais um clique
em “Preview”.
2. Selecione o estilo "rodape1TotalPlc" (este era o estilo originalmente utilizado no Total que veio
como referência, no relatório Modelo).
541
Capítulo F19
6. Agora realize um novo "Preview" e confira a melhoria. Repare que a fonte utilizada para caracteres
agora é "Arial" e o tamanho é "Medium" (assumido como um tamanho mediano pelo BIRT).
*
O uso de numerações é utilizado para manter espaço para outras variações padrões (2, 3, 4, etc.), previstas para versões futuras do
jCompany.
542
Introdução ao Eclipse BIRT
Esta é uma confusão comum: o alinhamento é uma propriedade da célula que contém o objeto e
não do objeto em si. Você pode selecionar a célula que contém o "CPF do Funcionário" com ó
mouse (e um cuidado cirúrgico) ou, o que é mais prático, via o “Outline”.
2. Localize a visão de Outline e clique na aba "Cell" acima de "Data (CPF do Funcionário)". É o
mesmo efeito do mouse. Note que agora novas opções para a "célula" aparecem. Selecione
"Center" em "Text Alignment".
543
Capítulo F19
Sumário
Neste capítulo, fizemos um primeiro relatório com base na tecnologia Eclipse BIRT, utilizando recursos
dos plugins disponibilizados de forma integrada na IDE Eclipse. Conhecemos seus recursos para reúso de
bibliotecas (via arquivos do tipo ".rptlibrary") e também para uso de modelos (via arquivos do tipo
".rpttemplate").
Utilizamos um primeiro modelo "Tabular" do jCompany para criar nosso relatório, definindo um Data
Source e um Data Set para confecção WYSIWYG do relatório, utilizando dado reais do Banco de Dados de
teste. Vinculamos estes dados com componentes visuais de apresentação para o corpo do relatório,
incluindo totalizadores com expressões e personalizamos uma página mestre, contendo topo e rodapé,
para finalizar a estrutura geral do relatório.
Aprendemos, por fim, como aplicar estilos do framework para obtenção de aparência padronizada entre
relatórios, e também como refinar estes estilos de forma específica.
No próximo capítulo, veremos as opções de tempo de execução que o BIRT e o jCompany oferecem para
execução deste relatório, com flexibilidade e segurança.
544
Introdução ao Eclipse BIRT
545
Capítulo
20
Utilizando o jCompany
0
2
F
BIRT Viewer
2. Informe argumentos apropriados, se a janela de parâmetros do relatório se abrir (será pedido uma
primeira vez – nas subseqüentes os dados informados ficarão em caching).
3. Agora acione a opção "File -> View Report -> View Report as DOC" (salte a primeira opção por
enquanto - voltaremos a ela mais tarde). Clique em Open (ou Abre), no diálogo que se segue.
Figura F20.1. Relatório em HTML ao fundo, com opção para ver em DOC em destaque.
4. O relatório deve ser exibido em formato "Open Document" acessível pelas principais suítes de
edição de texto do mercado.
546
Utilizando o jCompany BIRT Viewer
Importante: Note que alguns problemas de formatação ocorrem no título para o formato PPT. Isto
porque o relatório não foi ajustado para este formato - muito embora o BIRT tente fazer o melhor,
os diversos formatos usam tecnologias bem distintas e, portanto, requerem ajustes.
Para gerações em PPT, especificamente, o resultado com alguns problemas costuma ser aceitável,
pois usuários normalmente realizam edição posterior do resultado (em PowerPoint, por exemplo).
Os ganhos já compensam - pense no que já adianta ao usuário trazer dados de quaisquer de seus
relatórios imediatamente, para suas apresentações!
5. Clique agora em "View Report as PPT" e clique novamente em Open (ou Abrir). Uma nova versão
em PPT é renderizada.
Figura F20.3. Relatório em formato PPT (com alguns problemas), para apresentações.
6. Clique agora em "View Report as PDF" e clique novamente em Open (ou Abrir). Uma nova versão
em PDF é renderizada.
547
Capítulo F20
Figura F20.4. Relatório em formato PDF, para visualização e impressão de alta qualidade.
7. Clique agora em "View Report as XLS" e clique novamente em Open (ou Abrir). Uma nova versão
para uso em planilhas é renderizada.
Estes recursos são providos por uma aplicação chamada Viewer, muito parecida com a que nós
utilizaremos preferencialmente em tempo de execução, para prover facilidades diversas aos
usuários.
548
Utilizando o jCompany BIRT Viewer
#2. A barra de opções para o usuário traz diversas operações que trazem alta flexibilidade. A
primeira é o "Table of Contents", que exibe uma estrutura hierárquica de assuntos para o
relatório, definida pelo Desenvolvedor. Não desenvolvemos no relatório corrente, mas iremos
utilizar para o próximo, que contém uma estrutura mais interessante, com grupos em vários
níveis.
#4. A terceira "Export Data" traz opções de exportação dos dados do relatório somente, sem
incluir seu formato. É a opção acionada na figura.
#5. A quarta opção abre um diálogo para permitir ao usuário exportar o relatório para todos os
formatos que vimos, com opções que conheceremos a seguir.
#6. A quinta opção gera um arquivo PDF para impressão na máquina do usuário (Cliente).
#7. A sexta e última opção envia o relatório para impressão no servidor, via Postscript.
#9. Uma barra de navegação está disponível, inclusive para saltos diretos para alguma página
específica.
#11. No diálogo de exportação de dados, note que os valores de colunas aparecem com nomes
significativos para o usuário, graças às nossas boas práticas em defini-los, no diálogo "Output
Column"*. Clique nas setas duplas (">>") para enviar todos os campos para exportação.
*
Perceba que ainda restou "decorar" um "ELEMENT_203", propositalmente, como exemplo do resultado exibido sem informarmos
nomes mais significativos. Para alterá-lo, vá ao Outline e clique direito no único objeto "Table" abaixo de Body, dando o nome
"Funcionários". A lista do exportador exibe uma relação de Tables existente no relatório.
549
Capítulo F20
#12. Se deixarmos o formato default UTF-8, pode ser que tenhamos problemas com acento para
edição. Por este motivo, pode ser que o usuário tenha que informar o formato alternativo "ISO-
8859-1" (Latin 1), como mostra a figura. Apesar de desajeitado na primeira vez, o BIRT Viewer
mantém esta informação em caching, para as subseqüentes.
#13. Veja as diversas operações de separadores existentes. Pode-se variar conforme o interesse.
Clique em "Ok" e em seguida em Open (ou Abrir) para consultar os dados exportados.
2. Clique agora em "Export Report". Veja que as opções que utilizamos anteriormente estão aqui
disponíveis para que o usuário em tempo de execução possa acioná-las!
Figura F20.7. Exportação de relatórios para vários formatos, para usuários finais.
3. Clique nas demais opções para entender o recurso de impressão. Se estiver com o Application
Server local (como é o caso em desenvolvimento) não haverá diferença entre os dois tipos de
impressão, mas para impressões corporativas, muitas vezes em formulários especiais, a última
opção é bastante apropriada.
*
No caso dos Drivers JDBC, pode-se variar o nome da classe em alguns casos, para utilizar duas grandes versões de um mesmo
Driver, simultaneamente. Mas, na prática, também ocorrem limitações em versões menores - o que ameniza é o fato de que este é um
recurso mais simples e estável quando comparado, por exemplo, a bibliotecas de runtime de um motor de relatórios extenso como o
BIRT.
550
Utilizando o jCompany BIRT Viewer
Como uma mesma instância de Application Server pode conviver com dezenas de aplicações
jCompany* - e como a evolução do Eclipse BIRT em si ainda é intensa e o mercado altamente rico
e competitivo, a probabilidade de que venhamos a precisar de uma convivência entre diferentes
versões é alta.
Felizmente, o Eclipse BIRT provê as funções que vimos no Viewer como uma aplicação
independente, que pode ser compartilhada para executar relatórios presentes em
diversas outras aplicações. Pode-se, inclusive, ter mais de uma versão desta aplicação em
produção, para permitir o reúso por diferentes versões de projetos.
O jCompany FS Framework traz uma versão aprimorada deste aplicativo chamada jCompany
BIRT Viewer, inclusive com traduções dos rótulos e mensagens para português†, que é
homologada para disponibilizar relatórios em duas modalidades diferentes, como veremos mais
adiante.
o Flexibilidade para liberação de relatórios AD-HOC.
No mundo real, relatórios estão entre os requisitos que mais se alteram. Na medida em que
usuários exploram novas aplicações, demandas por extrações de dados diferentes das
originalmente requisitadas, ou mais sofisticadas, passam a entupir listas de demandas (backlogs)
das áreas de desenvolvimento.
O Eclipse BIRT já contribui para diminuir em boa parte este gargalo, quando permite aos usuários
exportarem dados para Excel ou outros aplicativos de manipulação - mas ainda restarão casos
mais complexos, onde a demanda por manutenção será inevitável - ou não?
É possível minimizarmos este desperdício liberando, de forma embalada nas aplicações,
somente um mínimo essencial (talvez exigido legalmente) de relatórios. A partir da
implantação da aplicação, em um esquema mais ágil, desenvolver e liberar novos relatórios "sob
demanda", na medida em que sejam efetivamente requisitados. É uma postura que tende a
produzir uma funcionalidade "enxuta", evitando o trabalho em relatórios que nunca serão
realmente utilizados.
Note que, para se obter esta vantagem, é importante que os relatórios possam ser
embalados de forma independente das aplicações! Se precisarmos reconstruir e liberar toda a
aplicação novamente, um sério problema de controle de versão terá que ser enfrentado. Note que
estamos falando de liberar um ou dois novos relatórios por dia, algo plenamente possível com a
produtividade que o Eclipse BIRT oferece.
Também para este caso, a arquitetura proposta pelo jCompany para liberação de relatórios é
adequada, como veremos mais adiante.
o Distribuição de processamento de relatórios para evitar gargalos de performance.
Um outro problema sério no mundo real são os níveis de consumo de recursos de memória e
processador, que determinados relatórios costumam exigir - aliás, muito comumente‡!
É preciso entender que a memória e o processador da máquina utilizada para hospedar o
Application Server são recursos compartilhados por várias "Threads" (usuários ativos) e que,
portanto, não há mágica aqui: um único relatório que irá processar 2.000 páginas e
renderizar um PDF ao final, por exemplo, pode ser suficiente para consumir 90% de
recursos de um servidor durante uma hora, digamos§. Durante este período, este único
relatório tornará em um sofrimento o trabalho de outros 200 usuários que, fora isso, estariam
utilizando suas transações OLTP com ótima performance.
*
Estamos nos referindo ao jCompany porque, com a arquitetura que o framework provê, há uma considerável otimização default de
memória. Conhecemos casos reais com quase 20 aplicações corporativas em produção, em uma única instância de Tomcat, com 2BG
RAM e acessos de nível mediano a este grupo (500 usuários ao todo). É possível, no entanto, em uma arquitetura artesanal, mesmo
com baixo acesso, consumir-se recursos de memória e processador que não permitam esta extrapolação.
†
O arquivo com traduções foi cedido como contribuição para a comunidade Eclipse BIRT, mas ainda não havia sido incorporada, no
momento desta escrita.
‡
Já testemunhamos três ou quatro casos reais de problemas críticos de quedas de Application Server em produção, originados por
relatórios que, eventualmente, realizavam consultas sem os filtros devidos (às 16:00 horas da tarde!) fazendo uma varredura (Full
Scan) que ocupava mais de 1GB de RAM da memória - suficiente para derrubar todos os demais usuários.
§
Os números de usuários e quantidade de recursos são hipotéticos, naturalmente, mas plausíveis.
551
Capítulo F20
Portanto, haverá que se tomar uma decisão a este respeito, evitando que determinados relatórios
sejam disparados em determinados horários "de pico", ou utilizando-se uma solução de servidor de
relatórios como o eCompany Reports*.
Uma solução provisória para quem não pode contar com uma solução dedicada para esta área é
liberar relatórios pesados em uma instância diferente de Application Server, deste modo deixando
relatórios concorrerem com outros relatórios somente†.
Cientes da problemática, vamos compreender agora as quatro opções de embalagem de relatórios BIRT
disponíveis na arquitetura proposta pelo jCompany:
1. Relatórios embalados com a aplicação, mas servidos via jCompany BIRT Viewer.
Esta é uma opção recomendada para relatórios estáveis, que tendem a não ser alterados - e
também que não sejam em demasiado pesados, já que irão executar no mesmo servidor da
aplicação. É possível realizar programações para impedir disparos em horários de picos, se for
necessário.
Iremos utilizar esta opção ainda neste capítulo, para nosso primeiro relatório.
2. Relatórios disponibilizados fora da aplicação, possivelmente embalados dentro do
jCompany BIRT Viewer.
Esta é a opção recomendada para relatórios desenvolvidos "sob demanda" (AD-HOC), ou cuja
natureza e complexidade sugiram a possível demanda por ajustes constantes. Um outro motivo é a
possível separação destes relatórios para outro servidor (fora do cluster principal que executa a
aplicação), para evitar os problemas de concorrência.
Também iremos explorar esta solução neste capítulo.
3. Relatórios embalados com a aplicação, e servidos diretamente (sem passarem pelo
jCompany BIRT Viewer).
Esta opção cairia nos problemas de embalagem que discutimos anteriormente. Apesar de possível,
não a discutiremos neste livro.
4. Relatórios utilizados via eCompany Reports.
Esta é nossa sugestão ideal para ambientes robustos, com centenas ou milhares de relatórios e
usuários. Porém também foge ao nosso escopo neste livro.
2. Troque seu nome para "plcVis" (apenas para não usar referências muito grandes em URLs, em
tempo de produção). O resultado deve ser como o da Figura F20.8.
*
O eCompany Reports é um produto comercializado em modalidade Open-Source gerenciada pela Powerlogic, integrante da suíte
Powerlogic jALM, que oferece um "Portal de Relatórios" com capacidade para coletar parâmetros de usuários e executar relatórios de
forma escalonada (à noite ou periodicamente, em determinadas "janelas de tempo"). Deste modo, permite que se faça uma gestão
deste problema, com flexibilidade, em tempo de execução.
†
Em empresas que utilizam Application Servers comerciais tais como Websphere, Oracle ou Weblogic, não há necessidade de
licenciamento para esta outra máquina - como irão basicamente utilizar JDBC em pools de conexão contra um SGBD-R, os serviços de
relatório não exigem APIs Java EE que justifiquem um novo licenciamento, somente para este fim.
552
Utilizando o jCompany BIRT Viewer
#3. Bibliotecas reutilizadas pelo BIRT Viewer. Repare que a o Viewer tem mais de 60MB no total,
mas liberado desta forma é reutilizado por várias aplicações.
<Context displayName="plcVis"
docBase="plcVis"
path="plcVis"
privileged="true" swallowOutput="off">
</Context>
Código F20.1. Arquivos de contexto para aplicativo "plcVis".
*
Desta forma, ficamos com dois pools de conexão para um mesmo SGBD, um para a aplicação e outro para relatórios. Em produção,
seria necessário alterar parâmetros "maxActive", "maxIdle", etc., para ajustar o tamanho de recursos que serão usados no pool, para
cada caso.
Outra opção seria definir um pool de conexões "rhtutorial" global, reutilizado por ambas as aplicações. Este tipo de recurso pode ser
definido, no caso do Tomcat, no arquivo "conf/context.xml".
†
Se 8080 for a porta utilizada. Se ocorrer erro, tente http://localhost/plcVis.
553
Capítulo F20
Obs.: Esta página não será exibida para usuário durante a execução de relatórios, serve apenas
para conferência da instalação e de versões.
6. Clique em "View Example", para agora testar a execução de um relatório. Este novo teste garante
que tudo está em ordem também nas bibliotecas de Runtime.
Importante: Uma janela requerendo autenticação deverá ser exibida, o que indica que estamos na
versão customizada do jCompany! Note que ela não traz a pele que criamos, e isto nem será
necessário - esta janela não será exibida quando chamamos os relatórios da aplicação, porque
trabalharemos com uma configuração de “single signon” do Tomcat (qualquer outro Application
Server de mercado também irá oferecer esta opção).
#1. Perceba que, tal como o jCompany, o Eclipse BIRT também utiliza URLs RESTful. Isso significa
que qualquer execução de relatório pode ser disparada com hiperlinks, inclusive com passagem
de parâmetros, com as vantagens de uso de "Favoritos", "História do Usuário", "Envio por e-
mail", etc..
#4. O parâmetro passado na URL é aqui exibido, indicando que foi recebido e renderizado
apropriadamente.
554
Utilizando o jCompany BIRT Viewer
7. Agora edite a URL, retirando a parte que passa o argumento "&sample=my+parameter". Confira
com a Figura F20.11.
#2. O parâmetro de URL "__report" (assim mesmo, com dois sublinhados) permite que se passe a
localização de um arquivo de relatório com sufixo ".rptdesign"*.
#3. No caso, o arquivo "test.rptdesign" está na raiz do projeto "plcVis", por isto pode ser
chamado somente a partir do nome, sem qualificação de diretórios.
#4. Note que, quando omitimos o parâmetro "sample" da URL, a janela de parâmetros aparece,
requisitando o valor interativamente ao usuário! Esta facilidade do BIRT Viewer permite que o
mesmo seja utilizado também para execução direta (com todos os parâmetros conhecidos e
passados via URL).
*
Este arquivo é o único necessário, em tempo de execução. Um outro arquivo com sufixo ".rptconfig" existirá em tempo de
desenvolvimento, mas não precisa ser disponibilizado para execução.
555
Capítulo F20
#1. A opção deve ser colocada no bloco "app.m.inicial", somente visível para usuários com papel
"Administrador"*.
#3. Note que esta chamada é diferente das demais que fizemos até agora, pois irá chamar uma
transação de outra aplicação (porém no mesmo Application Server), o BIRT Viewer. Para isso, o
endereço de chamada relativo deve estar como indicado, com três blocos de retorno “../”. Isso
porque temos que retornar para “webapp” de “webapp/rhtutorial/f/t”.
#4. Nesta passagem de parâmetro, o arquivo de relatório é passado em esquema inverso: como
endereço "de retorno" (Callback), para que o BIRT Viewer localize o arquivo que está dentro do
"rhtutorial". Neste caso, um único retorno é suficiente.
Note que com esta técnica nós "terceirizamos" execuções de relatório para o BIRT Viewer,
enquanto preservamos os arquivos de relatórios em si, encapsulados na aplicação.
2. Realize uma "Liberação Rápida com Reinício" e teste a execução do relatório, clicando no item de
menu.
“rhtutorial/rel/auditoriaFuncionario.rptdesign” ou
“rhtutorial/rel/funcionario/auditoriaFuncionario.rptdesign”.
o Relatório somente para quem possui a role “RHTUTORIAL_PLANOPROJETO”:
“rhtutorial/projeto/planoProjeto.rptdesign” ou
“rhtutorial/planoProjeto/plano.rptdesign”.
Note que, no primeiro caso, a role coincide com o nome do arquivo. Já no segundo, com o
nome do primeiro diretório abaixo do escopo da aplicação. Deste modo, pode-se registrar
segurança especial para um arquivo, ou definir para grupos de arquivos.
*
Lembre-se: esconder os itens de menu é apenas "conforto visual", não ainda "segurança".
†
Note que, para utilizarmos a segurança com o primeiro padrão, precisamos necessariamente incluir o relatório abaixo do diretório
"/rel", na raiz do projeto. Se incluirmos em outra pasta, a segurança por convenção de diretórios atuará primeiro.
556
Utilizando o jCompany BIRT Viewer
Importante: Note que estamos pensando do ponto de vista do projeto em seu formato de
execução (WAR ou EAR). Para que um diretório “/rel” seja apresentando logo abaixo de
“rhtutorial” no WAR file, por exemplo, nós tivemos que incluí-lo abaixo de “src/main/webapp”,
em tempo de desenvolvimento, segundo o padrão Maven.
1. Mude o relatório do atual diretório “/rel” para outro, digamos,
“/administrador/auditoriaFuncionario.rptdesign”, e criar uma nova role
“RHTUTORIAL_ADMINISTRADOR” no arquivo “[tomcat]/conf/tomcat-users.xml”,
atribuindo-a somente para usuários do grupo “Administrador”*.
2. Reinicie o Tomcat para que pegue a nova política de controle de acesso. Agora tente se autenticar
com um usuário que não seja um Administrador. O menu para acesso à auditoria não irá aparecer,
mas tente informar a URL de acesso ao relatório diretamente. Uma mensagem de restrição ao
acesso deverá aparecer.
Repare que a página de autenticação é exibida e, a partir daí a execução ocorre normalmente - já
que o relatório não dependente de nenhum recurso interno a aplicação‡. Esta é uma
*
Em nosso caso mais simples, para atender à especificação, teríamos que nos lembrar de incluir todos os usuários da role
“Administrador”, também na role “RHTUTORIAL_ADMINISTRADOR”. Mas note que, em um sistema de controle de acesso mais
sofisticado como provido pelo jCompany Security, teríamos o conceito de “grupos”, além do de “roles” (papéis) e “usuários” – o que
nos permitiria criar um “grupo” Administrador, contendo as duas roles, evitando esquecimentos básicos por parte de responsável pelo
cadastro da segurança.
†
Quando relatórios AD-HOC (desenvolvimento e liberados em taxa diária) são liberados juntamente com uma aplicação (WAR ou EAR),
a preocupação com o controle de versão se torna imensa (será que todos os artefatos são exatamente os mesmos atualmente
liberados?). Além disso, o tempo de liberação é maior e, por melhor que seja o recursos de "Hot-Deploy" dos Application Servers,
haverá sempre uma ligeira "congelada" e até eventual perda de alguma transação por parte de usuários, no momento da liberação.
Quando liberados de forma isolada, este risco é consideravelmente mitigado.
‡
Tanto o jCompany quando o BIRT Viewer possuem recursos para se utilizar classes mapeadas com Hibernate/JPA como Data Source.
Este caminho, no entanto, traz poucas vantagens que não compensam a grande perda de produtividade e o acoplamento que esta
estratégia cria, do relatório com a aplicação. Como o modelo relacional é extremamente eficiente para a produção de relatórios - e não
haverá codificação em 99% dos casos, o uso de OO aqui é desnecessário.
557
Capítulo F20
excepcional vantagem, pois nos permitirá estabelecer uma estratégia de BI (Business Inteligence)
com o Eclipse BIRT - que pode gerenciar relatórios, cubos, gráficos, etc., de forma separada da
aplicação.
4. Mova agora o relatório para um novo diretório “/administrador”, a ser criado abaixo da raiz de
“plcVis”. Tente, em seguida, chamá-lo com
http://localhost:8080/plcVis/frameset?__report=administrador/auditoriaFuncionario.rptdesign.
Uma mensagem de restrição ao acesso irá ser exibida, mesmo que estejamos com o usuário que
possua a role “RHTUTORIAL_ADMINISTRADOR”. Isso porque não estamos mais com o relatório
embalado dentro da aplicação. No caso de liberações isoladas no BIRT Viewer, deve-se dispensar o
prefixo da aplicação, utilizando-se apenas “ADMINISTRADOR”, neste caso (nome de um arquivo ou
do primeiro diretório que contenha arquivos de relatórios, mas sem o prefixo com nome da
aplicação!).
2. Inclua uma chamada para o bloco de menu genérico "jcompany.m.dinamico.jsf", na barra inicial
de menu, antes de "jcompany.m.ajuda.jsf".
558
Utilizando o jCompany BIRT Viewer
Figura F20.15. Reúso de bloco de menu com opções para menu dinâmico.
3. Faça uma "Liberação Rápida para Tomcat com Reinício" e, após autenticar, utilize o menu Área
Técnica para atualizar o esquema do Banco de Dados.
Figura F20.16. Esquema de criação de nova tabela para persistência de menu dinâmico.
Note que a tabela criada permite, basicamente, a persistência de rótulos e hiperlinks. O framework
irá inspecionar a estrutura de hiperlinks, para aplicar a segurança por convenção de diretórios.
4. Se você está autenticado com usuário com papel "Administrador", o bloco de menu "Dinâmico"
aparecerá contendo a opção "Manutenção do Menu". Chame-a para definirmos os itens de menu
dinâmicos.
5. Preencha um item dinâmico para chamada do relatório externo, conforme a Figura F21.17.
Figura F20.17. Itens de menu para chamadas de relatórios e outros, criados dinamicamente.
#2. Item de menu que permite a criação de demais itens dinamicamente - somente é exibido para
usuários com role “Administrador”.
#3. Os itens criados também são exibidos neste mesmo menu, utilizando os mesmos critérios de
segurança “baseado em diretórios” para relatórios.
559
Capítulo F20
#4. Note que a URL quando informada em menus dinâmicos, deve retroceder um nível a mais, pois
esta transação fica definida no framework em URL no padrão “/f/t/plc”, ou seja, um nível
abaixo das transações da aplicação. Assim, serão necessários quatro “../”.
6. Clique para testar o item de menu “Auditoria”. O relatório deve ser acionado.
Importante: Note que, com a liberdade para se criar itens com hiperlink para o mundo externo da
aplicação e uma arquitetura RESTful plena oferecida com o jCompany, é possível se disponibilizar
"atalhos corporativos" para quaisquer consultas, seleções e edições de documentos da corporação, não
somente relatórios!
#1. Identificador (este Caso de Uso produzirá uma Colaboração que irá basicamente abrir uma
página com argumentos do relatório).
560
Utilizando o jCompany BIRT Viewer
#2. O jCompany suporta também a tecnologia Jasper Reports / iReports, mas ela é considerada
"deprecated" a partir da versão 5.0.
#4. Selecione a Entidade Raiz da agregação que conterá os argumentos necessários para
recuperação do relatório.
#5. Informe "funcionario" para gerar as JSPs de argumento do relatório de auditoria abaixo do
pacote "WEB-INF/jsps/funcionario".
5. Encerre o Assistente de Criação e clique no próximo passo. Edite a JSP para incluir o "intervalo de
datas" e ajustar o nome das propriedades aos nomes dos argumentos do relatório, conforme
definidos no “Report Parameters”. Lembre-se de alterar os rótulos também, para ficarem coerentes.
*
Havia um Product Backlog para esta implementação, no momento da escrita deste livro. Se encontrar uma opção de operador
chamada "Intervalo de Datas", pode tentar utilizá-la.
561
Capítulo F20
#2. Explicite os tamanhos dos campos (já que, sem que exista uma propriedade com nome
correspondente na Entidade, eles não poderão ser herdados).
#3. Copie a célula de “data de início” para uma para a “data de fim”, e altere sufixos, para rótulos,
id e ajuda.
#4. Altere o nome da data de fim para “dataUltAlteracaoFimArg” (também o mesmo do BIRT).
7. Siga para o próximo passo, para editar artefatos da camada Controle. Edite o arquivo de metadados,
para realizar pequenos ajustes.
#1. Inclua um prefixo “rel” ou “administrador”, conforme o diretório onde se encontre o relatório,
no “plcVis”.
*
Relembrando: o jCompany IDE gera as chamadas sempre no último bloco de menu encontrado.
562
Utilizando o jCompany BIRT Viewer
#3. Crie um novo argumento para a data fim com nome “dataUltAlteracaoFimArg” e operador
MENOR_OU_IGUAL_QUE.
8. Faça uma "Liberação Rápida para Tomcat com Reinicialização" e acione o novo item de menu.
Informe os argumentos e clique em "Gerar Relatório". Veja que o relatório já será executado
imediatamente, sem o diálogo de parâmetros do BIRT, pois o jCompany já os compõe na URL,
apropriadamente.
*
Sempre pressupomos um ambiente de produção configurado com Cluster, ou seja, com dois ou mais servidores paralelos contendo
instâncias idênticas do Application Server e das aplicações, funcionando com solução de balanceamento de carga, login unificado e
tolerância à falhas.
563
Capítulo F20
Sumário
Neste capítulo, conhecemos as diversas opções que o aplicativo de visualização de relatórios do Eclipse
BIRT provê, para usuários finais, desde a renderização em vários formatos (HTML, PDF, PPT, XLS, etc.),
até a exportação de dados e impressão no cliente ou servidor.
Conhecemos também as facilidades disponíveis no jCompany para liberação de relatórios em diversas
arquiteturas distintas, em tempo de execução, seja de forma embutida na aplicação, seja de forma
independente e flexível, mais condizente com uma estratégia de Business Intelligence.
No próximo capítulo, iremos implementar um novo Caso de Uso através do Eclipse BIRT, que nos
permitirá conhecer recursos tais como agrupamentos, quebras e gráficos.
564
Utilizando o jCompany BIRT Viewer
565
Capítulo
21
Relatórios com quebras e
1
2
F
gráficos
- Entendendo a especificação
O próximo relatório que iremos desenvolver nos exigirá novos conhecimentos, para implementar alguns
requisitos bastante comuns nesta área:
o Agrupamentos hierarquizados de conjuntos de dados, com totalizações nas “quebras” (mudanças de
grupos).
o Gráficos sensíveis ao contexto (que podem ser exibidos para todo o relatório ou de forma recorrente,
para cada grupo).
A especificação nos diz para desenvolver um relatório “BIRT” com nome “folhapagamento.rptdesign”
para atender a este Caso de Uso. Devemos receber um “Mês de Referência” e recuperar todos os
proventos e descontos do tipo “SF” (Salário Final) e “IR” (Imposto de Renda), ambos calculados na rotina
de Folha de Pagamento.
Agruparemos funcionários em suas Unidades Organizacionais, totalizando salário por estas unidades.
Iremos, por fim, prover um total geral e um gráfico contendo uma torta, de “Total de Salários por
Unidade”.
3. Desta vez iremos utilizar o modelo “jCompany – Relatório Mínimo”. Este modelo não traz estruturas
pré-montadas, exceto na Master Page. Basicamente provê estilos para reuso.
566
Relatórios com quebras e gráficos
4. Após clicar em “Finish”, edite o Data Source na aba “Data Explorer” e complemente o nome do
endereço JNDI para o pool de conexões para “java:comp/env/jdbc/rhtutorial”, como fizemos
para o relatório anterior*. Teste a conexão em seguida.
5. Crie um novo Data Set, com nome FolhaPagamento, confeccionando um SQL como o da Figura
F21.3.
#1. Colunas necessárias, utilizando “alias” desta vez, para despoluir a cláusula.
#2. A situação deve ser “A”, já que “Funcionario” usa exclusão lógica.
#4. Vamos receber um único parâmetro que conterá uma data com “01” no dia e mês/ano de
referência. Como gravamos todos os proventos e descontos com este dia “01”, não será preciso
um intervalo de datas.
*
Reforçando que, para evitar esta definição redundante, deve-se criar um “.rptlibrary” em escopo do projeto. Consulte a
documentação do BIRT para este fim, já que não faz parte de nosso escopo neste livro.
567
Capítulo F21
6. Passe para a opção “Output” e informe os rótulos mais significativos, para melhorar o entendimento
para Desenvolvedores e também usuários finais, nas exportações de dados.
7. Passe agora para a opção de “Parameters”. Como da outra vez, um parâmetro foi
automaticamente criado pelo BIRT para o Data Set, já que informamos uma interrogação “?”
em nossa cláusula SQL. Precisaremos somente vinculá-lo a um parâmetro do relatório. Neste
modelo que usamos, no entanto, não há parâmetros pré-definidos para o relatório - teremos então
que criá-lo, seguindo instruções da Figura F21.5.
#2. Aperte no ícone “fx” em “Linked do Report Parameter”, para criar um novo parâmetro de
relatório vinculado ao parâmetro do Data Set.
#3. Informe as opções da esquerda, de modo similar ao que vimos no último relatório.
#4. Customize o formato da data para estes argumentos, clicando em “Change -> Custom”.
Informe “MM/yyyy” para requerer mês e ano conforme viemos utilizando.
Importante: Note que nossa cláusula SQL somente irá recuperar o período apropriadamente
porque tanto o jCompany quanto o BIRT incluem “01” no dia, quando a data informada não
recebe um valor para dia.
#5. É recomendável informar um valor default para orientar ainda melhor ao usuário sobre o
formato de entrada, especialmente porque o formato do BIRT não provê uma máscara
Javascript, como no jCompany (ou seja, o usuário deve informar as barras).
568
Relatórios com quebras e gráficos
8. Faça um “Preview Results”. Se existirem valores calculados para “IR” ou “SF” no período
informado aparecerão os registros.
Figura F21.7. Table criado automaticamente na visão de Layout, a partir do Data Set.
2. Vamos primeiro estruturar o relatório (grupos e totais), para depois formatá-lo, ao final. Crie um
primeiro agrupamento, para “Unidade Organizacional”, clicando direito na linha de cabeçalho
(Header) e acionando “Insert Group”.
569
Capítulo F21
- Ao identificar um primeiro valor diferente do anterior, o Eclipse BIRT irá realizada uma
“quebra de grupo”, o que significa que irá exibir valores em um novo cabeçalho.
Selecione o campo de “Unidade Organizacional” (funciona desde que não tenhamos duas
unidades com o mesmo nome).
#3. Se o campo do agrupamento for de temporalidade (data ou data/hora), o Eclipse BIRT irá
oferecer a possibilidade de se realizar mais de uma quebra para o campo, por ano, mês, dia,
etc..
#4. Informe um valor em “Bookmark”. Discutiremos mais a respeito ainda neste capítulo.
#5. Em “Table of Contents”, basta aceitar o default para que o Eclipse BIRT proveja um índice
hierárquico para acesso simplificado por usuários finais, no BIRT Viewer.
#6. Pode-se definir um estilo para a linha de cabeçalho do agrupamento. Não é necessário em
nosso caso.
#7. Opções de filtragem e ordenação estão disponíveis. Note, porém, que nossa cláusula SQL já
traz os dados com a ordenação necessária. As opções de filtro e ordenação deste diálogo
são realizadas após a recuperação no SGBD sendo. Portanto. bem menos eficazes, de uma
forma geral. Utilize-as apenas para fontes de dados não relacionais, como arquivos
convencionais ou XML, por exemplo.
570
Relatórios com quebras e gráficos
#8. Opção para a ordenação ascendente ou descendente – também sem utilidade para nosso caso,
cuja ordenação está em nível do SQL.
#9. Em “Page Break” pode-se forçar a quebra de uma página, por exemplo, no momento da
quebra de um grupo. Por exemplo, para iniciar uma nova “Unidade Organizacional” sempre em
uma nova página. As opções automáticas devem ser experimentadas antes, para ver se já não
atendem ao resultado esperado.
4. Na visão de Layout, retire agora o campo “Unidade Organizacional” da linha de detalhe. Repare que
ele foi criado na linha de agrupamento no cabeçalho, o que impedirá que seja exibido
repetidamente.
5. Realize um novo “Preview”. Confira o resultado, agora com “quebra” por Unidade Organizacional.
6. Vamos agora criar um segundo grupo, para Funcionários, para eliminar a repetição acima. Clique
direito na linha de cabeçalho do grupo 1 e crie um novo grupo, abaixo deste, usando “Insert Group
-> Below”.
7. Preencha o novo grupo, cuidando agora para definir a quebra não pelo nome, mas pelo CPF do
Funcionário. Este valor é mais seguro, uma vez que nomes podem estar duplicados. Já em “Table
of Contents” o valor a ser exibido deve ser alterado para o nome do funcionário (será assumido
CPF, em função do agrupamento – devendo ser alterado).
571
Capítulo F21
Figura F21.13. Definição do segundo grupo. Agrupa por CPF, exibe nome em "Table of Contents".
8. Na visão de Layout, mova agora o nome do funcionário da linha de detalhe para a de cabeçalho do
novo grupo (2), e retire o CPF gerado na primeira coluna. Execute um novo “Preview” e confira
com a Figura F21.14. Note que, desta vez, incluímos um funcionário com mesmo nome (um caso de
homônimos), mas naturalmente com CPFs diferentes, para testar nosso critério de quebra.
572
Relatórios com quebras e gráficos
2. A totalização geral será similar (porém com “Aggregate On -> Table”), mas antes de criá-la
precisamos ajustar definitivamente o leiaute dos cabeçalhos. Comece criando uma nova linha de
nível para o grupo 2, abaixo da atual.
#1. Retorne os campos de detalhe algumas colunas, para melhor aproveitamento do espaço do
relatório.
4. Faça um novo “Preview”. O resultado ainda não é perfeito esteticamente, mas se aproxima mais de
nossa especificação.
573
Capítulo F21
5. Crie duas novas linhas de cabeçalho geral, e inclua dois rótulos “Período:” e “Total Geral:”, na
primeira coluna das duas primeiras linhas. Na terceira, mescle as colunas a partir da segunda –
utilizaremos esta linha para produzir um gráfico, mais adiante. Remova a coluna “Mês Referência”
dos detalhes, já que aparecerá sempre com o mesmo valor (somente recuperamos para um único
período).
6. Copie o parâmetro de relatório “dataPeriodo” para a segunda coluna da primeira linha de cabeçalho
e crie o Aggregation para o total geral, conforme as dicas que demos anteriormente, colocando-o na
segunda linha do cabeçalho. Exclua o rótulo e campo para “Natureza” e mova o “Valor” para sua
coluna (poderíamos já ter retirado a coluna nos passos anteriores, mas estamos fazendo estas
operações por partes, para facilitar o acompanhamento). Confira.
7. Note que, com o último passo, toda a estrutura de dados que precisamos informar - à exceção do
gráfico - já existe no relatório. Precisamos, no entanto, aprimorar o seu leiaute, tornando as
endentações mais claras, dentre outra melhorias.
Inicie excluindo o rótulo “Funcionário” e, para melhor endentação, concatenando o rótulo “Nome:”
ao campo “Funcionário”, conforme a Figura F21.21. Faça o mesmo para CPF.
Note que esta técnica irá nos impedir de aplicar estilos diferenciados para o rótulo e o campo, mas
traz como vantagem um agrupamento mais rígido entre estes dois objetos. Em nosso caso,
poderemos utilizá-la.
Obs.: Sempre use textos (String) com aspas simples nas expressões BIRT, no padrão Javascript.
574
Relatórios com quebras e gráficos
2. Agora marque os dois campos agregados e vamos formatá-los como dinheiro (uma vez que os
estilos que utilizamos para eles já não trazem esta formatação). Selecione “Format Number” na
pasta “Property Editor – Data” e selecione “Custom” em “Format As”.
3. Selecione as células que contêm os campos de totais, para alinharmos estes valores à direita, como
deve ser para valores monetários. Lembre-se de que é possível se utilizar o mouse no layout ou
selecionar via Outline. Confira com a Figura F21.24.
575
Capítulo F21
4. Agora marque a primeira coluna da tabela. Marque para que tenha o tamanho exato de 150 pixels*
para garantir que seu tamanho não seja superestimado pelo BIRT.
*
Se preferir, pode usar o leiaute com outra escala. Porém, o uso de “cm” (centímetros) apresentou alguns problemas na versão
utilizada neste livro – e o uso de “%” (percentual), um hábito em leiautes HTML, pode não renderizar bem em outros formatos como
PDF e PPT. Fique atento, e teste para o universo de formatos de saída desejado.
576
Relatórios com quebras e gráficos
Figura F21.26. Resultado de relatório com duas quebras com estilos e totais.
577
Capítulo F21
#1. Digite na forma exemplificada ou, preferencialmente, utilize “fx” para selecionar a coluna
“Natureza”.
#4. Para o destaque em si, este diálogo permite associar um novo estilo à linha.
#5. Em nosso caso, altere a cor para “Red” conforme requer a especificação.
3. Clique em “Ok” e faça um novo “Preview”. Agora possuímos nosso relatório finalizado, faltando
apenas o gráfico.
2. Com o relatório renderizado no BIRT Viewer, clique no primeiro ícone da barra de opções, “Table of
Contents”. Note que esta aplicação provê agora uma visão hierarquia da estrutura de agrupamentos
do relatório para os usuários, inclusive com hiperlinks!
578
Relatórios com quebras e gráficos
- “Select Chart Type”: Permite seleções iniciais de tipo e formatos, da galeria disponível.
- “Format Chart”: Permite a formatação das diversas áreas (centro, legenda, título, eixos,
etc.), bem como rótulos, alinhamentos, estilos de formatação e opções de finalização em geral.
#2. Ao centro, é exibida uma visualização das seções típicas de cada gráfico da galeria.
#3. A galeria de gráficos do Eclipse BIRT se expande a cada novo release. Atualmente, possui
gráficos clássicos de torta, barra, linha, e ainda medidores de nível (meter), bolha, gantt e
variações como tubo, cone e pirâmide. Selecione “pie” (Torta) para nosso caso.
#4. Para cada tipo de gráfico, variações de dimensão são disponibilizadas. O default é 2D mas,
eventualmente conforme o tipo, opções de “2D com profundidade” e “3D” estarão disponíveis.
Selecione “2D with Depth” (2D com profundidade).
#5. No que diz respeito ao formato de saída, é interessante notar que, além de formatos de
imagem JPG, BMP ou PNG, o BIRT também possibilita a criação de SVG, que é um formato
vetorial, mais leve, renderizado no cliente (Navegador). Os demais se baseiam em imagens e
são renderizados (criados) no servidor, sendo portanto mais pesados, para criar e baixar. Mas o
SVG costuma costuma ser pouco utilizado por trazer problemas de compatibilidade (exige
certos plugins instalados…) - mas é providencial conforme a demanda específica (para
atualizações de gráficos em ‘tempo real via Ajax’, por exemplo).
579
Capítulo F21
3. Clique em “Next” para vincularmos dados ao nosso gráfico. Informe conforme a Figura F21.32.
#1. Pode-se trabalhar com o gráfico herdando do contêiner, no caso o componente Table, ou usar
diretamente o Data Set (que pode inclusive ser outro, por exemplo, com dados consolidados
via SQL!). Em nosso caso, usaremos o contêiner.
#2. Clique em “Unidade Organizacional” (no botão do cabeçalho da coluna) e arraste para o campo
em “Category Definition”. Note que uma cor azul irá indicar o vínculo. A categoria será
utilizada como critério para “repartir a torta”, neste tipo de gráfico.
#3. Em “Slice Size Definition” (definição do tamanho do pedaço) iremos informar uma fórmula
condicional, que somente soma valores de salários (evitando somar o Imposto de Renda).
Clique em “fx” e digite:
if (row["Natureza"]=='SF') {
row["TotalSalariosPorUnidade"]
}
Note que, com este teste, somente salários são agrupados. Quando a condição não é atendida,
então “zero” é somado.
#4. Não utilizaremos o agrupamento (3ª dimensão) no nosso gráfico. Isso produziria várias tortas
“paralelas”, neste caso.
#5. A amostragem de dados que aparece na tabela em “Data Preview” é a efetivamente utilizada
pelo gráfico. Um erro muito comum é imaginar que os campos Aggregation e outros cálculos
feitos em nível do Table estão disponíveis no gráfico – se não aparecem calculados na
amostragem, o cálculo não terá efeito no gráfico.
#6. É possível se aplicar “filtros” e realizar outras operações sobre os dados herdados do
contêiner.
4. Da forma como está, o comportamento ainda não será o esperado, pois não haverá “agrupamento
por Unidade Organizacional”, para o gráfico! Para obtenção deste efeito, clique no botão de “Group
and Sorting” da “Category Definition” e preencha o diálogo como na Figura F21.33.
580
Relatórios com quebras e gráficos
6. Retorne para a visão de “Layout” e dê um duplo clique no componente de gráfico para tornar a
editar suas propriedades.
7. Clique em “Format Chart” e, em seguida, em “Series -> Value Series”. Realize modificações como
orienta a Figura F21.35.
581
Capítulo F21
Figura F21.35. Opções de formatação para o valor das séries de gráficos de torta.
#1. A Treeview irá variar conforme o tipo de gráfico e outras opções anteriormente escolhidas.
#2. No caso do gráfico de torta, vamos iniciar alterando algumas informações nos valores das
séries (no caso, das “fatias” da torta).
#4. Movimente a barra de rolagem para “Pie Ratio”, para compreender como é possível se alterar o
tamanho e proporção da torta.
#5. Note que é possível se escrever uma expressão para definir a explosão de fatias determinadas.
#6. Em “By Distance”, altere para 2 o valor, para obter uma distância geral entre as fatias.
#7. Pode-se alterar a aparência das fatias, também, utilizando variações de transparência e paleta
de cores.
#8. Em “Leader Lines”, pode-se modificar as linhas que ligam as fatias nos valores.
- “Titles”: Definir um título para a série. Em nosso caso, como temos apenas uma torta, este
título redundaria com o título do gráfico – por isso o padrão é não exibir este título;
- “Interactivity”: Definir eventos tais como hiperlinks para cada fatia da torta, externos ou
internos (para determinadas seções do relatório).
8. Ainda no mesmo diálogo acima, vamos agora formatar os rótulos que aparecem nas fatias, para
conter o símbolo do real “R$”. Clique no botão “Series Label” e siga orientações da Figura F21.36.
582
Relatórios com quebras e gráficos
#1. Clique em “Series Labels” para diversas opções relacionadas aos rótulos das fatias.
#5. Em “Edit Format”, clique em “Standard” e inclua o prefixo “R$ ”, única modificação
necessária, já que as decimais e pontos já vêm configurados corretamente.
Obs.: Experimente também ligar o “Outline” e variar os “insets”, no diálogo “Labels”. Como a
variação é imediatamente refletida na “torta de exemplo”, aprende-se rapidamente com estas
explorações.
9. Clique em “Chart Area -> Title” e troque o título do gráfico por “Salário por Unidade
Organizacional”.
#1. O título pode ser informado diretamente em português e há também opções para I18n, se
necessário.
583
Capítulo F21
#2. Diversas opções para rotação, alinhamento, fontes, etc., estão disponíveis em diálogo para
“Font”.
#3. Outras opções podem ser acionadas nos botões “Text”, “Block” e “Interactivity”. Entre nestas
opções e explore suas possibilidades!
10. Vamos agora ajustar a legenda. Clique em “Chart Area -> Legend”, e em seguida em “Layout”.
Altere a legenda para aparecer abaixo e alinhada à esquerda.
11. Faça um ajuste também em “Chart Area -> Plot”, para contornar a torta.
12. Após os ajustes de legenda e contorno, retorne em “Value Series -> Pie Ratio” para melhorar a
ocupação da torta no espaço.
584
Relatórios com quebras e gráficos
585
Capítulo F21
Sumário
Neste capítulo, conhecemos recursos do Eclipse BIRT para desenvolvimento de agrupamento de dados,
quebras e totalizações por grupos. Além disso, produzimos um primeiro gráfico embutido no relatório,
conhecendo a galeria disponível e as diversas opções disponíveis para vínculo com conjuntos de dados e
formatações das diversas seções dos gráficos.
Com isso, finalizamos todos os Casos de Uso planejados para este livro. No próximo livro desta série,
“Volume II – Tópicos Avançados”, iremos abordar temas como:
o Uso de aplicações distribuídas via protocolos e tecnologias diversas (EJB3, SOAP, RESTful Web-
Services, JMS);
o Casos de Uso “Process-Centric” com fluxos de trabalho definido internamente (máquinas de estados)
ou externamente (BPM engines);
o Integrações com documentos em formatos convencionais (Open-Office, MS Word, Excel, etc.);
o Desenvolvimento Dirigido por Testes (Test-Driven Development) e Testes de Unidade em geral;
o Utilização de camada Bridge (camada arquitetural da empresa);
o Desenvolvimento sobre bases legadas (mapeamento sobre tabelas com chaves compostas, etc.);
o Arquitetura para aplicações multi-contexto (mesma base compartilhada para várias
empresas/departamentos, vários clientes em arquitetura SaaS, etc.);
o Tecnologias Web 2.0: Sindicalização com RDF/RSS, Ajax avançado, Integração com Google Maps,
Analytics, RIAs (Laszlo, Yahoo, ...);
o Hackeando o jCompany: Dicas arquiteturais avançadas sobre como integrar outras tecnologias no
jCompany, alterando padrões existentes. Exemplos de algumas tecnologias alternativas como
“Facelets” em lugar do “Tiles”, “Spring em lugar de JBoss Seam”, “Netbeans em lugar do Eclipse”,
etc.;
o Dentre outros.
586
Relatórios com quebras e gráficos
587
A
Apêndice
Apêndice - jCompany
.
G
588
Licenciado para mauren_ginaldo_souza mauren.souza@powerlogic.com.br
589
I
Apêndice A
Introdução aos Casos
I.
de Uso Padrões
D epois do grande sucesso da conhecida turma da “Gangue dos Quatro’ (Gang of Four), com a larga
aceitação da comunidade das duas edições principais de seu livro “Padrões de Projeto – Soluções
Reutilizáveis de Software Orientado a Objetos” [Gamma, Erich 2000], padrões começaram a ser levados
mais a sério na indústria de software, e a serem utilizados de forma mais abrangente e refinada.
Antes deste aprimoramento cultural, quando as empresas falavam em padrões, queriam dizer “Padrões
de Nomenclatura” para nomes de objetos, métodos, atributos, campos de formulário, URL ou outras
coisas do gênero. Algo importante, mas que não contribuía decisivamente para o objetivo maior:
desenvolver software de qualidade, rapidamente.
Mas de alguns anos para cá, os novos livros sobre “Padrões de Solução” (não “Padrões de
Nomenclatura”) têm trazido luz sobre como o “reuso” pode, de forma pragmática, cumprir parte dos
ganhos prometidos pela Orientação a Objetos.
Em “Organizational Patterns of Agile Software Development” [Coplien, Harrison 2005], os autores
introduzem padrões da seguinte forma:
“Um padrão é um elemento de projeto (design) que é mais comumente atribuído ao arquiteto
Christopher Alexander, que usa uma abordagem baseada em padrões para a construção de
cidades, vizinhanças e edifícios (...). Cada padrão resolve um problema, adicionando estrutura a
um sistema.”
Ref. I.1. James O. Coplien e Neil B. Harrison, em “Organizational Patterns of Agile Software Development”.
Em uma definição básica, um “Padrão de Solução” deve trazer “uma solução para um problema típico,
em um contexto”. Como cada contexto, especialmente em projetos de software, tende a ter nuances
específicas, naturalmente tais padrões deverão ser adaptáveis para serem úteis.
“Padrões capturam uma estrutura comum – usualmente uma muito localizada (...) – sem serem
muito concretos nos detalhes. Isso dá a você flexibilidade para ser criativo”.
Ref. I.2. Jenifer Tidwell em “Design Interfaces – Patterns for Effective Interaction Design”.
590
Introdução aos Casos de Uso Padrões
Uma vez que concordemos com a importância do reúso dos “Padrões de Solução”, precisamos conhecer o
que há disponível. Quais são os contextos contemplados por “Padrões de Solução”, que usamos como
base de partida para os padrões definidos neste documento?
1. O livro clássico “Padrões de Projeto” [Gamma, Erich 2000], através dos conhecidos Design
Patterns GoF, identifica padrões de solução para problemas de programação OO, em
granularidade mais fina e de forma mais abstrata que frameworks, como atestam os seus autores.
As soluções de modelagem identificadas em DDD são, deste modo, “horizontais”, mas não há a
intenção de definirem padrões que cubram todas as visões e camadas necessárias, para estarem em
nível de solução. Ainda assim, define importantes conceitos de modelagem em nível do Modelo de
Domínio, que deveriam ser “excluídas” dos modelos de Caso de Uso.
Para o nosso interesse, é o livro que mais se aproxima de uma sugestão de “Caso de Uso
Padrão”, neste caso chamados de “Casos de Uso CRUD” (manutenção) e “Casos de Uso
Parametrizados” (seleção).
591
Apêndice A-I
592
Introdução aos Casos de Uso Padrões
Portanto, complementamos:
9. O jCompany Patterns & Methods identifica “Padrões de Caso de Uso”, que são padrões de
solução para problemas horizontais de projeto OO, quando o contexto tecnológico é Java
EE, utilizando-se arquitetura MVC.
Abrangência da Solução: Abrange todo o espectro técnico, da Interface com o Usuário aos
Cenários do Caso de Uso e estrutura das Agregações de Domínio.
- Intenção
De um modo geral, todos os padrões que veremos visam padronizar a manipulação de Agregações de
Objetos em geral, incluindo a manutenção de seu ciclo de vida básico (inclusão, alteração, consulta
e exclusão), mas também operações de seleção, impressão, clonagem, assistente (apoio a outras
operações), etc..
Uma grande quantidade de variações típicas, tanto na forma de Extensões Padrões de Caso de Uso
(Uso assíncrono, caso o usuário deseje) quanto de Inclusões Padrões de Caso de Uso, também são
identificadas, deste modo tornando padronizados o uso de Arquivos Anexados, Exclusões Lógicas,
Auditoria (rígida e mínima), Exportação de Dados, dentre outras variantes possíveis.
- Motivações
Quaisquer aplicações de negócio que lidem com dados, especialmente em modelos refinados de OO, com
Modelos de Domínio ricos, irão exigir de Projetistas e Desenvolvedores uma série de decisões repetitivas,
tais como “Qual a melhor Interface com o Usuário para aquele tipo de estrutura?”, “Qual melhor
organização MVC?”, “Como obter a maior generalização possível, mantendo a flexibilidade?”, etc..
593
Apêndice A-I
Na maior parte das vezes, estas questões estão longe de ser “as perguntas chave para inovação”
em uma aplicação de negócio, e devem ser entendidas como “commodity”. Isto porque é possível
se definir um padrão de solução próximo ao ideal para estes casos, que funcione em qualquer vertical de
negócios - que possa atingir o ideal com pouco índice de customização.
Ao padronizarmos e automatizarmos esta solução, melhoramos não somente a produtividade na sua
implementação, mas também a qualidade, performance e escalabilidade do resultado final.
- Aplicabilidade
Utilize os Padrões de Caso de Uso, em sua forma original ou com ajustes de contextualização, para a
parcela de transações “de Manutenção de Ciclo de Vida de Agregações de Objetos”, presentes em
grande número em aplicações empresariais.
Manter Classe Este Caso de Uso prevê a manutenção de todos os objetos de uma
classe, de uma só vez. Por isso, somente deve ser utilizado em
classes com poucos objetos.
Manter Agregação Simples Este Caso de Uso prevê a manutenção de uma “Agregação de
Objetos Simples”, que não envolva composição do tipo Mestre-
Detalhe e variantes.
594
Introdução aos Casos de Uso Padrões
Manter Agregação Consulta- Este Caso de Uso prevê a manutenção de uma “Agregação de
Mestre/Mantém-Detalhe Objetos” que inclua uma composição do tipo Mestre-Detalhe, onde
o Mestre (raiz da agregação) já tenha sido incluído por outro Caso
de Uso Padrão.
Manter Agregação Consulta- Este Caso de Uso prevê a manutenção de uma “Agregação de
Mestre/Mantém-Detalhe- Objetos” que inclua uma composição do tipo Mestre-Detalhe-
SubDetalhe SubDetalhe, onde o Mestre (raiz da agregação) já tenha sido
incluído por outro Caso de Uso Padrão.
Manter Preferência de Aplicação Este Caso de Uso prevê a manutenção de preferências globais
do responsável (administrador) pela aplicação. Também
conhecidos como parâmetros globais.
Manter Preferência de Usuário Este Caso de Uso prevê a manutenção de preferências de cada
(para a Aplicação) usuário para a aplicação, podendo este registrar opções de
personalização de uso ou outras que se façam necessárias.
Consultar Objetos Este Caso de Uso prevê a consulta em formato não otimizado para
impressão (HTML, sem quebras), de coleções de grafos contendo
informações de diversos objetos.
Consultar/Imprimir Este Caso de Uso prevê a consulta em formato otimizado para impressão
Objetos (PDF, com quebras), de coleções de grafos contendo informações de
diversos objetos.
Além destes, existem variações padronizadas e reconhecidas como “Subcasos de Uso Padrões para
Inclusão e Extensão”, abaixo relacionados.
595
Apêndice A-I
Inclui Exclusão Lógica Este Subcaso de Uso provê cenário adicional para a exclusão, que deixa de
ser física (eliminação da agregação) para se tornar uma alteração de
propriedade padrão “sitHistoricoPlc” de “A” (Ativo) para “I” (Inativo).
Agregações onde sitHistoricoPlc=”I” são então consideradas excluídas para
o ponto de vista de usuários.
Inclui Auditoria Rígida Este Subcaso de Uso provê cenário adicional para registrar objetos
contendo “imagens” de dados alterados, incluídos ou excluídos em outras
classes “espelho”, para efeitos de auditoria.
Inclui Auditoria Este Subcaso de Uso provê diversos cenários adicionais que mantém uma
Recursiva auditoria de alterações, porém na mesma classe, através de padrões de
recursividade. É útil quando há possibilidade de se retornar com um estado
anterior de um objeto, com certa freqüência.
Inclui Pesquisa Este Subcaso de Uso provê cenários adicionais que alteram a pesquisa de
Paginada coleções contendo grafos de objetos para evitar que traga registros em
demasiado em seleções de objeto visando edição para manutenção,
limitando a quantidade por página.
Inclui Arquivo Este Subcaso de Uso provê cenários adicionais que permitem a anexação
Anexado (upload) de arquivos e sua recuperação (download) juntamente com a
agregação principal.
Inclui Aprovação Este Subcaso de Uso provê diversos cenários adicionais similares ao da
Auditoria Recursiva, que mantém uma lógica de “fluxo de aprovação”
(workflow) de um nível, mantendo uma agregação nos estados pendente de
aprovação (“P”), aprovada (“A”) ou reprovada/inativa (“I”), permitindo
ainda envio de email de reprovação e republicação de reprovações
anteriores.
596
Introdução aos Casos de Uso Padrões
Extensão Exportação Este Subcaso de Uso provê cenários alternativos (que podem ou não ser
acionados pelo usuário, após uma pesquisa de seleção ou consulta), para
exportação dos dados resultantes para formatos tais como CSV ou XML.
Extensão Assistente Este Subcaso de Uso provê cenários alternativos (que podem ou não ser
acionados pelo usuário, durante a entrada de dados), para acionar
diálogos de assistente de entrada de dados, passo a passo (Wizards).
Extensão Exploração Este Subcaso de Uso provê cenários alternativos que podem ou não ser
de Dados acionados pelo usuário, durante a entrada de dados, para que uma
treeview seja exibida contendo uma hierarquia de dados definida pelo
desenvolvedor, que pode ser utilizada como um menu “alternativo”,
orientado a dados, similar ao Explorador do Windows.
Extensão Detalhe por Este Subcaso de Uso provê cenários alternativos que podem ou não ser
Demanda acionados pelo usuário, provocando a recuperação de coleções de objetos
de detalhe, quando são declarados como “por demanda”.
Cenário Básico (Inclusão) - O usuário chama opção de menu ou clica em opção 'Novo'
- A aplicação dispara 'Antes Inicializar'
- A aplicação inicia o formulário com valores padrões
- A aplicacao disparar 'Apos Inicializar'
- O usuário preenche o formulário e aperta 'Gravar'
- A aplicação valida o formulário para restrições invariáveis e variáveis
- A aplicação dispara 'Antes Incluir'
- A aplicação grava os dados do formulário na Base de Dados
- A aplicação dispara 'Apos Incluir'
- A aplicação exibe mensagem 'Registro gravado com sucesso'
597
Apêndice A-I
Figura I.5. Especificação Lógica que reúso o Padrão de Implementação e especifica “por exceção”.
598
Introdução aos Casos de Uso Padrões
599
Apêndice A-I
Em jCompany, como nosso foco tecnológico é Java EE para Web, os diagramas de Realização de Casos
de Uso Padrões irão introduzir artefatos tais como “JSPs”, “Classes Java para Camadas de Controle,
Modelo e Persistência”, arquivos XML para “Menus”, arquivos de mensagens I18n, etc..
A Figura I.6 exibe, como exemplo, uma visão estrutural da Realização do Caso de Uso “Manter Classe”, o
mais simples dos padrões, utilizando uma Colaboração Padrão “tabular”, contendo rastreamento com
todos os artefatos típicos, agrupados por Camada MVC-P.
Figura I.6. Visão Estrutural Padrão para Realização de “Manter Classe“ - Colaboração “plcTabular”.
Existem vários artefatos presentes no diagrama com multiplicidade mínima “0” (zero), principalmente as
classes Java, significando que são opcionais para que funcione o padrão. Isso porque o jCompany as
generaliza, e não exige especializações se não forem necessárias. Mas arquivos de configuração,
metadados, JSPs, etc., existirão invariavelmente em todos os padrões.
600
Introdução aos Casos de Uso Padrões
Figura I.7. Visão Estrutural Padrão contendo parte comum a todas as Colaborações (Realizações Padrões).
#3. Classe de Controle (Java), opcional. Somente deve ser criada quando for preciso realizar
programações em nível da camada Controle.
#4. Arquivo de configuração de fluxo de navegação e controle (XML). Toda Colaboração Padrão no
jCompany é associada a uma “URL” específica, configurada neste arquivo, juntamente com
sua navegação para as demais.
#5. Classe de Entidade (Java), única classe obrigatória. Deve ser a raiz da Agregação a ser
mantida.
#6. Classe de Serviço (Java), opcional. Somente deve ser criada se for preciso definir “serviços” de
negócio adicionais à “manutenção de Ciclo de Vida”, ou prover implementação de negócio
específica, via extensão da programação genérica.
#7. Classe de Persistência (Java), opcional. Somente deve ser criada se for preciso se
reimplementar a “NamedQuery” de alguma forma que somente funcione via programação (uso
de Criteria do Hibernate, por exemplo).
601
Apêndice A-I
Figura I.8. Visão Estrutural Padrão contendo parte comum a todas as Colaborações (Realizações Padrões).
#2. As Colaborações de Seleção usam sempre dois artefatos JSP, contendo a parte de argumentos
para pesquisa e a de exibição da lista para seleção pelo usuário.
#3. Os metadados de Camada Controle para a Colaboração de Seleção são sempre realizados em
anotações seguindo o padrão de diretório e nomes do diagrama.
#5. Os metadados de Camada Domínio (Comuns) para a Colaboração de Seleção são sempre
realizados em anotações seguindo o padrão de diretório e nomes do diagrama.
Por fim, podemos ver como se organizam hierarquicamente as Colaborações Padrões do jCompany, pela
Figura I.9.
602
Introdução aos Casos de Uso Padrões
Neste diagrama, notamos claramente quais as quatro Colaborações de Manutenção que não
dependem de uma Colaboração de Seleção para Realizar um Caso de Uso Padrão. Vemos também
as seis que dependem.
Outra indicação importante é que a Colaboração de Seleção (“plcSelecao”) especializa a
Colaboração de consulta (“plcConsulta”). Veremos que a única diferença entre as duas é que a
Colaboração de Seleção traz uma “lista de resultado de sua consulta” com hiperlinks para que o
usuário selecione um registro, neste momento comutando para a Colaboração de Manutenção.
Por fim, é interessante notar que há uma padronização de nomes de URLs, que identificam
unicamente uma Colaboração, e que são formadas com base no “alias” do Caso de Uso Padrão que
elas implementam.
Exemplo de Diagrama de Realização de Caso de Uso (Projeto Físico).
Com toda esta fatoração da representação das estruturas invariáveis e generalizadas, conseguimos
chegar a um exemplo de especificação como o da Figura I.10, minimalista.
A Colaboração “plcTabular” da Figura I.10 herda todas as estruturas relacionadas obrigatórias mínimas
na Figura I.6. Por omitir as estruturas opcionais, tais como “Classes Java de Controle, Modelo e
Persistência”, assumimos que neste caso não irá requerê-las.
Portanto, para uma aplicação jCompany, a Figura I.10 é uma especificação de “Projeto Físico” válida e
suficiente para que um Desenvolvedor capacitado produza um resultado com conformidade.
Figura I.10. Diagrama de Realização de Caso de Uso para “UC001.1 Manter UF-“.
603
Apêndice A-I
Há também uma boa parte em comum no aspecto dinâmico entre todas as Colaborações. Poderíamos
tentar representá-la aqui de forma fatorada, como fizemos na Visão Estrutural, mas neste caso julgamos
que a “recomposição mental” das seqüências de execução, para cada Colaboração, seria bastante
dificultada, e vamos optar por apresentar as partes invariáveis de forma redundada, ao longo da
apresentação de cada padrão.
A Figura I.11 mostra uma visão comportamental da implementação do Caso de Uso “Manter Classe”, na
forma de Diagrama de Seqüência simplificado, como serão exibidos em cada Padrão.
Figura I.11. Visão Comportamental Padrão para Realização de “Manter Classe“ - Colaboração “plcTabular”.
- Conseqüências
O uso dos Padrões de Caso de Uso no contexto do jCompany traz pelo menos os seguintes benefícios:
o Aumento da Produtividade já que são eles, em sua maior parte, generalizados pelo framework de
integração, e sua parte variável gerada automaticamente.
o Aumento da Qualidade do resultado, na medida em que há dispensa de codificação excessiva em
Java, e as soluções obtidas são comprovadamente escaláveis e robustas, por serem reutilizadas em
centenas de projetos de natureza diversa.
o Preservação da Produtividade em tempo de manutenção, uma vez que não há geração de
código procedimental Java e tanto os artefatos básicos quanto a programação complementar
seguem padrões que reduzem a variação indesejada que dificulta o entendimento.
o Preservação da Flexibilidade do MVC, uma vez que não se corre o risco de um Desenvolvedor
“com pressa” ou “com desconhecimento” produza soluções que firam as camadas do MVC.
o Melhoria da Usabilidade das Aplicações, uma vez que os padrões de Interface com o Usuário
seguem padrões de ergonomia e usabilidade comprovados.
- Padrões Relacionados
Os Padrões de Caso de Uso são bem complementados por Padrões de Modelagem de Domínio (Domain
Driven Design), e implementados com DP GoF, Java EE e de Interface com o Usuário de mercado.
604
Introdução aos Casos de Uso Padrões
Sumário
Nesta introdução, identificamos os Casos de Uso Padrões, suas variações na forma de Subcasos de
Uso Padrões para Inclusão e Extensão e também padrões de realização (implementação), na
forma de Colaborações Padrões. Discutimos como estes padrões se inserem no “mercado geral dos
Padrões de Solução” e inclusive características e comportamentos genéricos, comuns a todos eles.
Estes padrões são reconhecidos pelos diversos módulos da solução jCompany Developer Suite, que
atuam de forma sinérgica para maximizar a produtividade. Deste modo, enquanto o jCompany FS
Framework possui generalizações de Orientação a Objetos para as partes fatoráveis da implementação
(código Java), o jCompany IDE conduz o desenvolvedor pela construção dos artefatos específicos,
gerando versões apropriadas para os mesmos.
605
II
Apêndice A
Caso de Uso Padrão
I.
"Manter Classe"
- Intenção
Padronizar a manutenção de ciclo de vida de agregações simples ou de uma única classe, com população
pequena e estável o suficiente para permitir recuperação e atualização em todos os seus objetos de uma
só vez (população de até 100 objetos, aproximadamente).
- Motivações
Qualquer aplicação de negócio que lide com dados, em qualquer vertical ou arquitetura que seja, conterá
um bom número de classes cujos objetos “classificam”, “segmentam” ou “agrupam” outros objetos, de
classes mais fundamentais para o negócio. Estas classes normalmente possuem conjuntos finitos de
objetos, sendo de população estável e pequena.
Tais objetos não somente precisarão ser mantidos (incluídos, alterados e excluídos), como a população
total de sua classe precisará ser disponibilizada de forma eficaz para uso em formulários principais do
negócio, tais como pedido, conta-corrente ou cadastro de funcionários. Normalmente, por existirem em
baixo número, estes objetos são apresentados em sua totalidade, através de componentes visuais do tipo
“listas de valores Pull-Down” ou “Combos”.
Muito embora se trate de um dos padrões mais simples que podemos identificar, ele está presente em
um largo espectro de aplicações – e frequentemente sem uma solução generalizada ou mesmo
padronizada em nível da arquitetura. Deste modo, deixa-se ao encargo de cada Desenvolvedor construir
a solução como bem lhe convier e, neste caso específico, normalmente ao encargo de Desenvolvedores
menos experientes (exatamente devido à aparente simplicidade).
Mas a ausência de um padrão resulta em uma grande diversidade de possíveis soluções artesanais,
especialmente quando se fala em Java EE para Web, em arquitetura MVC. E o desconhecimento de toda a
problemática em torno deste tipo de classes costuma conduzir os Desenvolvedores a soluções parciais
e/ou inadequadas, que geram problemas de performance e escalabilidade, como veremos.
Em uma arquitetura pobre, com pouca generalização, o Desenvolvedor será obrigado a definir códigos de
controle, contratos de fachada, implementações de serviço e acesso a dados que permitam as operações
de CRUD, para não ferir a arquitetura MVC, realizando muita programação potencialmente
“generalizável”. Deste modo, o resultado está mais sujeito a erros e a variações que dificultam o seu
entendimento e manutenção subseqüentes, além de variabilidade de padrões de Usabilidade
indesejáveis.
Mas o maior perigo, neste padrão especificamente, reside na forma como o Desenvolvedor irá
disponibilizar as populações de objetos para formulários que os referenciam. Quando um usuário abre um
novo formulário para preenchimento, que possua duas ou três listas (combos) classificatórias, algumas
possibilidades que o Desenvolvedor possui para disponibilizar seus valores são:
1. Fazer duas ou três recuperações ao SGBD para trazer as populações de objetos,
degradando consideravelmente a performance por realizarem transações de persistência
em um simples ato de abertura de formulários. Como estas populações não se alteram com
freqüência, há probabilidade de que em mais de 99% dos casos estas recuperações sejam
absolutamente desnecessárias, criando impacto em ambientes de larga escala.
606
Caso de Uso Padrão "Manter Classe"
2. Recuperar cada população de objetos uma única vez por usuário, mantendo-as a seguir
na memória do servidor, em escopo de sessão. Apesar de evitar recuperações desnecessárias
do mecanismo de Persistência, esta é uma alternativa ainda pior, pois consume um importante e
limitado recurso do servidor – memória RAM - com dezenas de coleções de objetos
redundadas, que não irão variar de usuário para usuário.
3. Recuperar cada população de objetos uma única vez por aplicação, mantendo-as a seguir
na memória do servidor, em escopo de aplicação (ou em caching, como normalmente se refere
a este escopo). Esta é a alternativa mais eficiente, tanto em termos de processamento
quanto de uso de memória, já que esta memória é compartilhada por todos os usuários. Mas a
correta aplicação desta técnica exigirá conhecimentos do Desenvolvedor acerca de problemas de
concorrência em Threads.
Mas para que seja segura (Thread Safety), esta solução deve implementar algoritmos ou
reutilizar frameworks que evitem problemas de integridade possíveis na concorrência
entre atualização e consultas destes dados, no mesmo local de memória. E ao resolver isso, a
solução deverá ainda evitar degradações possíveis neste acesso. Por exemplo, uma solução
simples para o problema da concorrência em Java seria o sequenciamento do acesso à memória via
sincronização dos métodos que a utilizam (syncronized) - mas isto degradaria consideravelmente a
performance, impedindo o paralelismo de acesso a estes dados.
Ao disponibilizar a aplicação em um cluster de servidores, um novo problema surge, sobre como
se distribuir este caching nos demais servidores, quando um usuário altera os dados em
um determinado nó.
Além da problemática da disponibilidade dos dados, um outro problema identificado ocorre na concepção
de formulários para Web, em manutenções deste tipo. Não é incomum encontrar-se páginas que
misturam seleção (listas de todos os objetos para consulta) com a manutenção de um objeto por vez.
Nesta ergonomia, o usuário seleciona um objeto por vez da lista, para alterá-lo ou excluí-lo – e também
submete um objeto por vez.
Esta mistura diminui a produtividade do usuários por impedir a edição simultânea de todos os objetos
como também a performance da aplicação, na medida em que aumenta tráfego na rede e número de
transações, desnecessariamente.
Ao tentar produzir formulários mais adequados, que ofereçam edição simultânea para todos os objetos
(desnormalizados), o Desenvolvedor terá ainda que lidar com problemas do tipo: “O que fará com linhas
em branco, puladas pelo usuário?”; “Como realizar programações complementares em escopo de cada
objeto?”, dentre outros – todos itens trabalhosos quando não são generalizadas.
Portanto, trata-se de um grande risco deixar ao encargo de cada Desenvolvedor conhecer e
resolver toda a problemática supracitada. Mesmo que cada um conheça todas as implicações em
torno deste padrão, haverá ainda uma impressionante variedade de soluções distintas – trazendo perdas
em evolução e manutenção.
Ao padronizarmos e generalizarmos esta solução completa - não somente a manutenção em si,
mas toda a problemática subjacente discutida, melhoramos a produtividade na construção da
solução e também a qualidade, performance e escalabilidade do resultado final.
- Aplicabilidade
Use o padrão “Manter Classe” quando:
o A Classe/Agregação tem população de objetos pequena e estável, de modo que a
manutenção dispense a programação de filtros de recuperação (Como nas Colaborações de Seleção)
e permita manutenção de todos os objetos de uma só vez.
o Toda a população de objetos da Classe/Agregação possa ser exibida em campos do tipo “lista”
(combos), em formulários da aplicação.
o Deseja-se prover formulários com leiautes eficientes para o usuário, mais próximos aos do “mundo
real”, permitindo ao mesmo incluir, excluir e alterar diversos objetos, simultaneamente em uma
única submissão e transação de persistência.
o Deseja-se garantir o mínimo de tráfego na rede, número de requisições ao Application Server,
transações de SGBD e uso de memória do servidor.
- Estrutura e Participantes
o Definição de Cenários em Alto Nível do Caso de Uso:
Cenário Básico (Recuperação) - O usuário chama opção de menu ou clica em opção ‘Pesquisar’
607
Apêndice A-II
o Esquema para Diagrama de Realização Padrão do Caso de Uso: A Figura II.1 mostra um
esquema típico para Diagrama de Projeto Físico, minimalista porém suficiente, para especificar a
implementação de um “Caso de Uso Padrão Manter Classe“. Isso porque todos os detalhes omitidos
são assumidos das versões ancestrais (estereotipadas), com exceção da JSP e da Entidade de
Domínio, artefatos mínimos de dependência específica, que devem ser explicitados.
- Colaborações
o Diagrama de Realização Padrão – Visão Estrutural: A Colaboração “plcTabular” que
implementa nosso Caso de Uso Padrão “Manter Classe” engloba todos os artefatos exibidos na
Figura II.2, representados aqui apenas para efeito didático. Eles não precisam ser explicitados em
uma especificação, por estarem presentes de forma invariável, em toda “Colaboração Padrão”.
608
Caso de Uso Padrão "Manter Classe"
Figura II.2. Visão Estrutural Padrão para Realização de “Manter Classe“ - Colaboração “plcTabular”.
o Diagrama de Realização Padrão – Visão Comportamental: Figura II.3 mostra uma visão
comportamental da implementação do Caso de Uso “Manter Classe”.
609
Apêndice A-II
Figura II.3. Visão Comportamental Padrão para Realização de “Manter Classe“ - Colaboração “plcTabular”.
Exemplo de Diagrama de Projeto Físico. A Figura II.4 mostra um exemplo de especificação de Projeto
Físico para o Caso de Uso “UC001.1 Manter UF-“, de nossa aplicação “RH Tutorial”, seguindo as
convenções até aqui discutidas.
Figura II.4. Diagrama de Realização do Caso de Uso Padrão “UC001.1 Manter UF-“.
- Conseqüências
O uso do Padrão de Caso de Uso “Manter Classe” tem pelo menos os seguintes benefícios:
o Aumento da Produtividade na confecção deste tipo de solução que pode ser realizada, com alta
qualidade, em questão de minutos, partindo-se unicamente da Classe que representa a Entidade de
Domínio.
o Aumento da Qualidade do resultado, na medida em que há dispensa de codificação Java, sendo
toda a lógica MVC “generalizada” no jCompany FS Framework.
o Preservação da Produtividade ao longo do tempo, nas manutenções do sistema, uma vez que
não há geração de código, e somente o uso de quantidade mínima de artefatos, tais como JSP,
rótulos, entrada de menu e declarações de metadados.
610
Caso de Uso Padrão "Manter Classe"
- Padrões Relacionados
Como visto, o padrão “Manter Classe” inclui tratamentos genéricos de caching para a população de
objetos das classes envolvidas, que podem ser utilizados por qualquer outro Caso de Uso Padrão. Neste
caso, basta que se declare o uso destas classes como “Classes de Lookup”, na definição do grafo de
objetos envolvidos no Caso de Uso.
Além disso, o Caso de Uso Padrão “Manter Coleção” (Colaboração “plcCrudTabular”) apresenta uma
similaridade com o padrão atual, mas neste último caso utiliza filtro para trazer uma coleção parcial de
objetos a serem mantidos, e não há utilização do caching. Este padrão será discutido em capítulos
posteriores.
611
Apêndice A-II
Sumário
Neste capítulo, definimos o Caso de Uso Padrão “Manter Classe” e da Colaboração Padrão “plcTabular”
que o implementa para Java EE Open-Source.
612
Caso de Uso Padrão "Manter Classe"
613
Referências Bibliográficas
LIVROS
[Allen, Bambara 2003] Allen, Paul, Joseph Bambara. Sun Certified Enterprise Architect for J2EE. Mac
Graw Hill, 2003
[Astels, David 2003] David Astels. Test-driven Development A Practical Guide. Prentice Hall, 2003
[Astels, Miller, Novak 2002] Astels, David, Granville Miller, Miroslav Novak. Extreme Programming: Guia
Prático. Editora Campus, 2002
[Beck, Kent 2003] Kent Beck. Test-Driven Development By Example. Addison-Wesley 2003
[Bell, Lambros, Ng 2003] Bell, John T., James T. Lambros, Stanford Ng. J2EE Open Source Toolkit :
Building an Enterprise Platform with Open Source Tools (Java Open Source Library).
[Boehm, Barry 2004] Barry Boehm, Richard Turner. Balancing Agility and Discipline. Addison-Wesley,
2004.
[Boock, Jacobsom, Rumbaugh 1998] Astels, David, Granville Miller, Miroslav Novak. Extreme
Programming: Guia Prático. Editora Campus, 2002
[Bye, Britton 2005] IT Architectures and Middleware - 2ª Edição. Peter Bye, Cris Britton, 2005.
[Callaway, Dustin R. 2001] Dustin R. Callaway. Inside Servlets Server-Side Programming for the Java
Platform 2nd Edition. Addison Wesley, 2001
[Carnell, Linwood, Zawadzki 2003] Carnell. John, Jeff Linwood, Maciej Zawadzki. Professional Struts
Aplications. Wrox Press, 2003
[Clark, Mike 2004]Mike Clark. Pragmatic Project Automation. Pragmatic Bookshelf, 2004
[Cockburn, Alistair. 2003] Alistair Cockburn. Escrevendo Casos de Uso Eficazes. Bookman, 2003
[Coplien, Harrison 2005] Coplien, James O., Neil B. Harrison. Organizational Patterns of Agile Software
Development. Prentice Hall, 2005.
[Crane, Pascarello, James 2006] Crane, Dave, Eric Pascarello, Darren James. Ajax In Action. Manning,
2006
[Dai, Mandel, Ryman 2007] Dai, Naci, Lawrence Mandel, Arthur Ryman. Eclipse Web Tools Platform –
Developing Java Web Applications. Addison Wesley, 2007.
[Deepak Alur, John 2000] Core J2EE Patterns. Deepak Alur/John Crupi/Dan Malks. 2000.
[Dudney, Lehr 2003] Dudney, Bill, Jonathan Lehr. Jakarta Pitfalls: Time-Saving Solutions for Struts, Ant,
JUnit, and Cactus (Java Open Source Library). Wiley Publishing, 2003
[Evans, Eric 2004] Domain-Driven Design Tackling Complexity in the Heart of Software. Eric Evans,
2004.
[Fields, Kolb 2000] Fields, Duane K., Mark A. Kolb. Desenvolvendo na Web com Java Server Pages.
Ciência Moderna, 2000t
[Forman, Forman 2005] Forman, Ira R., Nate Forman. Java Reflection in Action. Manning, 2005
[Fowler, Martin 1997] Martin Fowler. Analysis Patterns: Reusable Object Models. Addison Wesley, 1997
[Fowler, Martin 2003] Martin Fowler. Patterns of Enterprise Application Architecture. Addison Wesley,
2003
[Fowler, Martin 2004] Martin Fowler. Refatoração: Aperfeiçoando o Projeto de Código Existente.
Bookman, 2004
[Freeman, Freeman 2004] Freeman, Eric, Elisabeth Freeman. Use a Cabeça!: Padrões de Projetos
(Design Patterns). Alta Books, 2004
[Gallardo, Burnette, McGovern 2003] Gallardo, David, Ed Burnette, Robert McGovern. Eclipse In Action A
Guide for the Java Developer. Manning Publications, 2003
[Gamma, Erich 2000] Padrões de Projeto. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.
Bookman. 2000
614
Referências Bibliográficas
[Graham, Paul 2004] Hackars & Painters. Big Ideas From the Computer Age. O’Reilly. 2004
[Graham, Paul 2004] Paul Graham. Hackars & Painters. Big Ideas >From the Computer Age, O’Reilly,
2004.
[Hansen, Mark D. 2007] Mark D. Hansen. SOA Using Java Web Serviçes. Prentice Hall, 2007.
[Heffelfinger, David R. 2007] David R. Heffelfinge. Java EE 5 Development using GlassFish Application
Server. Packt Publishing, 2007.
[Hendricks, Galbraith, Irani, Milberny, Modi, Tost, Toussaint, Basha, Cable 2002] Hendricks, Mack, Ben
Galbraith, Romin Irani, James Milberny, Tarak Modi, Andre Tost, Alex Toussaint, S. Jeelani Basha, Scott
Cable. Profissional Java Web Services. Alta Books, 2002
[Hruby, Pavel 2006] Model-Driven Design Using Business Patterns. Springer, 2006.
[Husted, Dumoulin, Franciscus, Winterfeldt 2003] Husted, Ted, Cedric Drumoulin, George Franciscus,
David Winterfeldt. Struts In Action Building Web Applications with the Leading Java Framework. Manning
Publications, 2003
[Jacobson, Booch, Rumbaugh 1999] Jacobson, Ivar, Grady Booch, James Rumbaugh. The Unified
Software Development Process. Addison Wesley, 1999.
[Johnson, Rod 2004] Rod Johnson. J2EE Development Without EJB. Wrox, 2004.
[King, Andrew B. 2003] Andrew B. King. Speed Up Your Site – Web Site Optimization. New Riders, 2003.
[Krug, Steve 2000] Steve Krug. Don't Make Me Think: A Common Sense Approach to Web Usability. New
Riders, 2000
[Livingston, Jessica 2007] Jessica Livingston. Founders At Work – Stories Of Startups’ Early Days. Apress,
2007.
[Mann, Kito D. 2005] Kito D. Mann. Java Server Faces in Action. Manning, 2005
[Mason, Mike 2005] Mike Mason. Pragmatic Version Control: Using Subversion. Pragmatic Bookshelf,
2005
[Massol, Husted 2005] Massol, Vicent, Ted Husted. JUnit em Ação. Ciência Moderna, 2005
[McKay, Everett N. 1999] Developing User Interfaces for Microsoft Windows. Microsoft Press, 1999
[Mellor, Scott, UHL, Weise 2005] Mellor, Stephen J., Kendall Scott, Axel UHL, Dirk Weise. MDA Destilada:
Princípios da Arquitetura Orientada por Modelos. Ciência Moderna, 2005
[Menascé, Almeida 2003] Menascè, Daniel A., Virgilio A. F. Almeida. Planejamento de Capacidade para
Serviços na Web. Editora Campus, 2003
[Moddie, Matthew 2006] Matthew Moodie. Pro Apache Tomcat 6. Apress, 2007.
[Mugridge, Cunningham 2005] Mugridge, Rick, Ward Cunningham. Fit For Developing Software –
Framework For Integrated Tests. Prentice Hall, 2005.
[Nisairat, Josph Faisal 2007] Josph Faisal Nisairat. Beginning JBoss from Novice to Professional. Apress,
2007.
[Peh, Hannemann, Reeves, Hague 2006] Peh, Diana, Alethea Hannemann, Paul Reeves, Nola Hague.
BIRT: A Field Guide to Reporting. Addison Wesley, 2006
[Pugh, Gradecki 2004] Pugh, Eric, Joseph D. Gradecki. Professional Hibernate (Programmer to
Programmer). Wiley Publishing, 2004
[Richardson, Chris 2006] Chris Richardson. Pojos In Action – Developing Enterprise Applications With
Lightweight Frameworks. Manning, 2006.
[Richardson, Leonard 2007] Leonard Richardson, Sam Ruby. RESTful Web Services. O’Reilly, 2007.
[Rosenberg, Scott 2007] Scott Rosenberg. Dreaming in Code. , Crown. 2007.
[Rosenfeld, Morville 2002] Rosenfeld, Louis, Peter Morville. Information Architecture for the World Wide
Web – 2nd Edition. O’Reilly, 2002.
[Rosenfeld, Morville 2002] Rosenfeld, Louis, Peter Morville. Information Architecture – 2ª Edição. O’Reilly,
2002.
[Rothman, Johanna 2005] Behind Closed Doors. Secrets of Great Management. Johanna Rothman. Esther
Derby. The Pragmatic Bookshelf. 2005
[Savor, D’Anjou, Fairbrother, Kehn, Kellerman, McCarthy 2003] Shavor, Sherry, Jim D’Anjou, Scott
Fairbrother, Dan Kehn, John Kellerman, Pat McCarthy. The Java Developer´s Guide To Eclipse. Addison
Wesley, 2003
615
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
[Schlossnagle, Theo 2007] Theo Schlossnagle. Scalable Internet Architectures. Developer’s Library, 2007.
[Schwaber, Beedle 2002] Schwaber, Ken, Mike Beedle. Agile Software Development With Scrum. Prentice
Hall, 2002
[Siegel, David 1998] David Siegel. Criando Sites Arassadores na Web. Quark Books, 1998.
[Snyder, Carolyn 2003] Carolyn Snyder. Paper Prototypinhg – The Fast And Easy Way To Design And
Refine User Interfaces. Morgan Kaufmann, 2003.
[Souders, Koechley 2007] Souders, Steve, Nate Koechley. High Performance Web Sites Essential
Knowledge for Frontend Engineers. O'Reilly, 2007.
[Tapscott, Williams 2006] Tapscott, Don, Anthony D. Williams. Wikinomics Como a Colaboração em
Massa Pode Mudar o Seu Negócio. Editora Nova Fronteira, 2006.
[Terry, Shaun 2002] Shaun Terry. Enterprise JMS Programming. M&T Books, 2002
[Tidwell, Jenifer 2006] Jenifer Tidwell. Desegning Interfaces. O’Reilly, 2006.
[Weathersby, French, Bondur, Ttchell, Chatalbasheva 2006] Weathersby, Jason, Don French, Tom
Bondur, Jane Tatchell, Iana Chatalbasheva. Integrating and Extending BIRT. Addison Wesley, 2006.
[Weinschenk, Susan] GUI Design Essentials. Susan Weinschenk, Pamela Jamar, Sarah C. Yeo. 1997
[Yuan, Michael Juntao 2007] Michael Juntao Yuan, Thomas Heute. JBoss Seam Simplicity and Power
Beyond Java EE. Prentice Hall JBoss Series. Prentice Hal , 2007.
HIPERLI NKS
(http://codebetter.com/blogs/david.hayden/archive/2006/08/26/Over_2D00_Architecting-Via-Pure-
Fabrication-and-Indirection-to-Reduce-Coupling.aspx)
(http://domaindrivendesign.org/study/siliconvalleypatterns/svpg_2003-11-25.html)
(http://domaindrivendesign.org/study/siliconvalleypatterns/svpg_2003-12-09.html)
(http://domaindrivendesign.org/study/siliconvalleypatterns/svpg_2004-01-06.html)
(http://domaindrivendesign.org/study/siliconvalleypatterns/svpg_2004-01-13.html)
(http://domaindrivendesign.org/study/siliconvalleypatterns/svpg_2004-01-20.html)
(http://java.sys-con.com/read/284268_p.htm)
‘Google Gears’ vies to be de facto tech for offline Web apps
(http://blogs.zdnet.com/Berlind/?p=504&tag=nl.e540)
6th Sense Metric Overview – Company Vision (http://www.6thsenseanalytics.com/wp-
content/assets/pdfs/6thSenseMetrics.pdf)
Analyzing and Understanding Web 2.0 Apps
(http://www.ddj.com/blog/portal/archives/2007/05/analyzing_and_u.html)
Anders Holmgren “Using Annotations to add Validity Constraints to JavaBeans Properties”
(http://java.sun.com/developer/technicalArticles/J2SE/constraints/annotations.html)
Andrei Cioroianu “Developing Smart Web UIs with Ajax, JSF, and ADF Faces”
(http://www.oracle.com/technology/pub/articles/cioroianu_jsfajax.html?_template=/ocom/technology/co
ntent/print)
Andrei Cioroianu “Using Oracle ADF Faces in Existing JSF Applications”
(http://www.oracle.com/technology/pub/articles/cioroianu_jsfadf_v4.html?_template=/ocom/technology/
content/print)
Andrew Glover “In pursuit of code quality: JUnit 4 vs. TestNG” (http://www-
128.ibm.com/developerworks/java/library/j-cq08296/)
Apache “Comparing Struts 1 and 2” (http://cwiki.apache.org/WW/comparing-struts-1-and-2.html)
Apache “Mailing list archives”
(http://mail-archives.apache.org/mod_mbox/myfaces-
users/200509.mbox/%3Cd045fe00e04a7914a92cb4732abeff74@mac.com%3E)
Apache “Re: the biggest myfaces webapp” (http://www.mail-
archive.com/users@myfaces.apache.org/msg26743.html)
Apache Trinidad “API Changes from Oracle's ADF Faces” (http://incubator.apache.org/adffaces/api-
changes.html)
616
Referências Bibliográficas
617
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
618
Referências Bibliográficas
Managing Success in Offshore Software Development – A Framework for Reclaiming Visibility and Control
(http://www.6thsenseanalytics.com/wp-content/assets/whitepapers/6SA-managing-success-in-offshore-
soft-dev.pdf)
Maps Meet Mashups - Location data mixed with other information on the Web tells who, what, and most
important, where
(http://www.informationweek.com/shared/printableArticleSrc.jhtml?articleID=198001255)
Metrics: Understanding the Software Development Process
(http://www.ddj.com/article/printableArticle.jhtml;jsessionid=DTQYCD5CBUAMSQSNDLPCKH0CJUNN2JV
N?articleID=199900946&dept_url=/dept/debug/)
Michael Yuan “Is JSF really that bad? ”
(http://www.michaelyuan.com/blog/2006/10/23/is-jsf-really-that-bad/)
Migrating Struts Apps to Struts 2 (http://www.infoq.com/articles/converting-struts-2-part1)
Migrating to Struts 2 - Part II (http://www.infoq.com/articles/migrating-struts-2-part2)
Occam's Razor (http://en.wikipedia.org/wiki/Occam%27s_Razor)
OpenLaszlo “"Orbit" Project Frequently Asked Questions” (http://www.openlaszlo.org/orbit/faq)
Oracle Corporation. “Converting From Standard JSF Tags to ADF Faces Tags”
(http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/spec-
diff.html?_template=/ocom/technology/content/print)
Oracle Corporation. “Oracle Application Development Framework Overview”
(http://www.oracle.com/technology/products/jdev/collateral/papers/10g/ADF_overview.pdf)
Oracle Corporation. “Tag library information”
(http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/tagdoc/core
/imageIndex.html?_template=/ocom/technology/content/print)
Oracle Corporation. “Using the ADF Table Component”
(http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/doc/devguide/ta
ble.html?_template=/ocom/technology/content/print)
Oracle Corporation. e Chris Schalk “The JavaServer Faces Managed Bean Facility”
(http://www.oracle.com/technology/tech/java/newsletter/articles/jsf_pojo/index.html?_template=/ocom/
technology/content/print)
Phil Zoio “Building on Struts for Java 5 Users”
(http://www.theserverside.com/tt/articles/content/StrutsforJava5/article.html)
Pitching Agile to Senior Management - Here's a primer on "management speak"
(http://www.ddj.com/article/printableArticle.jhtml;jsessionid=WIOAVK0CSPWTEQSNDLRCKH0CJUNN2JV
N?articleID=199300107&dept_url=/dept/java/)
Processo de Teste de Software - Parte 01
(http://www.imasters.com.br/artigo/6102/des_de_software/processo_de_teste_de_software_-
_parte_01//imprimir/)
Red Hat Service-Oriented Architecture Strategy (http://www.jboss.com/pdf/rh_soa_stategy_04_07.pdf)
Rethinking JSF – The Real Problem – By Joseph Ottinger
(http://www.theserverside.com/tt/articles/content/RethinkingJSF/article.html)
Rich Seeley “There's more to JBoss Seam than it seems”
(http://searchwebservices.techtarget.com/qna/0,289202,sid26_gci1190274,00.html)
Richard Hightower “JSF for nonbelievers: Clearing the FUD about JSF” ( http://www-
128.ibm.com/developerworks/java/library/j-jsf1/)
Rod Coffin “Make the Right Decision with Our Side-by-Side Comparison of Spring and EJB 3.0”
(http://www.devx.com/Java/Article/32314/1954?pf=true)
Rod Coffin “Make the Right Decision with Our Side-by-Side Comparison of Spring and EJB 3.0, Part 2”
(http://www.devx.com/Java/Article/32447/1954?pf=true)
Scott W. Ambler “Scaling Agile Development Via Architecture”
(http://www.agilejournal.com/index2.php?option=com_content&task=view&id=146&pop=1&page=0)
Seam - Contextual Components - A Framework for Enterprise Java
http://docs.jboss.com/seam/2.0.0.GA/reference/en/pdf/seam_reference.pdf
SOA, Web Services, and RESTful Systems - A framework for building RESTful systems
(http://www.ddj.com/article/printableArticle.jhtml?articleID=199902676&dept_url=/dept/webservices/)
619
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
620
Referências Bibliográficas
Turning the Fragile into the Agile – Tool integrations are notoriously fragile; how can we fix this problem
once and for all?
(http://www.agilejournal.com/index2.php?option=com_content&task=view&id=23&Itemid=99999999&p
op=1&page=0)
Using Java to Crack Office 2007 (http://www.infoq.com/articles/cracking-office-2007-with-java)
Using JSF and JSR 168 Portals to Develop Ajax Applications - Jumping aboard the Ajax bandwagon
doesn't mean an easy ride and can be very demanding for IT developers
(http://www.ddj.com/article/printableArticle.jhtml;jsessionid=NTGBESTTSJBA0QSNDLRCKHSCJUNN2JVN
?articleID=198000640&dept_url=/dept/webservices/)
Vance McCarthy “Bringing Open Source to Enterprise”
(http://www.oetrends.com/news.php?action=view_record&idnum=537)
Vendors Duke It Out Over Open Source 'Forking'
(http://searchcio.techtarget.com/originalContent/0,289142,sid19_gci1259981,00.html?track=NL-
48&ad=591640&asrc=EM_NLN_1549695&uid=2745156)
VersionOne, LLC “Agile Development: A Manager’s Roadmap for Success”
(http://www.versionone.net/pdf/Agile_Managers_Roadmap.pdf)
Wendy Smoak “StrutsUpgradeNotes12to13” (http://wiki.apache.org/struts/StrutsUpgradeNotes12to13)
Who's killing SOA?
http://searchsoa.techtarget.com/tip/0,289483,sid26_gci1275920,00.html?track=NL-
110&ad=609428HOUSE&asrc=EM_NLN_2397752&uid=2745156
Writing the Rules (http://www.regdeveloper.co.uk/2007/02/05/writing_rules/print.html)
PALES TR AS
[TS-4619 JavaOne 2006] Merson, Paulo. "How to Represent the Architecture of Your Enterprise
Application Using UML 2.0 and more". JavaOne 2006
621
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
622
Glossário de Termos Técnicos
SIGLAS
Design Patterns: Padrões de Projeto de Programas, normalmente referindo-se aos padrões GoF.
Java EE Design Patterns: Padrões de Projetos de Programas JEE, normalmente referindo-se aos padrões
do livro "Core JEE Patterns" [Alur, Crupi, Malks 2003].
Mainframe: Computador de Grande Porte.
Software: Programa de computador.
Commodity: Produto (Parcela de software, no contexto) necessário mas cujas características são
padronizáveis, não trazendo diferencial competitivo.
Empacotamento "Co-locate": Empacotamento de componentes em um único arquivo (Ex.: WAR), em
contraposição com distribuição de executáveis (Ex.: EJBs ou Web-Services remotos).
623
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
624
Índice de Legendas
Ref. A1.1. Scott Resenberg, em Dreaming in Code [Rosenberg, Scott 2007]. ................................ 21
Figura A1.1. Dimensões de atuação da suíte do jCompany. ........................................................ 24
Figura A1.2. Arquitetura em camadas de uma aplicação Java EE com o jCompany Full Stack
Framework. ........................................................................................................................ 27
Figura A1.3. Arquitetura – Visão de Desenvolvimento. Estratégia similar à Visão de Componentes. .. 28
Figura A1.4. Alguns Casos de Uso, Inclusões e Extensões Padrões do jCompany Patterns & Methods.29
Figura A1.5. Visão estrutural de uma Colaboração, exibindo artefatos Java EE padrões, exigidos para
seu funcionamento............................................................................................................... 30
Figura A1.6. Agregação de Entidades com estereótipos que definem padrões da Arquitetura. .......... 30
Figura A1.7. Padrões de formulário de entrada de dados............................................................ 31
Figura A1.8. Leiautes altamente personalizáveis, incluindo pele e internacionalização. ................... 31
Figura A1.9. Arquitetura de Desenvolvimento de Testes de Unidade. ........................................... 32
Figura A1.10. Itens de configuração controlados no jCompany Developer Suite. ............................ 33
Figura A1.11. Ciclo de vida de gerenciamento de aplicações de software. ..................................... 33
Figura A1.12. Gerenciamento de Ciclo de Vida completo de Aplicações de Software, Open-Source 2.0.
......................................................................................................................................... 35
Figura A2.1. Exemplo da execução manual do instalador do jCompany. ....................................... 45
Figura A2.2. Tela de boas vindas do Assistente de Instalação do jCompany. ................................. 45
Figura A2.3. Diálogo customizado de entrada no Eclipse. ........................................................... 46
Figura A2.4. Versão do Eclipse e acesso a versões de plugins. .................................................... 46
Figura A2.5. Versões detalhadas de plugins homologados no jCompany. ...................................... 47
Figura A2.6. Exemplo do diretório de instalação do Eclipse, abaixo do diretório raiz do jCompany. ... 48
Figura A2.7. Exemplo do diretório de projetos Eclipse, abaixo do diretório “meus_projetos”. ........... 50
Figura A2.8. Bibliotecas do usuário no Eclipse, agrupando JARs no repositório do Maven. ............... 52
Figura A3.1. Subsistemas da Plataforma Eclipse. ...................................................................... 57
Figura A3.2. Arquitetura do ambiente de IDE do jCompany, com base no Eclipse. ......................... 58
Figura A3.3. Acionando o menu “Overview”, para obtenção de ajuda no Eclipse. ........................... 59
Figura A3.4. Diretório separado de instalação de plugins homologados. ....................................... 60
Figura A3.5. Plugin de processo do jCompany, gerando primeira versão de JSP............................. 61
Figura A3.6. Plugin de edição WYSIWYG do Red Hat Studio, especializado para modificações genéricas
de JSP................................................................................................................................ 62
Figura A3.7. Diretório de instalação dos plugins de processo do jCompany (jCompany Artifact
Generator).......................................................................................................................... 62
Figura A3.8. Configuração de filtro para busca textual ............................................................... 63
Figura A3.9. Seleção de filtro para que fique corrente (default)................................................... 63
Figura A3.10. Pesquisa por ‘email’ retornando capítulos da metodologia e base de conhecimento .... 64
Figura A3.11. Pesquisa com Control+F dentro do capítulo para achar termos. ............................... 64
Figura A3.12. Listas de pendências do usuário ou equipe, associadas ou não a linhas de códigos
fontes. ............................................................................................................................... 65
Figura A3.13. Acionamento do roteiro de importação do projeto RHDEMO. ................................... 66
Figura A3.14. Roteiro com instruções passo a passo.................................................................. 66
Figura A3.15. Opção de importação de projetos existentes para a Workspace. .............................. 66
Figura A3.16. Somente projetos jcompany_rhdemojsf, marcados para importação. ....................... 67
Figura A3.17. Projetos de demonstração da aplicação RHDEMO, importados para o Eclipse. ............ 67
Figura A3.18. Serviço Derby ativo, com indicadores em destaque. .............................................. 67
Figura A3.19. Serviço Tomcat ativo, com indicadores em destaque. ............................................ 68
Figura A3.20. Página principal da aplicação “RH Demo”. ............................................................ 68
Figura A3.21. Diálogo de criação do projeto “rhtutorial”............................................................. 69
Figura A3.22. Diálogo de criação do projeto “rhtutorial” preenchido............................................. 70
625
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura A3.23. Arquivo de configuração de pool JDBC padrão para o Tomcat (DBCP). ...................... 70
Figura A3.24. Arquivo de configuração Maven, do projeto. Reparar na versão sugerida e nos módulos.
......................................................................................................................................... 71
Ref. A4.1. [TS-4619 JavaOne 2006] ....................................................................................... 73
Ref. A4.2. [John Klein- “Architecture and Design”] .................................................................... 73
Ref. A4.3. [Haines, Steven 2006] ........................................................................................... 73
Figura A4.1. Arquitetura de software “Invisível”........................................................................ 74
Figura A4.2. Arquitetura de Software “Anêmica”. ...................................................................... 76
Figura A4.3. Arquitetura de Software Corporativa, em nível intermediário. ................................... 76
Figura A4.4. Arquitetura de Software Corporativa com alto nível de maturidade. ........................... 77
Figura A4.5. Arquitetura em camadas de uma aplicação Java EE com o jCompany Full Stack
Framework. ........................................................................................................................ 78
Figura A4.6. Arquitetura de Software do Ambiente de Desenvolvimento (IDE). ............................. 78
Figura A4.7. Arquitetura de Software para desenvolvimento de Testes de Unidade. ....................... 79
Figura A4.8. Organização em camadas.................................................................................... 81
Figura A4.9. Diagramação excessivamente simplificada de arquitetura......................................... 81
Figura A4.10. Melhor diagramação de camadas. ....................................................................... 81
Figura A4.11. Camadas paralelas. .......................................................................................... 82
Figura A4.12. Duas camadas transversais ou ortogonais. ........................................................... 82
Ref. A4.4. Paul Graham, citando E. B. White, em Hackers and Painters [Graham, Paul 2004]. Pág. 212
......................................................................................................................................... 83
Figura A4.13. Visão Geral inicial da arquitetura do jCompany FS Framework................................. 84
Figura A4.14. Visão Geral da Arquitetura do jCompany FS Framework - Aprimorada. ..................... 85
Figura A4.15. Segmentação típica de requisitos de aplicação corporativa...................................... 85
Figura A4.16. Percentual de contribuição do jCompany FS Framework, por natureza de requisitos. .. 86
Figura A4.17. Arquitetura MVC preconizada no J2EE clássico (até EJB 2.1). .................................. 87
Figura A4.18. Arquitetura MVC com camada ortogonal de Domínio. ............................................. 89
Figura A4.19. Arquitetura MVC2-P com dependências ortogonais globais e internas das camadas. ... 90
Figura A4.20. Rearranjo para visualização da camada Ortogonal - “layer”. ................................... 91
Figura A4.21. Projetos de desenvolvimento x arquitetura de camadas MVC-P................................ 92
Figura A4.22. Principais pacotes que segmentam internamente as camadas, dentro de projetos. ..... 93
Figura A4.23. Diagrama de dependência de módulos, em linguagem UML. ................................... 93
Figura A4.24. Dependências do projeto “principal”, geradas no Eclipse......................................... 93
Figura A4.25. Dependências do projeto “modelo”, geradas no Eclipse. ......................................... 94
Figura A4.26. Projeto “comuns” não possui dependências de outros projetos. .............................. 94
Figura A4.27. Dependências entre projetos gerados e jCompany, em tempo de desenvolvimento. ... 94
Figura A4.28. JARs agrupados em bibliotecas do usuário “jCompanyComuns” e “jCompanyControle”.95
Figura A4.29. Dependências entre projetos gerados e jCompany, em tempo de execução............... 96
Figura A4.30. Modelo de Componentes completo em nível macro, para o projeto RH que será
desenvolvido. ...................................................................................................................... 96
Figura A4.31. User Libraries agrupadas por “comuns, controle e modelo”, como dependências Eclipse.
......................................................................................................................................... 97
Figura A4.32. Organização interna do projeto principal “rhtutorial”. ............................................. 98
Figura A4.33. Organização do folder “webapp” do projeto principal “rhtutorial”. ...........................100
Figura A4.34. Organização interna do projeto modelo ”rhtutorial_modelo”...................................103
Figura A4.35Organização interna do projeto modelo ”rhtutorial_comuns”. ...................................105
Figura A5.1. Exemplo das fases de um PDS mais abrangente. ...................................................110
Ref. A5.1. Peter Bye e Cris Britton em “IT Architectures and Middleware”. Pág. 207......................111
Ref. A5.2. Peter Bye e Cris Britton. “IT Architectures and Middleware”. Pág. 206. .........................111
Ref. A5.3. Atribuído a Albert Einstein .....................................................................................112
Figura A5.2. Diagrama do Processo Unificado, destacando em branco uma iteração. .....................112
Figura A5.3. Modelo de Classe de Exemplo. ............................................................................114
Figura A5.4. Grafo de Objetos hipotético, em um determinado “estado” da aplicação. ...................115
Figura A5.5. Exemplo de formulário possível para manter o esquema de objetos da figura 4. .........115
Ref. A5.4. Eric Evans em Domain-Driven Design [Evans, Eric 2004]. Págs. 126-127. ....................116
626
Índice de Legendas
Ref. A5.5. Eric Evans em Domain-Driven Design [Evans, Eric 2004]. Pág. 129. ............................116
Figura A5.6. Formulário único que mantém a Agregação “Funcionário -> Dependentes -> Hist.
Profissional”. ......................................................................................................................117
Figura A5.7. Soluções generalizadas em todas as camadas MVC-P. ............................................117
Ref. A5.6. Alistair Cockburn em “Escrevendo Casos de Uso Eficazes”. Pág. 149. ...........................118
Ref. A5.7. Alistair Cockburn em “Escrevendo Casos de Uso Eficazes”. Pág. 150. ...........................118
Figura A5.8. Casos de Uso Padrões para Manutenção de Ciclo de Vida. .......................................118
Figura A5.9. Casos de Uso Padrões para Exibição. ...................................................................120
Figura A5.10. Subcasos de Uso Padrões para Inclusão..............................................................120
Figura A5.11. Subcasos de Uso Padrões para Extensão.............................................................121
Figura A5.12. Diagrama de Caso de Uso em escopo de Planejamento (Negócio) ...........................122
Figura A5.13.Casos de Uso para a versão 1.0 do “RH Tutorial”...................................................123
Figura A5.14. Casos de Uso para a versão 2.0 do “RH Tutorial"..................................................124
Figura A5.15. Casos de Uso “Concretos” em Nível de Implementação. ........................................126
Figura A5.16. Especificação Lógica “por exceção”, reutilizando o padrão de implementação. ..........127
Figura A5.17. Projeto Físico para Caso de Uso “UC001.1 Manter UF-“. ........................................128
Figura B6.1. Especificação para “UC001.1 Manter UF-“. ............................................................133
Figura B6.2. Diálogo padrão para criação de Classes, no pacote padrão para Entidades de Domínio 134
Figura B6.3. Classe Uf, com ‘abstract’ marcado e superclasse AppBaseEntity ...............................134
Figura B6.4. Classe Java correspondente à Entidade UF, com comentário Javadoc e práticas
recomendadas....................................................................................................................135
Figura B6.5. Acionando control+N sobre a classe Uf, e assistente para Mapeamento Objeto-Relacional.
........................................................................................................................................137
Figura B6.6. Primeiro passo do Assistente de Criação de Mapeamento Objeto-Relacional. ..............137
Figura B6.7. Organização Final do Modelo de Entidades. ...........................................................140
Figura B6.8. Classe de Domínio Uf, após geração de Mapeamento Objeto-Relacional com Plugin
jCompany. .........................................................................................................................140
Figura B6.9. Classe descendente UfEntity, gerada para separar implementações do Desenvolvedor
das informações de Domínio. ................................................................................................141
Figura B6.10. Arquivo hibernate.cfg.xml, gerado com configurações padrões e acrescido da Entidade
recém-mapeada. ................................................................................................................142
Figura B6.11. Opção de “desfazer” geração de mapeamento Objeto-Relacional. ...........................143
Figura B6.12. Validações via Anotações do jCompany (a anotação está deslocada para exibir a
propriedade. ......................................................................................................................144
Figura B6.13. Apertar shift com o cursor do mouse sobre a Anotação exibe suas propriedades. .....144
Figura B6.14. Validações invariáveis declaradas para a propriedade sigla. ...................................144
Figura B6.15. Anotação PlcTabular com propriedade nome como referência de desprezo e teste de
duplicata explícito (apesar de ser default)...............................................................................145
Figura B6.16. Relação de opções de roteiros do jCompany, com seleção do “Manter Classe”. .........146
Figura B6.17. Primeiro passo do Cheat-Sheet com destaque para o botão de ajuda. .....................147
Figura B6.18. Passo Inicial do Assistente de Criação para “Manter Classe”. ..................................147
Figura B6.19. Terceira página do Assistente de Criação do Caso de Uso Padrão “Manter Classe”. ....149
Figura B6.20. Configuração inicial do plugin Red Hat Studio. .....................................................150
Figura B6.21. Arquivo web.xml indicado. ................................................................................150
Figura B6.22. Configuração RHDS. ........................................................................................151
Figura B6.23. Desligando-se validação indevida do RHDS. ........................................................151
Figura B6.24. Editor RHDS, homologado para edições de JSP. ...................................................152
Figura B6.25. Mensagens em vários idiomas editadas simultaneamente, e com mensagens de
validação. ..........................................................................................................................153
Figura B6.26. Editor de menu Tiles do RHDS. ..........................................................................153
Figura B6.27. Visualização do Menu em forma de diagrama, mostrando a herança. O item
“jCompany.m.item” está mais opaco, já que sua definição não se encontra no arquivo atual..........154
Figura B6.28. Editor do Red Hat Studio homologado para arquivos faces-config.xml e struts-
config.xml..........................................................................................................................155
Figura B6.29. Modo gráfico para exibição de fluxos de navegação, representando inicialmente
“Desconexão” e “Manutenção de UF”. ....................................................................................156
627
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura B6.30. Acionando Menu “External Tools” da barra de ícones do Eclipse. .............................157
Figura B6.31. Diálogo do “External Tools” com diversas tarefas Maven genéricas e opções. ...........157
Figura B6.32. Relatório final do Maven sobre a liberação completa (primeira vez, mais demorada)..158
Figura B6.33. Diretórios do Tomcat modificados em destaque....................................................158
Figura B6.34. Para liberação, via Cheat-Sheets ou atalho External Tools, o projeto principal deve estar
em foco. ............................................................................................................................159
Figura B6.35. Duplicando uma tarefa do External Tools. ...........................................................159
Figura B6.36. Criando tarefas específicas de Liberação, com partes modificadas em amarelo. ........159
Figura B6.37. Adicionando Natureza Apache Derby ao projeto. ..................................................160
Figura B6.38. Iniciando serviço do Apache Derby.....................................................................161
Figura B6.39. Indicadores de serviço de Banco de Dados Derby ativo. ........................................161
Figura B6.40. Configurações chave de pool para o Derby. .........................................................161
Figura B6.41. Atalhos para disparo, parada e reinício do Tomcat. ...............................................162
Figura B6.42. Mensagem de serviço HTTP ok. .........................................................................162
Figura B6.43. Página de autenticação, após a chamada da aplicação. .........................................162
Figura B6.44. Página principal com leiaute e apresentação básicos. ............................................164
Figura B6.45. Seleção da pele “iTunes”. Lembre-se de clicar em F12-Gravar para confirmação. ......164
Figura B6.46. Seleção de formulário “Elegante”. Selecionar e clicar em F12-Gravar para confirmar. 165
Figura B6.47. Utilitário especialista em geração de DDL. Obtenção do esquema relacional a partir do
mapeamento O-R................................................................................................................166
Figura B6.48. Conferência de “Atualização” de esquema. Após a execução, nada mais é gerado. ....166
Figura B6.49. Formulário para preenchimento. ........................................................................166
Figura B6.50. Preenchimento com linhas desprezadas. .............................................................167
Figura B6.51. Todos os objetos persistidos em uma única requisição HTTP e transação de SGBD. ...167
Figura B6.52. Uma inserção, uma exclusão e duas alterações realizadas em uma única transmissão!
........................................................................................................................................167
Figura B6.53. Formulário sem coluna de exclusão e marcas de obrigatoriedade............................167
Figura B6.54. Leiaute apropriado para impressão. ...................................................................168
Figura B7.1. Especificação para “UC001.2 Manter Unidade Organizacional“..................................171
Figura B7.2. Grafo do Modelo de Domínio incluindo Agregação a ser Mantida e Classe referenciada. 172
Figura B7.3. Classe Java para Unidade Organizacional. .............................................................172
Figura B7.4. Classe Java para Endereço. ................................................................................172
Figura B7.5. Mapeamento de Endereco com estereótipo “Componente”, e CEP opcional.................173
Figura B7.6. Classe Java mapeada para componente Endereco. .................................................173
Figura B7.7. Classe Java mapeada para componente UnidadeOrganizacional, com partes importantes
em destaque. .....................................................................................................................174
Figura B7.8. Segundo passo do Assistente de Criação de mapeamento Objeto-Relacional. .............174
Figura B7.9. Classe Abstrata (do Projetista) para UnidadeOrganizacional, com mapeamentos.........175
Figura B7.10. Classe Concreta (do Desenvolvedor) para UnidadeOrganizacional, com mapeamentos.
........................................................................................................................................176
Figura B7.11. Control+Space após digitar as iniciais do atributo, traz lista de opções (auto-complete
do Eclipse).........................................................................................................................176
Figura B7.12. Anotação finalizada para exibir TreeView de leiaute com hierarquia organizacional. ...176
Figura B7.13. Criação de uma nova cláusula de “NamedQuery”, copiando-se a existente. ..............177
Figura B7.14. Definição apropriada da Named Query “naoDeveExistir”, com partes importantes em
destaque. ..........................................................................................................................177
Figura B7.15. Validações em nível do campo cep de Endereco. ..................................................177
Figura B7.16. Acionamento do roteiro de criação de Caso de Uso Padrão “Manter Agregação Simples”.
........................................................................................................................................178
Figura B7.17. Página inicial do Assistente de Criação para Caso de Uso Padrão “Manter Agregação
Simples”............................................................................................................................178
Figura B7.18. Terceira página do Assistente de Criação do Caso de Uso Padrão “Manter Agregação
Simples”............................................................................................................................179
Figura B7.19. Propriedade “id” retirada e “endereco_numero” acrescida à lista de seleção. ............180
Figura B7.20. Visualização inicial do formulário de Manutenção..................................................181
Figura B7.21. Modificações para atender à especificação, com pontos modificados em destaque. ....181
628
Índice de Legendas
Figura B7.22. Modificações na chamada de menu para acionar Explorador de Dados na abertura....182
Figura B7.23. Metadados da Colaboração de Seleção “unidadeorganizacionalsel”. .........................183
Figura B7.24. Metadados da Colaboração de Manutenção “CRUD” “unidadeorganizacionalman”. .....184
Figura B7.25. Editando metadados do jCompany, com uso do “auto-complete”. ...........................184
Figura B7.26. Acréscimo da declaração finalizado. ...................................................................184
Figura B7.27. Fluxos de navegação criados até aqui. ................................................................185
Figura B7.28. Metadados para camada de Domínio, Colaboração de Manutenção..........................185
Figura B7.29. Metadados para camada de Domínio, Colaboração de Seleção................................186
Figura B7.30. Conferindo o foco no projeto principal e clicando em “Fazer Liberação”....................187
Figura B7.31. Procurar “Liberação Rápida Reinicialização Tomcat”, em atalho ou dentro do diálogo
“External Tools”. .................................................................................................................187
Figura B7.32. Relatório final do Maven sobre a liberação completa (primeira vez mais demorada)...187
Figura B7.33. Mensagem final do Tomcat após reinício e botão para comutação da Console. ..........188
Figura B7.34. Esquema de DDL produzido a partir do mapeamento Objeto-Relacional da nova
Agregação. ........................................................................................................................188
Figura B7.35. Formulário para preenchimento. ........................................................................189
Figura B7.36. Validações de Entrada de Dados realizadas de uma só vez. ...................................189
Figura B7.37. Verificação de CEP parcialmente digitado. ...........................................................190
Figura B7.38. Primeiro registro gravado com sucesso. ..............................................................190
Figura B7.39. Imagem após o clique em “Clonar” e alteração do nome. ......................................190
Figura B7.40. Seleção popup aberta após clique em componente “vinculado”...............................191
Figura B7.41. Identificador e valores de exibição (toString) da Unidade Organizacional, exibidos em
vinculado...........................................................................................................................191
Figura B7.42. Mensagem de erro enviada, e seleção da parte que começa com “jcompany.”, sem
incluir os “???”, para registro da mensagem............................................................................192
Figura B7.43. Diálogo de seleção de recursos. Seleção de arquivo de mensagens em Português. ....192
Figura B7.44. Mensagem em português adicionada. .................................................................192
Figura B7.45. Explorador de dados trazendo todos os registros no mesmo plano. .........................193
Figura B7.46. Relação de Named Queries para UnidadeOrganizacional, com destaque para a última
codificada. .........................................................................................................................193
Figura B7.47. Nova liberação rápida com reinício. ....................................................................194
Figura B7.48. Explorador de Dados exibindo e expandindo corretamente. ...................................194
Figura B7.49. Explorador de Dados funcionando (item selecionado em destaque) e mensagem de
duplicidade. .......................................................................................................................194
Figura B7.50. Ativando ou desativando o Explorador de Dados, via painel. ..................................195
Figura B7.51. Colaboração de Seleção, com busca por parte do nome. .......................................195
Figura B7.52. Clique em um dos itens da lista de seleção, ou no botão F7-Novo, comutam para a
manutenção. ......................................................................................................................195
Figura B7.53. Confirmação de exclusão. .................................................................................196
Figura B7.54. Alteração da chave do rotulo, para se diferenciar da seção de unidade. ...................196
Figura B7.55. Definição de mensagem com a chave criada, com rótulo como “Endereço”...............196
Figura B7.56. Definição de mensagem diretamente em JSP de argumento, trocando-se “tituloChave”
por “titulo”.........................................................................................................................197
Figura B7.57. Definição de mensagem diretamente em JSP de seleção, trocando-se “tituloChave” por
“titulo”. .............................................................................................................................197
Figura B7.58. Propriedade exibindo ajuda bastando-se passar o mouse sobre ela. .......................197
Figura B7.59. Acionando o jCompany Hot Deploy.....................................................................198
Figura B7.60. Vinculado sem Object-Id e título de seção de Endereço alterado (falta reinício para texto
I18n aparecer). ..................................................................................................................198
Figura B7.61. Títulos de seção na seleção alterados (já ativos, pois neste caso não usamos I18n). .198
Figura B8.1. Especificação para “UC002 Manter Funcionário!“. ...................................................201
Figura B8.2. Grafo do Modelo de Domínio incluindo Agregação a ser Mantida e Classe referenciada.202
Figura B8.3. Projeto de GUI para formulários de manutenção (assistente e tab-folder)..................202
Figura B8.4. Projeto de GUI para Seleção de Funcionário. .........................................................202
Figura B8.5. Classes Java para prosseguir no “rhtutorial”, disponíveis no diretório de instalação. ....203
629
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
630
Índice de Legendas
Figura B8.49. Modificação da chamada para “/f/t/funcionariosel”, com a URL de manutenção como
parâmetro. ........................................................................................................................232
Figura B8.50. Modificações em metadados de controle, para alterar argumentos na Colaboração
“funcionariosel”. .................................................................................................................232
Figura B8.51. Variações relevantes nos metadados de controle para “funcionarioman”. .................233
Código B8.1. Esquema exemplo de "Template Method".............................................................235
Ref. B8.1. Kent Beck em “Test Driven-Design”. Págs. 170 e 171. ...............................................236
Figura B8.52. Acesso à opção de exibição de métodos de ancestral, para sobreposição. ................237
Figura B8.53. Diálogo para seleção de métodos para especialização. ..........................................237
Figura B8.54. Método de extensão da Classe de Controle, conforme gerado pelo Eclipse. ..............238
Figura B8.55. Alteração de chamada para novo método, ainda não existente, e acionamento do “Quick
Fix” do Eclipse. ...................................................................................................................238
Figura B8.56. Novo método criado via Quick Fix. .....................................................................239
Figura B8.57. Método para ajustes de argumentos de idade para data. .......................................239
Figura B8.58. Metadados para camada de Domínio, Colaboração de Manutenção..........................241
Figura B8.59. Propriedade padrão para uso em Exclusões Lógicas. .............................................242
Figura B8.60. Named Query utilizada para “Seleção”, alterada para trazer somente “Ativos”. .........242
Figura B8.61. Referência a FotoEntity comentada em Funcionário. Remover getFoto e SetFoto.......243
Figura B8.62. Esquema de DDL produzido a partir do mapeamento da nova Agregação Mestre-
Detalhe. ............................................................................................................................243
Figura B8.63. Somente a restrição em DATA_INICIO foi removida. A de salário pode ser mantida. .244
Figura B8.64. Foreign Key declaradas em Componentes exigem ajuste nos nomes, em nível de DDL.
........................................................................................................................................244
Figura B8.65. Conferencia normal para nosso estágio...............................................................245
Figura B9.1. Grafo do Modelo de Domínio. Faltando apenas a parte da classe Foto, com estereótipo
“arquivoAnexado”. ..............................................................................................................247
Figura B9.2. Classe típica para arquivo anexado. .....................................................................248
Figura B9.3. Classe ancestral com mapeamentos padrões para arquivos anexados. ......................249
Figura B9.4. Mapeamento padrão para referência a arquivos anexados. ......................................250
Figura B9.5. Declaração de Entidade no arquivo “hibernate.cfg.xml”...........................................250
Figura B9.6. Declaração de importação de Tag-Libs Tiles. .........................................................251
Figura B9.7. Inserção de um “componente de leiaute” inteiro, ao final da página..........................251
Figura B9.10. Campo que permite exclusão ou download. .........................................................251
Figura B9.11. Rótulos para a parte de arquivo.........................................................................251
Figura B9.12. Declaração de “componenteVisualFinal”, para inserir componente Tiles ou JSP ao final
do leiaute. .........................................................................................................................252
Figura B9.13. Classe de arquivo declarada com estereótipo especial, no Grafo de Classes..............252
Figura B9.14. Problema conhecido que exige reinício em desenvolvimento, após certo número de
liberações. .........................................................................................................................253
Figura B9.15. Configuração do Tomcat com PermGen 128M. .....................................................253
Figura B9.16. Parando o Tomcat no Eclipse.............................................................................254
Figura B9.17.Esquema gerado para a parte de arquivo anexado da classe Foto. ...........................254
Figura B10.1. Página de Seleção, como entrada para “UC002 Manter Funcionário!”. .....................257
Figura B10.2. Página de manutenção. Aba principal com dados da classe Raiz. ............................257
Figura B10.3. Dados de Endereco em uma Aba própria, separada do Mestre ................................258
Figura B10.4. Aba do Detalhe “Dependente”, iniciada com dois objetos, como solicitado................258
Figura B10.5. Aba do Detalhe “Dependente”, com mais itens para preenchimento, após clique em F7-
Novo.................................................................................................................................258
Figura B10.6. Formulário de manutenção, com partes modificadas em amarelo e após tentativa de
gravação. ..........................................................................................................................259
Figura B10.7. Inicialização explicita e em tempo de modelagem, para propriedades com tipo Boolean
........................................................................................................................................260
Figura B10.8. Erros de toda a Agregação exibidos em conjunto, de uma única vez. ......................260
Figura B10.9. Validação declarada de multiplicidade entre Funcionário e Dependente (0..2) ...........260
Figura B10.10. Validação das regras invariáveis, anotadas e programadas, ocorrem antes da
multiplicidade (1..*) ............................................................................................................261
631
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura B10.11. Validação codificada de piso salarial para quem tem curso superior. ......................261
Figura B10.12. Validação via programação procedimental, para verificação de maioridade. ............261
Figura B10.13. Dados de Funcionário, corretamente preenchidos. ..............................................262
Figura B10.14. Dados de Endereço, corretamente preenchidos. .................................................262
Figura B10.15. Dados de Dependentes, corretamente preenchidos. ............................................262
Figura B10.16. Dados de Histórico Profissional, corretamente preenchidos. .................................262
Figura B10.17. Operação sem mouse para diálogos popup. ......................................................263
Figura B10.18. Função “comutaAba” declarada em tabelas de componentes, em
“funcionarioMestre.jsp” ........................................................................................................263
Figura B10.19. Na página “funcionarioMestre2.jsp” (Endereço), o campo para foco é “enumerado”. 264
Figura B10.20. Formulário em modo de visualização, para conferência. ......................................264
Figura B10.21. Função gerada em “funcionarioDet2.jsp” (último componente Tiles do formulário). .264
Figura B10.22. Acionamento opcional do Assistente, de forma padronizada. ................................265
Figura B10.23. Primeira página do leiaute de Assistente de Entrada de Dados para usuários finais. .265
Figura B10.24. Passo de Assistente para Detalhe .....................................................................266
Figura B10.25. Confirmação final aparece com todos os dados informados e botão para gravação ..266
Figura B10.26. Mensagens editadas no editor homologado. Markups HTML podem ser incluídos. ....266
Figura B10.27. Imagens de boneco "assistente_falando[0,2,3,4].gif"..........................................267
Figura B10.28. Passos totais e do “Mestre”; e exemplo de imagem personalizada.........................267
Figura B10.29, Configurando Database Bookmark no Quantum DB............................................268
Figura B10.30. Configurando novo Driver JDBC para Acesso ao Apache Derby. ............................268
Figura B10.31. Driver JDBC para Apache Derby configurado, aparecendo na lista. ........................269
Figura B10.32. Conexão com Banco Local...............................................................................269
Figura B10.33. Nome para o bookmark. .................................................................................269
Figura B10.34. Acesso direto ao SGBD Apache Derby via Quantum DB .......................................270
Figura B10.35. Mensagem de confirmação de exclusão. CPF em destaque. ..................................271
Figura B10.36. Análise de Exclusão Lógica, diretamente no SGBD. .............................................271
Figura B10.37. Declaração “naoDeveExistir”, que não explicita o teste de exclusão lógica. .............271
Figura B10.38. Relação de SQLs enviados para inclusão de Funcionário, sem Dependentes. ...........272
Figura B10.39. Mensagem correta de validação de CPF duplicado (somente em ativos). ................273
Figura B10.40. Mensagem de validação de duplicidade de CPF, traduzida. ...................................273
Figura B10.41. Control+H para ver a historia de uso dos últimos tempos (Mozilla)........................274
Figura B10.42. Vários documentos diferenciados, na História do Usuário (IE 7). ...........................274
Figura B10.43. Quaisquer documentos podem ser “preferidos” (bookmarked), acessíveis a um clique
de distância. ......................................................................................................................275
Figura B10.44. Página de seleção com paginação.....................................................................275
Figura B10.45. Opção “show_sql” configurada para desenvolvimento, para conferência dos SQLs
gerados. ............................................................................................................................276
Figura B10.46. Primeiro SQL produzido pelo Hibernate, para Seleção Paginada, por inicial do nome.
........................................................................................................................................277
Figura B10.47. Segundo SQL produzido pelo Hibernate, para Seleção Paginada, por inicial do nome.
........................................................................................................................................278
Figura B10.48. Ajuste que alteraria a exibição do “toString” da classe Uf, para apenas nome. ........279
Figura B10.49. Ajuste para trazer mais campos de classe vinculada ...........................................279
Figura B10.50. Ajuste no construtor correspondente, para “acomodar” o dado no grafo de classes..279
Figura B10.51. Componente visual padrão para Arquivo Anexado, em modo Inativo. ....................279
Figura B10.52. Componente visual padrão para Arquivo Anexado, em modo Upload. ....................280
Figura B10.54. Manutenção típica em Detalhes........................................................................281
Figura B10.55. Estilo CSS diminuindo a largura do componente “radio”, para JSP Mestre...............282
Figura B10.56. Estilo CSS alterando a orientação para horizontal do componente “radio”, para JSP de
Dependente. ......................................................................................................................282
Figura B10.57. Resultado da mudança de orientação para “horizontal”, em Dependentes. .............282
Figura B10.58. Assistente da parte visual do Editor RHDS, exibindo palheta de opções JSTL ..........283
Figura B10.59. Reúso de rótulos de Endereço e ajuste de título. ................................................284
Figura B10.60. Rótulo revisado para o componente “Endereco”, em “Funcionario”. .......................284
632
Índice de Legendas
633
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura C12.9. Página JSP para “Mestre”, somente para consulta, sem Object-Id. ..........................321
Figura C12.10. Página JSP para Detalhe “Município”. ................................................................321
Figura C12.11. Ajuste de entrada de menu para “Município”......................................................322
Figura C12.12. Ajuste na página “ufTabular.jsp”, para incluir hiperlink para Municípios..................322
Figura C12.13. Rótulos para hiperlink de UF para seus municípios. .............................................322
Figura C12.14. Alteração de fluxo no “faces-config.xml”. ..........................................................323
Figura C12.15. Fluxos de navegação das várias Colaborações desenvolvidas, com a Colaboração atual
em destaque. .....................................................................................................................323
Figura C12.16. Esquema DDL de atualização para Caso de Uso e Solicitação de Mudança. .............324
Figura C12.17. Cláusulas com nomes de FK em Componentes, que não podemos sobrepor em
Hibernate. .........................................................................................................................324
Figura C12.18. UF com hiperlink para municípios. ....................................................................325
Figura C12.19. Formulário para “Manter Municípios de UF”........................................................325
Figura C12.20. Formulário “unidadeorganizacionalMan2.jsp”, editado para conter lista de municípios.
........................................................................................................................................325
Figura C12.21. Declarações em tags JSP para aninhar dois “combos” dinâmicos...........................326
Figura C12.22. Ajuste similar para “combos” aninhados, na JSP de “funcionarioMestre2.jsp”. .........326
Figura C12.23. Rótulo para município.....................................................................................326
Figura C12.24. Declaração de metadados de camada Controle para listas aninhadas, em
“unidadeorganizacionalman”.................................................................................................327
Figura C12.25. Declaração de metadados de camada Controle para listas aninhadas, em
“funcionarioman”. ...............................................................................................................327
Figura C12.26. Combos aninhados em “/f/t/unidadeorganizacionalman”......................................327
Figura C12.27. Resultado similar em “/f/t/funcionarioman”. ......................................................327
Figura C13.1. Diagrama de Casos de Uso para “UC004 Registrar Proventos e Descontos!”. ............331
Figura C13.2. Mapeamento Objeto-Relacional para “ProventoDesconto”. .....................................332
Figura C13.3. Validação de mais "baixo nível", incluída na implementação concreta. .....................333
Figura C13.4. Data no passado, sem parte temporal (horas). ....................................................333
Figura C13.7. Validação de valor máximo para natureza DT. .....................................................334
Figura C13.8. Primeira tela do Assistente de Criação “Manter Classe” para “ProventoDesconto”. .....334
Figura C13.9. Segunda tela do Assistente de Criação “Manter Classe” para “ProventoDesconto”. ....334
Figura C13.10. Terceira tela do Assistente de Criação “Manter Classe” para “ProventoDesconto”.....335
Figura C13.11. Alterando título para página de "itens"..............................................................335
Figura C13.12. Página de argumento para Caso de Uso “Manter Coleção”....................................336
Figura C13.13. Alteração do padrão da Colaboração.................................................................336
Figura C13.14. Definições de argumentos e ajustes em metadados de Controle. ..........................337
Código C13.1. Implementação de camada Controle, para funcionamento RESTful (opcional) ..........338
Figura C13.15. Declaração de evento Javascript, com chamada para função local. ........................338
Figura C13.16. Função javascript que modifica o formulário dinamicamente. ...............................339
Figura C13.17. Esquema DDL de atualização para “ProventoDesconto”. ......................................340
Figura C13.18. Formulário para entrada de Proventos e Descontos, em leiaute padrão para
Colaboração “plcCrudTabular”...............................................................................................340
Figura C13.19. Javascript atuando.........................................................................................341
Figura D14.1. Web-design livre básico, produzido em uma hora com Web-Style. ..........................346
Figura D14.2. Logotipo de entrada da aplicação, para login. ......................................................347
Figura D14.3. Esquema básico de leiaute................................................................................348
Figura D14.4. Cortes secundários do leiaute. ..........................................................................348
Figura D14.5. Corte de “terceiro nível”, na barra de ações. .......................................................349
Figura D14.6. Partes reutilizadas do leiaute. ...........................................................................349
Figura D14.7. Teste de edição em “pontos de extensão” previstos no leiaute. ..............................351
Figura D14.8. Edição no final do trecho específico de rodapé. ....................................................351
Figura D14.9. Especializações do tipo “leiaute por exceção”. .....................................................351
Figura D14.10. Criação de arquivo simples no diretório “WEB-INF/jsps” do “rhtutorial”..................352
Figura D14.11. Criação de conteúdo de teste. .........................................................................352
Figura D14.12. Topo substituído por sobreposição de página padrão da arquitetura. .....................352
634
Índice de Legendas
635
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura D14.64. Código Tiles que insere um componente de leiaute para exibição do título. ............380
Figura D14.65. Visão geral do leiaute.....................................................................................380
Figura D14.66. Modificações no leiaute Tiles para mudar a barra de ações de posição. ..................382
Figura D14.67. Modificações no leiaute Tiles para mudar a barra de ações...................................382
Figura D14.68. Barra de ações abaixo do formulário. ...............................................................383
Figura D14.69. Definição de metadados para uso de imagem grande em lugar de botões. .............383
Figura D14.70. Imagens em lugar de botões. ..........................................................................384
Figura D14.71. Definição de leiaute de colunas, a ser utilizado para formulário. ...........................384
Figura D14.72. Definição de leiaute de formulário que herda leiaute geral, seções de ações,
mensagens, etc.. ................................................................................................................385
Figura D14.73. Metadados para controle de “unidadeorganizacionalman”, com leiaute universal
retirado. ............................................................................................................................385
Figura D14.74. Leiaute customizado específico, através de definição Tiles. ..................................386
Figura D14.75. web.xml com declaração para uso de HTML “Strict”. ...........................................387
Figura D14.76. Problema no Firefox com “Strict” e uma combinação de estilos específica. .............387
Figura D14.77. Estilos movidos da página “principalTopoPlc.jsp” para o arquivo “PlcPele.css”. ........388
Figura D14.78. Páginas chave de declarações HTML. Declaração de <head> para todos os leiautes.389
Figura D14.79. Definição de sub-leiaute com base em tab-folder, para a página principal. .............390
Figura D14.80. Web-design com implementação inicial para a página principal. ...........................390
Figura D14.81. Web-design com implementação específica para a página principal. ......................391
Figura D14.82. Ajustes “principalTopoPlc.jsp” para aceitar leiaute clássico...................................392
Figura D14.83. Variação de leiaute “classico", para nossa pele “acme”........................................393
Figura D14.84. Declarações ajustadas de metadados para restringir as personalizações homologadas.
........................................................................................................................................393
Figura D14.85. Somente peles homologadas. ..........................................................................394
Figura D14.86. Somente leiautes homologados. ......................................................................394
Figura D14.87. Somente opções de personalização de formulário permitidas. ..............................394
Figura D15.1. Espião de leiaute em modo Tomografia. .............................................................397
Figura D15.2. Leiautes Primários do jCompany........................................................................397
Figura D15.3. Definição do leiaute primário na aplicação, com personalização pelos usuários. ........398
Figura D15.4. Espião para menu “Clássico”. ............................................................................399
Figura D15.5. Menu “clássico” com três níveis. ........................................................................400
Esquema D15.1. Definition: “app.m” Path: ”/plc/layouts/PlcMenuTopoLayoutPlc.jsp”. ...................400
Figura D15.6. Definição do leiaute secundário de menu. ...........................................................400
Figura D15.7. Inserção do leiaute de menu no leiaute primário da aplicação. ...............................401
Figura D15.8. No topo, indicação do uso do “PlcTabsLayout.jsp”, leiaute utilizado pela definição
“def.tab.app.home”. ............................................................................................................402
Figura D15.9. Metadados que indicam uso de Tab-Folder subdividindo formulários. ......................402
Figura D15.10. Radiografia de leiaute de pastas “PlcTabsLayoutAgil.jsp”, exibida em azul..............403
Código D15.1. Definição do leiaute de formulário.....................................................................403
Esquema D15.2. Esquema do leiaute de “PlcVboxManSelTabLayout.jsp”......................................404
Esquema D15.3. Definition: “def.corpo.ancestral”. Path: “/plc/layouts/PlcFormJsfLayout.jsp”. ........404
Esquema D15.4. Definition: “def.componente.acoes”. Path: “/plc/jsps/geralAcoesPlc.jsp”. .............405
Figura D15.11. Componentes de leiaute “VBox – vertical box” montados em “lista” do
“def.corpo.ancestral”. ..........................................................................................................406
Código D15.2. Definição do leiaute de assistente. ....................................................................406
Código D15.3. Radiografia em leiaute de assistente, “PlcAssistenteLayout.jsp”.............................406
Esquema D15.5. Definition: “def.pagina.ancestral”. Path: “PlcComutaPaginaLayout.jsp ->
/classico/PlcGeralLayoutPlc.jsp”. ...........................................................................................407
Figura E16.1. Categorias de classes/camadas participantes de uma seqüência de atendimento.......413
Figura E16.2. Diagrama de seqüência para “Manter Classe”. Eventos “F9-Pesquisar” e “F7-Novo”. ..417
Figura E16.3. Diagrama de seqüência para “Manter Classe”. F12-Gravar. ....................................418
Código E16.1. Código de Controle, decidindo sobre qual serviço utilizar do contrato de fachada......419
Figura E16.4. Diagrama de seqüência para “plcSelecao” ou “plcConsulta”. Evento “F9-Pesquisar”. ..419
636
Índice de Legendas
637
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
638
Índice de Legendas
Código E17.21. Nova cláusula de contrato com a persistência, para incluir objetos
“ProventoDesconto”. ...........................................................................................................496
Código E17.22. Método que realiza inclusões programaticamente...............................................497
Código E17.23. Cláusulas típicas para gerenciamento manual de transações................................497
Código E17.24. Implementação com reúso em “FuncionarioDAO”...............................................497
Código E17.25. Uso de fechamento de transação “manual”. ......................................................498
Código E17.26. Chamada para geração de novos objetos “ProventoDesconto”. ............................498
Código E17.27. Última cláusula de persistência, de nosso exemplo atual. ....................................498
Código E17.28. Implementação da última cláusula de persistência. ............................................499
Código E17.29. Cláusula OQL que utiliza função de agregação “count” e “subquery”. ....................499
Código E17.30. Método que testa se é para gerar fechamento de folha. ......................................499
Figura E17.17. FolhaPagamento participante da agregação de “Funcionario”. ...............................499
Código E17.31. Método que testa se é para gerar fechamento de folha. ......................................500
Figura E17.18. Exemplo de classe de escalonamento, baseada no “java.util.TimerTask”. ...............500
Código E17.32. Método que realiza tratamentos de exceção – neste caso somente exibição de log de
erro. .................................................................................................................................501
Código E17.33. Método que formata exibição de exceções. .......................................................501
Código E17.34. Classe AppFacadeImpl, em método estático, iniciando disparo de rotinas batch......501
Código E17.35. Testando o dia correto na rotina “TimerTask”. ...................................................502
Figura E18.1. Diagrama para Extensão de Casos de Uso para “UC005.1 Calcular Folha Interativo!”. 504
Figura E18.2. Página JSP de argumento, criada manualmente no diretório padrão “calculofolha”. ...505
Figura E18.3. Leiaute Tiles específico, alterando barra de mensagens e ações..............................506
Figura E18.4. Nova entrada de menu Tiles, exibida em XML. .....................................................506
Figura E18.5. Nova entrada de menu, em visão de formulário. ..................................................507
Figura E18.6. Rótulo para botão de “Calcular”, item de menu e título de página. ..........................507
Figura E18.7. Navigation-Rule JSF, no faces-config.xml. ...........................................................508
Figura E18.8. Classe de Controle “Backing Bean”, gerenciada pelo jBoss Seam. ...........................508
Figura E18.9. Classe de controle “CalculaFolhaAction”. .............................................................509
Figura E18.10. Mensagem de log aparecendo na console. .........................................................509
Figura E18.11. Mensagem realocada para baixo do formulário. ..................................................509
Código E18.1. Nova cláusula contratual, específica da aplicação.................................................510
Código E18.2. Implementação de fachada, sem gerenciamento de transação...............................510
Código E18.3. Código de método de controle, chamando fachada padrão. ...................................510
Código E18.4. Código para tratamento de erro na camada Controle. ..........................................511
Figura E18.12. Mensagens utilizadas no Caso de Uso. ..............................................................512
Figura E18.13. Execução parcialmente correta. .......................................................................512
Figura E18.14. Execução com erros individuais........................................................................513
Figura E18.15. Contrato de fachada independente para Cálculo de Folha.....................................513
Figura E18.16. Implementação independente de fachada, mas seguindo convenções. ...................513
Figura F19.1. Especificação para "UC006 Auditar Operação!". ....................................................518
Figura F19.2. Criação de um novo relatório.............................................................................520
Figura F19.3. Relatório utilizando modelo “jCompany – Relatório Tabular”...................................520
Figura F19.4. Perspectiva do Eclipse BIRT no Eclipse. ...............................................................521
Figura F19.5. Visualização de relatório conforme disponibilizado pelo modelo...............................521
Figura F19.6. Estilos do modelo "Tabular" em ação. .................................................................522
Figura F19.7. Biblioteca de base do jCompany para relatórios BIRT. ...........................................524
Figura F19.8. Definições globais do relatório. ..........................................................................525
Figura F19.9. Data Source BIRT com dados de conexões para Banco Local padrão do jCompany.....525
Figura F19.10. Definição de um primeiro Data Set. ..................................................................526
Figura F19.11. Início da confecção da cláusula SQL, com auxílio. ...............................................527
Figura F19.12. Relação de colunas definidas no SQL.................................................................527
Figura F19.13. Cláusula SQL para o Data Set finalizada. ...........................................................527
Figura F19.14. Preparando colunas para saída (output). ...........................................................528
Figura F19.15. Parâmetros de Data Set já associados a Parâmetros do Relatório. .........................529
639
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura F19.16. Valores retornados pela cláusula SQL utilizando valores de argumentos. ................530
Figura F19.17. Parâmetros de relatório, com agrupamento para intervalo de datas.......................530
Figura F19.18. Parâmetro do tipo String, para usuário..............................................................531
Figura F19.19. Diálogo de solicitação de valores para parâmetros de relatório..............................531
Figura F19.20. Arrasta e solta do Data Set para a tabela na visão de Design WYSIWYG.................533
Figura F19.21. Colunas acomodando dados do Data Set. ..........................................................533
Figura F19.22. Visualização do relatório com dados de teste......................................................533
Figura F19.23. Exclusão de coluna no Design. .........................................................................534
Figura F19.24. Inserindo uma nova linha de cabeçalho. ............................................................534
Figura F19.25. Mesclando colunas de uma linha. .....................................................................535
Figura F19.26. Arrastando um Grid........................................................................................535
Figura F19.27. Incluindo colunas em um Grid..........................................................................535
Figura F19.28. Espaço para totais criado. ...............................................................................536
Figura F19.29. Visão Master Page..........................................................................................536
Figura F19.30. Inserção de imagem em relatórios....................................................................537
Figura F19.31. Visualização do estágio atual do relatório. .........................................................538
Figura F19.32. Criação de um componente "Aggregation", para conter fórmulas e totalizações. ......539
Figura F19.33. Filtro definido no diálogo "Expression Builder". ...................................................539
Figura F19.34. Objeto Aggregation reposicionado para o Grid, após sua criação em Table..............540
Figura F19.35. Contador com expressão condicional funcionando. ..............................................540
Figura F19.36. Aggregation para "Total de Alterados"...............................................................541
Figura F19.37. Aggregation para "Total de Excluídos". ..............................................................541
Figura F19.38. Aplicando estilos padrões do framework aos campos de formulários. .....................542
Figura F19.39. Visão do relatórios com estilos nos campos........................................................542
Figura F19.40. Opções de propriedades para o objeto "CPF do Funcionário". ................................543
Figura F19.41. Alinhamento de célula para "centralizado". ........................................................543
Figura F20.1. Relatório em HTML ao fundo, com opção para ver em DOC em destaque. ................546
Figura F20.2. Relatório em formato DOC, para edições de texto complementares. ........................547
Figura F20.3. Relatório em formato PPT (com alguns problemas), para apresentações. .................547
Figura F20.4. Relatório em formato PDF, para visualização e impressão de alta qualidade..............548
Figura F20.5. Relatório em formato XLS, para planilhas. ...........................................................548
Figura F20.6. BIRT Viewer em tempo de desenvolvimento. .......................................................549
Figura F20.7. Exportação de relatórios para vários formatos, para usuários finais. ........................550
Figura F20.8. jCompany BIRT Viewer disponível no Tonmcat. ....................................................553
Código F20.1. Arquivos de contexto para aplicativo "plcVis". .....................................................553
Figura F20.9. Página principal do BIRT Viewer, indicando o correto funcionamento. ......................554
Figura F20.10. Relatório de teste executado corretamente. .......................................................554
Figura F20.11. Relatório exibindo diálogo de argumentos traduzido. ...........................................555
Figura F20.12. Chamada de relatório via menu........................................................................555
Figura F20.13. Cópia do relatório para a aplicação "plcVis"........................................................557
Figura F20.14. Classe que persiste itens dinâmicos de menu. ....................................................558
Figura F20.15. Reúso de bloco de menu com opções para menu dinâmico. ..................................559
Figura F20.16. Esquema de criação de nova tabela para persistência de menu dinâmico................559
Figura F20.17. Itens de menu para chamadas de relatórios e outros, criados dinamicamente. ........559
Figura F20.18. Criação de Colaboração para Relatórios. ............................................................560
Figura F20.19. Definição de argumentos para o relatório. .........................................................561
Figura F20.20. Página JSP de argumentos modificada para intervalo de datas. .............................561
Figura F20.21. Chamada de menu reposicionada. ....................................................................562
Figura F20.22. Metadados de Controle alterados para conter novo argumento. ............................562
Figura F20.23. Página de argumento, com chamada automatizada do relatório externo.................563
Figura F21.1. Especificação para "UC007 Consultar/Imprimir Folha de Pagamento".......................566
Figura F21.2. Relatório baseado em modelo "Mínimo". .............................................................567
Figura F21.3. SQL para o segundo relatório. ...........................................................................567
Figura F21.4. Rótulos aprimorando as colunas selecionadas do Data Set. ....................................568
640
Índice de Legendas
641
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Figura II.1. Especificação minimalista, reusando o Padrão de Caso de Uso e Colaboração. .............608
Figura II.2. Visão Estrutural Padrão para Realização de “Manter Classe“ - Colaboração “plcTabular”.
........................................................................................................................................609
Figura II.3. Visão Comportamental Padrão para Realização de “Manter Classe“ - Colaboração
“plcTabular”. ......................................................................................................................610
Figura II.4. Diagrama de Realização do Caso de Uso Padrão “UC001.1 Manter UF-“. .....................610
642
Índice Remissivo
Índice Remissivo
Arquitetura de Software Business Object, 91, 104, 449, 452, 461, 503
Invisível, 74 Data Access Object, 86, 88, 91, 142, 193, 194, 218, 234, 412,
415, 416, 420, 453, 458, 461, 462, 463, 465, 466, 467, 469,
Madura, 77
470, 471, 480, 482, 483, 486, 487, 488, 489, 490, 491, 492,
Autores Citados 493, 494, 496, 498, 499, 503
Albert Einstein, 112 Data Object-Id, 138, 140, 141, 176, 188, 197, 198, 220, 224,
231, 248, 270, 273, 308, 320, 321, 322, 418, 478, 485, 490
Alistair Cockburn, 29, 117, 118, 120, 126, 614
Data Version, 7, 137, 538, 615
Cris Britton, 111, 112, 614
Façade, 88, 90, 103, 104, 105, 106, 412, 414, 442, 449, 450,
Eric Evans, 30, 89, 116, 614, 617
453, 462, 463, 464, 492, 514
James O. Coplien, 590, 614
Factory, 434, 435, 443, 470
Jenifer Tidwell, 590, 591, 616
Front Controller, 413, 415, 436
John Klein, 73, 618
Service Locator, 412, 415, 421, 451, 452, 493
Martin Fowler, 83, 89, 614
Singleton, 240, 412, 439, 484, 511
Paul Graham, 83, 615
Template Method, 234, 235, 236, 238, 292, 295, 412, 437,
Peter Bye, 111, 112, 614 438, 442, 443, 456, 457, 458, 461, 462, 463, 471, 503
DDL, 139, 165, 166, 188, 243, 244, 250, 254, 324, 339, 340 Casos de Uso Eficazes, 117, 118, 591, 614
Prepared Statement, 272, 277, 295, 444 CMMI, 24, 32, 35, 110, 111
QBE, 118, 449, 490, 528 Domain-Driven Design, 30, 86, 89, 116, 414, 461, 591, 614,
617
Result Set, 88, 415, 479, 487
Métodos Ágeis, 5, 24, 44, 110, 492, 590, 592, 614, 616, 617,
SQL, 35, 88, 135, 160, 179, 270, 272, 276, 277, 278, 418, 444,
619, 620, 621
484, 485, 486, 497, 519, 526, 527, 528, 529, 530, 539, 567,
568, 570, 571, 580 MPS.Br, 5, 24, 35, 110, 111
Transação ULT, 270, 458, 465, 480 Processo Unificado, 109, 110, 111, 112
Manter Agregação Mestre/Detalhe, 119, 200, 201, 216, 246, Apache Derby, 60, 67, 70, 160, 161, 165, 166, 169, 176, 243,
257, 317, 331, 594 267, 268, 269, 270, 271, 445, 525, 526, 546
Manter Agregação Simples, 119, 128, 171, 178, 179, 184, 188, Apache Trinidad, 51, 59, 136, 197, 225, 226, 228, 233, 282,
200, 224, 232, 418, 419, 594, 599 283, 326, 339, 353, 413, 424, 427, 428, 430, 431, 432, 433,
436, 616, 617, 621
Manter Classe, 119, 127, 128, 133, 143, 146, 147, 149, 151,
155, 166, 169, 185, 186, 221, 317, 325, 331, 334, 335, 342, CGLib, 90, 446, 451, 456, 457, 621
415, 417, 418, 419, 420, 588, 594, 598, 599, 600, 604, 606,
Eclipse, 23, 28, 29, 32, 35, 41, 44, 45, 46, 47, 48, 49, 50, 51,
607, 608, 609, 610, 611, 612
52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 69, 72,
Manter Coleção, 119, 128, 331, 332, 334, 336, 337, 342, 425, 74, 83, 90, 91, 92, 93, 94, 95, 96, 97, 99, 104, 105, 109, 114,
427, 594, 595, 599, 611 129, 134, 136, 143, 146, 150, 153, 157, 159, 160, 161, 172,
176, 186, 192, 193, 196, 197, 198, 204, 206, 207, 228, 236,
Manter Preferência de Aplicação, 119, 129, 595, 599
237, 238, 239, 240, 241, 253, 254, 266, 267, 272, 276, 293,
Design Patterns 318, 319, 335, 350, 353, 354, 357, 360, 361, 362, 363, 364,
366, 374, 389, 445, 447, 448, 459, 460, 473, 476, 482, 483,
Application Service, 91, 104, 449, 464, 465, 471, 475, 478,
505, 509, 516, 518, 519, 520, 521, 524, 526, 528, 529, 531,
479, 500, 503, 510
532, 534, 535, 537, 538, 539, 544, 546, 550, 551, 554, 558,
Business Delegate, 88, 421, 451 564, 570, 577, 578, 579, 586, 614, 615, 617, 618, 621
643
Tirando o Máximo do Java EE 5 com jCompany Developer Suite
Eclipse BIRT, 35, 59, 129, 516, 518, 519, 520, 521, 526, 528, AOP, 85, 90, 412, 416, 421, 446, 451, 456, 457, 514, 620
529, 531, 534, 535, 537, 538, 539, 544, 546, 550, 551, 554,
Depuração, 293, 444, 446, 447, 448, 618
558, 564, 570, 577, 578, 579, 586, 618, 621
Escalonamento, 502
Glassfish, 53, 60, 161
Gestão de Leiautes, 75, 153, 154, 288, 344, 347, 395, 396,
Hibernate, 40, 51, 52, 58, 59, 60, 84, 86, 88, 96, 114, 135, 138,
430
141, 143, 145, 160, 165, 186, 194, 209, 211, 212, 213, 214,
218, 234, 243, 276, 277, 278, 323, 324, 414, 416, 418, 420, Gráfico, 124, 566, 581
422, 423, 444, 455, 457, 458, 467, 468, 469, 470, 471, 479,
Internacionalização, 99, 149, 152, 154, 182, 198, 203, 204,
482, 484, 490, 492, 497, 538, 557, 601, 615, 617, 618, 620,
205, 206, 214, 216, 218, 224, 225, 226, 227, 229, 274, 283,
621
303, 336, 391, 495, 505, 507, 511, 528, 583, 600, 623
Hibernate Validator, 143, 145, 212, 213, 214, 218, 243, 621
Mapeamento Objeto-Relacional, 28, 39, 88, 127, 136, 137,
Jasper Reports, 129, 519, 561 143, 145, 165, 166, 169, 172, 174, 178, 188, 208, 241, 319,
320, 332, 414, 416, 477, 490, 623
JBoss Seam, 51, 52, 84, 103, 114, 117, 226, 347, 413, 423,
431, 432, 434, 435, 436, 440, 441, 442, 505, 586, 616, 619, Mapeamento Thread, 446, 453, 455, 501, 607
622
Tecnologias Java
Linux, 40, 44, 158
Enumeração, 144, 203, 204, 205, 206, 209, 220, 226, 228,
Log4j, 64, 90, 293, 294, 295, 444, 445, 446, 471, 483, 621 230, 240, 257, 258, 332
Maven, 28, 32, 40, 41, 49, 50, 51, 52, 56, 70, 71, 90, 92, 93, Interface, 31, 80, 86, 88, 106, 127, 273, 274, 301, 311, 344,
96, 97, 98, 99, 104, 105, 146, 150, 156, 157, 158, 159, 162, 348, 349, 350, 367, 397, 413, 414, 428, 432, 433, 437, 449,
169, 186, 187, 194, 197, 198, 200, 243, 253, 293, 352, 353, 450, 451, 452, 453, 459, 460, 469, 470, 471, 482, 493, 514,
429, 445, 557, 621 558, 592, 593, 598, 604
Netbeans, 28, 56, 586 POJO, 49, 52, 87, 88, 89, 90, 137, 147, 234, 238, 398, 416,
422, 437, 438, 440, 441, 442, 444, 451, 452, 455, 456, 457,
Red Hat Studio, 62, 101, 150, 154, 155, 219, 622
458, 469, 513, 623
Spring, 79, 89, 114, 347, 422, 586, 619, 620
Tecnologias Java EE
Struts, 40, 48, 49, 51, 52, 57, 58, 59, 67, 69, 82, 86, 99, 103,
Application Server, 7, 28, 34, 41, 42, 43, 49, 51, 52, 53, 84, 89,
136, 143, 147, 148, 150, 153, 154, 155, 156, 163, 175, 182,
101, 102, 116, 150, 157, 159, 162, 163, 167, 197, 198, 273,
183, 185, 205, 206, 218, 225, 226, 227, 228, 234, 235, 250,
281, 293, 295, 310, 414, 416, 433, 447, 457, 458, 461, 465,
292, 295, 305, 347, 353, 382, 403, 404, 405, 413, 416, 422,
467, 550, 551, 552, 554, 555, 556, 557, 563, 607, 615, 623,
427, 431, 432, 436, 438, 439, 446, 508, 614, 615, 616, 618,
624
619, 620, 621
EJB, 52, 53, 80, 87, 88, 106, 137, 147, 157, 421, 422, 423,
Tiles, 40, 51, 52, 57, 58, 59, 84, 87, 88, 98, 99, 100, 101, 102,
451, 458, 615, 618, 619, 623, 624
103, 150, 153, 154, 155, 164, 180, 182, 183, 219, 224, 232,
233, 234, 250, 251, 252, 255, 264, 267, 279, 290, 297, 301, JDBC, 51, 60, 70, 88, 89, 138, 160, 161, 267, 268, 269, 281,
302, 304, 305, 306, 307, 308, 321, 335, 347, 350, 367, 368, 415, 416, 455, 456, 457, 458, 467, 468, 479, 483, 525, 550,
372, 380, 381, 382, 384, 385, 386, 388, 390, 393, 396, 399, 552
402, 404, 408, 412, 413, 430, 432, 436, 440, 446, 476, 504,
JMS, 34, 36, 51, 64, 124, 125, 161, 449, 586, 616
506, 507, 558, 586, 617, 621
JNDI, 416, 422, 451, 467, 468, 526, 553, 567
Tomcat, 51, 52, 53, 60, 67, 68, 70, 71, 83, 150, 157, 158, 160,
161, 162, 163, 166, 169, 186, 187, 188, 194, 197, 198, 243, JPA, 42, 58, 59, 84, 86, 88, 89, 96, 105, 114, 135, 137, 138,
253, 254, 269, 272, 276, 293, 294, 298, 301, 308, 323, 327, 139, 140, 141, 142, 160, 173, 175, 176, 177, 186, 193, 194,
351, 356, 369, 385, 426, 429, 445, 447, 519, 522, 525, 550, 208, 209, 210, 211, 212, 213, 234, 244, 248, 249, 267, 270,
551, 552, 553, 554, 557, 558, 559, 563, 615, 617, 621, 624 276, 278, 323, 412, 414, 416, 418, 420, 422, 423, 455, 457,
458, 469, 471, 477, 479, 482, 484, 488, 490, 492, 497, 499,
Produtos Powerlogic (Outros)
538, 557, 618
eCompany Portal Suite, 34, 36
JSF, 28, 40, 48, 49, 51, 57, 58, 59, 67, 68, 69, 70, 82, 86, 87,
eCompany Process Suite, 34, 35, 36, 60 88, 94, 95, 98, 99, 101, 102, 103, 114, 117, 128, 136, 143,
147, 148, 150, 153, 154, 155, 156, 163, 175, 183, 185, 197,
eCompany Reports, 35, 552, 558
205, 206, 219, 225, 226, 227, 228, 230, 231, 233, 234, 235,
jCompany Monitor, 34, 36, 64 250, 283, 305, 332, 337, 347, 353, 382, 393, 403, 404, 405,
412, 413, 415, 417, 422, 423, 424, 427, 428, 430, 431, 432,
jCompany Production, 34
433, 436, 437, 438, 439, 440, 441, 446, 504, 506, 508, 616,
jCompany QA Suite, 34, 36, 50, 60, 99 617, 618, 619, 620, 621
jCompany Security, 34, 36, 148, 307, 309, 310, 433, 557 JSP, 27, 39, 51, 57, 61, 62, 75, 87, 88, 99, 100, 101, 102, 128,
147, 148, 149, 151, 152, 163, 179, 180, 182, 183, 184, 196,
Técnicas de Programação
644
Índice Remissivo
197, 198, 218, 219, 224, 225, 227, 228, 229, 230, 231, 234, Pool de Conexões, 300
250, 251, 252, 263, 264, 278, 282, 283, 284, 296, 318, 321,
Protocolo http, 273, 300, 301, 308, 381, 387, 401, 415, 417,
322, 326, 336, 350, 352, 355, 359, 367, 368, 369, 381, 382,
424, 432, 433, 435, 556, 624
384, 385, 398, 399, 400, 401, 403, 408, 413, 415, 430, 436,
441, 505, 507, 508, 509, 561, 602, 608, 610, 617, 624 XHTML, 163, 387, 416, 429, 430
JSTL, 87, 88, 230, 283, 413, 430, 431 Tutoriais por Assunto
Servlet, 82, 83, 98, 99, 102, 103, 138, 154, 358, 368, 387, 415, Classes de Domínio Discreto, 203
417, 432, 433, 436, 439, 444, 453, 454, 468, 539
Construção e Liberação, 156, 186, 197, 253
Tag-File, 87, 136, 143, 205, 206, 225, 227, 396, 413, 422, 624
Controle de Acesso, 162, 299
Tag-Lib, 101, 225, 230, 251, 283, 380, 413, 431, 436, 624
Depuração e Logging, 293, 444, 446
Tecnologias Web
Edição de Camada Controle, 154, 182, 232, 252, 291, 305,
Ajax, 39, 75, 87, 99, 217, 218, 273, 281, 325, 326, 328, 329, 322, 326, 507
404, 405, 413, 417, 422, 423, 424, 427, 428, 436, 579, 586,
Edição de Camada Modelo/Domínio, 156, 185, 240, 252
614, 616, 620, 621
Edição de Camada Persistência, 156, 186
CSS, 39, 51, 57, 75, 87, 95, 99, 100, 101, 103, 113, 197, 198,
225, 228, 267, 282, 293, 296, 329, 339, 347, 350, 353, 354, Edição de Camada Visão, 151, 181, 196, 224, 250, 282, 301
355, 356, 357, 358, 360, 361, 364, 366, 370, 372, 373, 374,
Geração de Artefatos, 147, 178, 216, 320
375, 380, 386, 387, 388, 389, 393, 416, 424, 426, 519, 523
Geração de DDL, 165, 188, 243, 254, 323, 339
HTML, 35, 53, 75, 88, 92, 113, 120, 125, 149, 165, 225, 226,
227, 228, 230, 231, 247, 251, 263, 265, 266, 279, 288, 295, Javascript, 338, 424, 426, 427
339, 356, 357, 360, 361, 363, 364, 365, 367, 372, 373, 378,
Mapeamento Objeto Relacional, 136, 172, 207, 248, 319, 332,
380, 382, 386, 387, 388, 389, 403, 416, 417, 418, 419, 420,
477
422, 424, 429, 430, 433, 436, 518, 523, 528, 546, 548, 549,
564, 576, 595 Programação Batch, 500, 502
Javascript, 39, 51, 57, 60, 75, 87, 95, 99, 101, 103, 113, 189, Programação de Camada Controle, 234
196, 197, 198, 226, 227, 230, 257, 263, 264, 276, 290, 293,
Programação de Camada Modelo, 478, 480
296, 338, 339, 340, 341, 353, 354, 355, 356, 358, 370, 371,
372, 378, 399, 413, 416, 417, 424, 425, 426, 427, 428, 429, Programação de Persistência, 482, 486, 488, 490, 493, 496,
432, 505, 522, 538, 560, 568, 574 498
Navegadores, 274, 282, 356, 365, 371, 380, 386, 387, 426, Usabilidade, 188, 257, 262, 264, 272, 275, 279, 280, 324, 327,
427 340
PDF, 35, 88, 120, 518, 519, 546, 547, 548, 549, 551, 564, 576, Validação de Entrada, 143, 176, 212, 332
595
645