Boa noite a todos.
Irei tratar neste post do processo de acesso aos serviços RMI do servidor. Para realizar este procedimento usamos o Spring Framework, realizando sua configuração no contexto.
1. Módulo Utils
Inicialmente é realizado o desenvolvimento do módulo wpattern-northwind-application-utils. Neste módulos adicionamos os arquivos do log4j "log4j.xml" e "log4j.dtd".
Na parte de codificação existem apenas duas interfaces. A interface IApplicationServices torna os serviços mais claros para todo o sistema e tem o objetivo de tentar diminuir o acoplamento do sistema com a interfaces de serviço IServices do servidor.
package br.com.wpattern.northwind.application.utils.interfaces;
import br.com.wpattern.northwind.utils.service.interfaces.IServices;
public interface IApplicationServices extends IServices {
}
Finalmente temos a interface IApplication, que é responsável por iniciar a execução do cliente.
package br.com.wpattern.northwind.application.utils.interfaces;
public interface IApplication {
public void start();
}
2. Módulo de Conexão com o Servidor
O trabalho de conexão com o servidor é bem simples. Inicialmente temos a classe ApplicationServices que é responsável por abstrair os serviços do servidor para o sistema.
package br.com.wpattern.northwind.application.service.client;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import br.com.wpattern.northwind.application.utils.interfaces.IApplicationServices;
import br.com.wpattern.northwind.utils.database.beans.CategoriesAndSuppliersBean;
import br.com.wpattern.northwind.utils.database.beans.CategoryBean;
import br.com.wpattern.northwind.utils.service.interfaces.IServices;
@Named
public class ApplicationServices implements IApplicationServices {
@Inject
private IServices services;
@Override
public Long insertCategory(CategoryBean category) {
return this.services.insertCategory(category);
}
@Override
public void updateCategory(CategoryBean category) {
this.services.updateCategory(category);
}
@Override
public void deleteCategory(CategoryBean category) {
this.services.deleteCategory(category);
}
@Override
public List<CategoryBean> findAllCategories() {
return this.services.findAllCategories();
}
@Override
public CategoriesAndSuppliersBean findCategoriesAndSuppliersByProductName(String productName) {
return this.services.findCategoriesAndSuppliersByProductName(productName);
}
}
Para estabelecer o trabalho de comunicação é realizada a configuração do arquivo ctx-wpattern-northwind-applicaton-service-client.xml com os parâmetros de conexão e instanciação. É importante lembrar que nestas configurações parte dos valores são colocados no arquivo de configuração northwind-application-conf.properties, que é adicionado no módulo wpattern-northwind-application-factory.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- Define o pacote inicial que é considerado por este contexto. -->
<context:component-scan base-package="br.com.wpattern.northwind.application.service.client" />
<!-- Define o arquivo que é usado para buscar as informações de configuração. -->
<bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="location" value="file:./conf/northwind-application-conf.properties" />
</bean>
<bean id="services" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://${remote.service.rmi.hostname}:${remote.service.rmi.port}/remote-service" />
<property name="serviceInterface" value="br.com.wpattern.northwind.utils.service.interfaces.IServices" />
<property name="lookupStubOnStartup" value="false" />
<property name="refreshStubOnConnectFailure" value="true" />
</bean>
</beans>
Também é criado um JUnit que testa apenas o serviço remoto. Sua implementação é bem simples e se encontra no SVN do projeto.
3. Conclusão
O desenvolvimento da comunicação com o servidor é muito simples, já que o Spring Framework simplifica muito o nosso trabalho. A seguir é mostrado o vídeo deste desenvolvimento.
Até o próximo post.
Boa noite pessoal.
Hoje começamos a tratar do exemplo de um cliente que consome os serviços disponibilizadas pelo servidor. Será estabelecida uma conexão RMI com o servidor e serviços de CRUD serão invocados.
1. Interface Gráfica

Usamos o plugin Window Builder para a construção de uma interface gráfica bem simples. Temos um JTable com os dados de Categoria, os campos com dados selecionados e os botões com os eventos de CRUD.
2. Estrutura do Projeto

