quarta-feira, 24 de setembro de 2014

BeanMaker: Evolução - 24/09/2014

Codificação da camada de transação (transaction) finalizada. Partindo para finalizar a camada de serviços (service) e iniciar a camada de controle (control).

segunda-feira, 22 de setembro de 2014

BeanMaker: Evolução - 22/09/2014

No estágio atual de desenvolvimento o Bean Maker já está gerando seguintes artefatos:

1) Classe da camada modelo (model).
2) Interface da camada de acesso aos dados (DAO).
3) Classe da camada de acesso aos dados (DAO).

Estão em desenvolvimento os seguintes artefatos:
4) Diferenciação na classe da camada de dados do tratamento entre bancos de dados que utilizam sequências (sequences) e colunas auto-numeradas (identity).
5) Classe da camada de serviço (service).

Entrarão no desenvolvimento em sequência:
6) Classe da camada de transação (transaction).
7) Classe da camada de controle (control).
8) Artefato da camada de de visão (view).
9) Artefato para internalização (I18N).
10) Artefato para construção dos menus.

segunda-feira, 15 de setembro de 2014

Lançada a versão Beta 2 do RichFaces 4.5.0

Essa é a biblioteca de componentes visuais do Presto Cobranças e do BeanMaker. Estou aguardando a primeira versão RC (Release Candidate) para iniciar os testes. Mais detalhes aqui.

quarta-feira, 10 de setembro de 2014

Finalizei a função de documentação da relação entre as anotações e as camadas da aplicação.

O BeanMaker é todo governado por anotações (principalmente) a partir da classe da camada modelo, todas as demais camadas podem ser impactadas por elas.

Assim, é fundamental que as ações provocadas por cada anotação nas diversas camadas estejam muito bem documentadas. Essa funcionalidade nova atende a essa necessidade.

Exemplo de documentação das ações produzidas por anotações entre as camadas:

Anotação "@Id" da JPA:
1)Na camada DAO serve para:
1.a) Recuperar um exemplar da classe (uma linha da tabela) através dos métodos getById e getByIdLock.
1.b) Eliminar um exemplar da classe (uma linha da tabela) através do método delete.
2)Na camada View serve para:
2.a) Definir se o campo pode ser alterado em uma manutenção (update). Assim, se o campo estiver vinculado a uma propriedade com essa marcação terá que ser somente para leitura (readonly).

Anotação "@GeneratedValue" da JPA:
3)Na camada DAO serve para:
3.a) Indicar que o método insert não deverá ter para a coluna vinculada a propriedade atribuição de valor no comando insert do sql (MySql com colunas autonumeradas). Indica também que o valor atribuído pelo banco deve ser recuperado depois da execução do comando sql.
4)Na camada View serve para:
4.a) Definir que o campo associado à propriedade deverá ser "readonly" inclusive na inclusão.

sábado, 6 de setembro de 2014

BeanMaker: Atraso e documentação

Um pequeno atraso: estarei finalizando a versão 1.0.0 do BeanMaker apenas no dia 16/09.

Precisei refazer algumas funcionalidades para que o código ficasse mais legível e funcional e introduzir um novo relacionamento (ManyToMany) entre as tabelas/classes “Anotação” e “Camada”. Esse relacionamento me permite documentar as ações que cada anotação provoca em cada camada.

Embora a funcionalidade coberta por esse novo relacionamento não seja fundamental para o funcionamento primário do sistema (que é gerar o código), ela me permitirá ter o processo completamente documentado e fácil de acessar e alterar.

Inicialmente pensei em produzir essa documentação em Excel, depois em diagrama de redes ou de causas e efeitos ou de chuva de ideias (mapa mental). Todos pareceram muito trabalhosos de montar e manter.

Acredito que depois que a nova tabela esteja preenchida, poderei gerar alguns diagramas hierárquicos ou de árvore automaticamente.

As anotações são o coração do BeanMaker. Então mantê-las organizadas e bem explicadas são fundamentais para o projeto. Por isso, acho que esse esforço adicional é mais do que justificado.

Transparência e responsabilidade com a qualidade são padrões dos quais não abro mão.

quarta-feira, 3 de setembro de 2014

BeanMaker, Conceituação – One To Many/Many To One

Hoje vou demonstrar como o BeanMaker resolve os relacionamentos de “1 para ‘n’” (OneToMany) e de “’n’ para 1” (ManyToOne). O nosso objetivo será gerar o código completamente funcional para manutenção das tabelas/classes que possuam esses tipos de relacionamento.

Por razões de simplicidade e para reduzir o tamanho do artigo, vou omitir os detalhes da internacionalização das telas (I18N). Mas lembre-se: o código gerado será totalmente preparado para internacionalização.

Nosso cenário de hoje

Dando continuidade à nossa demonstração, focarei nas classes/tabela “Diretoria” e “Departamento”, conforme destaque abaixo:

Para os novatos ou não técnicos, a notação acima, indica que uma Diretoria pode ter de zero a “n” departamentos na sua hierarquia. Também indica que um Departamento tem que (é obrigado a) pertencer a uma Diretoria

Quando falamos de modelagem relacional e uma entidade tem um relacionamento de “1 para muitos”, a boa prática é exportar a chave primária da tabela “pai” (a que garante a unicidade, no nosso caso a coluna “idDiretoria”) para a tabela “filha”. Essa ação permite fazer uma navegação bidirecional entre as tabelas. Assim podemos partir de “Diretoria” e localizar os “Departamentos”, bem como podemos partir de um “Departamento” e localizar a sua diretoria.

