Mudanças entre as edições de "PJe2:Documento da Arquitetura de Referência"
(→Visão de Deployment da Arquitetura) |
|||
(316 edições intermediárias de 2 usuários não apresentadas) | |||
Linha 3: | Linha 3: | ||
Apresentamos neste documento a arquitetura de referência para o desenvolvimento do software '''Processo Judicial Eletrônico versão 2.0 (PJe 2.0)''' e suas evoluções futuras. | Apresentamos neste documento a arquitetura de referência para o desenvolvimento do software '''Processo Judicial Eletrônico versão 2.0 (PJe 2.0)''' e suas evoluções futuras. | ||
As seções e subseções do documento explicarão os detalhes pertinentes da arquitetura. | As seções e subseções do documento explicarão os detalhes pertinentes da arquitetura. | ||
+ | |||
== '''Objetivo do documento''' == | == '''Objetivo do documento''' == | ||
− | O objetivo principal é especificar a arquitetura de software de referência a ser utilizada como padrão para o desenvolvimento do PJe 2.0 e suas evoluções futuras. Nesta especificação está incluído: a estruturação do projeto do software, a organização das camadas do software, os componentes e arcabouços utilizados no software, a definição das principais tecnologias e ferramentas a serem utilizadas, os padrões de projeto | + | O objetivo principal é especificar a arquitetura de software de referência a ser utilizada como padrão para o desenvolvimento do PJe 2.0 e suas evoluções futuras. Nesta especificação está incluído: a estruturação do projeto do software, a organização das camadas do software, os componentes e arcabouços utilizados no software, a definição das principais tecnologias e ferramentas a serem utilizadas, os padrões de projeto, boas práticas de programação que devem ser utilizadas no desenvolvimento do software, entre outros assuntos relevantes. |
+ | |||
+ | Recomendamos que a leitura deste documento seja feita na ordem sequencial em que são apresentados os tópicos do sumário/índice do documento. | ||
+ | |||
+ | A metodologia de desenvolvimento do software definida será tratada em [[PJe2:Metodologia_de_desenvolvimento | outro documento]]. | ||
+ | |||
+ | |||
+ | == '''Público Alvo''' == | ||
+ | |||
+ | O documento tem como público alvo principal '''arquitetos de software''' visando orientá-los da criação de artefatos para o desenvolvimento e evoluções futuras do software PJe 2.0. Além da criação de artefatos, o arquiteto de software deverá utilizar este documento como '''referência''' para instruir os profissionais que atuarão como desenvolvedores especializados nas tecnologias requeridas para esta arquitetura, como por exemplo: desenvolvedores Java/JEE. | ||
+ | |||
+ | Este documento também contém informações úteis a gerentes de projeto, analistas de negócios/requisitos, analistas de teste, testadores, administradores de dados, administradores de infraestrutura e, possivelmente, outros perfis interessados no projeto do software PJe 2.0. | ||
+ | |||
== '''Termos, abreviações e convenções adotadas''' == | == '''Termos, abreviações e convenções adotadas''' == | ||
− | + | Apresentamos nesta seção uma tabela contendo os termos, abreviações e convenções adotadas no documento da arquitetura de referência do PJe 2.0. | |
A leitura prévia desta seção é fortemente recomendada para compreensão das demais seções. | A leitura prévia desta seção é fortemente recomendada para compreensão das demais seções. | ||
− | |||
− | |||
{| {{table border=1}} | {| {{table border=1}} | ||
Linha 32: | Linha 43: | ||
|- | |- | ||
| ''CRUD'' || Sigla para ''Create'' (Criar), ''Read'' (Ler), ''Update'' (Atualizar) e ''Delete'' (Remover): são operações básicas utilizadas em um software que gerencia bancos de dados. | | ''CRUD'' || Sigla para ''Create'' (Criar), ''Read'' (Ler), ''Update'' (Atualizar) e ''Delete'' (Remover): são operações básicas utilizadas em um software que gerencia bancos de dados. | ||
+ | |- | ||
+ | | ''CSS'' || Acrônimo para a expressão inglesa ''Cascading Style Sheets''; é uma linguagem de folhas de estilo utilizada para definir a apresentação de documentos escritos em uma linguagem de marcação, como ''HTML'' ou ''XML''. | ||
+ | |- | ||
+ | | ''DAO'' || Acrônimo para a expressão inglesa ''Data Access Object''; é um padrão para persistência de dados que permite separar regras de negócio das regras de acesso ao SGBD. | ||
|- | |- | ||
| ''DBA'' || ''Database Administrator'' ou administrador de bancos de dados. | | ''DBA'' || ''Database Administrator'' ou administrador de bancos de dados. | ||
Linha 51: | Linha 66: | ||
| Java || Linguagem de programação orientada a objetos. | | Java || Linguagem de programação orientada a objetos. | ||
|- | |- | ||
− | | Java EE || Plataforma de desenvolvimento Java voltada para ambientes corporativos/empresariais | + | | Java EE || Plataforma de desenvolvimento Java voltada para ambientes corporativos/empresariais; também chamada de ''Java Enterprise Edition'' (''JEE''). |
+ | |- | ||
+ | | ''Javascript'' || Linguagem de programação para navegadores web; é baseada em scripts, orientada a objetos e com sintaxe similar à linguagem de programação C. | ||
|- | |- | ||
| Login || Ato de fornecer credenciais a um determinado sistema, de modo a acessar suas funcionalidades. | | Login || Ato de fornecer credenciais a um determinado sistema, de modo a acessar suas funcionalidades. | ||
Linha 81: | Linha 98: | ||
| ''WAP'' || Sigla para ''Wireless Application Protocol'' ou protocolo para aplicações sem fio. | | ''WAP'' || Sigla para ''Wireless Application Protocol'' ou protocolo para aplicações sem fio. | ||
|- | |- | ||
− | | '' | + | | ''Webservice'' || De acordo com a W3C, ''webservice'' é um sistema de software responsável por proporcionar a interação entre duas máquinas através de uma rede de computadores. |
+ | |- | ||
+ | | ''XHTML'' || Acrônimo para a expressão inglesa ''eXtensible Hypertext Markup Language''; é uma reformulação da linguagem de marcação ''HTML'', baseada em XML. Combina as ''tags'' de marcação da linguagem ''HTML'' com regras da linguagem ''XML''. | ||
|- | |- | ||
| ''XML'' || ''eXtensible Markup Language'' é uma linguagem de marcação, recomendada pela W3C, que define um conjunto de regras para a codificação de documentos. | | ''XML'' || ''eXtensible Markup Language'' é uma linguagem de marcação, recomendada pela W3C, que define um conjunto de regras para a codificação de documentos. | ||
Linha 87: | Linha 106: | ||
| ''XSLT'' || ''XSL Transformations'' é uma linguagem de marcação XML usada para transformar documentos XML em outros documentos XML ou em outros formatos. | | ''XSLT'' || ''XSL Transformations'' é uma linguagem de marcação XML usada para transformar documentos XML em outros documentos XML ou em outros formatos. | ||
|- | |- | ||
+ | | ''W3C'' || ''World Wide Web Consortium'' é um consórcio de empresas de tecnologia que desenvolve padrões para a criação e a interpretação dos conteúdos para web. | ||
|} | |} | ||
== '''Restrições da arquitetura''' == | == '''Restrições da arquitetura''' == | ||
− | <font color=red> TODO: verificar se existem restrições impostas que foram obedecidas. | + | <font color=red> TODO: verificar se existem restrições impostas que foram obedecidas e incluí-las nesta seção. </font> |
− | + | ||
== '''Justificativas arquiteturais''' == | == '''Justificativas arquiteturais''' == | ||
Linha 98: | Linha 117: | ||
<br> | <br> | ||
;Requisitos do projeto PJe 2.0. | ;Requisitos do projeto PJe 2.0. | ||
− | : O conjunto completo de premissas e requisitos (funcionais e não funcionais) consta no Plano Geral do Projeto PJe 2.0 | + | : O conjunto completo de premissas e requisitos (funcionais e não funcionais) consta no Plano Geral do Projeto PJe 2.0. A saber, explicitamos apenas um resumo desse conjunto: |
* Isolamento dos módulos de negócio (ou seja, módulos responsáveis pela lógica de negócio do software PJe) a fim de evitar efeitos colaterais indesejáveis provenientes das modificações no código-fonte. | * Isolamento dos módulos de negócio (ou seja, módulos responsáveis pela lógica de negócio do software PJe) a fim de evitar efeitos colaterais indesejáveis provenientes das modificações no código-fonte. | ||
* Permitir que o desenvolvimento dos módulos de negócio seja realizado isoladamente, inclusive com equipes distribuídas. | * Permitir que o desenvolvimento dos módulos de negócio seja realizado isoladamente, inclusive com equipes distribuídas. | ||
Linha 107: | Linha 126: | ||
;Experiências prévias. | ;Experiências prévias. | ||
: Foram consideradas as seguintes experiências: | : Foram consideradas as seguintes experiências: | ||
− | * Experiência prévia da equipe de arquitetos servidores do Poder Judiciário. | + | * Experiência prévia da equipe de arquitetos servidores do Poder Judiciário. Alguns dos arquitetos com experiência no software PJe 1.0. |
− | * Foram analisadas arquiteturas de referência | + | * Foram analisadas arquiteturas de referência das seguintes instituições: TCU, STF, SERPRO, TJRO e TJPE. |
* Estudos diversos foram realizados pela equipe de arquitetos na primeira ''Sprint'' do projeto. | * Estudos diversos foram realizados pela equipe de arquitetos na primeira ''Sprint'' do projeto. | ||
<br> | <br> | ||
− | ;Tecnologias adotadas. | + | ;Tecnologias adotadas. |
: As tecnologias e/ou ferramentas adotadas para a implementação foram selecionadas a partir da análise dos requisitos do projeto PJe 2.0: | : As tecnologias e/ou ferramentas adotadas para a implementação foram selecionadas a partir da análise dos requisitos do projeto PJe 2.0: | ||
− | * ''Java Enterprise Edition'' (JEE): a escolha pela plataforma JEE foi um consenso dada a notória posição de destaque dessa plataforma na construção de aplicações corporativas com grande volume de acesso e necessidade de escalabilidade, de robustez, de segurança, de controle de transação e de processamento em ''batch'', entre outras necessidades. Além disso, a plataforma JEE traz um conjunto expressivo de ''API''s que aumentam a produtividade da construção do software | + | * ''Java Enterprise Edition Platform specification'' (''JEE''): a escolha pela plataforma ''JEE'' foi um consenso dada a notória posição de destaque dessa plataforma na construção de aplicações corporativas com grande volume de acesso e necessidade de escalabilidade, de robustez, de segurança, de controle de transação e de processamento em ''batch'', entre outras necessidades. Além disso, a plataforma ''JEE'' traz um conjunto expressivo de ''API''s que aumentam a produtividade da construção do software, encapsulam parte da complexidade inerente às funções que as ''API''s implementam, promovem a definição de padrões de desenvolvimento, contemplando independência de servidor de aplicações. |
− | * ''Apache Maven'': a escolha pela ferramenta ''Maven'' foi norteada pela necessidade de modularização do software e pela adoção da plataforma JEE, como também pelo consenso, na comunidade de desenvolvedores Java, de que a ferramenta ''Maven'' é a melhor ferramenta para gerenciamento de ''builds'' e dependências na atualidade. | + | * ''Apache Maven'': a escolha pela ferramenta ''Maven'' foi norteada pela necessidade de modularização do software e pela adoção da plataforma ''JEE'', como também pelo consenso, na comunidade de desenvolvedores Java, de que a ferramenta ''Maven'' é a melhor ferramenta para gerenciamento de ''builds'' e dependências na atualidade. |
* ''Git'': a escolha pela ferramenta ''Git'' (um software de controle de versões de código-fonte) se deu pela complexidade do ambiente de desenvolvimento do software PJe no qual é desejável que várias equipes, em diferentes localidades (Tribunais de Justiça), estejam trabalhando, paralelamente, no desenvolvimento de diferentes módulos do software PJe e, também, na manutenção dos módulos já implementados. | * ''Git'': a escolha pela ferramenta ''Git'' (um software de controle de versões de código-fonte) se deu pela complexidade do ambiente de desenvolvimento do software PJe no qual é desejável que várias equipes, em diferentes localidades (Tribunais de Justiça), estejam trabalhando, paralelamente, no desenvolvimento de diferentes módulos do software PJe e, também, na manutenção dos módulos já implementados. | ||
− | * ''JBoss Enterprise Application Platform'' (''JBoss''): a escolha pelo servidor de aplicações ''Red Hat JBoss'' é justificada pela reconhecida posição de destaque, entre a comunidade de desenvolvedores JEE, deste servidor de aplicação que oferece a completa implementação das ''API''s da plataforma JEE. Além disso, a versão do ''JBoss'' denominada ''EAP'' (''Enterprise Application Platform''), em particular, foi a escolhida porque permite a contratação do serviço de suporte da empresa ''Red Hat''. É importante destacar que, o uso do servidor de aplicações ''JBoss'' é adotado como o servidor de aplicação padrão do projeto e, para o uso de outro servidor de aplicação diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas. | + | * ''JBoss Enterprise Application Platform'' (''JBoss EAP''): a escolha pelo servidor de aplicações ''Red Hat JBoss'' é justificada pela reconhecida posição de destaque, entre a comunidade de desenvolvedores ''JEE'', deste servidor de aplicação que oferece a completa implementação das ''API''s da plataforma ''JEE''. Além disso, a versão do ''JBoss'' denominada ''EAP'' (''Enterprise Application Platform''), em particular, foi a escolhida porque permite a contratação do serviço de suporte da empresa ''Red Hat''. É importante destacar que, o uso do servidor de aplicações ''JBoss'' é adotado como o servidor de aplicação padrão do projeto e, para o uso de outro servidor de aplicação diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas. |
− | * ''PostgreSQL'': a escolha do SGBD ''PostgreSQL'' deve-se pelo fato deste SGBD ser de uso gratuito e ''open source''( | + | * ''PostgreSQL'': a escolha do SGBD ''PostgreSQL'' deve-se pelo fato deste SGBD ser de uso gratuito e ''open source'' (ou seja, é um software cujo código-fonte está aberto para comunidade), implementar o padrão objeto-relacional com a robustez desejada pelo projeto. Além de, ser um SGBD amplamente utilizado pela comunidade de desenvolvedores de diversas linguagens de programação. É importante destacar que, o uso do SGBD ''PostgreSQL'' é adotado como o SGBD padrão do projeto e, para o uso de outro SGBD diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas. |
<br> | <br> | ||
+ | <font color=red> TODO: falta definir quais serão os navegadores web padrões que serão adotados para o software PJe 2.0 e incluir as justificativas. | ||
+ | </font> | ||
+ | |||
= '''Definição da arquitetura de referência''' = | = '''Definição da arquitetura de referência''' = | ||
− | + | Nesta seção descrevemos a arquitetura de referência definida para o desenvolvimento do software PJe 2.0 e suas evoluções futuras. A sigla batizada para arquitetura de referência é '''ArqJus'''. Dentre os assuntos que serão tratados, podemos destacar: a forma como a arquitetura foi estruturada/organizada e as responsabilidades da arquitetura. É importante informarmos que, '''ArqJus''' também poderá ser reutilizada para outros projetos cujo domínio do negócio seja diferente do PJe. | |
− | + | '''ArqJus''' é formada por 5 '''"camadas"''' lógicas relacionadas entre si e, além das camadas, é possível agruparmos logicamente elementos da arquitetura por meio de '''"módulos"'''. Vejamos o significado desses dois conceitos importantes: | |
− | + | *'''Camada''': representa uma associação abstrata de elementos que atendem a um conjunto bem definido de responsabilidades dentro do contexto do software. | |
− | + | *'''Módulo''': são blocos de implementação (código-fonte, arquivos de configuração, arquivos de propriedades, arquivos de ''templates'' (ou modelos) de janelas gráficas, scripts de banco de dados, etc.) responsáveis por um ou mais serviços ofertados pelo software. Um módulo é classificado por um dos seguintes tipos assim definidos: | |
+ | **'''Tipo 1''': é um módulo que representa abstrações do modelo de negócio inerente ao software, em outras palavras, um '''módulo do tipo 1''' agrupa classes Java que representam conceitos do domínio do negócio. Também o chamaremos de '''módulo de negócio'''. Um módulo do tipo 1 '''não pode conhecer''' um outro módulo do tipo 1, caso contrário, será violado a independência entre esses módulos. Todo módulo tipo 1 deve ter: uma única ''interface'' Java, local e/ou remota e a classe Java que implementa os serviços ofertados por essa ''interface''. | ||
+ | **'''Tipo 2''': é um módulo que representa abstrações da própria '''ArqJus''', em outras palavras, um '''módulo do tipo 2''' agrupa classes Java e um conjunto de arquivos que fazem parte da arquitetura. Exemplo desse conjunto de arquivos: ''XHTML'', ''CSS'', ''Javascript'', ''HTML'', ''XML'', etc. Um módulo do tipo 2 '''pode conhecer''' um outro módulo do tipo 2. | ||
+ | Concretamente, cada módulo tornar-se-á um projeto específico gerenciado pelo aplicativo ''Maven''. Dessa forma, garantiremos o isolamento dos módulos do software. Além de ser gerenciado pelo ''Maven'', cada módulo é construído separadamente, com repositório próprio no aplicativo ''Git'' e com versionamento exclusivo, permitindo o isolamento do código-fonte e a especialização das equipes de desenvolvimento, contribuindo com o objetivo de facilitar a manutenção do software e minimizar os impactos de efeitos colaterais das diversas manutenções do software. | ||
+ | <br><br> | ||
+ | Explicaremos nas próximas subseções mais detalhes da '''ArqJus''' por meio de visões gráficas arquiteturais. | ||
+ | <br> | ||
+ | == '''Visão geral das camadas da arquitetura''' == | ||
+ | A primeira visão da '''ArqJus''' é exibida na Figura 1 e a denominamos de '''Visão Geral das Camadas da Arquitetura'''. | ||
+ | <br><br> | ||
+ | '''Figura 1. Visão Geral das Camadas da Arquitetura.''' | ||
+ | [[Arquivo:VisaoDeCamadas.jpg | '''Figura 1. Visão Geral das Camadas da Arquitetura.''' | 1000px]] | ||
+ | <br> | ||
+ | <font color=red> TODO: Deve-se explicar 'qual camada conhece qual camada' na Figura 1</font> | ||
+ | <br><br> | ||
+ | Conforme pode ser visto na Figura 1, há 5 '''camadas''' lógicas e a definição de cada uma dessas camadas é apresentada seguir: | ||
+ | #'''Camada de Apresentação''': encapsula toda a lógica de interação com usuários, desde a exibição de informações, passando pela captura de dados informados pelos usuários por meio das janelas gráficas do software, até o reconhecimento de ações realizadas nessas janelas gráficas. | ||
+ | #'''Camada de ''API''s''': encapsula o acesso aos módulos ofertados pelo software. Normalmente, nesta camada terão módulos do tipo 2. | ||
+ | #'''Camada de Negócio''': encapsula toda a lógica do domínio de negócio do software, ou seja, as regras de manipulação dos dados e informações controlados pelo software. | ||
+ | #'''Camada de Domínio''': encapsula as representações dos dados e informações inerentes ao domínio de negócio do software, em outras palavras, esta camada é responsável pela realização do mapeamento objeto-relacional. | ||
+ | #'''Camada de Serviços''': encapsula toda a lógica de acesso ao software, servindo como porta de entrada de requisições dos diversos clientes do software, por exemplo: requisições de usuários por meio de janelas gráficas; requisições de outros softwares por meio de ''webservices''. | ||
+ | <font color=red> TODO: citar as tecnologias adotadas na ArqJus predominantes em cada uma das camadas</font> | ||
+ | <br> | ||
− | + | == '''Visão modular da arquitetura''' == | |
− | + | A segunda visão da '''ArqJus''' é exibida na Figura 2 e a denominamos de '''Visão Modular da Arquitetura'''. | |
− | + | <br><br> | |
− | + | '''Figura 2. Visão Modular da Arquitetura.''' | |
− | + | [[imagem:Visao_Modular_da_Arquitetura.jpg | '''Figura 2. Visão Modular da Arquitetura.'''| 1000px]] | |
− | + | <br> | |
− | + | Na Figura 2 apresentamos uma visão da '''ArqJus''' contemplando os conceitos já explicados: camadas e módulos. Nessa visão também demonstramos um exemplo de uso da arquitetura. Observando a Figura 2 no sentido 'de cima para baixo', explicaremos, a seguir, a estrutura da '''ArqJus''': | |
− | + | # Um módulo tipo 2 que denominamos de '''Módulo WEB'''. Esse módulo no aplicativo ''Maven'' é denominado '''pje-web'''. Nesse módulo inclui-se: | |
− | + | ## Uma pasta denominada '''recursos''' que contém um conjunto de arquivos. Exemplos desses arquivos: ''XHTML'', ''CSS'', ''Javascript'', imagens, entre outros. | |
− | + | ## Um pacote denominado '''controlador''' que contém classes Java que realizam o trabalho definido pela Camada de Apresentação do software. Somente as classes desse pacote têm acesso ao conjunto de arquivos da pasta '''recursos'''. Também poderemos chamá-las de classes controladoras (ou ''backbeans''). Essas classes também têm acesso às ''interfaces'' Java do '''Módulo Orquestrador'''. Também podem ter acesso às ''interfaces'' Java de módulos do tipo 1 (módulo de negócio) que existirem no software, por exemplo: na Figura 2, a classe Java 'MinhaEntidadeAOperacaoCtrl' acessa o módulo 'Meu negócio A' por meio de sua ''interface'' Java.<br> | |
− | + | # Um módulo tipo 2 que denominamos de '''Módulo Orquestrador'''. Esse módulo no aplicativo ''Maven'' é denominado '''pje-service'''. Nesse módulo inclui-se: | |
− | + | ## Um pacote denominado '''api''' que contém ''interfaces'' Java que representam o trabalho definido pela Camada de ''API''s'' do software. | |
− | + | ## Um pacote denominado '''impl''' que contém classes Java que implementam o trabalho definido pela Camada de Serviços do software. Em outras palavras, uma classe Java do pacote '''impl''' implementa os serviços ofertados por uma ''interface'' Java do pacote '''api''' correspondente. <br>Uma classe do pacote '''impl''' não, necessariamente, implementa por completo um determinado serviço o qual ela é responsável. Logo, é possível que essa classe obtenha o resultado de 'partes desse serviço' por meio de um outro módulo da '''ArqJus'''. Um exemplo: na Figura 2 temos um ou mais serviços da classe 'MeuServicoSrv' fazendo uso de serviços disponíveis nas ''interfaces'' Java 'IMeuNegocioASrv' do módulo 'Meu negócio A' e 'IMeuNegocioBSrv' do módulo 'Meu negócio B'.<br> | |
− | + | # 'Meu Negócio A' é exemplo de como pode ser estruturado um módulo tipo 1 no software. Nesse exemplo, inclui-se: | |
− | + | ## Uma ''interface'' Java denominada 'IMeuNegocioASrv'; essa ''interface'' representa o trabalho definido pela Camada de ''API''s'' do módulo 'Meu Negócio A'. | |
− | + | ## Uma classe Java denominada 'MeuNegocioASrv'; essa classe implementa os serviços ofertados pela Camada de Serviços do módulo 'Meu Negócio A'. Em outras palavras, a classe 'MeuNegocioASrv' implementa os serviços ofertados pela ''interface'' Java 'IMeuNegocioASrv'. | |
− | + | ## Uma ou mais classes Java que implementam o trabalho definido pela Camada de Negócio do módulo 'Meu Negócio A'. Exemplos: na Figura 2 temos as classes 'MinhaEntidadeAManager' e 'MinhaEntidadeCManager' e as suas classes ''DAO'' correspondentes. <br> | |
− | + | # 'Meu Negócio B' é exemplo de como pode ser estruturado um módulo tipo 1 no software. Nesse exemplo, inclui-se: | |
− | -- | + | ## Uma ''interface'' Java denominada 'IMeuNegocioBSrv'; essa ''interface'' representa o trabalho definido pela Camada de ''API''s'' do módulo 'Meu Negócio B'. |
+ | ## Uma classe Java denominada 'MeuNegocioBSrv'; essa classe implementa os serviços ofertados pela Camada de Serviços do módulo 'Meu Negócio B'. Em outras palavras, a classe 'MeuNegocioBSrv' implementa os serviços ofertados pela ''interface'' Java 'IMeuNegocioBSrv'. | ||
+ | ## Uma ou mais classes Java que implementam o trabalho definido pela Camada de Negócio do módulo 'Meu Negócio B'. Exemplos: na Figura 2 temos as classes 'MinhaEntidadeBManager' e sua classe ''DAO'' correspondente. <br> | ||
+ | # Um módulo tipo 2 que denominamos de '''Módulo Modelo'''. Esse módulo no aplicativo ''Maven'' é denominado '''pje-modelo'''. Nesse módulo inclui-se: | ||
+ | ## Um pacote denominado '''modelo''' que contém classes Java que realizam o trabalho definido pela Camada de Domínio do software. Por exemplo: na Figura 2 temos as classes 'MinhaEntidadeA', 'MinhaEntidadeB' e 'MinhaEntidadeC'. Todos os módulos do software (tanto módulo do tipo quanto do tipo 2) têm acesso às classes do pacote '''modelo'''. | ||
− | A | + | É importante destacar que: |
+ | * O módulo de negócio 'Meu Negócio A' '''não conhece''' o módulo de negócio 'Meu Negócio B', logo, está consistente com a definição de módulo tipo 1. | ||
+ | * Uma classe Java pertencente à Camada de Negócio pode acessar uma outra classe da Camada de Negócio desde que, ambas classes, pertençam ao mesmo módulo de negócio. | ||
+ | * Classes Java da Camada de Negócio podem ser acessadas por classes Java da Camada de Serviços somente dentro de um mesmo módulo de negócio. | ||
+ | == '''Organização dos projetos no ''Maven''''' == | ||
+ | Nesta subseção, apresentamos a organização dos projetos no aplicativo ''Maven'', consolidando os módulos citados no decorrer da explicação da Figura 2 e outros módulos necessários para estruturação da '''ArqJus'''. | ||
− | + | * '''pje-pom''': projeto que contém as dependências que são comuns entre todos os demais projetos. Não deve conter código-fonte, apenas as configurações dessas dependências. O aplicativo ''Maven'' exige a presença do arquivo ''POM'' (''Project Object Model''). | |
− | + | * '''pje-modelo''': projeto que contém todas as entidades de domínio do negócio mapeadas de acordo com o padrão ''JPA'' (''Java Persistence API''). | |
+ | * '''pje-comum''': projeto que contém todas as classes Java utilitárias do software. Também é classificado como um módulo tipo 2. Exemplos de classes Java desse projeto: classes que implementam os registros de auditoria das operações do software (também chamado de registro de ''log''), classes que implementam o controle de acesso, o tratamento de exceções, entre outras classes responsáveis pela infraestrutura do software. | ||
+ | * '''pje-service''': projeto que contém as classes do '''Módulo Orquestrador''' das funcionalidades que envolvam mais de um módulo de negócio. | ||
+ | * '''pje-web''': projeto que contém todo o código-fonte associado à Camada de Apresentação, exemplos: classes controladoras (também conhecidas por ''back-beans''), arquivos ''HTML'', ''XHTML'', ''CSS'' e scripts ''JavaScript''. | ||
− | + | A nomenclatura de cada projeto específico no aplicativo ''Maven'' obedece o padrão '''pje<modulo>''', em 'modulo' deve conter o nome do módulo correspondente. | |
− | + | ||
− | + | Os projetos no ''Maven'' serão empacotados em arquivos com extensão ''jar'' (''Java ARchive''), com exceção do projeto "pje-web", que será empacotado em um arquivo com extensão ''war'' (''Web application ARchive''). | |
− | + | ||
+ | Para cada módulo do software, independente do tipo do módulo, será preciso criar três arquivos com extensão ''jar'', vejamos: | ||
+ | # pje-modulo-X.Y.Z.jar: este arquivo contém todas as classes Java do módulo e será utilizado no momento da instalação (''deploy'') do módulo. | ||
+ | # pje-modulo-X.Y.Z-api.jar: este arquivo contém apenas as ''interfaces'' Java do respectivo módulo e será utilizado como dependência na implementação dos módulos "pje-web" e "pje-service". Lembrando que, os módulos "pje-web" e "pje-service" somente terão acesso à Camada de ''APIs'' do módulo em questão. | ||
+ | # pje-modulo-X.Y.Z-sources.jar: este arquivo contém o código-fonte do módulo e será utilizado para fins de depuração do código-fonte (ou ''debug''). | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | == '''Visão de ''Deployment'' da Arquitetura''' == | |
+ | Esta subseção tem o objetivo de apresentar os principais componentes envolvidos no processo de ''deploy'' do software. | ||
+ | <br><br> | ||
+ | '''Figura 3. Visão de ''Deployment'' do Software.''' | ||
+ | [[Arquivo:VisaoDeDeployment.jpg | '''Figura 3. Visão de Deployment do Software.''' | 1050px]] | ||
+ | <br> | ||
+ | A Figura 3 apresenta a visão de implantação padrão do software PJe 2, conforme definido pela arquitetura estabelecida. É possível identificar os principais recursos envolvidos no processo de ''deploy'', desde o servidor de aplicação e o servidor de banco de dados, passando pelo ''build'' da aplicação, até alguns arquivos de configuração de maior relevância para o funcionamento do PJe 2. | ||
+ | <br><br> | ||
+ | Para configurar o ''log'' da aplicação é necessário ajustar alguns parâmetros no arquivo "core_configurations.properties", localizado no módulo ''pje2-comum''. Além dos 5 parâmetros listados abaixo, é necessário definir a variável de ambiente '''PJE2_LOGFILE_PATH''', com o path onde o arquivo HTML contendo o log será gravado. Caso esta variável não esteja corretamente definida, será considerado o local default ''/tmp''. | ||
+ | * '''logger.level''': define quais níveis de log serão exibidos, tanto no arquivo HTML quanto no log do servidor de aplicação. Os valores permitidos são os definidos pela API Logger de Java (ALL, CONFIG, FINE, FINER, FINEST, INFO, OFF, SEVERE, WARNING). | ||
+ | * '''logger.useparenthandlers''': define se o log do servidor de aplicação será utilizado ou não. Os valores aceitos são ''true'' e ''false''. | ||
+ | * '''logger.file.name''': define o nome do arquivo HTML que contém o log formatado. | ||
+ | * '''logger.file.size''': define o tamanho máximo do arquivo HTML gerado, em bytes. | ||
+ | * '''logger.file.backups''': define a quantidade de arquivos HTML que serão mantidos quando o arquivo HTML atingir o tamanho máximo definido no parâmetro ''logger.file.size''. | ||
+ | <br> | ||
+ | Para habilitar o acesso remoto ao servidor de banco de dados ''PostgreSQL'' é necessário realizar ajustes nas configurações definidas nos arquivos “pg_hba.conf” e “postgresql.conf”. Para identificar a localização física destes arquivos, é possível executar os comandos “show hba_file” e “show config_file”, respectivamente, no console do ''PostgreSQL''. Os ajustes necessários podem ser verificados na documentação on-line do SGBD. | ||
+ | <br><br> | ||
+ | Para criar e configurar os ''datasources'' do PJe 2 é necessário manipular os arquivos “module.xml”, “jdbc-postgresql.jar”, "jdbcdslog.jar" e “standalone.xml”, conforme descrito posteriormente neste documento. Já o arquivo “persistence.xml” é utilizado para configurar como o provider JPA irá se conectar aos datasources criados. | ||
+ | <br><br> | ||
+ | Uma vez criados os ''datasources'', é possível realizar o ''deploy'' padrão do PJe 2 a partir do arquivo “pje-web.war” disponibilizado pelo CNJ. Este arquivo é composto por todos os módulos do software, empacotados em arquivos ''.jar'' conforme já mencionado em sessão anterior deste documento. | ||
+ | <br><br> | ||
− | + | = '''Padrões, regras e boas práticas''' = | |
+ | Esta seção tem o objetivo de apresentar os padrões estabelecidos, as regras definidas e algumas boas práticas de programação para construção do software sob a consonância com os requisitos da '''ArqJus'''. As explicações serão divididas nas subseções desta seção. | ||
− | == ''' | + | == '''Padrões de nomenclatura e codificação''' == |
+ | * Padrões de nomenclatura para '''classes Java''': | ||
+ | ** Classes do Módulo Web (também chamaremos de "controladores/controlador(a)" ou de ''backbeans''): <Entidade><operação>Ctrl.java | ||
+ | ** ''Interfaces'' Java do Módulo Orquestrador (também chamaremos de "orquestradores/orquestrador(a)"): I<Serviço>Srv.java | ||
+ | ** Implementações dos orquestradores: <Serviço>Srv.java | ||
+ | ** ''Interfaces'' Java dos módulos: I<Módulo>Srv.java | ||
+ | ** Implementações dos módulos: <Módulo>Srv.java | ||
+ | ** Classes de negócio (também chamaremos de "''managers''/''manager''"): <Entidade>Manager.java | ||
+ | ** Classes de acesso aos dados: <Entidade>DAO.java | ||
+ | ** Entidades: <Entidade>.java | ||
+ | <br> | ||
+ | * Padrões de nomenclatura para '''pacotes Java''': | ||
+ | ** br.jus.cnj.pje.web.controlador: todos os controladores do software devem pertencer a este pacote. | ||
+ | ** br.jus.cnj.pje.service.api: todas as ''interfaces'' Java dos orquestradores do software devem pertencer a este pacote. | ||
+ | ** br.jus.cnj.pje.service.impl: todas as implementações das ''interfaces'' Java dos orquestradores devem pertencer a este pacote. | ||
+ | ** br.jus.cnj.pje.<negócio>.api: a ''interface'' Java do módulo deve pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio. | ||
+ | ** br.jus.cnj.pje.<negócio>.impl: a implementação da ''interface'' Java do módulo deve pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio. | ||
+ | ** br.jus.cnj.pje.<negócio>.manager: todas as classes de negócio (''managers'') do módulo de negócio devem pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio. | ||
+ | ** br.jus.cnj.pje.<negócio>.dao: todas as classes de acesso aos dados inerentes ao módulo de negócio devem pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio. | ||
+ | ** br.jus.cnj.pje.modelo: todas as classes das entidades mapeadas no padrão ''JPA'' devem pertencer a este pacote. | ||
+ | <br> | ||
+ | * Padrões de nomenclatura para '''arquivos ''XHTML''''': | ||
+ | ** <entidade><operação>.xhtml: entende-se por <entidade> o nome da principal da entidade manipulada pela janela gráfica (ou tela), e por <operação> a principal manipulação que se deseja realizar a partir desta tela (visualizar, excluir, alterar, desativar, cadastrar, etc). | ||
+ | <br> | ||
+ | É importante ressaltar que, os padrões apresentados no decorrer da explicação da Figura 2 também foram considerados. | ||
− | + | Além dos padrões definidos nesta subseção, recomendamos a adoção do padrão de codificação Java, disponível no endereço http://www.oracle.com/technetwork/java/codeconvtoc-136057.html. | |
− | + | == '''Regras definidas''' == | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | '''<u>Sobre o relacionamento entre classes:</u>''' | |
− | + | É permitido na '''ArqJus''' o relacionamento entre as diversas classes do software distribuídas nos módulos e nas camadas lógicas, logo, esse relacionamento deve obedecer as seguintes regras: | |
− | -- | + | # Um orquestrador deve ser criado sempre que houver a necessidade de uma operação no Módulo Controlador que envolva mais de um módulo de negócio. |
+ | # As classes dos controladores apenas terão acesso às ''interfaces'' Java dos serviços ofertados pelos orquestradores e módulos de negócio. | ||
+ | # Para cada tela (ou arquivo ''XHTML'') deve haver um controlador específico e único. | ||
+ | # Todas as operações que um módulo de negócio disponibilizará devem ser expostas através de sua Camada de ''API'' (ou ''interface'' Java). | ||
+ | # Os módulos de negócio não podem, em hipótese alguma, acessar funcionalidades e/ou classes de outros módulos de negócio. Somente poderão acessar classes e funcionalidades disponíveis nos projetos '''pje-modelo''' e '''pje-comum'''. | ||
+ | # As classes managers de um módulo só podem ser acessadas pela classe que implementa a ''interface'' Java desse módulo em questão, ou pelos demais ''managers'' do mesmo módulo. | ||
+ | # As regras de negócio devem ser implementadas exclusivamente nas classes ''managers'' correspondentes. | ||
+ | # O BaseDAO já oferece um conjunto de métodos implementados para as operações de consulta (com ou sem paginação), inclusão, alteração e exclusão das entidades. Caso sejam necessários métodos de acesso/manipulação de dados específicos para uma entidade, deve ser implementada uma, e apenas uma, classe no padrão ''DAO'' que estende o BaseDAO. | ||
+ | # Cada classe ''DAO'' só deve ser acessada pela sua classe ''manager'' correspondente. | ||
+ | # Validações dos atributos que caracterizam uma entidade (por exemplo: não nulo, não vazio, restrição de tamanho, restrição de valores) devem ser realizadas na própria entidade, por meio das anotações disponíveis na ''API Bean Validation'' da especificação ''JEE''. | ||
− | = ''' | + | == '''Utilização da Classe Filter''' == |
+ | A classe ''br.jus.cnj.pje.comum.utils.filter.Filter'', localizada no módulo ''pje2-comum'', tem por objetivo permitir a construção de queries orientadas a objeto, utilizando a Java Persistence Query Language (JPQL), encapsulando detalhes de implementação, gerando padronização de código-fonte, menor complexidade e, consequentemente, menor esforço para manutenção. | ||
+ | * Principais aplicações: | ||
+ | ** Adicionar restrições na cláusula WHERE: =, >, <, LIKE, IS NULL, IN além de várias outras; | ||
+ | ** Navegar pelo grafo de objetos sem limite de profundidade; | ||
+ | ** Determinar FETCH em qualquer propriedade no grafo de objetos; | ||
+ | ** Formar cláusulas WHERE complexas, através dos conjuntivos AND e OR; | ||
+ | ** Determinar qual tipo de JOIN será utilizado nos relacionamentos; | ||
+ | ** Realizar ordenações; | ||
+ | ** Paginar consultas. | ||
+ | * Exemplos de uso: | ||
+ | ** Restrições na cláusula WHERE <br> Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
+ | filter.addEquals("login", "admin"); | ||
+ | filter.addBetween("birthDate", new Date(), new Date()); | ||
+ | filter.addLikeIgnoreCase("name", "%José"); | ||
+ | filter.addGreaterOrEqualThan("id", 10L); | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | Select //All properties of User | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | where | ||
+ | user0_.login=? | ||
+ | and ( | ||
+ | user0_.birth_date between ? and ? | ||
+ | ) | ||
+ | and ( | ||
+ | upper(user0_.name) like ? | ||
+ | ) | ||
+ | and user0_.id>=10 | ||
+ | </pre> | ||
+ | ** Navegação no grafo de objetos <br> Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
+ | filter.addEquals("profiles.screens.module.name", "Controle de Acesso"); | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | Select //All properties of User | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | inner join | ||
+ | systemuser_accessprofile profiles1_ | ||
+ | on user0_.id=profiles1_.systemuser | ||
+ | inner join | ||
+ | AccessProfile accessprof2_ | ||
+ | on profiles1_.accessprofile=accessprof2_.id | ||
+ | inner join | ||
+ | accessprofile_screen screens3_ | ||
+ | on accessprof2_.id=screens3_.accessprofile | ||
+ | inner join | ||
+ | Screen screen4_ | ||
+ | on screens3_.screen=screen4_.id | ||
+ | inner join | ||
+ | Module module5_ | ||
+ | on screen4_.module=module5_.id | ||
+ | where | ||
+ | module5_.name=? | ||
+ | </pre> | ||
+ | **Definição do FETCH nas propriedades <br> Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
+ | filter.fetch("profiles"); | ||
+ | filter.fetch("blockedFunctionalities"); | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | select //All properties of User, AccessProfile(profiles) and | ||
+ | //Functionality(blockedFunctionalities) | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | inner join | ||
+ | systemuser_accessprofile profiles1_ | ||
+ | on user0_.id=profiles1_.systemuser | ||
+ | inner join | ||
+ | AccessProfile accessprof2_ | ||
+ | on profiles1_.accessprofile=accessprof2_.id | ||
+ | inner join | ||
+ | exceptions_systemuser_functionality blockedfun3_ | ||
+ | on user0_.id=blockedfun3_.systemuser | ||
+ | inner join | ||
+ | Functionality functional4_ | ||
+ | on blockedfun3_.functionality=functional4_.id | ||
+ | where | ||
+ | 1=1 | ||
+ | </pre> | ||
+ | Código: | ||
+ | <pre> | ||
+ | Filter<Client> filter = new Filter<Client>(Client.class); | ||
+ | filter.addEquals("address.streetType.name", "Rua",JoinTypes.INNER,true); | ||
+ | //addEquals(attribute, value, joinType, fetch) | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | select //All properties of User, AccessProfile(profiles) and | ||
+ | //Functionality(blockedFunctionalities) | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | inner join | ||
+ | systemuser_accessprofile profiles1_ | ||
+ | on user0_.id=profiles1_.systemuser | ||
+ | inner join | ||
+ | AccessProfile accessprof2_ | ||
+ | on profiles1_.accessprofile=accessprof2_.id | ||
+ | inner join | ||
+ | exceptions_systemuser_functionality blockedfun3_ | ||
+ | on user0_.id=blockedfun3_.systemuser | ||
+ | inner join | ||
+ | Functionality functional4_ | ||
+ | on blockedfun3_.functionality=functional4_.id | ||
+ | where | ||
+ | 1=1 | ||
+ | </pre> | ||
+ | **Construção de cláusulas WHERE complexas <br> Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
− | = | + | ComposedRestriction orExtern = Filter.createOr(); |
+ | orExtern.addRestriction(Filter.createEquals("active", Boolean.TRUE,null,null)); | ||
+ | ComposedRestriction and = Filter.createAnd(); | ||
+ | and.addRestriction(Filter.createNotEquals("name", "José",null,null)); | ||
+ | and.addRestriction(Filter.createEquals("login", "admin",null,null)); | ||
+ | |||
+ | ComposedRestriction orIntern = Filter.createOr(); | ||
+ | orIntern.addRestriction(Filter.createBetween("birthDate", new Date(), new Date(),null,null)); | ||
+ | orIntern.addRestriction(Filter.createEquals("office", "Arquiteto", null,null)); | ||
+ | |||
+ | and.addRestriction(orIntern); | ||
+ | |||
+ | orExtern.addRestriction(and); | ||
+ | |||
+ | filter.addComposedRestriction(orExtern); | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | select //All properties of User | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | where | ||
+ | user0_.active=? | ||
+ | or (user0_.name<>? and user0_.login=? | ||
+ | and (user0_.birth_date between ? and ? or user0_.office=?) | ||
+ | ) | ||
+ | </pre> | ||
+ | **Definição do tipo de JOIN <br> Código: | ||
+ | <pre> | ||
+ | Filter<Client> filter = new Filter<Client>(Client.class); | ||
+ | filter.addEquals("address.streetType.name", "Rua",JoinTypes.LEFT,false); | ||
+ | filter.addLike("contacts.email", "%gmail%");//Default: INNER | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | Select //All properties of Client | ||
+ | from | ||
+ | Client client0_ | ||
+ | left outer join | ||
+ | Address address1_ | ||
+ | on client0_.address=address1_.id | ||
+ | left outer join | ||
+ | StreetType streettype2_ | ||
+ | on address1_.streettype=streettype2_.id | ||
+ | inner join | ||
+ | client_contact contacts3_ | ||
+ | on client0_.id=contacts3_.client | ||
+ | inner join | ||
+ | Contact contact4_ | ||
+ | on contacts3_.contact=contact4_.id | ||
+ | where | ||
+ | streettype2_.name=? | ||
+ | and ( | ||
+ | contact4_.email like ? | ||
+ | ) | ||
+ | </pre> | ||
+ | Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
+ | filter.addEquals("profiles.name", "Admin",JoinTypes.INNER,false); | ||
+ | filter.addEquals("profiles.name", "Admin",JoinTypes.LEFT,false); | ||
+ | //generates 2 joins: a with INNER and other with LEFT | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | Select //All properties of User | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | inner join | ||
+ | systemuser_accessprofile profiles1_ | ||
+ | on user0_.id=profiles1_.systemuser | ||
+ | inner join | ||
+ | AccessProfile accessprof2_ | ||
+ | on profiles1_.accessprofile=accessprof2_.id | ||
+ | left outer join | ||
+ | systemuser_accessprofile profiles3_ | ||
+ | on user0_.id=profiles3_.systemuser | ||
+ | left outer join | ||
+ | AccessProfile accessprof4_ | ||
+ | on profiles3_.accessprofile=accessprof4_.id | ||
+ | where | ||
+ | accessprof2_.name=? | ||
+ | and accessprof4_.name=? | ||
+ | </pre> | ||
+ | **Ordenações <br> Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
+ | filter.addOrderDesc("name"); | ||
+ | filter.addOrderAsc("profiles.name", JoinTypes.LEFT,false); | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | Select //All properties of User | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | left outer join | ||
+ | systemuser_accessprofile profiles1_ | ||
+ | on user0_.id=profiles1_.systemuser | ||
+ | left outer join | ||
+ | AccessProfile accessprof2_ | ||
+ | on profiles1_.accessprofile=accessprof2_.id | ||
+ | where | ||
+ | 1=1 | ||
+ | order by | ||
+ | user0_.name desc, | ||
+ | accessprof2_.name asc | ||
+ | </pre> | ||
+ | **Paginação de consultas <br> Código: | ||
+ | <pre> | ||
+ | Filter<User> filter = new Filter<User>(User.class); | ||
+ | filter.getPaginator().setPageSize(5); | ||
+ | filter.getPaginator().setFirstResult(10); | ||
+ | </pre> | ||
+ | SQL Gerado: | ||
+ | <pre> | ||
+ | Select //All properties of User | ||
+ | from | ||
+ | systemuser user0_ | ||
+ | where | ||
+ | 1=1 limit ? offset ? | ||
+ | </pre> | ||
+ | *Considerações finais | ||
+ | **Por padrão, qualquer cláusula ou FETCH, que não especifica o tipo de JOIN, utiliza o tipo INNER. | ||
+ | **Por padrão, qualquer cláusula que não especifica o FETCH da propriedade, o Filter entende que NÃO deve ser feito FETCH nesta propriedade. | ||
+ | **Há duas formas de informar ao Filter que se deve fazer FETCh numa propriedade: | ||
+ | ***A primeira é usando o método fetch(String) o qual recebe uma string com o nome da propriedade ou das propriedades aninhadas. Lembrando que não se deve usar propriedade “primitiva” neste método; caso contrário ocorrerá um erro: | ||
+ | <pre> | ||
+ | filter.fetch(“usuarios”) → ok | ||
+ | filter.fetch(“usuarios.name”) → RuntimeException | ||
+ | </pre> | ||
+ | ***A segunda maneira é especificando o parâmetro (Boolean fetch) nas clausulas: | ||
+ | <pre> | ||
+ | boolean isFetch = true; | ||
+ | ... | ||
+ | filter.addEquals(“usuarios.nome”,”José”,JoinTypes.INNER, isFetch); → OK | ||
+ | </pre> | ||
+ | O Filter entende que deve fazer FETCH JOIN com usuários e depois igualar sua propriedade nome a José. Se uma mesma propriedade faz mais de um JOIN com o mesmo tipo, o SQL resultante só fará um único JOIN: | ||
+ | <pre> | ||
+ | filter.addEquals(“usuarios.nome”,”Fulano”,JoinTypes.INNER, false); | ||
+ | filter.addEquals(“usuarios.login”,”beltrano”,JoinTypes.INNER, false); → só haverá um único join com a tabela usuário | ||
+ | </pre> | ||
+ | Se uma mesma propriedade faz mais de um JOIN com tipos diferentes, o SQL resultante fará mais de um JOIN: | ||
+ | <pre> | ||
+ | filter.addEquals(“usuarios.nome”,”Fulano”,JoinTypes.INNER,false); | ||
+ | filter.addEquals(“usuarios.login”,”beltrano”,JoinTypes.LEFT, false); → haverá um inner join e um left join com usuários | ||
+ | </pre> | ||
+ | Por limitações do JPA não é possível com uma mesma propriedade usá-la fazendo FETCH e em seguida sem fazer FETCH. Isso causará erro: | ||
+ | <pre> | ||
+ | filter.addEquals("profiles.screens.id", 1L, JoinTypes.INNER, TRUE); → aqui faz fetch join em profiles e screens | ||
+ | filter.addEquals("profiles.screens.module.id", 1L, JoinTypes.INNER, FALSE); → aqui faz join sem fetch em profiles, screens e module. A ideia dessa consulta seria fazer FETCH apenas em profiles e screens, mas, não em module, mesmo que, seja filtrado por uma propriedade em module. | ||
+ | </pre> | ||
+ | |||
+ | == '''Utilização da Classe BaseDAO''' == | ||
+ | A classe ''br.jus.cnj.pje.comum.BaseDAO'', localizada no módulo ''pje2-comum'' contém os métodos básicos de persistência e acesso das entidades no bando de dados do sistema. Os métodos são genéricos e permitem apenas a utilização das classes que representam as entidades de negócio (''extends'' BaseEntity). | ||
+ | |||
+ | Esta classe supre as necessidades para a maior parte dos cadastros (CRUD) e demais funcionalidades do sistema, no que se refere ao acesso ao banco de dados. Caso seja necessário algum método específico para uma determinada entidade, deve ser criado um DAO específico para esta entidade e este DAO deve ''extends'' a classe BaseDAO. Caso seja necessário sobrescrever algum método do BaseDAO no DAO específico, é fortemente recomendado que seja realizada uma chamada ao método da classe pai, através da palavra reservada ''super''. | ||
+ | |||
+ | == '''Internacionalização''' == | ||
+ | |||
+ | '''<u>Para a internacionalização das mensagens utilizadas nas classes Java:</u>''' | ||
+ | * A ''enum'' ''br.jus.cnj.pje.comum.messages.CoreMessages'', localizada no módulo ''pje-comum'', contém todas as mensagens utilizadas pela aplicação. Cada mensagem é encapsulada por uma enumeração e tem uma chave única, conforme exemplo a seguir:<pre>GENERICO_AVISO_SUCESSO_CADASTRO("generico.aviso.sucessocadastro")</pre> | ||
+ | * A chave da mensagem deve ter sua correspondência no arquivo ''core_messages.properties'', também localizado no módulo ''pje-comum'', conforme exemplo abaixo:<pre>generico.aviso.sucessocadastro=Cadastro realizado com sucesso!</pre> | ||
+ | *A utilização da ''enum'' para internacionalização deve seguir o exemplo que segue. O método ''getMessage()'' permite que qualquer quantidade de parâmetros seja informada, de acordo com a mensagem definida no arquivo ''core_messages.properties''.<pre>CoreMessages.GENERICO_AVISO_SUCESSO_CADASTRO.getMessage();</pre> | ||
+ | '''<u>Para a internacionalização das telas da aplicação:</u>''' | ||
+ | * As mensagens e suas chaves também estão no arquivo ''core_messages.properties'', no entanto não é necessário adicioná-las à ''enum'' CoreMessages'', pois elas serão acessadas diretamente nos arquivos XHTML, conforme exemplo abaixo:<pre>#{mensagens['parametro.label.titulopagina']}</pre> | ||
+ | |||
+ | As chaves das mensagens devem seguir a lógica já estabelecida, que consiste em identificar a entidade à qual pertence a mensagem, identificar o tipo de mensagem (aviso, erro, label, botão, etc.) e por fim identificar a própria mensagem. Atenção para as mensagens ''genéricas'', ou seja, aquelas que podem ser utilizadas por várias entidades. Recomenda-se que antes de criar uma nova mensagem, seja analisada a possibilidade de utilizar uma mensagem genérica. | ||
+ | |||
+ | == '''Implementação de um CRUD''' == | ||
+ | Para a criação de um novo CRUD de uma entidade é necessário seguir os passos abaixo: | ||
+ | # Mapear a entidade, no projeto pje2-modelo, conforme as regras definidas pela JPA. A classe da entidade deve ''extends'' BaseEntity. | ||
+ | #Identificar o módulo que o CRUD faz parte. | ||
+ | # Implementar, no módulo identificado no passo anterior, a classe ''Manager'', onde devem ser implementadas as regras de negócio para a entidade. Esta classe deve ''extends'' BaseManager. | ||
+ | # Atualizar a classe ''API'', no módulo identificado anteriormente, incluindo os métodos necessários para as operações que serão realizadas sobre a entidade, normalmente consultar paginado, cadastrar, buscar por ID e editar. | ||
+ | # Atualizar a classe ''SRV'', no módulo identificado anteriormente, para implementar os novos métodos definidos na interface, conforme o passo acima. | ||
+ | # Implementar as classes ''CTRL'', no pacote ''controlador'' do projeto pje-web, correspondentes às telas criadas. Estas classes devem ''extends'' BaseCtrl. | ||
+ | ## Para as consultas paginadas, deve ser implementado o método ''inicializarFiltroConsulta'' na classe ''CTRL'' da pesquisa. Ele é responsável por instanciar o objeto ''Filter'' que dará origem à query JPQL, a partir dos campos de filtro informados na tela de consulta. | ||
+ | ## Também é necessário implementar o método ''consultarPaginado'' na classe ''CTRL'' da pesquisa. Este método acessará o serviço correspondente e fará a consulta paginada ao banco de dados. | ||
+ | # Criar os arquivos XHTML para as telas da entidade, no projeto pje2-web, na pasta src/main/webapp/pages/''nomeEntidade'', seguindo as regras de nomenclatura definidas. | ||
+ | ## Dever ter como template o arquivo ''default.xhtml''. | ||
+ | ## O conteúdo da tag ''<ui:define name="content">'' deve conter o formulário correspondente à operação a ser implementada. Caso seja uma operação de consulta, a tabela com o resultado também deve estar contida nesta tag. | ||
+ | # Ajustar o arquivo ''pretty-config.xml'' para incluir as URLs REST das operações. | ||
+ | |||
+ | == '''Boas práticas''' == | ||
+ | <font color=red> [TODO: citar e explicar as boas práticas recomendadas para construção do software.] | ||
+ | <br>Dica: veja o conteúdo sobre boas práticas do PJe1 no link http://www.cnj.jus.br/wikipje/index.php/Desenvolvedor#Revis.C3.A3o_de_C.C3.B3digo | ||
+ | </font> | ||
+ | |||
+ | |||
+ | === '''Problemas conhecidos e preocupações''' === | ||
+ | <font color=red> [TODO: citar e explicar, caso tenham: problemas conhecidos e como resolvê-los, lições aprendidas, preocupações futuras]</font> | ||
= '''Instruções de montagem do ambiente de desenvolvimento''' = | = '''Instruções de montagem do ambiente de desenvolvimento''' = | ||
− | + | Nesta seção, apresentamos os roteiros/instruções para instalação e configuração do ambiente de desenvolvimento. As explicações serão divididas nas subseções desta seção, e, recomendamos que a leitura seja obedecida na ordem em que serão apresentadas as subseções. | |
− | + | ||
− | + | ||
− | + | ||
+ | == '''Roteiro para instalação e configuração do ''Eclipse''''' == | ||
+ | |||
+ | 1. Realizar o ''download'' da ferramenta ''Eclipse Platform Runtime Binary'' (''latest release'', 32 ou 64 bits, dependendo do SO (Sistema Operacional) utilizado) disponível no endereço ''http://download.eclipse.org/eclipse/downloads/''. Após o ''download'', realizar a instalação. Esta | ||
+ | versão é a mais básica e simples do ''Eclipse'', logo, será preciso realizar também a instalação do ''marketplace'' no ''Eclipse''. | ||
+ | |||
+ | 2. Para instalar o ''marketplace'', é necessário abrir o ''Eclipse'' e acessar o menu "''Help > Install New Software...''". Na janela aberta (vide Figura 4), selecionar "''All Available Sites''" na lista "''Work with''". Em seguida, digitar "''marketplace''" no campo texto "''type filter text''" e, depois, selecionar a opção do ''marketplace'' e prosseguir com a instalação. | ||
+ | <br> | ||
+ | <br> | ||
+ | '''Figura 4. Instalar ''marketplace''.'''<br> | ||
+ | [[imagem:Install_AvaliableSoftware.jpg | '''Figura 4. Instalar ''marketplace''.'''| 700px]] | ||
+ | <br> | ||
+ | <br> | ||
+ | |||
+ | 3. Após instalar o "''marketplace''" deve ser realizada a instalação do ''JBoss Tools'' no ''Eclipse''. Com o ''Eclipse'' aberto, acessar o menu "''Help > Eclipse Marketplace...''". Na janela aberta (vide Figura 5), na aba "''Search''", digitar "''jboss tools''" no campo "''Find''" e pressionar a tecla ''Enter''. Em seguida, selecionar a versão mais recente do ''JBoss Tools'' compatível com a versão do ''Eclipse'' utilizada. | ||
+ | <br> | ||
+ | <br> | ||
+ | '''Figura 5. Instalar ''JBoss Tools''.'''<br> | ||
+ | [[imagem:Install_JbossTools.jpg | '''Figura 5. Instalar ''JBoss Tools''.'''| 700px]] | ||
+ | <br> | ||
+ | <br> | ||
+ | |||
+ | 4. Configurar no ''Eclipse'' a codificação do projeto para utilizar o padrão "''UTF8''": acessar o menu "''Window > Preferences''" e escolher a opção "''UTF8''" para o campo "''Text file encoding''". | ||
+ | <br> | ||
+ | <br> | ||
+ | |||
+ | <font color=red>TODO:<br> | ||
+ | - É importante explicar detalhes da preparação do clone do projeto no Git, entre outros detalhes que forem necessários. | ||
+ | Dica: veja o conteúdo postado em http://www.cnj.jus.br/wikipje/index.php/Desenvolvedor#Configura.C3.A7.C3.A3o_do_ambiente_de_desenvolvimento | ||
+ | </font> | ||
+ | |||
+ | == '''Roteiro para instalação e configuração do ''PostgreSQL''''' == | ||
+ | <font color=red>TODO:<br> | ||
+ | - Explicar roteiro para instalar e configurar PostgreSQL. <br> | ||
+ | </font> | ||
+ | |||
+ | |||
+ | === '''Diretrizes de configuração caso use um SGBD diferente do ''PostgreSQL''''' === | ||
+ | <font color=red>TODO:<br> | ||
+ | - Incluir as diretrizes de configuração que precisarão ser feitas caso use um SGBD diferente do PostgreSQL. <br> | ||
+ | </font> | ||
+ | |||
+ | |||
+ | |||
+ | == '''Roteiro para instalação e configuração do ''JBoss EAP''''' == | ||
+ | |||
+ | 1. Realizar o ''download'' do ''JBoss EAP'' versão 6.4 disponível no endereço ''http://www.jboss.org/products/eap/download/''. A utilização do ''JDK'' (''Java Development Kit'') é obrigatória na versão 1.6 (''JDK6'') ou superior. Após o ''download'', realizar a instalação. | ||
+ | |||
+ | 2. Realizar o ''download'' da versão 4 do ''driver JDBC'' do ''PostgreSQL'' (''JDBC4 Postgresql Driver'') disponível no endereço ''https://jdbc.postgresql.org/download.html''. Essa versão 4 é compatível com a versão do ''JDK6''. | ||
+ | |||
+ | 3. Realizar o ''download'' da versão mais recente da ferramenta ''jdbcdslog'' disponível no endereço ''https://code.google.com/p/jdbcdslog/''. Esta ferramenta permite a geração de estatísticas e logs das consultas SQL geradas pela ''JPA'' a partir do ''datasource'' configurado a seguir. | ||
+ | |||
+ | 4. Configurar o ''driver JDBC'' do ''PostgreSQL'' como módulo do ''JBoss'', obedecendo os passos a seguir: | ||
+ | * Passo 1: Criar a pasta "''JBOSS_HOME/modules/system/layers/base/org/postgresql/main''". | ||
+ | * Passo 2: Criar o arquivo "''module.xml''" na pasta criada no passo 1; nesse arquivo deve conter o nome correto do arquivo com extensão ''jar'' do ''driver JDBC'' do ''PostgreSQL''. Veja, a seguir, como é o conteúdo do arquivo "''module.xml''": | ||
+ | <pre> | ||
+ | <module xmlns="urn:jboss:module:1.1" name="org.postgresql"> | ||
+ | <resources> | ||
+ | <resource-root path="postgresql-9.3-1101.jdbc4.jar"/> | ||
+ | </resources> | ||
+ | <dependencies> | ||
+ | <module name="javax.api"/> | ||
+ | <module name="javax.transaction.api"/> | ||
+ | </dependencies> | ||
+ | </module> | ||
+ | </pre> | ||
+ | * Passo 3: Copiar o arquivo com extensão ''jar'' do ''driver JDBC'' do ''PostgreSQL'' para a mesma pasta do arquivo "''module.xml''" criada no passo 1. | ||
+ | |||
+ | 5. Configurar a ferramenta ''jdbcdslog'' como módulo do ''JBoss'', obedecendo os passos a seguir: | ||
+ | * Passo 1: Criar a pasta "''JBOSS_HOME/modules/system/layers/base/com/googlecode/usc/jdbcdslog/main/''". | ||
+ | * Passo 2: Criar o arquivo "''module.xml''" na pasta criada no passo 1; nesse arquivo deve conter o nome correto do arquivo com extensão ''jar'' da ferramenta ''jdbcdslog''. Veja, a seguir, como é o conteúdo do arquivo "''module.xml''": | ||
+ | <pre> | ||
+ | <module xmlns="urn:jboss:module:1.1" name="com.googlecode.usc.jdbcdslog"> | ||
+ | <resources> | ||
+ | <resource-root path="jdbcdslog-1.0.6.2.jar"/> | ||
+ | </resources> | ||
+ | <dependencies> | ||
+ | <module name="org.slf4j"/> | ||
+ | <module name="javax.api"/> | ||
+ | <module name="javax.transaction.api"/> | ||
+ | <module name="org.postgresql" optional="true"/> | ||
+ | </dependencies> | ||
+ | </module> | ||
+ | </pre> | ||
+ | * Passo 3: Copiar o arquivo com extensão ''jar'' da ferramenta ''jdbcdslog'' para a mesma pasta do arquivo "''module.xml''" criada no passo 1. | ||
+ | * Passo 4: Incluir no arquivo "''JBOSS_HOME/standalone/configuration/standalone.xml''", dentro da ''tag'' <pre><subsystem xmlns="urn:jboss:domain:logging:1.5"></pre> o código: | ||
+ | <pre> | ||
+ | <logger category="org.jdbcdslog.StatementLogger"> | ||
+ | <level name="DEBUG"/> | ||
+ | </logger> | ||
+ | <logger category="org.jdbcdslog.ConnectionLogger"> | ||
+ | <level name="OFF"/> | ||
+ | </logger> | ||
+ | <logger category="org.jdbcdslog.ResultSetLogger"> | ||
+ | <level name="OFF"/> | ||
+ | </logger> | ||
+ | <logger category="org.jdbcdslog.SlowQueryLogger"> | ||
+ | <level name="OFF"/> | ||
+ | </logger> | ||
+ | </pre> | ||
+ | * Passo 5: Incluir no arquivo "''JBOSS_HOME/standalone/configuration/standalone.xml''", dentro da ''tag'' <pre><datasources></pre> o código: | ||
+ | <pre> | ||
+ | <drivers> | ||
+ | <driver name="jdbcdslog" module="com.googlecode.usc.jdbcdslog"> | ||
+ | <driver-class>org.jdbcdslog.DriverLoggingProxy</driver-class> | ||
+ | <xa-datasource-class>org.jdbcdslog.XADataSourceProxy</xa-datasource-class> | ||
+ | </driver> | ||
+ | </drivers> | ||
+ | </pre> | ||
+ | 6. Configurar o ''datasouce'' da aplicação: | ||
+ | * Incluir dentro da ''tag'' <pre><datasources></pre> no arquivo "''JBOSS_HOME/standalone/configuration/standalone.xml''" o código: | ||
+ | |||
+ | <pre> | ||
+ | <datasource jta="true" jndi-name="java:jboss/datasources/pjeDS" pool-name="pjeDS" enabled="true" use-java-context="true" use-ccm="true"> | ||
+ | <connection-url>jdbc:jdbcdslog:postgresql://db_server:5432/db_name;targetDriver=org.postgresql.Driver</connection-url> | ||
+ | <driver>jdbcdslog</driver> | ||
+ | <pool> | ||
+ | <min-pool-size>2</min-pool-size> | ||
+ | <max-pool-size>20</max-pool-size> | ||
+ | <prefill>true</prefill> | ||
+ | </pool> | ||
+ | <security> | ||
+ | <user-name>db_user</user-name> | ||
+ | <password>db_password</password> | ||
+ | </security> | ||
+ | <validation> | ||
+ | <check-valid-connection-sql>SELECT 1</check-valid-connection-sql> | ||
+ | <validate-on-match>false</validate-on-match> | ||
+ | <background-validation>false</background-validation> | ||
+ | <use-fast-fail>false</use-fast-fail> | ||
+ | </validation> | ||
+ | </datasource> | ||
+ | </pre> | ||
+ | |||
+ | Lembre-se de informar corretamente o nome do servidor do SGBD, o nome do esquema do banco de dados, o usuário e a senha para acesso ao banco de dados. | ||
+ | |||
+ | 7. Essas configurações consideram que o ''JBoss'' será utilizado no modo "''standalone''". Caso o modo escolhido seja "''domain''", é necessário que as modificações no arquivo "''standalone.xml''" sejam também realizadas no arquivo "''domain.xml''" do diretório "''JBOSS_HOME/domain/configuration/''". | ||
+ | |||
+ | |||
+ | === '''Diretrizes de configuração caso use um servidor de aplicação diferente do ''JBoss EAP''''' === | ||
+ | <font color=red>TODO | ||
+ | <br> - Explicar as diretrizes de configuração que precisarão ser feitas caso use um servidor de aplicação diferente do JBoss. | ||
+ | </font> | ||
+ | |||
+ | |||
+ | <font color=red>TODO:<br> | ||
+ | - Incluir novas seções para explicar as diretrizes extras de configuração que surgirem. <br> | ||
+ | </font> | ||
= '''Referências bibliográficas''' = | = '''Referências bibliográficas''' = | ||
− | <!-- <div class="references-small"> | + | <!-- |
− | + | <div class="references-small"> | |
− | + | <references/> | |
+ | </div> | ||
+ | --> | ||
1. World Wide Web Consortium (W3C) disponível em http://www.w3.org/, último acesso em 26/05/2015. | 1. World Wide Web Consortium (W3C) disponível em http://www.w3.org/, último acesso em 26/05/2015. | ||
2. Maven – Welcome to Apache Maven disponível em https://maven.apache.org/, último acesso em 28/05/2015. | 2. Maven – Welcome to Apache Maven disponível em https://maven.apache.org/, último acesso em 28/05/2015. | ||
+ | 3. Code Conventions disponível em http://www.oracle.com/technetwork/java/codeconvtoc-136057.html, último acesso em 02/06/2015. | ||
[[Category:PJe2]] | [[Category:PJe2]] |
Edição atual tal como às 14h41min de 10 de julho de 2015
Conteúdo
|
[editar] Introdução
Apresentamos neste documento a arquitetura de referência para o desenvolvimento do software Processo Judicial Eletrônico versão 2.0 (PJe 2.0) e suas evoluções futuras. As seções e subseções do documento explicarão os detalhes pertinentes da arquitetura.
[editar] Objetivo do documento
O objetivo principal é especificar a arquitetura de software de referência a ser utilizada como padrão para o desenvolvimento do PJe 2.0 e suas evoluções futuras. Nesta especificação está incluído: a estruturação do projeto do software, a organização das camadas do software, os componentes e arcabouços utilizados no software, a definição das principais tecnologias e ferramentas a serem utilizadas, os padrões de projeto, boas práticas de programação que devem ser utilizadas no desenvolvimento do software, entre outros assuntos relevantes.
Recomendamos que a leitura deste documento seja feita na ordem sequencial em que são apresentados os tópicos do sumário/índice do documento.
A metodologia de desenvolvimento do software definida será tratada em outro documento.
[editar] Público Alvo
O documento tem como público alvo principal arquitetos de software visando orientá-los da criação de artefatos para o desenvolvimento e evoluções futuras do software PJe 2.0. Além da criação de artefatos, o arquiteto de software deverá utilizar este documento como referência para instruir os profissionais que atuarão como desenvolvedores especializados nas tecnologias requeridas para esta arquitetura, como por exemplo: desenvolvedores Java/JEE.
Este documento também contém informações úteis a gerentes de projeto, analistas de negócios/requisitos, analistas de teste, testadores, administradores de dados, administradores de infraestrutura e, possivelmente, outros perfis interessados no projeto do software PJe 2.0.
[editar] Termos, abreviações e convenções adotadas
Apresentamos nesta seção uma tabela contendo os termos, abreviações e convenções adotadas no documento da arquitetura de referência do PJe 2.0. A leitura prévia desta seção é fortemente recomendada para compreensão das demais seções.
Termo | Descrição |
Apache Maven | É um software capaz de gerenciar componentes de software e as dependências entres esses componentes, de prover a integração contínua desses componentes, de gerenciar a construção do projeto do software e de documentar e reportar informações inerentes à essa construção. |
API | Acrônimo para a expressão inglesa Application Programming Interface ou interface de programação de aplicativos; essa interface é composta por um conjunto de rotinas, protocolos, padrões de programação e ferramentas que permitem a construção de aplicativos de software. |
Applet | Applet é um software aplicativo que é executado no contexto de outro programa. |
Batch | Termo usado para expressar processamento de dados que ocorre através de um lote (batch) de tarefas enfileiradas, de modo que o software responsável por esse processamento somente processa a próxima tarefa após o término completo da tarefa anterior. |
Browser | Navegador web. Ex.: Firefox, Internet Explorer. |
Build | Termo do inglês que significa 'construir', isto é, é o ato de realizar a compilação de todos os componentes de um ou mais projetos de software envolvidos cujo intuito é deixar pronta a aplicação de software para ser instalada em um ambiente real, por exemplo, em um servidor de aplicações. |
Cache | É um dispositivo de acesso rápido, interno a um sistema, que serve de intermediário entre um operador de um processo e o dispositivo de armazenamento ao qual esse operador concede autorização. |
CRUD | Sigla para Create (Criar), Read (Ler), Update (Atualizar) e Delete (Remover): são operações básicas utilizadas em um software que gerencia bancos de dados. |
CSS | Acrônimo para a expressão inglesa Cascading Style Sheets; é uma linguagem de folhas de estilo utilizada para definir a apresentação de documentos escritos em uma linguagem de marcação, como HTML ou XML. |
DAO | Acrônimo para a expressão inglesa Data Access Object; é um padrão para persistência de dados que permite separar regras de negócio das regras de acesso ao SGBD. |
DBA | Database Administrator ou administrador de bancos de dados. |
Deploy | Instalar/implantar uma aplicação de software em um servidor de aplicações. |
DHTML | Dynamic HTML, ou DHTML, é a união das tecnologias HTML, Javascript e uma linguagem de apresentação. |
DOM | Document Object Model ou Modelo de Objetos de Documentos é uma especificação da W3C, independente de plataforma e linguagem, onde se pode dinamicamente alterar e editar a estrutura, conteúdo e estilo de um documento eletrônico. |
EJB | Enterprise Java Bean. É um componente do tipo servidor da plataforma Java EE que executa no container do servidor de aplicação. |
HTML | Acrônimo para a expressão inglesa HyperText Markup Language (ou linguagem de marcação de hipertexto); essa linguagem de marcação é utilizada para produzir páginas para web. |
HTTP | Acrônimo para a expressão inglesa Hypertext Transfer Protocol (ou protocolo de transferência de hipertexto); é um protocolo de comunicação entre sistemas de informação o qual permite a transferência de dados entre redes de computadores, principalmente na web. |
IDE | Integrated Development Environment ou ambiente integrado para desenvolvimento de software. |
Java | Linguagem de programação orientada a objetos. |
Java EE | Plataforma de desenvolvimento Java voltada para ambientes corporativos/empresariais; também chamada de Java Enterprise Edition (JEE). |
Javascript | Linguagem de programação para navegadores web; é baseada em scripts, orientada a objetos e com sintaxe similar à linguagem de programação C. |
Login | Ato de fornecer credenciais a um determinado sistema, de modo a acessar suas funcionalidades. |
MVC | Model-View-Controller é um padrão de arquitetura de software que visa isolar a lógica (Model) do negócio da apresentação da tela (View) e do controle de navegação (Controller) da tela. |
Query | É a operação de consulta realizada em um SGBD. |
Servidor de aplicação | Software responsável por disponibilizar e gerenciar um ambiente para a instalação e execução de certas aplicações de software, centralizando e dispensando a instalação nos computadores dos usuários clientes dessas aplicações. Ex.: Jboss, Tomcat, entre outros. |
Sessão HTTP | Sessão HTTP provém um modo de armazenar, no servidor de aplicação web, dados importantes relativos a um determinado usuário de uma aplicação. |
RAD | Rapid application development (RAD), também conhecido como desenvolvimento rápido de aplicação; é um modelo de processo de desenvolvimento de software iterativo e incremental que enfatiza um ciclo de desenvolvimento extremamente curto. |
SCRUM | É uma metodologia ágil para planejamento e gestão de projetos de software. |
SGBD | Sistema gerenciador de bancos de dados. Ex.: Oracle, PostgreSQL, entre outros. |
SQL | Structured Query Language ou linguagem de consulta estruturada; é a linguagem de declarativa padrão para bancos de dados relacionais. |
SOA | Service Oriented Architecture ou arquitetura orientada a serviços; é um estilo de arquitetura de software cujo princípio fundamental preconiza que as funcionalidades implementadas pelas aplicações devem ser disponibilizadas na forma de serviços. |
Sprint | Um sprint é a unidade básica de desenvolvimento em conforme a metodologia ágil SCRUM. |
Stored procedure | Procedimento armazenado ou stored procedure é uma coleção de comandos da linguagem SQL para gerenciamento de bancos de dados. |
SUN | Empresa criadora da plataforma Java. |
WAP | Sigla para Wireless Application Protocol ou protocolo para aplicações sem fio. |
Webservice | De acordo com a W3C, webservice é um sistema de software responsável por proporcionar a interação entre duas máquinas através de uma rede de computadores. |
XHTML | Acrônimo para a expressão inglesa eXtensible Hypertext Markup Language; é uma reformulação da linguagem de marcação HTML, baseada em XML. Combina as tags de marcação da linguagem HTML com regras da linguagem XML. |
XML | eXtensible Markup Language é uma linguagem de marcação, recomendada pela W3C, que define um conjunto de regras para a codificação de documentos. |
XSLT | XSL Transformations é uma linguagem de marcação XML usada para transformar documentos XML em outros documentos XML ou em outros formatos. |
W3C | World Wide Web Consortium é um consórcio de empresas de tecnologia que desenvolve padrões para a criação e a interpretação dos conteúdos para web. |
[editar] Restrições da arquitetura
TODO: verificar se existem restrições impostas que foram obedecidas e incluí-las nesta seção.
[editar] Justificativas arquiteturais
Nesta seção, explicitamos o conjunto de memorandos (técnicos, gerenciais, institucionais) que justificam as decisões arquiteturais da arquitetura de referência do PJe 2.0. Esses memorandos são resumos das discussões e estudos os quais balizam este trabalho.
- Requisitos do projeto PJe 2.0.
- O conjunto completo de premissas e requisitos (funcionais e não funcionais) consta no Plano Geral do Projeto PJe 2.0. A saber, explicitamos apenas um resumo desse conjunto:
- Isolamento dos módulos de negócio (ou seja, módulos responsáveis pela lógica de negócio do software PJe) a fim de evitar efeitos colaterais indesejáveis provenientes das modificações no código-fonte.
- Permitir que o desenvolvimento dos módulos de negócio seja realizado isoladamente, inclusive com equipes distribuídas.
- Permitir que a implementação de um módulo de negócio qualquer seja totalmente substituída por nova implementação, sem prejudicar o funcionamento dos demais módulos.
- Isolamento das camadas lógicas do software, para evitar ao máximo o embaralhamento da lógica de negócio do software PJe e a dificuldade de leitura e compreensão do código-fonte
- Permitir que os módulos mais exigentes, quanto ao consumo de recursos de infraestrutura, possam ser "instalados" (deploy) mais de uma vez.
- Experiências prévias.
- Foram consideradas as seguintes experiências:
- Experiência prévia da equipe de arquitetos servidores do Poder Judiciário. Alguns dos arquitetos com experiência no software PJe 1.0.
- Foram analisadas arquiteturas de referência das seguintes instituições: TCU, STF, SERPRO, TJRO e TJPE.
- Estudos diversos foram realizados pela equipe de arquitetos na primeira Sprint do projeto.
- Tecnologias adotadas.
- As tecnologias e/ou ferramentas adotadas para a implementação foram selecionadas a partir da análise dos requisitos do projeto PJe 2.0:
- Java Enterprise Edition Platform specification (JEE): a escolha pela plataforma JEE foi um consenso dada a notória posição de destaque dessa plataforma na construção de aplicações corporativas com grande volume de acesso e necessidade de escalabilidade, de robustez, de segurança, de controle de transação e de processamento em batch, entre outras necessidades. Além disso, a plataforma JEE traz um conjunto expressivo de APIs que aumentam a produtividade da construção do software, encapsulam parte da complexidade inerente às funções que as APIs implementam, promovem a definição de padrões de desenvolvimento, contemplando independência de servidor de aplicações.
- Apache Maven: a escolha pela ferramenta Maven foi norteada pela necessidade de modularização do software e pela adoção da plataforma JEE, como também pelo consenso, na comunidade de desenvolvedores Java, de que a ferramenta Maven é a melhor ferramenta para gerenciamento de builds e dependências na atualidade.
- Git: a escolha pela ferramenta Git (um software de controle de versões de código-fonte) se deu pela complexidade do ambiente de desenvolvimento do software PJe no qual é desejável que várias equipes, em diferentes localidades (Tribunais de Justiça), estejam trabalhando, paralelamente, no desenvolvimento de diferentes módulos do software PJe e, também, na manutenção dos módulos já implementados.
- JBoss Enterprise Application Platform (JBoss EAP): a escolha pelo servidor de aplicações Red Hat JBoss é justificada pela reconhecida posição de destaque, entre a comunidade de desenvolvedores JEE, deste servidor de aplicação que oferece a completa implementação das APIs da plataforma JEE. Além disso, a versão do JBoss denominada EAP (Enterprise Application Platform), em particular, foi a escolhida porque permite a contratação do serviço de suporte da empresa Red Hat. É importante destacar que, o uso do servidor de aplicações JBoss é adotado como o servidor de aplicação padrão do projeto e, para o uso de outro servidor de aplicação diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas.
- PostgreSQL: a escolha do SGBD PostgreSQL deve-se pelo fato deste SGBD ser de uso gratuito e open source (ou seja, é um software cujo código-fonte está aberto para comunidade), implementar o padrão objeto-relacional com a robustez desejada pelo projeto. Além de, ser um SGBD amplamente utilizado pela comunidade de desenvolvedores de diversas linguagens de programação. É importante destacar que, o uso do SGBD PostgreSQL é adotado como o SGBD padrão do projeto e, para o uso de outro SGBD diferente, explicaremos em outra seção deste documento as diretrizes de configuração que precisarão ser feitas.
TODO: falta definir quais serão os navegadores web padrões que serão adotados para o software PJe 2.0 e incluir as justificativas.
[editar] Definição da arquitetura de referência
Nesta seção descrevemos a arquitetura de referência definida para o desenvolvimento do software PJe 2.0 e suas evoluções futuras. A sigla batizada para arquitetura de referência é ArqJus. Dentre os assuntos que serão tratados, podemos destacar: a forma como a arquitetura foi estruturada/organizada e as responsabilidades da arquitetura. É importante informarmos que, ArqJus também poderá ser reutilizada para outros projetos cujo domínio do negócio seja diferente do PJe.
ArqJus é formada por 5 "camadas" lógicas relacionadas entre si e, além das camadas, é possível agruparmos logicamente elementos da arquitetura por meio de "módulos". Vejamos o significado desses dois conceitos importantes:
- Camada: representa uma associação abstrata de elementos que atendem a um conjunto bem definido de responsabilidades dentro do contexto do software.
- Módulo: são blocos de implementação (código-fonte, arquivos de configuração, arquivos de propriedades, arquivos de templates (ou modelos) de janelas gráficas, scripts de banco de dados, etc.) responsáveis por um ou mais serviços ofertados pelo software. Um módulo é classificado por um dos seguintes tipos assim definidos:
- Tipo 1: é um módulo que representa abstrações do modelo de negócio inerente ao software, em outras palavras, um módulo do tipo 1 agrupa classes Java que representam conceitos do domínio do negócio. Também o chamaremos de módulo de negócio. Um módulo do tipo 1 não pode conhecer um outro módulo do tipo 1, caso contrário, será violado a independência entre esses módulos. Todo módulo tipo 1 deve ter: uma única interface Java, local e/ou remota e a classe Java que implementa os serviços ofertados por essa interface.
- Tipo 2: é um módulo que representa abstrações da própria ArqJus, em outras palavras, um módulo do tipo 2 agrupa classes Java e um conjunto de arquivos que fazem parte da arquitetura. Exemplo desse conjunto de arquivos: XHTML, CSS, Javascript, HTML, XML, etc. Um módulo do tipo 2 pode conhecer um outro módulo do tipo 2.
Concretamente, cada módulo tornar-se-á um projeto específico gerenciado pelo aplicativo Maven. Dessa forma, garantiremos o isolamento dos módulos do software. Além de ser gerenciado pelo Maven, cada módulo é construído separadamente, com repositório próprio no aplicativo Git e com versionamento exclusivo, permitindo o isolamento do código-fonte e a especialização das equipes de desenvolvimento, contribuindo com o objetivo de facilitar a manutenção do software e minimizar os impactos de efeitos colaterais das diversas manutenções do software.
Explicaremos nas próximas subseções mais detalhes da ArqJus por meio de visões gráficas arquiteturais.
[editar] Visão geral das camadas da arquitetura
A primeira visão da ArqJus é exibida na Figura 1 e a denominamos de Visão Geral das Camadas da Arquitetura.
Figura 1. Visão Geral das Camadas da Arquitetura.
TODO: Deve-se explicar 'qual camada conhece qual camada' na Figura 1
Conforme pode ser visto na Figura 1, há 5 camadas lógicas e a definição de cada uma dessas camadas é apresentada seguir:
- Camada de Apresentação: encapsula toda a lógica de interação com usuários, desde a exibição de informações, passando pela captura de dados informados pelos usuários por meio das janelas gráficas do software, até o reconhecimento de ações realizadas nessas janelas gráficas.
- Camada de APIs: encapsula o acesso aos módulos ofertados pelo software. Normalmente, nesta camada terão módulos do tipo 2.
- Camada de Negócio: encapsula toda a lógica do domínio de negócio do software, ou seja, as regras de manipulação dos dados e informações controlados pelo software.
- Camada de Domínio: encapsula as representações dos dados e informações inerentes ao domínio de negócio do software, em outras palavras, esta camada é responsável pela realização do mapeamento objeto-relacional.
- Camada de Serviços: encapsula toda a lógica de acesso ao software, servindo como porta de entrada de requisições dos diversos clientes do software, por exemplo: requisições de usuários por meio de janelas gráficas; requisições de outros softwares por meio de webservices.
TODO: citar as tecnologias adotadas na ArqJus predominantes em cada uma das camadas
[editar] Visão modular da arquitetura
A segunda visão da ArqJus é exibida na Figura 2 e a denominamos de Visão Modular da Arquitetura.
Figura 2. Visão Modular da Arquitetura.
Na Figura 2 apresentamos uma visão da ArqJus contemplando os conceitos já explicados: camadas e módulos. Nessa visão também demonstramos um exemplo de uso da arquitetura. Observando a Figura 2 no sentido 'de cima para baixo', explicaremos, a seguir, a estrutura da ArqJus:
- Um módulo tipo 2 que denominamos de Módulo WEB. Esse módulo no aplicativo Maven é denominado pje-web. Nesse módulo inclui-se:
- Uma pasta denominada recursos que contém um conjunto de arquivos. Exemplos desses arquivos: XHTML, CSS, Javascript, imagens, entre outros.
- Um pacote denominado controlador que contém classes Java que realizam o trabalho definido pela Camada de Apresentação do software. Somente as classes desse pacote têm acesso ao conjunto de arquivos da pasta recursos. Também poderemos chamá-las de classes controladoras (ou backbeans). Essas classes também têm acesso às interfaces Java do Módulo Orquestrador. Também podem ter acesso às interfaces Java de módulos do tipo 1 (módulo de negócio) que existirem no software, por exemplo: na Figura 2, a classe Java 'MinhaEntidadeAOperacaoCtrl' acessa o módulo 'Meu negócio A' por meio de sua interface Java.
- Um módulo tipo 2 que denominamos de Módulo Orquestrador. Esse módulo no aplicativo Maven é denominado pje-service. Nesse módulo inclui-se:
- Um pacote denominado api que contém interfaces Java que representam o trabalho definido pela Camada de APIs do software.
- Um pacote denominado impl que contém classes Java que implementam o trabalho definido pela Camada de Serviços do software. Em outras palavras, uma classe Java do pacote impl implementa os serviços ofertados por uma interface Java do pacote api correspondente.
Uma classe do pacote impl não, necessariamente, implementa por completo um determinado serviço o qual ela é responsável. Logo, é possível que essa classe obtenha o resultado de 'partes desse serviço' por meio de um outro módulo da ArqJus. Um exemplo: na Figura 2 temos um ou mais serviços da classe 'MeuServicoSrv' fazendo uso de serviços disponíveis nas interfaces Java 'IMeuNegocioASrv' do módulo 'Meu negócio A' e 'IMeuNegocioBSrv' do módulo 'Meu negócio B'.
- 'Meu Negócio A' é exemplo de como pode ser estruturado um módulo tipo 1 no software. Nesse exemplo, inclui-se:
- Uma interface Java denominada 'IMeuNegocioASrv'; essa interface representa o trabalho definido pela Camada de APIs do módulo 'Meu Negócio A'.
- Uma classe Java denominada 'MeuNegocioASrv'; essa classe implementa os serviços ofertados pela Camada de Serviços do módulo 'Meu Negócio A'. Em outras palavras, a classe 'MeuNegocioASrv' implementa os serviços ofertados pela interface Java 'IMeuNegocioASrv'.
- Uma ou mais classes Java que implementam o trabalho definido pela Camada de Negócio do módulo 'Meu Negócio A'. Exemplos: na Figura 2 temos as classes 'MinhaEntidadeAManager' e 'MinhaEntidadeCManager' e as suas classes DAO correspondentes.
- 'Meu Negócio B' é exemplo de como pode ser estruturado um módulo tipo 1 no software. Nesse exemplo, inclui-se:
- Uma interface Java denominada 'IMeuNegocioBSrv'; essa interface representa o trabalho definido pela Camada de APIs do módulo 'Meu Negócio B'.
- Uma classe Java denominada 'MeuNegocioBSrv'; essa classe implementa os serviços ofertados pela Camada de Serviços do módulo 'Meu Negócio B'. Em outras palavras, a classe 'MeuNegocioBSrv' implementa os serviços ofertados pela interface Java 'IMeuNegocioBSrv'.
- Uma ou mais classes Java que implementam o trabalho definido pela Camada de Negócio do módulo 'Meu Negócio B'. Exemplos: na Figura 2 temos as classes 'MinhaEntidadeBManager' e sua classe DAO correspondente.
- Um módulo tipo 2 que denominamos de Módulo Modelo. Esse módulo no aplicativo Maven é denominado pje-modelo. Nesse módulo inclui-se:
- Um pacote denominado modelo que contém classes Java que realizam o trabalho definido pela Camada de Domínio do software. Por exemplo: na Figura 2 temos as classes 'MinhaEntidadeA', 'MinhaEntidadeB' e 'MinhaEntidadeC'. Todos os módulos do software (tanto módulo do tipo quanto do tipo 2) têm acesso às classes do pacote modelo.
É importante destacar que:
- O módulo de negócio 'Meu Negócio A' não conhece o módulo de negócio 'Meu Negócio B', logo, está consistente com a definição de módulo tipo 1.
- Uma classe Java pertencente à Camada de Negócio pode acessar uma outra classe da Camada de Negócio desde que, ambas classes, pertençam ao mesmo módulo de negócio.
- Classes Java da Camada de Negócio podem ser acessadas por classes Java da Camada de Serviços somente dentro de um mesmo módulo de negócio.
[editar] Organização dos projetos no Maven
Nesta subseção, apresentamos a organização dos projetos no aplicativo Maven, consolidando os módulos citados no decorrer da explicação da Figura 2 e outros módulos necessários para estruturação da ArqJus.
- pje-pom: projeto que contém as dependências que são comuns entre todos os demais projetos. Não deve conter código-fonte, apenas as configurações dessas dependências. O aplicativo Maven exige a presença do arquivo POM (Project Object Model).
- pje-modelo: projeto que contém todas as entidades de domínio do negócio mapeadas de acordo com o padrão JPA (Java Persistence API).
- pje-comum: projeto que contém todas as classes Java utilitárias do software. Também é classificado como um módulo tipo 2. Exemplos de classes Java desse projeto: classes que implementam os registros de auditoria das operações do software (também chamado de registro de log), classes que implementam o controle de acesso, o tratamento de exceções, entre outras classes responsáveis pela infraestrutura do software.
- pje-service: projeto que contém as classes do Módulo Orquestrador das funcionalidades que envolvam mais de um módulo de negócio.
- pje-web: projeto que contém todo o código-fonte associado à Camada de Apresentação, exemplos: classes controladoras (também conhecidas por back-beans), arquivos HTML, XHTML, CSS e scripts JavaScript.
A nomenclatura de cada projeto específico no aplicativo Maven obedece o padrão pje<modulo>, em 'modulo' deve conter o nome do módulo correspondente.
Os projetos no Maven serão empacotados em arquivos com extensão jar (Java ARchive), com exceção do projeto "pje-web", que será empacotado em um arquivo com extensão war (Web application ARchive).
Para cada módulo do software, independente do tipo do módulo, será preciso criar três arquivos com extensão jar, vejamos:
- pje-modulo-X.Y.Z.jar: este arquivo contém todas as classes Java do módulo e será utilizado no momento da instalação (deploy) do módulo.
- pje-modulo-X.Y.Z-api.jar: este arquivo contém apenas as interfaces Java do respectivo módulo e será utilizado como dependência na implementação dos módulos "pje-web" e "pje-service". Lembrando que, os módulos "pje-web" e "pje-service" somente terão acesso à Camada de APIs do módulo em questão.
- pje-modulo-X.Y.Z-sources.jar: este arquivo contém o código-fonte do módulo e será utilizado para fins de depuração do código-fonte (ou debug).
[editar] Visão de Deployment da Arquitetura
Esta subseção tem o objetivo de apresentar os principais componentes envolvidos no processo de deploy do software.
Figura 3. Visão de Deployment do Software.
A Figura 3 apresenta a visão de implantação padrão do software PJe 2, conforme definido pela arquitetura estabelecida. É possível identificar os principais recursos envolvidos no processo de deploy, desde o servidor de aplicação e o servidor de banco de dados, passando pelo build da aplicação, até alguns arquivos de configuração de maior relevância para o funcionamento do PJe 2.
Para configurar o log da aplicação é necessário ajustar alguns parâmetros no arquivo "core_configurations.properties", localizado no módulo pje2-comum. Além dos 5 parâmetros listados abaixo, é necessário definir a variável de ambiente PJE2_LOGFILE_PATH, com o path onde o arquivo HTML contendo o log será gravado. Caso esta variável não esteja corretamente definida, será considerado o local default /tmp.
- logger.level: define quais níveis de log serão exibidos, tanto no arquivo HTML quanto no log do servidor de aplicação. Os valores permitidos são os definidos pela API Logger de Java (ALL, CONFIG, FINE, FINER, FINEST, INFO, OFF, SEVERE, WARNING).
- logger.useparenthandlers: define se o log do servidor de aplicação será utilizado ou não. Os valores aceitos são true e false.
- logger.file.name: define o nome do arquivo HTML que contém o log formatado.
- logger.file.size: define o tamanho máximo do arquivo HTML gerado, em bytes.
- logger.file.backups: define a quantidade de arquivos HTML que serão mantidos quando o arquivo HTML atingir o tamanho máximo definido no parâmetro logger.file.size.
Para habilitar o acesso remoto ao servidor de banco de dados PostgreSQL é necessário realizar ajustes nas configurações definidas nos arquivos “pg_hba.conf” e “postgresql.conf”. Para identificar a localização física destes arquivos, é possível executar os comandos “show hba_file” e “show config_file”, respectivamente, no console do PostgreSQL. Os ajustes necessários podem ser verificados na documentação on-line do SGBD.
Para criar e configurar os datasources do PJe 2 é necessário manipular os arquivos “module.xml”, “jdbc-postgresql.jar”, "jdbcdslog.jar" e “standalone.xml”, conforme descrito posteriormente neste documento. Já o arquivo “persistence.xml” é utilizado para configurar como o provider JPA irá se conectar aos datasources criados.
Uma vez criados os datasources, é possível realizar o deploy padrão do PJe 2 a partir do arquivo “pje-web.war” disponibilizado pelo CNJ. Este arquivo é composto por todos os módulos do software, empacotados em arquivos .jar conforme já mencionado em sessão anterior deste documento.
[editar] Padrões, regras e boas práticas
Esta seção tem o objetivo de apresentar os padrões estabelecidos, as regras definidas e algumas boas práticas de programação para construção do software sob a consonância com os requisitos da ArqJus. As explicações serão divididas nas subseções desta seção.
[editar] Padrões de nomenclatura e codificação
- Padrões de nomenclatura para classes Java:
- Classes do Módulo Web (também chamaremos de "controladores/controlador(a)" ou de backbeans): <Entidade><operação>Ctrl.java
- Interfaces Java do Módulo Orquestrador (também chamaremos de "orquestradores/orquestrador(a)"): I<Serviço>Srv.java
- Implementações dos orquestradores: <Serviço>Srv.java
- Interfaces Java dos módulos: I<Módulo>Srv.java
- Implementações dos módulos: <Módulo>Srv.java
- Classes de negócio (também chamaremos de "managers/manager"): <Entidade>Manager.java
- Classes de acesso aos dados: <Entidade>DAO.java
- Entidades: <Entidade>.java
- Padrões de nomenclatura para pacotes Java:
- br.jus.cnj.pje.web.controlador: todos os controladores do software devem pertencer a este pacote.
- br.jus.cnj.pje.service.api: todas as interfaces Java dos orquestradores do software devem pertencer a este pacote.
- br.jus.cnj.pje.service.impl: todas as implementações das interfaces Java dos orquestradores devem pertencer a este pacote.
- br.jus.cnj.pje.<negócio>.api: a interface Java do módulo deve pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.<negócio>.impl: a implementação da interface Java do módulo deve pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.<negócio>.manager: todas as classes de negócio (managers) do módulo de negócio devem pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.<negócio>.dao: todas as classes de acesso aos dados inerentes ao módulo de negócio devem pertencer a este pacote. Entende-se por <negócio> o nome do módulo de negócio.
- br.jus.cnj.pje.modelo: todas as classes das entidades mapeadas no padrão JPA devem pertencer a este pacote.
- Padrões de nomenclatura para arquivos XHTML:
- <entidade><operação>.xhtml: entende-se por <entidade> o nome da principal da entidade manipulada pela janela gráfica (ou tela), e por <operação> a principal manipulação que se deseja realizar a partir desta tela (visualizar, excluir, alterar, desativar, cadastrar, etc).
É importante ressaltar que, os padrões apresentados no decorrer da explicação da Figura 2 também foram considerados.
Além dos padrões definidos nesta subseção, recomendamos a adoção do padrão de codificação Java, disponível no endereço http://www.oracle.com/technetwork/java/codeconvtoc-136057.html.
[editar] Regras definidas
Sobre o relacionamento entre classes:
É permitido na ArqJus o relacionamento entre as diversas classes do software distribuídas nos módulos e nas camadas lógicas, logo, esse relacionamento deve obedecer as seguintes regras:
- Um orquestrador deve ser criado sempre que houver a necessidade de uma operação no Módulo Controlador que envolva mais de um módulo de negócio.
- As classes dos controladores apenas terão acesso às interfaces Java dos serviços ofertados pelos orquestradores e módulos de negócio.
- Para cada tela (ou arquivo XHTML) deve haver um controlador específico e único.
- Todas as operações que um módulo de negócio disponibilizará devem ser expostas através de sua Camada de API (ou interface Java).
- Os módulos de negócio não podem, em hipótese alguma, acessar funcionalidades e/ou classes de outros módulos de negócio. Somente poderão acessar classes e funcionalidades disponíveis nos projetos pje-modelo e pje-comum.
- As classes managers de um módulo só podem ser acessadas pela classe que implementa a interface Java desse módulo em questão, ou pelos demais managers do mesmo módulo.
- As regras de negócio devem ser implementadas exclusivamente nas classes managers correspondentes.
- O BaseDAO já oferece um conjunto de métodos implementados para as operações de consulta (com ou sem paginação), inclusão, alteração e exclusão das entidades. Caso sejam necessários métodos de acesso/manipulação de dados específicos para uma entidade, deve ser implementada uma, e apenas uma, classe no padrão DAO que estende o BaseDAO.
- Cada classe DAO só deve ser acessada pela sua classe manager correspondente.
- Validações dos atributos que caracterizam uma entidade (por exemplo: não nulo, não vazio, restrição de tamanho, restrição de valores) devem ser realizadas na própria entidade, por meio das anotações disponíveis na API Bean Validation da especificação JEE.
[editar] Utilização da Classe Filter
A classe br.jus.cnj.pje.comum.utils.filter.Filter, localizada no módulo pje2-comum, tem por objetivo permitir a construção de queries orientadas a objeto, utilizando a Java Persistence Query Language (JPQL), encapsulando detalhes de implementação, gerando padronização de código-fonte, menor complexidade e, consequentemente, menor esforço para manutenção.
- Principais aplicações:
- Adicionar restrições na cláusula WHERE: =, >, <, LIKE, IS NULL, IN além de várias outras;
- Navegar pelo grafo de objetos sem limite de profundidade;
- Determinar FETCH em qualquer propriedade no grafo de objetos;
- Formar cláusulas WHERE complexas, através dos conjuntivos AND e OR;
- Determinar qual tipo de JOIN será utilizado nos relacionamentos;
- Realizar ordenações;
- Paginar consultas.
- Exemplos de uso:
- Restrições na cláusula WHERE
Código:
- Restrições na cláusula WHERE
Filter<User> filter = new Filter<User>(User.class); filter.addEquals("login", "admin"); filter.addBetween("birthDate", new Date(), new Date()); filter.addLikeIgnoreCase("name", "%José"); filter.addGreaterOrEqualThan("id", 10L);
SQL Gerado:
Select //All properties of User from systemuser user0_ where user0_.login=? and ( user0_.birth_date between ? and ? ) and ( upper(user0_.name) like ? ) and user0_.id>=10
- Navegação no grafo de objetos
Código:
- Navegação no grafo de objetos
Filter<User> filter = new Filter<User>(User.class); filter.addEquals("profiles.screens.module.name", "Controle de Acesso");
SQL Gerado:
Select //All properties of User from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id inner join accessprofile_screen screens3_ on accessprof2_.id=screens3_.accessprofile inner join Screen screen4_ on screens3_.screen=screen4_.id inner join Module module5_ on screen4_.module=module5_.id where module5_.name=?
- Definição do FETCH nas propriedades
Código:
- Definição do FETCH nas propriedades
Filter<User> filter = new Filter<User>(User.class); filter.fetch("profiles"); filter.fetch("blockedFunctionalities");
SQL Gerado:
select //All properties of User, AccessProfile(profiles) and //Functionality(blockedFunctionalities) from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id inner join exceptions_systemuser_functionality blockedfun3_ on user0_.id=blockedfun3_.systemuser inner join Functionality functional4_ on blockedfun3_.functionality=functional4_.id where 1=1
Código:
Filter<Client> filter = new Filter<Client>(Client.class); filter.addEquals("address.streetType.name", "Rua",JoinTypes.INNER,true); //addEquals(attribute, value, joinType, fetch)
SQL Gerado:
select //All properties of User, AccessProfile(profiles) and //Functionality(blockedFunctionalities) from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id inner join exceptions_systemuser_functionality blockedfun3_ on user0_.id=blockedfun3_.systemuser inner join Functionality functional4_ on blockedfun3_.functionality=functional4_.id where 1=1
- Construção de cláusulas WHERE complexas
Código:
- Construção de cláusulas WHERE complexas
Filter<User> filter = new Filter<User>(User.class); ComposedRestriction orExtern = Filter.createOr(); orExtern.addRestriction(Filter.createEquals("active", Boolean.TRUE,null,null)); ComposedRestriction and = Filter.createAnd(); and.addRestriction(Filter.createNotEquals("name", "José",null,null)); and.addRestriction(Filter.createEquals("login", "admin",null,null)); ComposedRestriction orIntern = Filter.createOr(); orIntern.addRestriction(Filter.createBetween("birthDate", new Date(), new Date(),null,null)); orIntern.addRestriction(Filter.createEquals("office", "Arquiteto", null,null)); and.addRestriction(orIntern); orExtern.addRestriction(and); filter.addComposedRestriction(orExtern);
SQL Gerado:
select //All properties of User from systemuser user0_ where user0_.active=? or (user0_.name<>? and user0_.login=? and (user0_.birth_date between ? and ? or user0_.office=?) )
- Definição do tipo de JOIN
Código:
- Definição do tipo de JOIN
Filter<Client> filter = new Filter<Client>(Client.class); filter.addEquals("address.streetType.name", "Rua",JoinTypes.LEFT,false); filter.addLike("contacts.email", "%gmail%");//Default: INNER
SQL Gerado:
Select //All properties of Client from Client client0_ left outer join Address address1_ on client0_.address=address1_.id left outer join StreetType streettype2_ on address1_.streettype=streettype2_.id inner join client_contact contacts3_ on client0_.id=contacts3_.client inner join Contact contact4_ on contacts3_.contact=contact4_.id where streettype2_.name=? and ( contact4_.email like ? )
Código:
Filter<User> filter = new Filter<User>(User.class); filter.addEquals("profiles.name", "Admin",JoinTypes.INNER,false); filter.addEquals("profiles.name", "Admin",JoinTypes.LEFT,false); //generates 2 joins: a with INNER and other with LEFT
SQL Gerado:
Select //All properties of User from systemuser user0_ inner join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser inner join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id left outer join systemuser_accessprofile profiles3_ on user0_.id=profiles3_.systemuser left outer join AccessProfile accessprof4_ on profiles3_.accessprofile=accessprof4_.id where accessprof2_.name=? and accessprof4_.name=?
- Ordenações
Código:
- Ordenações
Filter<User> filter = new Filter<User>(User.class); filter.addOrderDesc("name"); filter.addOrderAsc("profiles.name", JoinTypes.LEFT,false);
SQL Gerado:
Select //All properties of User from systemuser user0_ left outer join systemuser_accessprofile profiles1_ on user0_.id=profiles1_.systemuser left outer join AccessProfile accessprof2_ on profiles1_.accessprofile=accessprof2_.id where 1=1 order by user0_.name desc, accessprof2_.name asc
- Paginação de consultas
Código:
- Paginação de consultas
Filter<User> filter = new Filter<User>(User.class); filter.getPaginator().setPageSize(5); filter.getPaginator().setFirstResult(10);
SQL Gerado:
Select //All properties of User from systemuser user0_ where 1=1 limit ? offset ?
- Considerações finais
- Por padrão, qualquer cláusula ou FETCH, que não especifica o tipo de JOIN, utiliza o tipo INNER.
- Por padrão, qualquer cláusula que não especifica o FETCH da propriedade, o Filter entende que NÃO deve ser feito FETCH nesta propriedade.
- Há duas formas de informar ao Filter que se deve fazer FETCh numa propriedade:
- A primeira é usando o método fetch(String) o qual recebe uma string com o nome da propriedade ou das propriedades aninhadas. Lembrando que não se deve usar propriedade “primitiva” neste método; caso contrário ocorrerá um erro:
filter.fetch(“usuarios”) → ok filter.fetch(“usuarios.name”) → RuntimeException
- A segunda maneira é especificando o parâmetro (Boolean fetch) nas clausulas:
boolean isFetch = true; ... filter.addEquals(“usuarios.nome”,”José”,JoinTypes.INNER, isFetch); → OK
O Filter entende que deve fazer FETCH JOIN com usuários e depois igualar sua propriedade nome a José. Se uma mesma propriedade faz mais de um JOIN com o mesmo tipo, o SQL resultante só fará um único JOIN:
filter.addEquals(“usuarios.nome”,”Fulano”,JoinTypes.INNER, false); filter.addEquals(“usuarios.login”,”beltrano”,JoinTypes.INNER, false); → só haverá um único join com a tabela usuário
Se uma mesma propriedade faz mais de um JOIN com tipos diferentes, o SQL resultante fará mais de um JOIN:
filter.addEquals(“usuarios.nome”,”Fulano”,JoinTypes.INNER,false); filter.addEquals(“usuarios.login”,”beltrano”,JoinTypes.LEFT, false); → haverá um inner join e um left join com usuários
Por limitações do JPA não é possível com uma mesma propriedade usá-la fazendo FETCH e em seguida sem fazer FETCH. Isso causará erro:
filter.addEquals("profiles.screens.id", 1L, JoinTypes.INNER, TRUE); → aqui faz fetch join em profiles e screens filter.addEquals("profiles.screens.module.id", 1L, JoinTypes.INNER, FALSE); → aqui faz join sem fetch em profiles, screens e module. A ideia dessa consulta seria fazer FETCH apenas em profiles e screens, mas, não em module, mesmo que, seja filtrado por uma propriedade em module.
[editar] Utilização da Classe BaseDAO
A classe br.jus.cnj.pje.comum.BaseDAO, localizada no módulo pje2-comum contém os métodos básicos de persistência e acesso das entidades no bando de dados do sistema. Os métodos são genéricos e permitem apenas a utilização das classes que representam as entidades de negócio (extends BaseEntity).
Esta classe supre as necessidades para a maior parte dos cadastros (CRUD) e demais funcionalidades do sistema, no que se refere ao acesso ao banco de dados. Caso seja necessário algum método específico para uma determinada entidade, deve ser criado um DAO específico para esta entidade e este DAO deve extends a classe BaseDAO. Caso seja necessário sobrescrever algum método do BaseDAO no DAO específico, é fortemente recomendado que seja realizada uma chamada ao método da classe pai, através da palavra reservada super.
[editar] Internacionalização
Para a internacionalização das mensagens utilizadas nas classes Java:
- A enum br.jus.cnj.pje.comum.messages.CoreMessages, localizada no módulo pje-comum, contém todas as mensagens utilizadas pela aplicação. Cada mensagem é encapsulada por uma enumeração e tem uma chave única, conforme exemplo a seguir:
GENERICO_AVISO_SUCESSO_CADASTRO("generico.aviso.sucessocadastro")
- A chave da mensagem deve ter sua correspondência no arquivo core_messages.properties, também localizado no módulo pje-comum, conforme exemplo abaixo:
generico.aviso.sucessocadastro=Cadastro realizado com sucesso!
- A utilização da enum para internacionalização deve seguir o exemplo que segue. O método getMessage() permite que qualquer quantidade de parâmetros seja informada, de acordo com a mensagem definida no arquivo core_messages.properties.
CoreMessages.GENERICO_AVISO_SUCESSO_CADASTRO.getMessage();
Para a internacionalização das telas da aplicação:
- As mensagens e suas chaves também estão no arquivo core_messages.properties, no entanto não é necessário adicioná-las à enum CoreMessages, pois elas serão acessadas diretamente nos arquivos XHTML, conforme exemplo abaixo:
#{mensagens['parametro.label.titulopagina']}
As chaves das mensagens devem seguir a lógica já estabelecida, que consiste em identificar a entidade à qual pertence a mensagem, identificar o tipo de mensagem (aviso, erro, label, botão, etc.) e por fim identificar a própria mensagem. Atenção para as mensagens genéricas, ou seja, aquelas que podem ser utilizadas por várias entidades. Recomenda-se que antes de criar uma nova mensagem, seja analisada a possibilidade de utilizar uma mensagem genérica.
[editar] Implementação de um CRUD
Para a criação de um novo CRUD de uma entidade é necessário seguir os passos abaixo:
- Mapear a entidade, no projeto pje2-modelo, conforme as regras definidas pela JPA. A classe da entidade deve extends BaseEntity.
- Identificar o módulo que o CRUD faz parte.
- Implementar, no módulo identificado no passo anterior, a classe Manager, onde devem ser implementadas as regras de negócio para a entidade. Esta classe deve extends BaseManager.
- Atualizar a classe API, no módulo identificado anteriormente, incluindo os métodos necessários para as operações que serão realizadas sobre a entidade, normalmente consultar paginado, cadastrar, buscar por ID e editar.
- Atualizar a classe SRV, no módulo identificado anteriormente, para implementar os novos métodos definidos na interface, conforme o passo acima.
- Implementar as classes CTRL, no pacote controlador do projeto pje-web, correspondentes às telas criadas. Estas classes devem extends BaseCtrl.
- Para as consultas paginadas, deve ser implementado o método inicializarFiltroConsulta na classe CTRL da pesquisa. Ele é responsável por instanciar o objeto Filter que dará origem à query JPQL, a partir dos campos de filtro informados na tela de consulta.
- Também é necessário implementar o método consultarPaginado na classe CTRL da pesquisa. Este método acessará o serviço correspondente e fará a consulta paginada ao banco de dados.
- Criar os arquivos XHTML para as telas da entidade, no projeto pje2-web, na pasta src/main/webapp/pages/nomeEntidade, seguindo as regras de nomenclatura definidas.
- Dever ter como template o arquivo default.xhtml.
- O conteúdo da tag <ui:define name="content"> deve conter o formulário correspondente à operação a ser implementada. Caso seja uma operação de consulta, a tabela com o resultado também deve estar contida nesta tag.
- Ajustar o arquivo pretty-config.xml para incluir as URLs REST das operações.
[editar] Boas práticas
[TODO: citar e explicar as boas práticas recomendadas para construção do software.]
Dica: veja o conteúdo sobre boas práticas do PJe1 no link http://www.cnj.jus.br/wikipje/index.php/Desenvolvedor#Revis.C3.A3o_de_C.C3.B3digo
[editar] Problemas conhecidos e preocupações
[TODO: citar e explicar, caso tenham: problemas conhecidos e como resolvê-los, lições aprendidas, preocupações futuras]
[editar] Instruções de montagem do ambiente de desenvolvimento
Nesta seção, apresentamos os roteiros/instruções para instalação e configuração do ambiente de desenvolvimento. As explicações serão divididas nas subseções desta seção, e, recomendamos que a leitura seja obedecida na ordem em que serão apresentadas as subseções.
[editar] Roteiro para instalação e configuração do Eclipse
1. Realizar o download da ferramenta Eclipse Platform Runtime Binary (latest release, 32 ou 64 bits, dependendo do SO (Sistema Operacional) utilizado) disponível no endereço http://download.eclipse.org/eclipse/downloads/. Após o download, realizar a instalação. Esta versão é a mais básica e simples do Eclipse, logo, será preciso realizar também a instalação do marketplace no Eclipse.
2. Para instalar o marketplace, é necessário abrir o Eclipse e acessar o menu "Help > Install New Software...". Na janela aberta (vide Figura 4), selecionar "All Available Sites" na lista "Work with". Em seguida, digitar "marketplace" no campo texto "type filter text" e, depois, selecionar a opção do marketplace e prosseguir com a instalação.
Figura 4. Instalar marketplace.
3. Após instalar o "marketplace" deve ser realizada a instalação do JBoss Tools no Eclipse. Com o Eclipse aberto, acessar o menu "Help > Eclipse Marketplace...". Na janela aberta (vide Figura 5), na aba "Search", digitar "jboss tools" no campo "Find" e pressionar a tecla Enter. Em seguida, selecionar a versão mais recente do JBoss Tools compatível com a versão do Eclipse utilizada.
Figura 5. Instalar JBoss Tools.
4. Configurar no Eclipse a codificação do projeto para utilizar o padrão "UTF8": acessar o menu "Window > Preferences" e escolher a opção "UTF8" para o campo "Text file encoding".
TODO:
- É importante explicar detalhes da preparação do clone do projeto no Git, entre outros detalhes que forem necessários.
Dica: veja o conteúdo postado em http://www.cnj.jus.br/wikipje/index.php/Desenvolvedor#Configura.C3.A7.C3.A3o_do_ambiente_de_desenvolvimento
[editar] Roteiro para instalação e configuração do PostgreSQL
TODO:
- Explicar roteiro para instalar e configurar PostgreSQL.
[editar] Diretrizes de configuração caso use um SGBD diferente do PostgreSQL
TODO:
- Incluir as diretrizes de configuração que precisarão ser feitas caso use um SGBD diferente do PostgreSQL.
[editar] Roteiro para instalação e configuração do JBoss EAP
1. Realizar o download do JBoss EAP versão 6.4 disponível no endereço http://www.jboss.org/products/eap/download/. A utilização do JDK (Java Development Kit) é obrigatória na versão 1.6 (JDK6) ou superior. Após o download, realizar a instalação.
2. Realizar o download da versão 4 do driver JDBC do PostgreSQL (JDBC4 Postgresql Driver) disponível no endereço https://jdbc.postgresql.org/download.html. Essa versão 4 é compatível com a versão do JDK6.
3. Realizar o download da versão mais recente da ferramenta jdbcdslog disponível no endereço https://code.google.com/p/jdbcdslog/. Esta ferramenta permite a geração de estatísticas e logs das consultas SQL geradas pela JPA a partir do datasource configurado a seguir.
4. Configurar o driver JDBC do PostgreSQL como módulo do JBoss, obedecendo os passos a seguir:
- Passo 1: Criar a pasta "JBOSS_HOME/modules/system/layers/base/org/postgresql/main".
- Passo 2: Criar o arquivo "module.xml" na pasta criada no passo 1; nesse arquivo deve conter o nome correto do arquivo com extensão jar do driver JDBC do PostgreSQL. Veja, a seguir, como é o conteúdo do arquivo "module.xml":
<module xmlns="urn:jboss:module:1.1" name="org.postgresql"> <resources> <resource-root path="postgresql-9.3-1101.jdbc4.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module>
- Passo 3: Copiar o arquivo com extensão jar do driver JDBC do PostgreSQL para a mesma pasta do arquivo "module.xml" criada no passo 1.
5. Configurar a ferramenta jdbcdslog como módulo do JBoss, obedecendo os passos a seguir:
- Passo 1: Criar a pasta "JBOSS_HOME/modules/system/layers/base/com/googlecode/usc/jdbcdslog/main/".
- Passo 2: Criar o arquivo "module.xml" na pasta criada no passo 1; nesse arquivo deve conter o nome correto do arquivo com extensão jar da ferramenta jdbcdslog. Veja, a seguir, como é o conteúdo do arquivo "module.xml":
<module xmlns="urn:jboss:module:1.1" name="com.googlecode.usc.jdbcdslog"> <resources> <resource-root path="jdbcdslog-1.0.6.2.jar"/> </resources> <dependencies> <module name="org.slf4j"/> <module name="javax.api"/> <module name="javax.transaction.api"/> <module name="org.postgresql" optional="true"/> </dependencies> </module>
- Passo 3: Copiar o arquivo com extensão jar da ferramenta jdbcdslog para a mesma pasta do arquivo "module.xml" criada no passo 1.
- Passo 4: Incluir no arquivo "JBOSS_HOME/standalone/configuration/standalone.xml", dentro da tag
<subsystem xmlns="urn:jboss:domain:logging:1.5">
o código:
<logger category="org.jdbcdslog.StatementLogger"> <level name="DEBUG"/> </logger> <logger category="org.jdbcdslog.ConnectionLogger"> <level name="OFF"/> </logger> <logger category="org.jdbcdslog.ResultSetLogger"> <level name="OFF"/> </logger> <logger category="org.jdbcdslog.SlowQueryLogger"> <level name="OFF"/> </logger>
- Passo 5: Incluir no arquivo "JBOSS_HOME/standalone/configuration/standalone.xml", dentro da tag
<datasources>
o código:
<drivers> <driver name="jdbcdslog" module="com.googlecode.usc.jdbcdslog"> <driver-class>org.jdbcdslog.DriverLoggingProxy</driver-class> <xa-datasource-class>org.jdbcdslog.XADataSourceProxy</xa-datasource-class> </driver> </drivers>
6. Configurar o datasouce da aplicação:
- Incluir dentro da tag
<datasources>
no arquivo "JBOSS_HOME/standalone/configuration/standalone.xml" o código:
<datasource jta="true" jndi-name="java:jboss/datasources/pjeDS" pool-name="pjeDS" enabled="true" use-java-context="true" use-ccm="true"> <connection-url>jdbc:jdbcdslog:postgresql://db_server:5432/db_name;targetDriver=org.postgresql.Driver</connection-url> <driver>jdbcdslog</driver> <pool> <min-pool-size>2</min-pool-size> <max-pool-size>20</max-pool-size> <prefill>true</prefill> </pool> <security> <user-name>db_user</user-name> <password>db_password</password> </security> <validation> <check-valid-connection-sql>SELECT 1</check-valid-connection-sql> <validate-on-match>false</validate-on-match> <background-validation>false</background-validation> <use-fast-fail>false</use-fast-fail> </validation> </datasource>
Lembre-se de informar corretamente o nome do servidor do SGBD, o nome do esquema do banco de dados, o usuário e a senha para acesso ao banco de dados.
7. Essas configurações consideram que o JBoss será utilizado no modo "standalone". Caso o modo escolhido seja "domain", é necessário que as modificações no arquivo "standalone.xml" sejam também realizadas no arquivo "domain.xml" do diretório "JBOSS_HOME/domain/configuration/".
[editar] Diretrizes de configuração caso use um servidor de aplicação diferente do JBoss EAP
TODO
- Explicar as diretrizes de configuração que precisarão ser feitas caso use um servidor de aplicação diferente do JBoss.
TODO:
- Incluir novas seções para explicar as diretrizes extras de configuração que surgirem.
[editar] Referências bibliográficas
1. World Wide Web Consortium (W3C) disponível em http://www.w3.org/, último acesso em 26/05/2015. 2. Maven – Welcome to Apache Maven disponível em https://maven.apache.org/, último acesso em 28/05/2015. 3. Code Conventions disponível em http://www.oracle.com/technetwork/java/codeconvtoc-136057.html, último acesso em 02/06/2015.