Criando um Plugin
Definições do Plugin
Como qualquer aplicação de computador, a primeira coisa a definir é a sua função. Levantar os requisitos do plugin. Depois do objetivo e dos requisitos definidos, é hora de começar a implementar o plugin. Para implementa-lo a melhor ideia é seguir o passo a passo abaixo:
Pacote Raiz
Para começar a organizar o código criado é importante ter os packages bem definidos e estruturados desde o começo para evitar diversos refactores.futuros. É padrão da linguagem Java utilizar o nome dos pacotes similar aos domínios da web. Por exemplo, o BISCore utiliza como pacote raiz "br.com.biserp.bis.core" e depois separa suas classes em sub-pacotes de acordo com a necessidade.
Esse pacote raiz também será utilizado em outras partes do sistema, como por exemplo, para definir o ID do plugin, variáveis de sistema, etc. É recomendado que este pacote raiz não seja igual ao de nenhum outro plugin ou aplicação, por isso uma boa estrutura sugerida é o domínio da empresa (Ex: "br.com.biserp") + nome da aplicação e plugin (Ex: "bis.core").
Prefixos
A definição de um prefixo é utilizada em diversos lugares em que os recursos dos vários plugins acabam se misturando. O prefixo não deve ser tão curto a ponto de não evitar duplicatas com outros plugins e nem tão longo que dificulte a programação e leitura dos objetos. Recomendamos um mínimo de 10 caracteres, ficando liberado apenas para plugins do próprio BIS a utilização de prefixos menores, por conhecer o prefixo de todos os outros plugins.
Lembre ao definir o prefixo que ele deve ser único, por isso escolha palavras ou abreviações/siglas que não sejam comuns de alguém escolher. Quando possível, é recomendado que se utiliza o próprio ID do plugin ou o pacote raiz da aplicação como prefixo de distinção entre os plugins.
Alguns exemplos são:
- tabelas do banco de dados: as tabelas dos plugins são colocadas todas juntos no mesmo banco de dados, usar um prefixo é conveniente para evitar nomes duplicados, principalmente em tabelas comuns como "contacts", "users", "items", "addresses", etc., e também para agilizar a identificação do plugin dono da tabela; O BISCore, por exemplo, tem todas as suas tabelas com o prefixo "core_".
- nomes das fachadas das camadas de negócio: as fachadas de todos os plugins estarão disponíveis no mesmo ambiente, por isso é importante que sejam todas distintas ou o servidor de aplicação não disponibilizará uma das fachadas para ser encontrada por lookup;
- mensagens de I18N: Cada plugin registrará seu bundle com base em um prefixo no BISCore. Sempre que alguma mensagens precisar ser resolvida, o BISCore analisa o prefixo da mensagem, e de acordo com esse prefixo ele chamará o Bundle registrado. Por isso, além de ser importante que seja único o prefixo, é importante que todas as mensagens do bundle tenham o prefixo definido; o plugin de Itens utiliza "ModItem_";
- chaves de segurança: o plugin pode ter várias chaves de segurança definidas, o que permite ou não que o usuário faça alguma tarefa, acesse alguma informação, etc.. O BISCore trata todas as chaves de segurança junto, se as chaves forem duplicadas, o acesso dado em um plugin acabará garantindo acesso no outro. Para este uso é recomendado que os plugins utilizando o pacote raiz como prefixo de distinção.
Classes de Implementação
Para implementar um novo módulo devemos começar implementando a classe de integração do Módulo com o BISCore Framework. Feita a integração cada módulo basta que cada módulo implemente suas próprias funcionalidades, usando a base do BISCore para facilitar o desenvolvimento.
Para criar um novo módulo para o BISCore, a "única" coisa que precisa ser feita é criar um Singleton, que será inicializado pelo servidor de aplicações. Essa inicialização tem apenas o propósito de notificar o BISCore que carregue o módulo. Não é recomendado realizar nenhuma outra ação neste bloco além da solicitação de carregamento do PlugIn. As inicializações dos plugins deverão ser realizadas mais tarde, quando o BISCore carregar o plugin e chamar o método initPlugin().
![]() |
Esqueleto de um CorePlugin
/*
* Classe que implementa um novo CorePlugin
*/
@Singleton
@Startup
public class <ModulePrefix>CorePlugin extends CorePluginAdapter {
@PostConstruct
private void startup() {
try {
<ModulePrefix>CorePlugin plugin = new <ModulePrefix>CorePlugin();
getBISFacade().queuePluginToLoadList(plugin);
} catch (BISException e) {
BISLogger.logException(e);
}
}
...
}
|
O método startup será chamado assim que o servidor de aplicações tiver terminado o deploy. Neste método chamamos a fachada do BIS e colocamos nosso plugin na fila para ser carregado. Há ainda outros métodos que o Adapter força a implementação, assim como outros que têm uma implementação padrão e podem ser sobrescritos para adapta-los à necessidade do plugin. Para maiores detalhes consulte o JavaDoc de cada método.
Alguns dos métodos de implementação obrigatória são:
- getId(): Este método deve retornar o ID do Plugin, que deve ser único em todo o sistema. Recomenda-se usar o pacote raiz do plugin como prefixo no ID para garantir sua unicidade no sistema.
- getRequiredLicense(): Este método retorna o ID da licença que o módulo precisa para funcionar adequadamente. Pode ser usada a mesma chave do ID do módulo.
- getVersion(): Retorna a versão atual do Plugin.
- getDependencies(): Retorna um array com a definição dos módulos necessários para que este módulo funcione.
![]() |
|
O método initPlugin()
Este método é chamado pelo Core depois que o módulo foi iniciado com sucesso, depois de ter suas dependências carregados, licença validada, banco atualizado, etc. Neste método o plugin deve realizar as tarefas que precisa para funcionar. Com exceção de atualização do banco de dados que é feita antes do plugin ser carregado, depois validações e setups devem ser feitas neste método. Entre as funções que o Plugin deve realizar nesta etapa estão:
- Registrar seus Bundles: Para que a aplicação funcione adequadamente, o Plugin deve registrar seus Bundles no BundleManager da aplicação. Desta forma, toda a aplicação saberá internacionalizar suas mensagens, como erros, mensagens, etc. Mesmo quando usadas por outros módulos. Leia em: Bundle i18n.)
- Registro de Eventos: Registrar o plugin para escutar eventos de outros módulos, como o recebimento de um e-mail pelo BISCore, a manipulação de um objeto de outro módulo, etc.
- Outros Setups: Ao inicializar, o plugin pode fazer checagens e definições no sistema para garantir que não vá falhar durante o uso. Por exemplo, verificar se determinadas tarefas agendadas continuam agendada e funcionando, redefinir variáveis que se deseja reiniciar toda vez que a aplicação sofrer um deploy, etc.