No entanto, quando estamos falando de objetos, principalmente quando não estão persistidos (gravados no BD), temos que montar esses dois relacionamentos explicitamente. Assim, temos que declarar na classe “Diretoria” uma lista com os seus “Departamentos” e na classe “Departamento” a qual “Diretoria” ele está subordinado.

Aprofundando a geração de código para ‘Diretoria’

Na postagem BeanMaker, Conceituação – Construindo código para a primeira classe apresentei a tela abaixo para a tabela/classe Diretoria:

Vamos construir várias pequenas telas para a manutenção (CRUD; Create, Retrieve, Update & Delete) de Diretorias e Departamentos. Observe que na tela de resultado da pesquisa de diretorias, incluí a coluna “Departamentos” que exibirá a quantidade de departamentos com um link para exibi-los.

Se for solicitada a inclusão de uma nova diretoria (através do botão “Novo”) ou se for clicado no link da coluna “Id” da tela de “Diretorias Localizadas” será apresentada a tela abaixo.

A diferença entre o resultado da ação de clicar no botão “Novo” e no “link com Id” é o não preenchimento ou preenchimento dos campos, respectivamente. Nessa tela apareceu o botão “Departamentos” que conduz a uma lista de departamentos da diretoria. Acho que não é necessário dizer que todos os botões dessa tela são sensitivos ao contexto. Por exemplo, se for uma inclusão, o botão “Excluir” estará desabilitado.

O mais importante desse tópico é que você perceba, que dada um classe “Diretoria” da camada “Model” como descrita abaixo, é possível criar todos esses comportamentos em códigos totalmente funcionais, de forma automática, sem nenhuma intervenção humana direta.

@Entity
@Table (name=”Diretoria”)
public class Diretoria {
   @Id
   @Column (name=”idDiretoria”)
   @BMViewField(size=5, maxLength=5)
   private Integer idDiretoria;
   @NotNull
   @BMViewField(size=50, maxLength=50)
   @BMDataPropertyUniqueKey
   @BMDataListBy
   private String nmDiretoria;
   @OneToMany(mappedBy="idDiretoria")
   private List<Departamento> departamentos;
   // constructors
   // getters and setters
   // methods like “toString”
}

A simples inclusão da anotação ‘@OneToMany(mappedBy="idDiretoria")’ provocou o aparecimento da coluna “Departamentos” nova na lista de diretoria e na inclusão do botão “Departamentos” na tela de manutenção de diretoria.

Aprofundando a geração de código para ‘Departamento’

Vou apresentar as telas de pesquisa e manutenção de departamentos e como o BeanMaker vai se utilizar das anotações para cria-las.

O fundamental é observar que aparecerá um componente novo nas telas: Uma caixa de seleção (ComboBox, DropDownList) de diretorias tanto na tela de pesquisa quanto na de manutenção. Na segunda tela, é gerado pelo simples fato de existir uma anotação “ManyToOne” na propriedade.

Para a tela de pesquisa, no entanto, foi necessário incluir a nova anotação “BMViewSearchCriteria” para indicar que desejaremos fazer pesquisa de departamentos, limitando a pesquisa por alguma diretoria fornecida.

Apresento abaixo a definição da classe/tabela “Departamento”:

@Entity
@Table (name=”Departamento”)
public class Departamento {
   @Id
   @Column (name=”idDepartamento”)
   @BMViewField(size=5, maxLength=5)
   private Integer idDepartamento;
   @NotNull
   @BMViewField(size=50, maxLength=50)
   @BMDataPropertyUniqueKey
   @BMDataListBy
   private String nmDepartamento;
   @ManyToOne
   @JoinColumn(name="idDepartamento")
   BMViewSearchCriteria
   private Diretoria diretoria;
   // constructors
   // getters and setters
   // methods like “toString”
}


Pequenos insights da geração de código


1) A inclusão da propriedade “OneToMany” em “Diretoria”, obriga a criação de um método (funcionalidade) no código que implementa o acesso a dados em “Departamento” para fornecer a quantidade de departamentos de uma diretoria.
2) A inclusão da propriedade “ManyToOne” em Departamento, obriga a criação de um método (funcionalidade) no código que implementa o acesso a dados em “Departamento” para fornecer uma lista de departamentos de uma diretoria.
3) A anotação “BMViewSearchCriteria” possui elementos que permitem definir a ordem do componente na tela e em quais componentes a sua mudança deve refletir (AJAX – atualização parcial da tela). No presente caso, essas informações são desnecessárias.

A conceituação acabou. O que vem pela frente?

Nas próximas postagens tenciono apresentar as telas, e principalmente, franquear o uso para um pequeno grupo inicial de pessoas interessadas em "embarcar nesse projeto".

Alguns poderão perguntar, se ao invés do esquema de navegação proposto usando "botões" e "links" não poderia ser usado os componentes de "painel com abas", ou "sanfona" ou ainda "arvore hierárquica". A resposta é: sim. Mas como estou tentando provar um conceito, estou sempre partindo para a solução mais fácil (pelo menos para mim).

Evidentemente essa questão poderá ser resolvida por uma anotação (quem sabe BMVIEWStrategy?).