/*
* Created on 13 juin 2004
*
*
*
*/
package fr.mch.mdo.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.Session;
import org.hibernate.Transaction;
import fr.mch.mdo.logs.ILogger;
import fr.mch.mdo.restaurant.dao.hibernate.DefaultSessionFactory;
import fr.mch.mdo.restaurant.exception.MdoDataBeanException;
import fr.mch.mdo.restaurant.services.business.managers.IMdoManager;
import fr.mch.mdo.restaurant.services.logs.LoggerServiceImpl;
/**
* @author Mathieu MA
*
* To change the template for this generated type comment go to Window -
* Preferences - Java - Code Generation - Code and Comments
*/
//@Aspect("percflow(bussinessMethod())")
@Aspect()
public class AspectTransaction
{
private ILogger logger = LoggerServiceImpl.getInstance().getLogger(AspectTransaction.class.getName());
private Session session;
public AspectTransaction() {
// logger.debug("New Instance of AspectTransaction==>" + this);
// try {
// session = DefaultSessionFactory.getInstance().currentSession();
// } catch (MdoDataBeanException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
@Pointcut("call(* fr.mch.mdo.restaurant.services.business.managers.*+.*(..) throws fr.mch.mdo.restaurant.exception.MdoException+)")
public void bussinessMethod() {
}
/**
* In some cases aspect can process twice.
* This happens if code inside the package itself calls a public method of the package.
* In that case this code will process at both the outermost call into the package and the re-entrant call.
* The !this() pointcut can be used in a nice way to exclude these re-entrant calls.
*
* @param pjp
* @param manager
* @return
* @throws Throwable
*/
@Around("bussinessMethod() && target(manager) && !this(fr.mch.mdo.restaurant.services.business.managers.IMdoManager)")
public Object aroundBussinessMethod(ProceedingJoinPoint pjp, IMdoManager manager) throws Throwable {
logger.debug("START AOP aroundTransaction with " + manager + " == " + pjp.getSignature());
Object result = null;
// The true parameter value is used to specify that we are in service layer transaction
// Session session = (Session) manager.getDao().getCurrentSession();
session = DefaultSessionFactory.getInstance().currentSession();
logger.debug("AOP aroundTransaction Hibernate session " + session);
Transaction t = session.beginTransaction();
logger.debug("AOP aroundTransaction Hibernate Transaction " + t);
try {
t.begin();
logger.debug("AOP aroundTransaction before proceed ");
result = pjp.proceed();
logger.debug("AOP aroundTransaction after proceed ");
// The commit from this session(Hibernate.currentSession) is auto close
t.commit();
} catch (Throwable e) {
t.rollback();
logger.error("message.error.dao.aop.around.transaction", e);
throw e;
} finally {
try {
// The true parameter value is used to specify that we want to force to close because we are in service layer transaction
//manager.getDao().closeSession();
if (session.isOpen()) {
session.close();
}
} catch (Exception e) {
logger.error("message.error.dao.session.close", e);
}
}
logger.debug("END AOP aroundTransaction with " + manager + " == " + pjp.getSignature());
return result;
}
@Pointcut("execution(org.hibernate.Session fr.mch.mdo.restaurant.dao.hibernate.MdoDaoBase.getCurrentSession())")
public void getSession() {
}
/**
*
* @param pjp
* @return
*/
@Around("getSession()")
public Session aroundGetSession(ProceedingJoinPoint pjp) {
// Do not call pjp.proceed() just return the session of this aspect
return session;
}
@Pointcut("call(* *.closeSession()) && within(fr.mch.mdo.aop.AspectTransaction)")
public void closeSessionCall() {
}
@Around("closeSessionCall()")
public void aroundCloseSessionCall(ProceedingJoinPoint pjp) throws Throwable {
logger.debug("START AOP aroundCloseSessionCall");
// Call proceed method in this around advice
// Because we want to call closeSession only on aroundBussinessMethod advice
logger.debug("END AOP aroundCloseSessionCall");
}
@Pointcut("execution(protected void fr.mch.mdo.restaurant.dao.hibernate.MdoDaoBase.closeSession())")
public void closeSessionExecution() {
}
@Around("closeSessionExecution() && !cflow(closeSessionCall())")
public void aroundCloseSessionExecution(ProceedingJoinPoint pjp) {
logger.debug("START AOP aroundCloseSessionExecution");
// Do not call proceed method in this around advice
// Because we want to call closeSession only on aroundBussinessMethod advice
// try {
// pjp.proceed();
// } catch (Throwable e) {
// logger.error("message.error.dao.aop.around.close.session", e);
// }
logger.debug("END AOP aroundCloseSessionExecution");
}
@Pointcut("execution(* fr.mch.mdo.restaurant.dao.hibernate.MdoDaoBase.endTransaction(..))")
public void endTransaction() {
}
@Around("endTransaction()")
public void aroundEndTransaction(ProceedingJoinPoint pjp) {
logger.debug("START AOP aroundEndTransaction");
// Do not call proceed method in this around advice
// try {
// pjp.proceed();
// } catch (Throwable e) {
// logger.error("message.error.dao.aop.around.close.session", e);
// }
logger.debug("END AOP aroundEndTransaction");
}
}