Dentro dos módulos entraremos pacotes que denotam uma das camadas do MVC. A seguir apresentamos os padrões de projetoexistentes nos pacotes que podem ser encontrados dentro dos módulos de uma aplicação futurepages.
CONTROLE;
As actions denotam um caso de uso disparado por um usuário (ator);
Recebem os entradas (inputs) da visão, chamam os validadores de entradas caso necessário e disparam serviços que denotam o caso de uso, retornando no final os resultados para a saída;
As actions lançam ErrorException para o usuário.
-
São AjaxActions que retornam AjaxConsequences.
Exemplos: CarregaServentias, CarregaAlunos, AutoCompletaAlunos.
Pacote actions/core;
São reusabilidades inerentes ao CONTROLE;
Lançam ErrorException ao usuário.
Código reutilizado somente entre Actions;
Geralmente utilizado para manipulação de session, application, request;
É comum que seja passado como parâmetro a action (Action);
Terminação “AC” após o nome da entidade ou o módulo de referência.
Aqui encontramos as actions dinâmicas (que herdam DynAction). Estas possuem em seu nome o prefixo “Dyn”. Ex.: DynAtualizaAluno, DynLogin, DynLogout, etc.
MODELO;
Classes anotadas com @Entity() e @Table(“moduleName_beanName”);
Refletem as Entidades (Tabelas ou Views) do Banco de Dados;
Possuem métodos que aplicam-se aos atributos do objeto em memória.
Neste pacote encontram-se as classes mapeadas com as seguintes anotações:
@MappedSuperclass - classes que possuem seus campos persistidos em suas subclasses anotadas com @Entity (vide documentação do Hibernate).
@Embeddable - classe que possuem seus campos persistidos nas classes @Entity que a possuem como atributo.
MODELO;
Interface da aplicação com o banco de dados;
Possuem métodos simples que não devem ultrapassar 15 linhas;
Consultas simples ao banco para abstração de Strings
HQL/SQL;
ATENÇÃO: Devemos encontrar fragmentos de strings HQL/
SQL somente nos DAOs;
Nunca deve existir métodos transacionais dentro de um Dao;
Métodos Dao não devem lançar Exceptions.
VISÃO;
Classes que herdam de ErrorException;
São as Exceptions tratadas na visão;
Exceptions que exibem a mensagem ao usuário.
Pode-se considerar como as Exceptions “Esperadas”.
Quando anotadas com @NotListDependencies, ao retornar para tela de erro, não listam as dependênciass
MODELO;
São classes que implementam Job
São atividades que são executadas de tempos em tempos (definido na anotação em sua classe)
Veja a seguir um exemplo de um Job que envia emails pendentes nos segundos 0 e 30 de qualquer minuto, qualquer hora, qualquer dia, mês e ano.
package modules.carteiro.jobs;
import modules.carteiro.services.EmailMensagemServices;
import org.futurepages.core.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@CronTrigger(expression = "0/30 * * ? * *")
public class EnviaEmailsPendentes implements Job {
@Override
public void execute(JobExecutionContext jec) throws JobExecutionException {
EmailMensagemServices.enviaPendentes();
}
}
CONTROLE;
Classes que ficam escutando quando uma sessão de usuário (sessão http) é criada ou destruída.
Implementa a interface SessionEventListener (dois métodos: onCreate e onDestroy).
Vejamos o exemplo a seguir de um listener que nada faz na criação da sessão e atualiza dados do membro logado na sessão assim que ela é destruída.
package modules.portal.listeners;
import java.util.Date;
import javax.servlet.http.HttpSession;
import modules.portal.beans.MembroPortal;
import modules.portal.core.MembrosLogadosManager;
import org.futurepages.core.persistence.Dao;
import org.futurepages.core.session.SessionEventListener;
import org.futurepages.util.DateUtil;
public class MembrosLogadosListener implements SessionEventListener {
public void onCreate(HttpSession session) {
//Realiza ação na 'session' assim que é criada.
}
public void onDestroy(HttpSession session) {
MembroPortal membroLogado = MembrosLogadosManager.getInstance().getBySession(session);
if(membroLogado!=null){
Dao.updateTransaction(membroLogado.getUltimoAcesso());
MembrosLogadosManager.getInstance().remove(membroLogado);
}
}
}
MODELO;
Acumulam regras de negócio que envolvem unicamente o modelo da aplicação;
Utilizam-se do Dao para acessar o banco;
Realizam atividades relativas aos Beans, envolvendo ou não banco de dados;
Pode existir (ou não) transações dentro de Services;
Os Services quando lançam Exceptions, as mesmas não devem herdar nem ErrorException e nem RunTimeException.
CONTROLE;
Os validadores são validadores de entradas de fórmulários que lançam ErrorException caso não satisfaça a validação;
Em seus métodos devem existir somente validação de entradas de dados do usuário;
Se para um dado bean Aluno, possuímos uma Action AlunoActions, o validador para esta action seria assim (note o método de validação da innerAction “create”):
package modules.escola.validators;
import modules.escola.beans.Aluno;
import org.futurepages.core.persistence.Dao;
import org.futurepages.core.validation.Validator;
import org.futurepages.util.Is;
public class AlunoValidator extends Validator {
public void create(Aluno aluno) {
// Validação do nome
if (Is.empty(aluno.getNomeCompleto())) {
error("Preencha o nome do aluno.");
}
// Validação da matrícula
if (Is.empty(aluno.getMatricula())) { //verifica se matrícula vazia
error("Especifique a matrícula do aluno.");
} else {
// Caso matrícula não seja vazia, verifica se a matrícula já existe
if (Dao.uniqueResult(Aluno.class, "matricula='" + aluno.getMatricula() + "'") != null) {
error("Já existe um aluno com esta matrícula.");
}
}
}
}