1 /*
2 * The Apache Software License, Version 1.1
3 *
4 * Copyright (c) 1999 The Apache Software Foundation. All rights
5 * reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. The end-user documentation included with the redistribution, if
20 * any, must include the following acknowlegement:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowlegement may appear in the software itself,
24 * if and wherever such third-party acknowlegements normally appear.
25 *
26 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
27 * Foundation" must not be used to endorse or promote products derived
28 * from this software without prior written permission. For written
29 * permission, please contact apache@apache.org.
30 *
31 * 5. Products derived from this software may not be called "Apache"
32 * nor may "Apache" appear in their names without prior written
33 * permission of the Apache Group.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
53 *
54 */
55
56 package org.apache.commons.jelly.tags.sql;
57
58 import java.sql.*;
59 import java.util.*;
60 import javax.sql.DataSource;
61 import javax.naming.InitialContext;
62 import javax.naming.Context;
63 import javax.naming.NamingException;
64
65 import org.apache.commons.jelly.JellyContext;
66 import org.apache.commons.jelly.JellyException;
67 import org.apache.commons.jelly.TagSupport;
68 import org.apache.commons.jelly.XMLOutput;
69 import org.apache.commons.jelly.tags.Resources;
70
71 /***
72 * <p>Tag handler for <Transaction> in JSTL.
73 *
74 * @author Hans Bergsten
75 */
76
77 public class TransactionTag extends TagSupport {
78
79 //**********************************************************************
80 // Private constants
81
82 private static final String TRANSACTION_READ_COMMITTED = "read_committed";
83 private static final String TRANSACTION_READ_UNCOMMITTED = "read_uncommitted";
84 private static final String TRANSACTION_REPEATABLE_READ = "repeatable_read";
85 private static final String TRANSACTION_SERIALIZABLE = "serializable";
86
87 //*********************************************************************
88 // Protected state
89
90 protected Object rawDataSource;
91 protected boolean dataSourceSpecified;
92
93 //*********************************************************************
94 // Private state
95
96 private Connection conn;
97 private int isolation = Connection.TRANSACTION_NONE;
98 private int origIsolation;
99
100 //*********************************************************************
101 // Constructor and initialization
102
103 public TransactionTag() {
104 }
105
106 /**
107 * Sets the SQL DataSource. DataSource can be
108 * a String or a DataSource object.
109 */
110 public void setDataSource(Object dataSource) {
111 this.rawDataSource = dataSource;
112 this.dataSourceSpecified = true;
113 }
114
115
116 //**********************************************************************
117 // Tag logic
118
119 /**
120 * Prepares for execution by setting the initial state, such as
121 * getting the <code>Connection</code> and preparing it for
122 * the transaction.
123 */
124 public void doTag(XMLOutput output) throws Exception {
125
126 if ((rawDataSource == null) && dataSourceSpecified) {
127 throw new JellyException(Resources.getMessage("SQL_DATASOURCE_NULL"));
128 }
129
130 DataSource dataSource = DataSourceUtil.getDataSource(rawDataSource, context);
131
132 try {
133 conn = dataSource.getConnection();
134 origIsolation = conn.getTransactionIsolation();
135 if (origIsolation == Connection.TRANSACTION_NONE) {
136 throw new JellyException(Resources.getMessage("TRANSACTION_NO_SUPPORT"));
137 }
138 if ((isolation != Connection.TRANSACTION_NONE)
139 && (isolation != origIsolation)) {
140 conn.setTransactionIsolation(isolation);
141 }
142 conn.setAutoCommit(false);
143 }
144 catch (SQLException e) {
145 throw new JellyException(
146 Resources.getMessage("ERROR_GET_CONNECTION", e.getMessage()));
147 }
148
149 boolean finished = false;
150 try {
151 invokeBody(output);
152 finished = true;
153 }
154 catch (Exception e) {
155 if (conn != null) {
156 try {
157 conn.rollback();
158 }
159 catch (SQLException s) {
160 // Ignore to not hide orignal exception
161 }
162 doFinally();
163 }
164 throw e;
165 }
166
167 // lets commit
168 try {
169 conn.commit();
170 }
171 catch (SQLException e) {
172 throw new JellyException(
173 Resources.getMessage("TRANSACTION_COMMIT_ERROR", e.getMessage()));
174 }
175 finally {
176 doFinally();
177 }
178 }
179
180 //**********************************************************************
181 // Public utility methods
182
183 /**
184 * Sets the transaction isolation level.
185 */
186 public void setIsolation(String iso) throws JellyException {
187
188 if (TRANSACTION_READ_COMMITTED.equals(iso)) {
189 isolation = Connection.TRANSACTION_READ_COMMITTED;
190 }
191 else if (TRANSACTION_READ_UNCOMMITTED.equals(iso)) {
192 isolation = Connection.TRANSACTION_READ_UNCOMMITTED;
193 }
194 else if (TRANSACTION_REPEATABLE_READ.equals(iso)) {
195 isolation = Connection.TRANSACTION_REPEATABLE_READ;
196 }
197 else if (TRANSACTION_SERIALIZABLE.equals(iso)) {
198 isolation = Connection.TRANSACTION_SERIALIZABLE;
199 }
200 else {
201 throw new JellyException(Resources.getMessage("TRANSACTION_INVALID_ISOLATION"));
202 }
203 }
204
205 /***
206 * Called by nested parameter elements to get a reference to
207 * the Connection.
208 */
209 public Connection getSharedConnection() {
210 return conn;
211 }
212
213 //**********************************************************************
214 // Implementation methods methods
215
216 /**
217 * Restores the <code>Connection</code> to its initial state and
218 * closes it.
219 */
220 protected void doFinally() {
221 if (conn != null) {
222 try {
223 if ((isolation != Connection.TRANSACTION_NONE)
224 && (isolation != origIsolation)) {
225 conn.setTransactionIsolation(origIsolation);
226 }
227 conn.setAutoCommit(true);
228 conn.close();
229 }
230 catch (SQLException e) {
231 // Not much we can do
232 }
233 }
234 conn = null;
235 }
236
237 }
This page was automatically generated by Maven