Customização do Fusion Platform
Introdução
O Fusion Platform foi projetado com a escalabilidade em mente. Como conseqüência disso, cada contexto do Fusion está preparado para receber novas funções, o que significa que tudo que não está incluso no produto padrão pode ser desenvolvido e personalizado usando Adapters Java. Para que estes adapters sejam gerados, será necessário possuir um ambiente de desenvolvimento Fusion disponível. O ambiente utilizado pela Neomind é o Eclipse IDE. Ter um conhecimento em linguagem de programação Java também é essencial, em particular no contexto do desenvolvimento de aplicações WEB.
Entendendo os Principais Objetos do Fusion
NeoObject
- NeoObject é o mais genérico dos objetos do Fusion - todos os outros objetos estendem a ele.
- Para obter a identificação de um objeto, use o método getNeoId().
- As questões de segurança do Fusion também estão ligadas a este objeto.
- Vários métodos de validação de segurança são invocados a partir do NeoObject.
InstatiableEntityInfo
As entidades são classes que mapeiam e representam uma tabela no banco de dados.
Para obter a instância de uma entidade, um tipo de objeto InstantiableEntityInfo deve ser criado para representá-la. Para criar a instância de uma entidade, é utilizado o método createNewEntityInstance (String entityName) da classe AdapterUtils.
O parâmetro do método é um objeto do tipo String que servirá como o nome da entidade (forma ou tabela) criada dentro do Fusion. Os formulários podem ser dinâmicos ou externos. Posteriormente, este objeto é passado como um argumento dos métodos getObject() e getObjects() da classe PersitEngine, que realizam a busca na tabela (formulário).
O código abaixo ilustra o uso da entidade para mapear a tabela (Formulário) "Produto". O formulário "Produto" pode ser tanto um formulário dinâmico criado no banco de dados Fusion ou uma tabela externa pertencente a um sistema legado.
Se "Produto" for um formulário externo, a Fonte de Dados deve ser criada primeiro no Fusion e depois, o formulário externo. O nome do formulário será o argumento a ser passado ao método createNewEntityInstance;
// NeoObject é inicializado com uma instância da entidade Produto
NeoObject productFusion = AdapterUtils.createNewEntityInstance("Produto");
EntityWrapper
Wrappers são classes responsáveis por encapsular as Entidades, abstraindo sua interface e simplificando a leitura e escrita de dados no banco de dados. Em Fusion, EntityWrapper é a classe que encapsula a entidade.
A tabela abaixo ilustra os métodos EntityWrapper mais comumente utilizados:
| Método | Descrição |
|---|---|
| findField | Retorna um Wrapper para ter seu campo manipulado (se o campo existir; se não existir, o retorno é nulo). |
| fiendValue | Devolve um objeto com o valor do campo. |
| findValues | Devolve uma coleção de objetos. |
| findeGenericValue | Devolve um objeto genérico com o valor do campo. |
No código abaixo primeiro criamos uma instância da entidade “Produto” e atribuímos ela a um NeoObject que representará a tabela no banco. Em seguida, embrulhamos ela com um wrapper instanciando a classe EntityWrapper, passamos para o construtor desta o argumento NeoObject contendo a entidade e encapsulamos assim sua complexidade. Neste momento, todas as operações de leitura e escrita no banco serão realizados através do objeto wrapper.
Este método simplifica as operações de banco escondendo os detalhes de relacionamentos entre tabelas que serão controlados pelo Hibernate.
// O NeoObject é inicializado com uma instância da entidade Produto.
NeoObject productFusion = AdapterUtils.createNewEntityInstance("Produto");
EntityWrapper wrapperProductFusion = new EntityWrapper(productFusion);
A classe PersistEngine, presente no núcleo do Fusion, centraliza toda a comunicação com o banco de dados. É aí que são implementados os principais métodos de aquisição e atribuição de valores existentes no banco de dados.
A tabela abaixo ilustra alguns dos métodos mais utilizados de PersistEngine:
| Método | Descrição |
|---|---|
| getConnection | Retorna um objeto de conexão para o banco de dados. Recebe uma String tendo como parâmetro o nome da fonte de dados. |
| persit | Ele persiste os dados no banco de dados, recebe como parâmetro um objeto referente a uma entidade. |
| getObject | Retorna a instância de um objeto. Toma como parâmetro um objeto que faz referência à entidade. |
| getObjects | Retorna uma lista ou coleção de instâncias de objetos. Além do objeto que representa uma entidade, os métodos também podem ter filtros como parâmetro. Desta forma, o resultado do retorno será uma instância específica ou um subgrupo de instâncias, de acordo com os critérios estabelecidos pelos filtros. |
// Instantiate object in Fusion and set values
NeoObject productFusion = AdapterUtils.creacteNewEntityInstance("Product");
// Creates wrapper to abstract the entity that represents "productFusion"
EntityWrapper wrapperProductFusion = new EntityWrapper(productFusion);
// Assign values to local variables
String productNumber = "AFR - 233";
String description = "Montain Bike";
// Use the wrapper to assign values to fiels
wrapperProductFusion.findField("code").setValue(productNumber);
wrapperProductFusion.findField("description").setValue(description);
// Persisting data in the database
PersistEngine.persist(ProductFusion)
Dados Persistentes em um Formulário
No exemplo abaixo, foi criado um formulário dinâmico chamado "Produto" contendo dois campos cujos nomes são "código" e "descrição". Em seguida, uma entrada foi adicionada ao formulário através do uso de uma embalagem e finalmente, a entrada foi persistida através do uso do médoto persistente da classe PersistEngine.
Normalmente, os passos necessários para ler/escrever nos formulários são: Criar uma entidade para representar o formulário (tabela):
// Instantiate object in Fusion and set values
NeoObject productFusion = AdapterUtils.createNewEntityInstance("Product");
- Criar um wrapper para encapsular a entidade
// Creates wrapper to abstract the entity that represents "Product"
EntityWrapper wrapperProductFusion = new EntityWrapper(productFusion);
Use o wrapper para escrever/ler/modificar os dados no banco de dados.
Usar o mecanismo de hibernate de persistência para persistir/remover dados.
// Persisting data in the database
PersistEngine.persist(productFusion);
Recuperando Dados de um Formulário
O código abaixo exemplifica a recuperação dos registros em um formulário. Através do método getObjects, os registros encontradas no formulário "Produto" são carregadas em uma lista de objetos NeoObject.
Então, é utilizado um looping "for" para escanear a lista com um iterador, que passa por cada registro até chegar ao final da lista.
Observe que um wrapper é usado para realizar a operação na entidade (tabela), o método findField retorna o campo do objeto e o método getValue traz o valor do campo. No final, uma classe System é usada para exibir os valores no console em cada interação da lista.
// Assign values to local variables
String productNumber = "AFR - 223";
Sting description = "Montain Bike";
// Use the wrapper to assign values to fields
wrapperProductFusion.findField("code").setValue(productNumber);
wrapperProductFusion.findField("description").setValue(description);
List<NeoObject> listaProduto = (List<NeoObject>)
PersistEngine.getObjects(AdapterUtils.getEntityClass("Produts"));
for(NeoObject : listaProduto)
{
// External E-form data
EntityWrapper wrapperProducts = new EntityWrapper(product);
String code = (String) wrapperProducts.findField("code").getValue();
String description = (String)
wrapperProducts.findField("description").getValue();
// Show field values
System.out.printIn(code+"\n");
System.out.printIn(description);
// Romeve object
PersistEngine.remove(ProductFusion)
}
NeoUser
A classe NeoUser representa a abstração de um usuário do sistema. É utilizada quando uma ação específica a um usuário ou grupo de usuários deve ser executada.
Através dela, uma referência ao usuário atual do sistema é obtida, retornando um objeto, que pode ser utilizado em diversas ocasiões, como na verificação do papel do usuário, por exemplo.
Para obter as informações relativas a um usuário atualmente logado no sistema, utilize o código representado abaixo:
// The "user" variable receives the object that represents the user
NeoUser user = PortalUtil.getCurrentUser();
Para verificar o papel em que o usuário está inserido, é necessário criar o objeto que mantém a referência do usuário, conforme o código acima.
O exemplo abaixo demonstra como verificar se o usuário está ativo ou não.
boolean ativo = user.isActive();
A partir do comando acima, retorna se o usuário é ativo ou não (true ou false).
Bloco Try Catch
Para manter um melhor controle de execução do código e também otimizar o tratamento de erros, é importante que o código dos adapters sejam inseridos entre uma ou mais blocos Try Catch.
A função desde bloco é isolar e tratar qualquer erro que possa ocorrer no código, evitando que esses erros interrompam a execução de outra parte do código.
O exemplo abaixo demonstra um código simples de adapter. Primeiramente, um campo é lido no workflow e se o valor dele foi diferente de "Processo Judicial", o valor é alterado. Todo o código está envolvido no Bloco Try Catch. Caso ocorra um erro, uma mensagem será apresentada.
public void start(Task origin, EntityWrapper wrapper, Activity activity)
{
try // Try block start
{
String typeProcess = wrapper.findValue("TypeProcess");
if (!typeProcess.equals("Judicial Process"))
{
wrapper.findField("TypeProcess").setValue("Judicial Process");
}
}catch (Exception e) // Try block end
{
// Message displayed when the error occurs
System.out.printIn("Error when executing the adapter code!")
}
}
Geração de Logs
A geração de logs é muito importante para a manutenção do sistema. Quando ocorre um evento inesperado, é necessário que sejam geradas informações referentes a esse evento. Isso é feito através da classe LogFactory, que fornece os métodos necessários para gerar o log do evento.
// Criação do objeto log, utilizando o nome da classe atual
private static final Log log = LogFactory.getLog(ClassName.class);
public void start(Task origin, EntityWrapper wrapper, Activity activity)
{
try
{
String version = wrapper.findField("Version").getValue();
}catch (Expection e)
{
log.error("Error Reading the Version field in the E-form!",e);
}
}
Copiar Conteúdo de Campo Texto Área
Dados vindo do summer notes vem com tags HTML e caso não seja feito o tratamento, serão salvo com elas.
Para retirar as tags HTML de variáveis do tipo String utilizar o método removeTagsFromText(String value) da classe NeoUtils.
Neste caso, serão removidas todas as tags associadas ao texto inserido, inclusive as que foram digitadas pelo usuário.
Ex.:
public class novaClasse implements AdapterInterface
{
@Override
public void start(Task task, EntityWrapper wrapper, Activity activity)
{
NeoObject newInstance = AdapterUtils.createNewEntityInstance("EntityName");
EntityWrapper entityWrapper = new EntityWrapper(newInstance);
String data = wrapper.findGenericValue("IdField");
data = NeoUtils.removeTagsFromText(data);
entityWrapper.findField("IdField").setValue(data);
}
}
Para retirar as tags HTML do summer notes, mas manter as tags digitadas pelo usuário, é necessário utilizar um regex junto com o método replaceAll e em seguida utilizar o método decodeHTMLValue(String value) da classe NeoUtils.
Ex.:
public class novaClasse implements AdapterInterface
{
@Override
public void start(Task task, EntityWrapper wrapper, Activity activity)
{
NeoObject newInstance = AdapterUtils.createNewEntityInstance("EntityName");
EntityWrapper entityWrapper = new EntityWrapper(newInstance);
String data = wrapper.findGenericValue("IdField");
data = data.replaceAll("\\<.*?>", "");
data = NeoUtils.decodeHTMLValue(data);
entityWrapper.findField("IdField").setValue(data);
}
}