====== Padrões Futurepages2 ======= 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. ===== actions ===== * **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. * Na raiz deste pacote encontraremos actions, que herdam actions do futurepages, como: [[actions|FreeActions, LoginAction, ProtectedAction, CrudActions]] ==== actions/ajax ==== * São **AjaxAction**s que retornam AjaxConsequences. * Exemplos: **CarregaServentias, CarregaAlunos, AutoCompletaAlunos**. ==== actions/core ==== * 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. * Exemplos: **EscolaAC, AdminAC, AlunoAC**. ==== actions/dyn ==== Aqui encontramos as actions dinâmicas (que herdam **DynAction**). Estas possuem em seu nome o prefixo "**Dyn**". Ex.: DynAtualizaAluno, DynLogin, DynLogout, etc. ==== actions/global ==== * Actions mapeadas em ModuleManager com globalAction(Action.class) * Requisitadas ao Servlet **PrettyGlobalURLController** mapeado em web.xml ===== beans ====== * **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. ==== beans/core ==== 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. ===== core ===== * **MODELO**; * Interfaces, Classes Abstratas, etc pertencentes à cerne da regra de negócio. ===== dao ===== * **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. ===== enums ===== * **MODELO**; * São enumerações referentes ao modelo do módulo. ===== errors ===== * **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 ===== exceptions ===== * **MODELO**; * Exceções do Modelo; * Não devem ser RuntimeException. ===== filters ===== * **CONTROLE**; * Pacote de filtros para controle do módulo. ===== formatters ===== * **VISÃO**; * Formatam outputs (saídas) para a visão. ===== install ===== * **MODELO**; * Instalação de dados iniciais no banco de dados. ===== jobs ===== * **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(); } } * Para que o futurepages execute o job no tempo determinado é necessário ligar o modo quartz. **QUARTZ_MODE = ON** em app-params.xml. ===== listeners ===== * **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); } } } ===== services ===== * **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**. ===== tags ===== * **VISÃO**; * Podem ser condicionais (**ConditionalTag**) * exemplo: ** ... ** * Podem ser imprimíveis (**PrintTag**) * exemplo: **** * Podem ser lista (**ListTag**) * exemplo: ** ... ** ===== validators ===== * **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."); } } } }