/* * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * matic */ package org.eclipse.ecr.runtime.transaction; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Start a user transaction if method or class is annotated for and if there is no * transaction active * * @author matic * * @param <T> */ public class TransactedInstanceHandler<T> implements InvocationHandler{ protected final T object; public static <T> T newProxy(T object, Class<T> itf) { InvocationHandler h = new TransactedInstanceHandler<T>(object); return itf.cast(Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { itf }, h)); } protected TransactedInstanceHandler(T object) { this.object = object; } protected boolean requireTransaction(Method m) { if (!m.isAnnotationPresent(Transacted.class) && !m.getClass().isAnnotationPresent(Transacted.class)) { return false; } return !TransactionHelper.isTransactionActive(); } protected Object doInvoke(Method m, Object[] args) throws Throwable { try { return m.invoke(object, args); } catch (InvocationTargetException e) { throw e.getCause(); } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (!requireTransaction(method)) { return doInvoke(method, args); } TransactionHelper.startTransaction(); try { return doInvoke(method, args); } catch (Throwable e) { TransactionHelper.setTransactionRollbackOnly(); throw e; } finally { TransactionHelper.commitOrRollbackTransaction(); } } }