A estrutura do projeto segue a mesma forma do servidor.
Também é usado o Maven para o gerenciamento das dependências e o Spring na injeção de dependência.
São criados os módulos:
wpattern-northwind-application: Parte visual da aplicação baseado na API Swing.
wpattern-northwind-application-all: Agrupa todos os módulos.
wpattern-northwind-application-factory: Responsável por realizar a integração entre os módulos.
wpattern-northwind-application-service-client: Estabelece a comunicação RMI com o servidor.
wpattern-northwind-application-utils: Classes, interfaces e enumerations, de transporte de dados e integração dos módulos.
Um fato importante é que neste cliente existe a dependência do módulo Utils do servidor. Isso é necessário pois a interface de serviço do servidor está neste módulo.
3. Considerações Finais
O desenvolvimento desta estrutura segue os mesmos passos que foram demonstrados no servidor. No vídeo abaixo são mostrados passo a passo todo este processo.
Até mais, abraços.
Bom dia pessoal.
Neste último post vou apresentar um exemplo de como vocês podem importar o projeto no eclipse. Para isso, usamos o Tortoise SVN para baixar nosso projeto e em seguida importamos ele no eclipse. Além disso, é possível baixar o projeto do seguinte local: Projeto Northwind.
No vídeo abaixo é mostrado todo este processo.
Abraço e até mais.
Boa noite.
Neste post vou apresentar um resumo do projeto. Irei falar sobre os conceitos que foram trabalhados até agora e os diagramas do sistema.
1. Diagramas
1.1. Diagrama de Pacotes do Servidor

No Diagrama de Pacotes do Servidor são mostradas as dependências entre os pacotes e o que são cada um dos módulos.
1.2. Diagrama de Pacotes do Database

No diagrama de pacotes do database são apresentados os pacotes do módulo wpattern-northwind-database. Temos neste módulo as entidades, DAOs, Serviços e Classes Utilitárias.
1.3. Diagrama de Classes das Entidades

As entidades estão no módulo wpattern-northwind-database e no diagrama podemos observar que são simples. As entidades possuem chaves simples ou compostas, e todas herdam a classe BaseEntity.
1.4. Diagrama de Classes dos DAOs

No diagrama de classes dos DAOs observamos que um DAO é composto pela herança do abstract GenericDao. Além disso, cada DAO possui uma interface e os métodos específicos de acesso a dados são implementadas nos DAOs de cada entidade. Ou seja, o que é geral é implementado no GenericDao e os métodos específicos são colocados nas classes concretas de cada DAO.
1.5. Diagrama de Classes dos Serviços

Os serviços trabalham sobre interfaces especificas e todos eles herdam os abstract GenericService e GenericServiceWithKey com os métodos gerais. Os métodos específicos são implementados nos Serviços concretos e não nos abstracts.
1.6. Diagrama de Classes dos Serviços do Database

O diagrama de classes mostra a relação entre as interfaces dos serviços do database. Temos apenas uma classe de factory dos serviços.
1.7. Diagrama de Pacotes do Módulo Utils

O diagrama de pacotes do módulo utils mostra as classes "puras" que temos no wpattern-northwind-utils. São apenas alguns beans e interfaces.
1.8. Diagrama de Classes dos Serviços (Remotos)

O diagrama de classes dos serviços remotos trabalham com os serviços do database. Não existem muitos detalhes neste diagrama, sendo necessário apenas lembrar que a responsabilidade de disponibilizar os serviços está a cargo do Spring Framework.
1.9. Diagrama de Pacotes do Módulo Factory

O diagrama de pacotes do módulo Factory tem duas partes principais. Um para os testes e outra que é usada para a execução a partir do JAR que executamos externamente ao eclipse.
2. Vídeo
Mais detalhes são apresentados no vídeo disponível abaixo.
Até o próximo post.

