EMMA Coverage Report (generated Sat Nov 03 21:53:04 GMT 2007)
[all classes][sf.qof.session]

COVERAGE SUMMARY FOR SOURCE FILE [BaseSessionRunner.java]

nameclass, %method, %block, %line, %
BaseSessionRunner.java100% (1/1)100% (3/3)97%  (64/66)91%  (20/22)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BaseSessionRunner100% (1/1)100% (3/3)97%  (64/66)91%  (20/22)
execute (Object []): Object 100% (1/1)96%  (53/55)88%  (15/17)
BaseSessionRunner (): void 100% (1/1)100% (4/4)100% (2/2)
BaseSessionRunner (String): void 100% (1/1)100% (7/7)100% (3/3)

1/*
2 * Copyright 2007 brunella ltd
3 *
4 * Licensed under the LGPL Version 3 (the "License");
5 * you may not use this file except in compliance with the License.
6 *
7 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
8 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
11 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
12 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
13 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
14 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
15 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
16 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
17 * THE POSSIBILITY OF SUCH DAMAGE.
18 */
19package sf.qof.session;
20 
21import java.sql.Connection;
22import java.sql.SQLException;
23 
24/**
25 * Abstract base class for implementing a <code>SessionRunner</code>.
26 * 
27 * <p>Implements the <code>execute</code> method that has the following
28 * behaviour: 
29 * <br>Start a new session, start a new transaction and call
30 * <code>run</code>. If no exception occured and the transaction is not 
31 * in rollback only state then commit the transaction, stop the session
32 * and return the result of <code>run</code>. Otherwise rollback the 
33 * transaction, stop the session and re-throw the exception wrapped
34 * in a <code>SystemException</code>.</p>
35 * 
36 * <p><code>BaseSessionRunner</code> is used by default implementations
37 * of <code>SessionRunner</code> that use a <code>TransactionRunnable</code>
38 * to execute queries but it can also be used directly:</p>
39 * 
40 * <p><blockquote><pre>
41 * String result = new BaseSessionRunner&lt;String&gt;("MY_CONTEXT_NAME") {
42 *   protected String run(Connection connection, Object... arguments) throws SQLException {
43 *     PreparedStatement ps = connection.prepareStatement("select name from person where id = ?");
44 *     String result = null;
45 *     try {
46 *       ps.setInt(1, (Integer)arguments[0]);
47 *       ResultSet rs = ps.executeQuery();
48 *       if (rs.next()) {
49 *         result = rs.getString(1);
50 *       }
51 *       rs.close();
52 *     } finally {
53 *       ps.close();
54 *     }
55 *     return result;
56 *   }
57 * }.execute(55);
58 * </pre></blockquote></p>
59 *
60 * @param <T> the type of the result of the <code>run</code> method.
61 */
62public abstract class BaseSessionRunner<T> implements SessionRunner<T> {
63 
64  /**
65   * Holds the current session context.
66   */
67  protected SessionContext sessionContext;
68 
69  /**
70   * Creates a <code>BaseSessionRunner</code> that creates a session
71   * from the default session context.
72   *
73   */
74  public BaseSessionRunner() {
75        this(SessionContext.DEFAULT_CONTEXT_NAME);
76  }
77 
78  /**
79   * Creates a <code>BaseSessionRunner</code> that creates a session
80   * from the session context with the given name.
81   * 
82   * @param contextName the context name
83   */
84  public BaseSessionRunner(String contextName) {
85        sessionContext = SessionContextFactory.getContext(contextName);
86  }
87 
88  /**
89    * @see SessionRunner#execute(Object[])
90    */
91  public T execute(Object... arguments) throws SystemException {
92        T result;
93        sessionContext.startSession();
94        try {
95          sessionContext.getUserTransaction().begin();
96          try {
97                result = run(sessionContext.getConnection(), arguments);
98          } catch (Throwable e) {
99                try {
100                  sessionContext.getUserTransaction().rollback();
101                } catch (SystemException se) {
102                  // ignore - nothing we can do about
103                }
104                throw new SystemException(e);
105          }
106          if (sessionContext.getUserTransaction().isRollbackOnly()) {
107                sessionContext.getUserTransaction().rollback();
108          } else {
109                try {
110                  sessionContext.getUserTransaction().commit();
111                } catch (RollbackException re) {
112                  // can't happen
113                }
114          }
115        } finally {
116          sessionContext.stopSession();
117        }
118        return result;
119  }
120  
121  /**
122   * This method is called once during the call to <code>execute</code>.
123   * It must be overridden and should contain the code that needs to be
124   * run in a transaction context.
125   * 
126   * @param connection     the thread's current database connection 
127   * @param arguments      arguments passed to the <code>execute</code> method 
128   * @return               a result
129   * @throws SQLException  throw this if an error occured. This will cause a rollback
130   *                       of the current transaction.
131   */
132  protected abstract T run(Connection connection, Object... arguments) throws SQLException;
133}

[all classes][sf.qof.session]
EMMA 2.0.5312 (C) Vladimir Roubtsov