/* * * Copyright (c) 2013 - 2014 INT - National Institute of Technology & COPPE - Alberto Luiz Coimbra Institute - Graduate School and Research in Engineering. * See the file license.txt for copyright permission. * */ package service.controleTransacao; import java.lang.reflect.Method; import DAO.exception.InfraestruturaException; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import service.anotacao.Transacional; import util.JPAUtil; public class InterceptadorDeAppService implements MethodInterceptor { /* Observe que o m�todo intercept() s� iniciar� uma transa��o se * o m�todo original contiver a anota��o "@Transacional". O * m�todo isTransacional � respons�vel por identificar os * m�todos que s�o transacionais, isto �, os m�todos que cont�m * a anota��o "@Transacional". * * Observe tamb�m que o EntityManager � sempre fechado. */ /* Parametros: * * objeto - "this", o objeto "enhanced", isto �, o proxy. * * metodo - o m�todo interceptado, isto �, um m�todo da classe * ProdutoAppService ou LanceAppService. * * args - um array de args; tipos primitivos s�o empacotados. * Cont�m os argumentos que o m�todo interceptado * recebeu. * * metodoProxy - utilizado para executar um m�todo super. Veja o * coment�rio abaixo. * * MethodProxy - Classes geradas pela classe Enhancer passam * este objeto para o objeto MethodInterceptor registrado quando * um m�todo interceptado � executado. Ele pode ser utilizado * para invocar o m�todo original, ou chamar o mesmo m�todo * sobre um objeto diferente do mesmo tipo. * */ public Object intercept (Object objeto, Method metodo, Object[] args, MethodProxy metodoProxy) throws Throwable { try { Object resultado = null; if (isTransacional(metodo)) { JPAUtil.beginTransaction (); resultado = metodoProxy.invokeSuper(objeto, args); JPAUtil.commitTransaction (); } else { resultado = metodoProxy.invokeSuper(objeto, args); } return resultado; } catch(RuntimeException e) { try { JPAUtil.rollbackTransaction(); } catch(InfraestruturaException ie) { } throw e; } catch(Exception e) { if (isTransacional(metodo)) { if(efetuarRollback(e)) { JPAUtil.rollbackTransaction(); } else { JPAUtil.commitTransaction(); } } throw e; } finally { JPAUtil.closeEntityManager(); } } /** * m�todo que � responsavel por verificar se o metodo passado como parametro � transacional ou nao * * @param metodo * @return * @throws Exception */ public boolean isTransacional(Method metodo) throws Exception { return metodo.isAnnotationPresent(Transacional.class); } public boolean efetuarRollback(Exception e) { if(e.getClass().isAnnotationPresent(ExcecaoDeAplicacao.class)) { return e.getClass().getAnnotation(ExcecaoDeAplicacao.class).rollback(); } else { return true; } } }