Java tutorial
/* * Copyright (c) 2008-2011, Martijn Brinkers, Djigzo. * * This file is part of Djigzo email encryption. * * Djigzo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License * version 3, 19 November 2007 as published by the Free Software * Foundation. * * Djigzo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with Djigzo. If not, see <http://www.gnu.org/licenses/> * * Additional permission under GNU AGPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, * wsdl4j-1.6.1.jar (or modified versions of these libraries), * containing parts covered by the terms of Eclipse Public License, * tyrex license, freemarker license, dom4j license, mx4j license, * Spice Software License, Common Development and Distribution License * (CDDL), Common Public License (CPL) the licensors of this Program grant * you additional permission to convey the resulting work. */ package mitm.common.hibernate; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import javassist.util.proxy.RuntimeSupport; import mitm.common.hibernate.annotations.InjectHibernateSession; import mitm.common.hibernate.annotations.InjectHibernateSessionSource; import mitm.common.reflection.BasicProxyFactory; import mitm.common.reflection.ProxyFactoryException; import mitm.common.reflection.ProxyMethodHandler; import mitm.common.reflection.ReflectionUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.hibernate.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class InjectSessionProxyFactory<T> extends BasicProxyFactory<T> { private static final Logger logger = LoggerFactory.getLogger(AutoCommitProxyFactory.class); private final HibernateSessionSource sessionSource; private Method injectHibernateSessionMethod; private Method injectHibernateSessionSourceMethod; class InjectSessionMethodHandler implements ProxyMethodHandler { @Override public Object invoke(Object self, Method method, Method proceed, Object[] args) throws Throwable { if (logger.isDebugEnabled()) { String methodDescriptor = ReflectionUtils.createMethodDescriptor(method); logger.debug("invoking '" + methodDescriptor + "'"); } boolean sessionInjected = false; try { /* only inject for protected and public methods */ if (!Modifier.isPrivate(method.getModifiers())) { Session activeSession = sessionSource.getSession(); // inject the session injectHibernateSessionMethod.invoke(self, new Object[] { activeSession }); sessionInjected = true; } /* execute the real method */ Object result = proceed.invoke(self, args); return result; } catch (Exception e) { logger.debug("Exception in invoke.", e); /* * A checked exception gets wrapped in an InvocationTargetException. We want to throw the * cause exception so we need to get the cause. */ if (e instanceof InvocationTargetException) { /* try to re-throw the source exception. */ Throwable cause = ExceptionUtils.getCause(e); if (cause != null) { throw cause; } } throw e; } finally { /* clear the session */ try { if (sessionInjected) { injectHibernateSessionMethod.invoke(self, new Object[] { null }); } } catch (Exception e) { logger.error("Exception while clearing the session.", e); } } } } public InjectSessionProxyFactory(Class<T> clazz, HibernateSessionSource sessionSource) throws NoSuchMethodException { super(clazz); this.sessionSource = sessionSource; findInjectMethods(clazz); if (injectHibernateSessionMethod == null) { throw new NoSuchMethodException("@InjectHibernateSession annotation was not found."); } this.setMethodHandler(new InjectSessionMethodHandler()); } @Override protected void postConstruction(T newInstance) throws ProxyFactoryException { /* inject the session source */ if (injectHibernateSessionSourceMethod != null) { try { injectHibernateSessionSourceMethod.invoke(newInstance, new Object[] { sessionSource }); } catch (IllegalArgumentException e) { throw new ProxyFactoryException(e); } catch (IllegalAccessException e) { throw new ProxyFactoryException(e); } catch (InvocationTargetException e) { throw new ProxyFactoryException(e); } } } /* * Searched the annotations for a method with the @InjectHibernateSession annotations and * checks if that method has the parameter signature (org.hibernate.Session session) */ private void findInjectMethods(Class<T> clazz) throws NoSuchMethodException { Method[] methods = clazz.getMethods(); for (Method method : methods) { if (method.isAnnotationPresent(InjectHibernateSession.class)) { String parameterDescriptor = RuntimeSupport.makeDescriptor(method); if (!parameterDescriptor.equals("(Lorg/hibernate/Session;)V")) { throw new NoSuchMethodException( "@InjectHibernateSession method does not have the correct parameters."); } injectHibernateSessionMethod = method; } else if (method.isAnnotationPresent(InjectHibernateSessionSource.class)) { String parameterDescriptor = RuntimeSupport.makeDescriptor(method); if (!parameterDescriptor.equals("(Lmitm/common/hibernate/HibernateSessionSource;)V")) { throw new NoSuchMethodException( "@InjectHibernateSessionSource method does not have the correct parameters."); } injectHibernateSessionSourceMethod = method; } } } }