Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
João Pessoa
10 de fevereiro de 2005
Relatório de Estágio - Fábio Pereira Carneiro - NEUS BeanGen
SUMÁRIO
RESUMO ............................................................................................................................................................... 5
DEDICATÓRIA.................................................................................................................................................... 6
IDENTIFICAÇÃO................................................................................................................................................ 7
ESTAGIÁRIO ......................................................................................................................................................... 7
EMPRESA ............................................................................................................................................................. 7
INTRODUÇÃO..................................................................................................................................................... 8
PROPÓSITO DO DOCUMENTO ................................................................................................................................ 8
ORGANIZAÇÃO DO DOCUMENTO.......................................................................................................................... 9
Aquisição de Conhecimento............................................................................................................................ 9
Desenvolvimento do Projeto ........................................................................................................................... 9
Treinamento .................................................................................................................................................... 9
MOTIVAÇÃO ........................................................................................................................................................ 9
Estado da Arte – Arquitetura NEUS ............................................................................................................. 10
AQUISIÇÃO DE CONHECIMENTO .............................................................................................................. 11
MAPEAMENTO OBJETO RELACIONAL ................................................................................................................ 11
PROGRAMAÇÃO ORIENTADA A OBJETOS (POO) ................................................................................................ 12
SGBD’S – RELACIONAL X OO........................................................................................................................... 13
OO X SGBD ...................................................................................................................................................... 13
JDBC................................................................................................................................................................. 15
GERAÇÃO DE CÓDIGO ........................................................................................................................................ 17
ANT .................................................................................................................................................................. 18
XDOCLET .......................................................................................................................................................... 21
O que é? ........................................................................................................................................................ 21
XDoclet X JavaDoc ....................................................................................................................................... 21
Integração com ANT ..................................................................................................................................... 23
XDoclet Template (arquivo.xdt).................................................................................................................... 23
Tag Handlers................................................................................................................................................. 24
Geração (1 – 1) X (N – 1) ............................................................................................................................. 25
Exemplo......................................................................................................................................................... 25
DESENVOLVIMENTO DO PROJETO .......................................................................................................... 30
METODOLOGIA .................................................................................................................................................. 30
PROCESSO .......................................................................................................................................................... 31
Planejamento ................................................................................................................................................ 31
Escopo....................................................................................................................................................... 31
Recursos.................................................................................................................................................... 32
Riscos........................................................................................................................................................ 33
Métricas..................................................................................................................................................... 35
Cronograma............................................................................................................................................... 36
Modelo de Ciclo de Vida............................................................................................................................... 36
Análise de Requisitos .................................................................................................................................... 38
Estudo de Viabilidade ............................................................................................................................... 38
Projeto do Sistema ........................................................................................................................................ 38
Estruturas de Dados................................................................................................................................... 38
Arquitetura do Sistema.............................................................................................................................. 39
Interfaces do Sistema ................................................................................................................................ 40
Implementação .............................................................................................................................................. 41
ÍNDICE DE FIGURAS
FIGURA 1 - ARQUITETURA EM CAMADAS USADA NA NEUS ............................................................. 10
FIGURA 2 – MOR – MAPEAMENTO OBJETO RELACIONAL................................................................ 12
FIGURA 3 – XDOCLET X JAVADOC............................................................................................................ 21
FIGURA 4 – CAMADAS DA ENGENHARIA DE SOFTWARE .................................................................. 30
FIGURA 5 – MODELO DE CICLO DE VIDA CASCATA ........................................................................... 37
FIGURA 6 – ARQUITETURA DO NEUS BEANGEN................................................................................... 39
FIGURA 7 – INTERFACES DO NEUS BEANGEN ....................................................................................... 41
ÍNDICE DE TABELAS
TABELA 1 – COMPOSIÇÃO – PESSOA/CIDADENATAL – CLASSES JAVA ........................................ 13
TABELA 2 – COMPOSIÇÃO – PESSOA/CIDADENATAL – TABELAS SGBDR .................................... 14
TABELA 3 – HERANÇA – VEICULO/TAXI – CLASSES JAVA ................................................................ 14
TABELA 4 – HERANÇA – VEICULO/TÁXI – TABELAS SGBDR ............................................................ 15
TABELA 5 – LOOKUP.JAVA - EXEMPLO DE USO DA API JDBC ......................................................... 16
TABELA 6 – RGC X CDG................................................................................................................................ 17
TABELA 7 – ARQUIVO “.BAT” PARA BUILD SIMPLES.......................................................................... 19
TABELA 8 – ARQUIVO DO ANT - BUILD.XML..................................................................................... 19
TABELA 9 – EXEMPLO XDOCLET - HELLOWORLD.JAVA .................................................................. 22
TABELA 10 – HTML GERADO PELO JAVADOC ...................................................................................... 22
TABELA 11 – CRIAÇÃO DE UMA TAG PRÓPRIA..................................................................................... 25
TABELA 12 – RAIZ DE GERAÇÃO DE CÓDIGO RGC.............................................................................. 26
TABELA 13 – GERAÇÃO 1 – 1........................................................................................................................ 29
Resumo
O projeto NEUS BeanGen se propõe a automatizar a camada responsável pelo
mapeamento de objetos Java em tabelas de bancos de dados relacionais, com o propósito de
aumentar a produtividade no desenvolvimento de software abstraindo ao máximo o uso de
API’s como JDBC. A automatização será adquirida através de geração de código que
proporciona a diminuição no tempo de desenvolvimento de softwares visto que códigos
redundantes antes escritos por programadores, a partir de então serão gerados a partir de uma
raiz de geração. A detecção de erros de programação será facilitada devido ao fato de que os
erros são centralizados na raiz de geração de código. Portanto o projeto tende a aumentar a
produtividade trazendo mais segurança para o desenvolvimento de softwares.
Dedicatória
Identificação
Estagiário
Nome: Fábio Pereira Carneiro
Endereço: Av. Olinda, 385 apto 901 Tambaú – João Pessoa - PB
Telefones: 226-2823 / 8802-1610
Curso: Bacharelado em Ciências da Computação
Período do Estágio: 11/2003 a 03/2004
Empresa
Nome: NEUS – Tecnologia da Informação
Endereço: Av Ruy Carneiro, Trade Office Center Nº 300, Sala 206
Tambauzinho, João Pessoa – PB
Telefone: 225-8257
A NEUS – Tecnologia da Informação é uma empresa especializada em
desenvolvimento de software para Internet, sistemas de comércio eletrônico
entre empresas e serviços executivos de suporte à decisão (Data Warehousing e
Data Mining).
Sua missão é construir softwares de excelência como meio para seus clientes e
a sociedade, como um todo, prosperarem. Já se destaca no mercado regional
como provedora de soluções tecnológicas, em particular soluções orientadas
para a Internet. Atualmente possui uma equipe de 11 pessoas (entre
desenvolvedores e sócios) e atua em três áreas de competência:
desenvolvimento de sistemas; serviços educacionais; e serviços de suporte à
decisão.
Introdução
Propósito do Documento
Um dos requisitos para a conclusão do curso de Bacharelado em Ciências da
Computação na Universidade Federal da Paraíba UFPB é a realização de um
estágio supervisionado com o objetivo de aprimorar os conhecimentos
adquiridos na universidade, colocando os mesmos em prática a fim de preparar
o aluno para a vida profissional.
Este documento tem como objetivo relatar os estudos feitos e as atividades
desenvolvidas pelo aluno Fábio Pereira Carneiro durante seu estágio, realizado
sob a supervisão de Mário Henrique Matos Alves (gerente de projetos da
NEUS – Tecnologia da Informação) e orientação do professor Hamilton Soares
da Silva.
Organização do Documento
O estágio realizado pelo aluno, assim como este documento, foi dividido em
três partes:
Aquisição de Conhecimento
Nesta etapa o aluno se dedicou a estudar as tecnologias, conceitos e
ferramentas que seriam utilizadas no projeto.
Desenvolvimento do Projeto
Foi estabelecida uma metodologia de desenvolvimento do projeto. Nesta parte
do documento será detalhado o processo utilizado para o desenvolvimento,
assim como o modelo de ciclo de vida do projeto que define analise, projeto,
implementação, testes e implantação.
Treinamento
O projeto consiste em estabelecer uma forma de abstração para o
desenvolvimento de softwares na empresa, portanto, seus usuários, os
desenvolvedores, precisam entender como funciona o NEUS BeanGen.
Para isso o aluno elaborou um treinamento com um exemplo didático que foi
ministrado pelo mesmo na empresa ao termino do projeto. Nesse treinamento
foram esclarecidas as interfaces necessárias para a utilização do NEUS
BeanGen.
Motivação
O projeto NEUS BeanGen se propõe a automatizar, usando geração de código,
a camada de Mapeamento Objeto Relacional de objetos Java em Bancos de
Dados Relacionais.
Para se entender a necessidade dessa automatização, será apresentada a
arquitetura de desenvolvimento utilizado na NEUS – Tecnologia da
Informação antes do NEUS BeanGen, ou seja, o “estado da arte”.
Percebeu-se que muito código dessas duas camadas era replicado em vários
lugares. Quando se fala em código replicado não significa que o código era
“igual”, mas significa dizer que a escrita de um código “parecido” era
necessário em diversos arquivos. Essa replicação era realmente necessária, ou
seja, não se tratava de algo que poderia ser abstraído com uso de herança ou
polimorfismo, mas sim replicações devido, principalmente ao uso da API
JDBC que disponibiliza uma interface SQL, portanto temos que mapear os
objetos em statements SQL. Mais adiante essas replicações serão detalhadas.
As replicações da camada Business ocorrem principalmente na Fachada que
estabelece uma interface única e centralizada às funcionalidades do sistema.
Foi determinado que as replicações de código eram necessárias e que uma
forma de evitar a escrita das mesmas seria a geração automática do código
replicado. Ou seja, a partir de um código seriam gerados as suas replicações.
Aquisição de Conhecimento
Para o desenvolvimento do projeto foi necessário o aprendizado, por parte do
aluno, tanto da arquitetura da empresa como de conceitos e tecnologias que
seriam usadas no projeto.
SGBD’s – Relacional x OO
Os Sistemas de Gerenciamento de Bancos de Dados (SGBD, ou Data Base
Management System DBMS) não evoluíram no mesmo sentido das linguagens
de programação. Foram desenvolvidos Bancos de Dados Orientados a Objetos,
mas a grande maioria dos softwares usa, como base de dados, Sistemas de
Gerenciamento de Banco de Dados Relacional (SGBDR – ou RDBMS) devido,
principalmente, a fatores de performance.
Os Bancos de Dados Relacionais armazenam as informações em forma de
tabelas que possuem relacionamentos entre si. Os relacionamentos são
conseguidos através do uso de “chaves” que referenciam outras tabelas.
OO x SGBD
Veremos algumas características da programação orientada a objetos e como
representá-las em um SGBD. Não veremos formas de fazer o mapeamento,
mas sim as duas representações isoladamente. [FUSSEL]
Composição – um objeto é composto de outro. Como exemplo
podemos citar o relacionamento entre as classes Pessoa e Cidade. Onde cada
Pessoa possui um objeto interno que significa a cidade onde nasceu. Vejamos o
código Java abaixo que representa essa associação:
* A criação do atributo “código” na classe Cidade foi com o intuito de se ter uma chave
primária ao criarmos, posteriormente, uma tabela Cidade.
TAXI
PLACA (CHAVE_PRIMARIA)
ANOFABRICACAO
NUMEROPORTAS
NUMEROTAXIMETRO
JDBC
JDBC (Java DataBase Connection) é uma interface padrão para acesso a
Bancos de Dados. Foi desenvolvido no nível de SQL, o que nos permite
construir statements SQL e embuti-los dentro de chamadas de uma API Java.
É através do uso dessa interface JDBC que é feito o Mapeamento Objeto
Relacional. [java.sun. com]
Uma classe chamada Driver JDBC controla todo o acesso ao banco. O usuário
da API JDBC somente “enxerga” comandos SQL. Cada Banco de Dados
possui o seu Driver JDBC.
Através desse Driver consegue-se uma conexão (java.sql.Connection) como
banco. Essa Connection nos fornece um Statement que ao serem executados
resultam em ResultSet (conjunto de resultados que representa a tabela de
retorno de um SELECT por exemplo). Abaixo está um exemplo retirado do
livro “Thinking in Java” (Bruce Eckel)
Geração de Código
Detectou-se a necessidade em duas camadas da arquitetura usada na NEUS –
Tecnologia da Informação, a presença de muito código que podia ser derivado
de outro. Chamou-se esse código que poderia ser derivado de Código
Derivável por Geração (CDG). Ele pode ser derivado de uma Raiz de Geração
de Código (RGC). Abaixo vemos um exemplo de RGC e CDG.
Esse dois exemplos retratam bem os conceitos de RGC e CDG. Isso ocorre
porque foi estabelecido um padrão de código. A partir de então, ao se fornecer
outro código RGC pode-se derivar o seu respectivo CDG.
O XDoclet é uma ferramenta que auxilia no processo de percorrer a RGC
resultando no seu CDG. Para trabalhar com XDoclet faz-se necessário o
entendimento de outra ferramenta chamada ANT.
ANT
O ANT é uma ferramenta desenvolvida pela Jakarta (projeto Apache / Sun)
para automatização de tarefas de construção de software utilizando classes Java
e arquivos XML ao invés de uma comunicação direta com o Shell do sistema
operacional. [ant.apache.org]
Existem algumas definições para a sigla ANT, uma delas é Another Neat Tool,
que significa “Mais uma ferramenta perfeita”; outra definição é associar o
nome ANT ao seu significado do inglês “formiga”, no sentido de que o ANT é,
assim como a formiga, pequeno, mas com um grande “poder”.
O ANT funciona em torno do conceito de tarefas. Vejamos um exemplo:
Suponha um software simples que está organizado em dois diretórios:
src – código fonte do projeto (arquivos .java)
bin – código compilado (arquivos .class)
O processo de construção, chamado build, desse software exemplo consiste
nas tarefas:
clean – limpar o diretório de código compilado, ou seja, apagar o
diretório bin e criá-lo novamente.
compile – compilar o código que está em src e jogar os arquivos
compilados no diretório bin.
Existem algumas formas de automatizar esse processo de build. Uma delas é
fazer um arquivo “.bat”, caso o sistema operacional utilizado seja Windows,
que realiza as duas tarefas:
<target name="clean">
<delete dir="${dir.bin}"/>
<mkdir dir="${dir.bin}"/>
</target>
<target name="compile"
depends="clean">
<javac
srcdir="${dir.src}"
includes="com/**/*.java"
destdir="${dir.bin}"
debug="off"
optimize="on"
failonerror="true"
>
</javac>
</target>
</project>
Outro detalhe a ser citado é que se a tarefa não for especificada na chamada do
ANT, a tarefa chamada é a definida como default na tag:
<project default="compile"...>
Uma forma de chamar a tarefa “clean” por exemplo, seria:
XDoclet
O que é?
XDoclet é uma ferramenta de geração de código. Pode-se adicionar mais
significado ao seu código através de meta-dados que são representados através
de tags semelhantes às do JavaDoc, que gera arquivos html de documentação
para o código Java. [xdoclet.sourceforge.net]
XDoclet X JavaDoc
A grande diferença do XDoclet para o JavaDoc é que o último possui suas tags
pré-definidas que são colocadas nas classes, atributos e métodos. Alguns
exemplos dessas tags são: @author, @version, @param, @return. E a sua saída
também é pré-definida, ele gera somente arquivos html com um formato que
não pode ser alterado. Enquanto que o XDoclet disponibiliza a criação das
nossas próprias tags, por exemplo @minhaTag1, @minhaTag2; e, além disso,
pode-se gerar qualquer arquivo a partir das raízes com essas tags. Veja Figura 3
Figura 3 – XDoclet X JavaDoc
Arquivos “.html”
Arquivos “.java”
@author, @param,
@Return
JAVADOC
O exemplo abaixo mostra como funciona o uso das tags JavaDoc: A classe
HelloWorld (arquivo HelloWorld.java) foi comentada com as tags JavaDoc
@author que é uma tag de classe, portanto colocada logo antes da definição da
classe e a tag de método @param que explica a função de um parâmetro do
método. Logo abaixo pode-se ver o resultado em html gerado pelo JavaDoc.
Method Detail
Main
public static void main(java.lang.String[] args)
Parameters:
args - argumentos passados na linha de comando
Tag Handlers
O XDoclet possui uma grande quantidade de tags de templates definidas como
é o caso dos exemplos vistos anteriormente: forAllClasses, className,
methodName, etc. Mas existem ocasiões onde há a necessidade de criação das
nossas próprias tags. Por exemplo, se quisermos uma tag para indicar no
arquivo gerado a data da geração, poderíamos criar o nosso próprio namespace
“meuNamespace” e um taghandler, que nada mais é do que uma classe Java
filha da classe xdoclet.XDocletTagSupport com métodos que representam as
tags. A nossa tag da data poderia ser chamada de minhaTagDataAtual. Logo
deveria ser criado uma classe TagHandler e citá-la no arquivo xdoclet.xml que
é o arquivo de configuração da geração. O arquivo xdoclet.xml pode ser
comparado ao web.xml em uma aplicação web.
/** <taghandler
namespace="meuNamespace"
*@xdoclet.taghandler
class="com.taghandler.MeuTagHander"
namespace="meuNamespace" />
*/ </xdoclet-module>
public class MeuTagHandler
extends XDocletTagSupport{
Geração (1 – 1) X (N – 1)
XDoclet disponibiliza duas formas de geração, essas duas se caracterizam pelo
fato de que na geração 1 – 1 a partir de cada arquivo RGC será gerado um
correspondente CDG. Enquanto que na geração N – 1 é gerado apenas um
arquivo CDG a partir de vários arquivos RGC.
Exemplo
Vamos gerar o CDG abaixo a partir da RGC dada:
/** /**
* @minhaTagAuthor Autor da Classe Pessoa * @minhaTagAuthor Autor da Classe Veiculo
*/ */
public class Pessoa { public class Veiculo {
private String nome; private String placa;
public String getNome() { public String getPlaca() {
return this.nome; return this.placa;
} }
public void setNome(String nome) { public void setPlaca(String placa) {
this.nome = nome; this.placa = placa;
} }
} }
Classe – Pessoa
Autor – Autor da Classe Pessoa
Metodos:
getNome
setNome
Classe – Veiculo
Autor – Autor da Classe Veiculo
Metodos:
getPlaca
setPlaca
O exemplo tem como CDG um arquivo txt com o intuito de demonstrar que
não necessariamente “código” pode ser gerado, mas sim qualquer arquivo.
infoTemplate.xdt
<XDtClass:forAllClasses>
Classe - <XDtClass:className />
Autor - <XDtClass:classTagValue tagName="minhaTagAuthor" />
Metodos:
<XDtMethod:forAllMethods>
<XDtMethod:methodName />
</XDtMethod:forAllMethods>
</XDtClass:forAllClasses>
build.xml
<path id="classpath.lib.xdoclet">
<fileset dir="${dir.lib}">
<include name="**/*.jar"/>
</fileset>
<pathelement path="${dir.build}/"/>
</path>
<target name="infoClasses"
description="Gera o arquivo.">
<taskdef name="taskInfoClasses"
classname="xdoclet.DocletTask">
<classpath refid="classpath.lib.xdoclet"/>
</taskdef>
<taskInfoClasses
destdir="${dir.dest}">
<fileset dir="${dir.src}">
<include name="**/*.java"/>
</fileset>
<template
templateFile="${dir.templates}/${nomeTemplateInfo}"
destinationFile="infoClasses.txt"
/>
</taskInfoClasses>
</target>
<target name="clean">
<delete dir="${dir.dest}"/>
<delete dir="${dir.bin}"/>
<mkdir dir="${dir.dest}"/>
<mkdir dir="${dir.bin}"/>
</target>
</project>
Tabela 13 – Geração 1 – 1
infoClassPessoa.txt infoClassVeiculo.txt
Classe – Pessoa Classe – Veiculo
Autor – Autor da Classe Pessoa Autor – Autor da Classe Veiculo
Metodos: Metodos:
getNome getPlaca
setNome setPlaca
Desenvolvimento do Projeto
Metodologia
Processo
Planejamento
O planejamento de um software consiste em realizar as atividades de definição
do escopo, definição de recursos, análise de riscos, definição de métricas e
elaboração de cronograma. O aluno acompanhou, para um maior aprendizado
do processo como um todo, o planejamento do NEUS BeanGen, gerido
principalmente pelo seu supervisor Mário Henrique Matos Alves, que é o
gerente de projetos da empresa e, portanto, o responsável por essa tarefa.
A seguir serão citadas as etapas do planejamento com um resumo sobre cada
uma delas.
Escopo
A definição do escopo de um software consiste em chegar a respostas básicas
sobre às perguntas citadas abaixo:
Recursos
Os recursos utilizados foram divididos em três tipos: humanos, hardware e
software.
Humanos
Os recursos humanos definem quem são as pessoas envolvidas no projeto do
software. No caso do NEUS BeanGen:
Hardware
Foram utilizadas duas máquinas com a seguinte descrição:
Processador: Pentium 4 de 1.6 GHz
Memória RAM: 512Mb
HD: 40Gb
Software
Foram utilizados os softwares:
Sistema Operacional: Windows 2000
IDE (Integrated Development Environment): NetBeans
Softwares de apoio: XDoclet, Máquina Virtual Java da Sun (JVM), WinCVS.
Riscos
Riscos são características que possam vir a dificultar o projeto. Existem três
etapas na análise de riscos:
Identificação: elicitar os riscos e categorizar cada um deles como risco de
negócio, de projeto ou técnico.
Estimativas: estimar a probabilidade de sua realidade e qual seria o impacto
sobre o projeto caso ele se tornasse real.
Administração: consiste em encontrar uma solução para diminuir ou acabar
com o impacto do risco caso ele realmente se concretize.
Abaixo está a tabela de análise de riscos do NEUS BeanGen.
Risco Técnico
Probabilidade Moderado
Risco Técnico
Probabilidade Moderado
Risco de Negócio
Probabilidade Improvável
Métricas
O processo de medir software tem o objetivo de estimar o tamanho do mesmo
para facilitar estimativas de esforço (pessoa-mês) e cronograma.
As medições feitas no NEUS BeanGen foram através dos arquivos a serem
gerados. Para cada arquivo a ser gerado foi dado um nível de complexidade e
para cada nível de complexidade (NC) foi estimado um esforço. A tabela
abaixo ilustra as medições:
Cronograma
O cronograma representa os prazos do projeto. Quando as tarefas começam e
quando terminam. Baseado nas métricas citadas anteriormente foi criado o
seguinte cronograma para o projeto NEUS BeanGen.
Estimativa de Tempo
Planejamento
Análise
Projeto
Implementação
Testes
Implantação
Manutenção
0 1 2 3 4 5
Projeto do
Sistema
Implementação
Teste
Manutenção
Documentação
uma vantagem pelo fato de que o programador, que é o cliente, avalia a etapa
antes de passar para a próxima.
Análise de Requisitos
Segundo o IEEE a definição de Análise de Requisitos é:
“Processo de aquisição, refinamento e verificação das necessidades do
cliente com o objetivo de obter uma especificação correta e completa dos
requisitos”
Os clientes do NEUS BeanGen eram os próprios desenvolvedores da empresa,
portanto o processo de análise de requisitos se deu através de reuniões entre os
mesmos para identificar necessidades. Necessitava-se de geração de arquivos
considerados deriváveis, portanto, foram elicitados todos os arquivos que
poderiam ser gerados.
Estudo de Viabilidade
Nessa etapa deve-se verificar se o projeto é realmente factível, isso inclui um
estudo de viabilidade de custos e viabilidade técnica. O aluno foi o responsável
pelo estudo de viabilidade técnica procurando tecnologias disponíveis para
geração de código e verificando se elas atendem as necessidades do projeto.
Nessa etapa o aluno adquiriu conhecimentos suficientes sobre geração de
código, ferramentas e API’s para o desenvolvimento do projeto. Essas
tecnologias foram detalhadas na introdução deste documento.
Projeto do Sistema
Projeto é uma representação de engenharia de algo que será construído
posteriormente. Basicamente foram realizadas as tarefas de definição das
estruturas de dados, arquitetura do software e definição das interfaces.
Estruturas de Dados
Os “dados” maipulados pelo NEUS BeanGen são arquivos com código Java
comentado com suas devidas tags XDoclet. Não há armazenamento de
Arquitetura do Sistema
Arquitetura é a forma como as várias partes do software são integradas para
formar um total coeso. Ou seja, deve-se definir os módulos do software e suas
interligações. A definição abaixo foi dada por Jarrold Grochow:
“A arquitetura de um sistema é um arcabouço abrangente que descreve sua
forma e estrutura, seus componentes e como eles se articulam”
Jerrold Grochow
O projeto NEUS BeanGen está apoiado sobre a arquitetura da NEUS.
Basicamente em cima das duas camadas que necessitam de geração de código
para o Mapeamento Objeto Relacional que são Data e Business. Para cada uma
dessas camadas foi feito um modelo com sub-camadas de geração de acordo
com a especificação do XDoclet para geração de código, ou seja, para cada
camada da NEUS foi definido um TagHandler, um conjunto de templates e
uma tarefa ant que execute essa geração. Essa arquitetura está na Figura 6.
Figura 6 – Arquitetura do NEUS BeanGen
Interfaces do Sistema
A comunicação Usuário – NEUS BeanGen será realizada através de scripts
ANT. Nesses scripts são estabelecidos os diretórios de origem e de destino para
os arquivos. Portanto a interface de entrada para o NEUS BeanGen será uma
tarefa ANT para cada camada da NEUS (Data e Business). Para essa tarefa
ANT deve-se estabelecer um local onde estão os arquivos Raiz de Geração de
Código que chamaremos de NEUS Beans contendo as devidas tags que serão
detalhadas posteriormente.
Uma das grandes características do NEUS BeanGen é o seu alto nível de
abstração, portanto o usuário terá uma interface simples que esconde ao
máximo os detalhes da geração do código.
O resultado da geração será a geração de toda a camada Data e parte da
camada Business. A partir de então o usuário disponibilizará de uma Fachada
do sistema que está desenvolvendo usando o NEUS BeanGen com acesso a
todos os objetos do sistema que estão armazenados em um banco de dados, que
para ele se torna transparente.
Os métodos da Fachada serão a interface que o usuário irá usar a partir de
então para programar. Para cada entidade com persistência no banco de dados,
que chamaremos mais adiante de NEUS Bean, existirão métodos de acesso
(filtrar, get, soma, mínimo, maximo, etc), cadastro(cadastrar) e
alteração(alterar) na Fachada. O detalhamento dos métodos da Fachada foge
ao escopo do projeto NEUS BeanGen que consiste em gerar arquivos onde um
desses arquivos é a Fachada do sistema. Após a geração de todos os arquivos,
essa Fachada será um dos arquivos mais importantes por ser o ponto através do
qual o usuário (programador) terá acesso as funcionalidades do sistema. Mas
ela se torna importante para o desenvolvimento pós-geração de código, ou seja,
dentro da arquitetura de desenvolvimento.
A figura abaixo mostra uma visão macro do NEUS BeanGen com suas
entradas e saídas.
Implementação
A implementação do NEUS BeanGen consistiu em criar, para cada arquivo que
deveria ser gerado os seguintes artefatos: template, tags no TagHander, tarefa
ANT. E finalmente uma tarefa ANT que unificasse a geração da camada Data e
outra para a camada Business.
Devido a fatores de sigilo de código da empresa, não serão mostrados todos os
arquivos gerados, mas sim apenas um deles.
RGC – Pessoa.java
CDG – ComandoRepositorioPessoaJDBC.java
public class ComandoRepositorioMunicipioJDBC extends
ComandosRepositorioAbstratoJDBC
{
public void cadastrar(ObjetoChave objeto, PreparedStatement ps)
throws SQLException
{
Pessoa objetoPessoa = (Pessoa) objeto;
SetadorPreparedStatement setador
= new SetadorPreparedStatement(ps);
setador.set(objetoPessoa.getCodigo(), false);
setador.set(objetoPessoa.getNome(), false);
setador.set(objetoPessoa.getIdade(), false);
}
Template – comandoRepositorioTemplate.xdt
public class ComandoRepositorio<XDtNeusClass:className/>JDBC extends
ComandosRepositorioAbstratoJDBC
{
public void cadastrar(ObjetoChave objeto, PreparedStatement ps)
throws SQLException
{
<XDtNeusClass:className/> objeto<XDtNeusClass:className/> =
(<XDtNeusClass:className/>) objeto;
SetadorPreparedStatement setador = new
SetadorPreparedStatement(ps);
<XDtNeusData:
instrucoesSetarPSComandoRepositorioSuperclassesForaDoProjeto />
<XDtMethod:forAllMethods>
<XDtMethod:ifHasMethodTag tagName="neus.isColumn">
<XDtNeusData:setarPSComandoRepositorioMetodoGetter />
</XDtMethod:ifHasMethodTag>
</XDtMethod:forAllMethods>
}
<XDtNeusData:
instrucoesSetarPSCamposNotPrimaryKeyComandoRepositorioSuperclassesForaDoProjeto />
<XDtMethod:forAllMethods>
<XDtMethod:ifHasMethodTag tagName="neus.isNotPrimaryKey">
<XDtMethod:ifHasMethodTag tagName="neus.isColumn">
<XDtNeusData:setarPSComandoRepositorioMetodoGetter />
</XDtMethod:ifHasMethodTag>
</XDtMethod:ifHasMethodTag>
</XDtMethod:forAllMethods>
<XDtNeusData:instrucoesSetarPSCamposPrimaryKeyComandoRepositorioSuperclassesForaDoProjet
/>
<XDtMethod:forAllMethods>
<XDtMethod:ifHasMethodTag tagName="neus.isPrimaryKey">
<XDtMethod:ifHasMethodTag tagName="neus.isColumn">
<XDtNeusData:setarPSComandoRepositorioMetodoGetter />
</XDtMethod:ifHasMethodTag>
</XDtMethod:ifHasMethodTag>
</XDtMethod:forAllMethods>
}
<XDtNeusData:
instrucoesSetarObjetoComandoRepositorioSuperclassesForaDoProjeto/>
<XDtMethod:forAllMethods>
<XDtMethod:ifHasMethodTag tagName="neus.isColumn">
<XDtNeusData:setarObjetoComandoRepositorioMetodoGetter />
</XDtMethod:ifHasMethodTag>
</XDtMethod:forAllMethods>
}
{
return new <XDtNeusClass:className/>();
}
Notemos que algumas das tags usadas no template não são tags de namespaces
já definidos pelo XDoclet que são Class, Method, etc. Um exemplo de uma tag
definida pelo NEUS BeanGen é
<XDtNeusData:setarObjetoComandoRepositorioMetodoGetter />
Para o uso dessa tag foi necessária a criação de um TagHandler com o
namespace NeusData. Criação de TagHandler já foi explicado enquanto
detalhava-se o funcionamento do XDoclet, portanto aqui será mostrado apenas
uma parte do NeusDataTagHandler.java.
TagHandler – NeusDataTagHandler.java
/**
* @xdoclet.taghandler namespace="NeusData"
*
*/
public class NeusDataTagHandler extends NeusTagHandlerAbstract
{
(...)
if (isComposto)
{
tipo = tipoRetornoFullMetodo();
nomeColuna = "ID" + nomeColuna.toUpperCase();
}
else
{
tipo = tipoRetornoMetodo();
}
str += getSetarObjetoComandoRepositorio(nomeObjeto,
nomeCampoMetodoGetter(),
nomeColuna,
isComposto,
tipo,
possuiTag("neus.isNull", FOR_METHOD));
return str;
}
(...)
}
<target name="generate.comandoRepositorio"
description="Gera a classe ComandoRespositorio.">
<taskdef name="generate.comandoRepositorio"
classname="xdoclet.DocletTask">
<classpath refid="classpath.drivers.build" />
</taskdef>
<generate.comandoRepositorio
destdir="${dir.comandoRepositorio}" >
<fileset dir="${dir.beans}">
<include name="**/*.java"/>
</fileset>
<template
havingClassTag="neus.isBean"
templateFile=
"${dir.templates}/${nomeTemplateComandoRepositorio}"
destinationFile="ComandoRepositorio{0}JDBC.java"
/>
</generate.comandoRepositorio>
</target>
(...)
<target name="generate.data"
depends="generate.comandoRepositorio,
generate.complementoRepositorio,
generate.xml,
generate.scriptsBD" />
</project>
Testes
Testar um software significa executá-lo com o objetivo de descobrir um ou
mais erros. No projeto em questão foi criado um exemplo com todos os
requisitos que foram implementados para a geração do código e esse exemplo
foi submetido à geração. Alguns erros foram encontrados e corrigidos.
Os testes eram parcialmente automatizados pelo ANT, pelo próprio princípio
da geração de código com XDoclet que já utiliza essa ferramenta de automação
de construção.
Foram necessários testes manuais como abrir arquivos gerados e compará-los
com o que eles deveriam realmente ser.
Implantação
Logo após o termino do desenvolvimento e testes do NEUS BeanGen ele
estava em condições de ser implantado. Nesse instante a empresa iniciava o
desenvolvimento de dois sistemas e, portanto, a implantação do NEUS
BeanGen consistiu em utilizá-lo para o desenvolvimento desses sistemas.
Uma parte da implantação consistiu também na realização de treinamento dos
programadores que iriam usar o NEUS BeanGen.
Manutenção
Existem quatro tipos de manutenção de software: corretiva, adaptativa,
perfectiva e preventiva. Durante o desenvolvimento dos dois sistemas usando o
Treinamento
Uma das tarefas realizadas pelo aluno foi elaborar um treinamento para os
desenvolvedores da empresa quer serão os usuários do NEUS BeanGen.
Nesta seção será mostrada uma parte desse treinamento através de uma visão
geral de alguns conceitos como NEUS Beans e NEUS BeanGen Tags.
NEUS Beans
Cada classe do projeto que necessita de armazenamento no banco de dados é
considerada um NEUS Bean. Por exemplo, em um projeto de controle
acadêmico será criada uma classe Aluno que deverá possuir persistência no
banco de dados. Portanto a classe Aluno deverá ser um NEUS Bean.
Acessor Methods
Assim como os Java Beans, origem da denominação, os NEUS Beans possuem
accessor methods para os seus atributos. Accessor Methods são métodos de
acesso aos atributos de uma classe. No caso dos NEUS Beans eles devem ser
getter e setter. Por exemplo, se a classe Aluno possuir um atributo String
nome, ela deve possuir dois métodos:
public String getNome() e public void setNome(String nome).
Os NEUS Beans são parte da camada Business da arquitetura NEUS. Eles
realizam o papel principal no momento em que se está utilizando o NEUS
BeanGen, pois são a Raiz Geração de Código (RGC) para todo o processo de
geração das dos arquivos deriváveis.
Chave Primária
Uma característica dos NEUS Beans é que a classe IntegerChaveImpl sempre
está acima na sua árvore de herança. Essa classe interpreta como chave
Representação Gráfica
Foi criada uma representação parecida com a UML para os NEUS Beans.
Suponha uma classe Aluno com os campos: nome, dataNascimento. Sua
representação seria:
Aluno
String nome
Date dataNascimento
BeanTags
São as tags colocadas como documentação da classe NEUS Bean, ou seja, no
mesmo lugar onde as tags JavaDoc de classe ficam.
Aluno.java
/**
* @author Fabio Pereira
* @neus.isBean
* @neus.poolSize 100
*/
public class Aluno extends IntegerChaveImpl{
(...)
}
@neus.isBean
Todos os NEUS Bean devem possuir essa tag. É essa tag que informa que
aquela classe é realmente um NEUS Bean.
@neus.poolSize
A arquitetura da NEUS usa o um cache de objetos em memória. Isso significa
dizer que quando precisa-se acessar um objeto primeiramente procura-se esse
objeto em memória no seu devido cache e somente se ele não estiver lá deve-se
buscá-lo no Banco de Dados. Essa técnica é utilizada devido ao fato de que
acesso à memória é bem mais rápido do que acesso ao banco de dados.
Portanto, cada NEUS Bean possui um cache com tamanho definido através
dessa tag. Exemplo: @neus.poolSize 100.
GetterMethodTags
Algumas informações são específicas de cada atributo do NEUS Bean. O
método getter do atributo foi o escolhido para a documentação de informações
sobre o mesmo. Logo elas ficam no mesmo local da documentação JavaDoc
para métodos.
Todos os métodos getter do NEUS Bean devem possuir uma tag de cada um
dos pares de GetterMethodTags.
Os pares são do tipo @neus.isAlgumaCoisa ou @neus.isNotAlgumaCoisa.
Essas tags são subdivididas em dois subgrupos: DBGetterMethodTags e
CompositionGetterMethodTags
DBGetterMethodTags
Data Base GetterMethodTags são tags que informam ao NEUS BeanGen
características diretas do Banco de Dados. São elas:
@neus.isColumn / @neus.isNotColumn
Essa tag estará em um método getter de um atributo, ela indica se esse atributo
é ou não (is ou isNot) uma coluna no banco. Ela se faz necessária pelo fato de
que o NEU Bean pode possuir atributos que não são persistentes, como por
exemplo um campo calculado a partir de outros.
Portanto no exemplo do Aluno para indicar que o campo nome é persistente no
banco na forma de uma coluna colocaria-se a tag @neus.isColumn no método
getter do atributo nome. Veremos esse exemplo mais a frente.
@neus.isNull / @neus.isNotNull
Essa tag é auto explicativa. Determina se o atributo pode ou não ser null. Essa
característica será repassada para os scripts de criação do Banco de Dados.
@neus.isDateTime / @neus.isNotDateTime
Alguns Bancos de Dados fazem diferença entre o tipo DATE e DATETIME,
que diferenciam o armazenamento apenas da data ou data e hora.
Nos NEUS Beans deve-se usar sempre o tipo java.util.Date para atributos data,
mas é necessário indicar para o banco se esse campo usa data e hora
(@neus.isDateTime) ou somente a data (@neus.isNotDateTime).
Exemplo
O exemplo abaixo ilustra o uso das DBGetterMethodTags com a classe Aluno.
Aluno.java
(...)
public class Aluno extends IntegerChaveImpl{
private String nome;
private Date dataNascimento;
/**
* @neus.isColumn
* @neus.isNotNull
* @neus.isString VARCHAR(60)
*/
public String getNome() {return nome;}
public void setNome(String nome) {this.nome = nome;}
/**
* @neus.isColumn
* @neus.isNotNull
* @neus.isNotDateTime
*/
public Date getDataNascimento() {return dataNascimento;}
public void setDataNascimento(String dataNascimento) {
this. dataNascimento = dataNascimento;
}
}
CompositionGetterMethodTags
São usadas para definir características específicas de objetos com composição,
ou seja, objetos que possuem outros objetos dentro deles.
Suponha que queiramos desenvolver um sistema acadêmico e no cadastro do
aluno estão os dados sobre o seu endereço. Vamos então criar duas classes
Aluno e Endereco e uma composição entre eles. Será mostrado o modelo das
tabelas no banco para um entendimento de como é implementada composição
em um banco de dados relacional (SGBDR).
Composição em Classes
Endereço Aluno
String logradouro String nome
int numero Date dataNascimento
String cidade Endereco endereco
String cep
T_ENDERECO T_ALUNO
IDENDERECO NOME
LOGRADOURO DATANASCIMENTO
NUMERO IDENDERECO
CIDADE
CEP
@neus.isFilled / @neus.isNotFilled
Essa tag define se um objeto dentro de outro será preenchido (filled) ou não.
Portanto, no exemplo mostrado acima, o getter method de endereço na classe
Aluno deveria possuir essa tag. Com isso, ao solicitar um objeto Aluno através
de algum método da fachada esse aluno virá com os campos do seu objeto
interno endereco (logradouro, numero, cidade, cep) preenchidos. Caso essa tag
não seja colocada, o objeto interno endereco virá apenas como o seu
IDENDERECO que é o único campo que está na tabela do Aluno.
@neus.isInsertedAfter / @neus.isInsertedBefore
Algumas vezes, ao fazermos uma solicitação de cadastro de um objeto,
queremos que algum objeto interno seja cadastrado também. É o caso do
exemplo anterior. Suponha que preenchemos um objeto Aluno da seguinte
forma:
CadastradorDeAluno.java
objAluno.setEndereco(objEnderecoDoAluno);
FachadaAccessor.getFachada().cadastrar(objAluno);
Aluno.java
Conclusões
O mercado de trabalho na área de informática está cada vez mais competitivo,
exigindo que os profissionais tenham um alto grau de qualificação. O estagio
realizado pelo aluno na NEUS Tecnologia da Informação foi de grande
importância para colocar em prática os conceitos aprendidos na universidade.
O aluno teve a oportunidade de lidar com conceitos de ponta, como é o caso de
geração de código, POO e aplicações web.
O espírito de equipe foi cultivado durante todo o projeto e o aluno teve a
oportunidade de vivenciar um trabalho com pessoas cujas personalidades e
conhecimentos eram os mais variados.
A escolha das ferramentas e API’s foram acertadas. O ANT unido ao XDoclet
fizeram com que o NEUS BeanGen obtivesse sucesso trazendo para a empresa
os objetivo desejado que era o aumento na produtividade devido ao foco da
programação estar voltado para os pontos chaves dos sistemas em oposição à
programação de códigos repetitivos que eram desenvolvidos anteriormente.
Competitividade é também uma palavra chave para empresas de software
atualmente. Esse aumento na produtividade torna a empresa mais competitiva
no mercado ao qual ela se destina de aplicações web.
O aluno se sente lisonjeado de ter a oportunidade de fazer um estágio produtivo
em uma empresa que proporciona um ambiente de trabalho amigável com
tecnologias de ponta. Uma experiência de vida que lhe servirá de embasamento
prático para toda a sua vida profissional.
Referências
Bibliografia
Internet
• ant.apache.org
• xdoclet.sourceforge.net
• java.sun.com
Avaliação
Supervisor – Mario Henrique Matos Alves
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
Nota: _________________
______________________________________________________________
MARIO HENRIQUE MATOS ALVES
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
___________________________________________________________________________
Nota: _________________
__________________________________________________________
HAMILTON SOARES DA SILVA