Filtros são o que permite que o Mentawai implemente a maioria de suas funcionalidades. Você pode configurá-los no application manager por action ou globalmente para todas as action (filtro global). O framework vem de fábrica com vários filtros mas como você verá abaixo é muito fácil criar os seus próprios filtros.
Configurando no application manager:
// o filtro será aplicado apenas para a action especificada: @Override public void loadActions() { action("/Hello", HelloAction.class, "sayHi") .filter(new SomeFilter()) .on(SUCCESS, redir("/index.jsp")); } // um filtro global será aplicado em todas as actions @Override public void loadFilters() { filter(new SomeGlobalFilter()); }
Exemplo básico:
import org.mentawai.core.*; import java.util.*; public class CacheFilter implements Filter { private static final String KEY = "cache"; @Override public String filter(InvocationChain chain) throws Exception { Action action = chain.getAction(); Context application = action.getApplication(); Map<String, Object> cache = (Map<String, Object>) application.getAttribute(KEY); if (cache != null) { Input input = action.getInput(); input.setValue(KEY, cache); } return chain.invoke(); // próximo filtro na cadeia ou a action } @Override public void destroy() { } }
Um filtro simples de autenticação
DICA: Você não precisa codificar o seu próprio filtro de autenticação porque o Mentawai já vem de fábrica com um filtro completo para isso!
import org.mentawai.core.*; public class AuthenticationFilter implements Filter { public static final String LOGIN = "login"; @Override public String filter(InvocationChain chain) throws Exception { Action action = chain.getAction(); Context session = action.getSession(); if (session.hasAttribute("user")) { return chain.invoke(); } return LOGIN; } @Override public void destroy() { } }
Modificando uma action antes e após a sua execução:
import org.mentawai.core.*; import java.util.Date; public class TimerFilter implements Filter { @Override public String filter(InvocationChain chain) throws Exception { Action action = chain.getAction(); Output output = action.getOutput(); output.setValue("timeBefore", new Date()); // antes da action ser executada long now = System.currentTimeMillis(); String result = chain.invoke(); // action será eventualmente executada aqui (depois de todos os filtros da cadeia) long totalTime = System.currentTimeMillis() - now; output.setValue("timeAfter", new Date()); // depois da action ser executada output.setValue("totalTime", totalTime); return result; } @Override public void destroy() { } }
Interceptando a action depois que a consequência foi executada:
package examples.helloworld.filter; import org.mentawai.core.*; import java.util.Date; public class TimerFilter implements AfterConsequenceFilter { @Override public String filter(InvocationChain chain) throws Exception { Action action = chain.getAction(); Output output = action.getOutput(); output.setValue("timeBefore", new Date().toString()); // antes da action ser executada long now = System.currentTimeMillis(); String result = chain.invoke(); long totalTime = System.currentTimeMillis() - now; output.setValue("timeAfter", new Date().toString()); // depois da action ser executada output.setValue("totalTime", totalTime); // seta o tempo inicial que será pega depois da consequência ser executada Input input = action.getInput(); input.setValue("initialTime", System.currentTimeMillis()); return result; } @Override public void afterConsequence(Action action, Consequence c, boolean conseqExecuted, boolean actionExecuted, String result) { // Nota: Vc deve entender que depois que a consequencia foi executada o response já foi enviado para o cliente, ou seja, // já é tarde para incluir qualquer coisa no output da action. if (!conseqExecuted) { System.out.println("There was an error executing the consequence!"); } else { Input input = action.getInput(); Long initialTime = (Long) input.getValue("initialTime"); long totalTime = System.currentTimeMillis() - initialTime.longValue(); System.out.println("The total time for the consequence was: " + totalTime); } } @Override public void destroy() { } }