Boa noite pessoal.
Neste post demonstro a criação de um serviço usando HQL (Hibernate Query Language).
Este serviço busca todos os Supplier(s) e Category(s) baseado no nome de produtos que estão relacionados com essas entidades. Caso o nome do produto contenha uma determinada cadeia de caracteres são recuperadas todos os Supplier(s) e Category(s).
De acordo com o DER do banco de dados Northwind é possível observar que para um category ou supplier podemos ter vários product(s). Sendo assim, o resultado do nosso HQL não pode retornar as entidades category e supplier repetidas/duplicadas.
Este serviço é implementado remotamente, na camada de serviço e nos DAOs do módulo wpattern-northwind-database. A implementação é mostrada abaixo.
package br.com.wpattern.northwind.database.services;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import br.com.wpattern.northwind.database.entities.ProductEntity;
import br.com.wpattern.northwind.database.interfaces.IProductDao;
import br.com.wpattern.northwind.database.utils.GenericService;
import br.com.wpattern.northwind.database.utils.interfaces.IGenericDao;
import br.com.wpattern.northwind.utils.database.beans.CategoriesAndSuppliersBean;
import br.com.wpattern.northwind.utils.database.beans.CategoryBean;
import br.com.wpattern.northwind.utils.database.beans.ProductBean;
import br.com.wpattern.northwind.utils.database.beans.SupplierBean;
import br.com.wpattern.northwind.utils.database.interfaces.ICategoryService;
import br.com.wpattern.northwind.utils.database.interfaces.IProductService;
import br.com.wpattern.northwind.utils.database.interfaces.ISupplierService;
@Named
public class ProductService extends GenericService<ProductBean, ProductEntity, Long> implements IProductService {
@Inject
private ICategoryService categoryService;
@Inject
private IProductDao productDao;
@Inject
private ISupplierService supplierService;
@Override
protected IGenericDao<ProductEntity, Long> getConcreteDao() {
return this.productDao;
}
@Override
public CategoriesAndSuppliersBean findCategoriesAndSuppliersByProductName(String productName) {
List<CategoryBean> categories = this.categoryService.findCategoriesByProductName(productName);
List<SupplierBean> suppliers = this.supplierService.findSuppliersByProductName(productName);
CategoriesAndSuppliersBean suppliersAndCategoriesBean = new CategoriesAndSuppliersBean(categories, suppliers);
return suppliersAndCategoriesBean;
}
}
package br.com.wpattern.northwind.database.services;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import br.com.wpattern.northwind.database.entities.CategoryEntity;
import br.com.wpattern.northwind.database.interfaces.ICategoryDao;
import br.com.wpattern.northwind.database.utils.GenericService;
import br.com.wpattern.northwind.database.utils.interfaces.IGenericDao;
import br.com.wpattern.northwind.utils.database.beans.CategoryBean;
import br.com.wpattern.northwind.utils.database.interfaces.ICategoryService;
@Named
public class CategoryService extends GenericService<CategoryBean, CategoryEntity, Long> implements ICategoryService {
@Inject
private ICategoryDao categoryDao;
@Override
protected IGenericDao<CategoryEntity, Long> getConcreteDao() {
return this.categoryDao;
}
@Override
public List<CategoryBean> findCategoriesByProductName(String productName) {
List<CategoryEntity> categoriesEntity = this.categoryDao.findCategoriesByProductName(productName);
return parserEntity(categoriesEntity);
}
}
O serviço do DAO que implementa o HQL é mostrado a seguir.
package br.com.wpattern.northwind.database.daos;
import java.util.List;
import javax.inject.Named;
import br.com.wpattern.northwind.database.entities.CategoryEntity;
import br.com.wpattern.northwind.database.interfaces.ICategoryDao;
import br.com.wpattern.northwind.database.utils.GenericDao;
@Named
public class CategoryDao extends GenericDao<CategoryEntity, Long> implements ICategoryDao {
@Override
public List<CategoryEntity> findCategoriesByProductName(String productName) {
return executeQuery("SELECT c FROM CategoryEntity c WHERE (SELECT count(*) FROM ProductEntity p WHERE (p.productName LIKE '%" + productName + "%') AND (p.categoryId = c.categoryId)) > 0");
}
}
O vídeo mostra o desenvolvimento e teste deste serviço.
Até mais a todos.