View Javadoc

1   package com.atlassian.xwork.interceptors;
2   
3   import com.opensymphony.xwork.ActionInvocation;
4   import com.opensymphony.xwork.interceptor.Interceptor;
5   import com.opensymphony.xwork.interceptor.PreResultListener;
6   import org.apache.log4j.Logger;
7   import org.springframework.transaction.PlatformTransactionManager;
8   import org.springframework.transaction.TransactionStatus;
9   
10  /**
11   * Manages two separate database transactions around the action execution and result execution
12   * in XWork, using the Spring PlatformTransactionManager.
13   * <p/>
14   * The first transaction begins as soon as this interceptor executes. It is committed in a {@link
15   * PreResultListener} which runs just before the result executes. The second transaction is opened
16   * in the same listener. The second transaction is committed when control returns to the interceptor
17   * after the action and result executions are both complete.
18   * <p/>
19   * The active transaction will be rolled back if an exception is caught by this interceptor during
20   * the execution of either the action or the result.
21   * <p/>
22   * Implementations should override {@link #getTransactionManager()} to provide the Spring transaction
23   * manager, and {@link #shouldIntercept(ActionInvocation)} to configure when transactions should be
24   * applied to actions.
25   */
26  public abstract class XWorkTransactionInterceptor implements Interceptor
27  {
28      /**
29       * Template method for retrieving the transaction manager for the current application.
30       *
31       * @return the transaction manager for this application
32       */
33      public abstract PlatformTransactionManager getTransactionManager();
34  
35      /**
36       * Determine if a certain action should be wrapped in a transaction. Applications should override this method
37       * if they want to prevent specific actions from being intercepted, or want to prevent transactions from being
38       * created before the system is fully set up.
39       *
40       * @param invocation the action being invoked
41       * @return true if the action should be wrapped in a transaction
42       */
43      protected abstract boolean shouldIntercept(ActionInvocation invocation);
44  
45      public void destroy()
46      {
47      }
48  
49      public void init()
50      {
51      }
52  
53      public String intercept(final ActionInvocation invocation) throws Exception
54      {
55          if (shouldIntercept(invocation))
56              return new TransactionalInvocation(getTransactionManager()).invokeInTransaction(invocation);
57          else
58              return invocation.invoke();
59      }
60  
61      /**
62       * Return the transaction status of the current method invocation.
63       * Mainly intended for code that wants to set the current transaction
64       * rollback-only but not throw an application exception.
65       *
66       * @throws RuntimeException
67       *          if the invocation cannot be found, because the method was invoked
68       *          outside an AOP invocation context
69       * @return the status of the current transaction
70       * @deprecated since atlassian-xwork 1.1 - you should really use Spring directly for this sort of thing
71       */
72      public static TransactionStatus currentTransactionStatus() throws RuntimeException
73      {
74          TransactionStatus status = (TransactionStatus) TransactionalInvocation.currentTransactionThreadLocal.get();
75          if (status == null)
76              throw new RuntimeException("No transaction status in scope");
77          return status;
78      }
79  
80  }